diff options
author | Christoph Hellwig <hch@lst.de> | 2009-01-24 15:08:50 +0100 |
---|---|---|
committer | Christoph Hellwig <hch@brick.lst.de> | 2009-01-24 15:08:50 +0100 |
commit | 116ac9f29b9daa1a83e7d2620205102434304c1c (patch) | |
tree | bc4281e9352654d9a42f8406e1ca41864821d882 | |
parent | 9502587dbbfdd465958889a568dc2842f10b1ff9 (diff) | |
download | xfsdump-dev-116ac9f29b9daa1a83e7d2620205102434304c1c.tar.gz |
remove files moved over to xfsprogs
xfs_fsr has been moved to xfsprogs, so delete it from xfsdump. Also
remove the xfs_estimate manpage which now has followed the xfs_estimate
tool.
Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | fsr/Makefile | 19 | ||||
-rw-r--r-- | fsr/xfs_fsr.c | 1601 | ||||
-rw-r--r-- | man/man8/xfs_estimate.8 | 104 | ||||
-rw-r--r-- | man/man8/xfs_fsr.8 | 171 | ||||
-rw-r--r-- | po/Makefile | 1 |
6 files changed, 2 insertions, 1898 deletions
@@ -16,7 +16,7 @@ LDIRT = config.log .dep config.status config.cache confdefs.h conftest* \ Logs/* built .census install.* install-dev.* *.gz LIB_SUBDIRS = include librmt -TOOL_SUBDIRS = common fsr inventory invutil dump restore \ +TOOL_SUBDIRS = common inventory invutil dump restore \ m4 man doc po debian build SUBDIRS = $(LIB_SUBDIRS) $(TOOL_SUBDIRS) @@ -29,7 +29,7 @@ else endif # tool/lib dependencies -fsr invutil dump restore: librmt +invutil dump restore: librmt ifeq ($(HAVE_BUILDDEFS), yes) include $(BUILDRULES) diff --git a/fsr/Makefile b/fsr/Makefile deleted file mode 100644 index 6b252765..00000000 --- a/fsr/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved. -# - -TOPDIR = .. -include $(TOPDIR)/include/builddefs - -LTCOMMAND = xfs_fsr -CFILES = xfs_fsr.c -LLDLIBS = $(LIBHANDLE) $(LIBATTR) - -default: $(LTCOMMAND) - -include $(BUILDRULES) - -install: default - $(INSTALL) -m 755 -d $(PKG_BIN_DIR) - $(LTINSTALL) -m 755 $(LTCOMMAND) $(PKG_BIN_DIR) -install-dev: diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c deleted file mode 100644 index c5cf0d52..00000000 --- a/fsr/xfs_fsr.c +++ /dev/null @@ -1,1601 +0,0 @@ -/* - * 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 <xfs/xfs.h> -#include <xfs/jdm.h> -#include "config.h" - -#include <fcntl.h> -#include <errno.h> -#include <malloc.h> -#include <mntent.h> -#include <syslog.h> -#include <signal.h> -#include <sys/ioctl.h> -#include <sys/wait.h> -#include <sys/vfs.h> -#include <sys/statvfs.h> -#include <attr/attributes.h> -#include <xfs/xfs_dfrag.h> - - -#ifndef XFS_XFLAG_NODEFRAG -#define XFS_XFLAG_NODEFRAG 0x00002000 /* src dependancy, remove later */ -#endif - -#define _PATH_FSRLAST "/var/tmp/.fsrlast_xfs" - -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 char *mtab = MOUNTED; -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(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 * ); -static int getmntany(FILE *, struct mntent *, struct mntent *, struct stat64 *); - -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 = 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 = 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); -} - -int -main(int argc, char **argv) -{ - struct stat64 sb, sb2; - char *argname; - char *cp; - int c; - struct mntent mntpref; - register struct mntent *mntp; - struct mntent ment; - register FILE *mtabp; - - 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 (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]; - mntp = NULL; - 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) && stat64(argname, &sb2) == 0 && - (S_ISBLK(sb2.st_mode) || S_ISCHR(sb2.st_mode))) - sb = sb2; - if (S_ISBLK(sb.st_mode) || (S_ISDIR(sb.st_mode))) { - if ((mtabp = setmntent(mtab, "r")) == NULL) { - fprintf(stderr, - _("%s: cannot read %s\n"), - progname, mtab); - exit(1); - } - bzero(&mntpref, sizeof(mntpref)); - if (S_ISDIR(sb.st_mode)) - mntpref.mnt_dir = argname; - else - mntpref.mnt_fsname = argname; - - if (getmntany(mtabp, &ment, &mntpref, &sb) && - strcmp(ment.mnt_type, MNTTYPE_XFS) == 0) { - mntp = &ment; - if (S_ISBLK(sb.st_mode)) { - cp = mntp->mnt_dir; - if (cp == NULL || - stat64(cp, &sb2) < 0) { - fprintf(stderr, _( - "%s: could not stat: %s: %s\n"), - progname, argname, - strerror(errno)); - continue; - } - sb = sb2; - argname = cp; - } - } - } - if (mntp != NULL) { - fsrfs(mntp->mnt_dir, 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(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(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 */ -} - - -/* - * 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 (statp->bs_xflags & XFS_XFLAG_HASATTR) { - if (attr_setf(tfd, "X", "X", 1, ATTR_CREATE) != 0) { - fsrprintf(_("could not set ATTR on tmp: %s:\n"), tname); - close(tfd); - return -1; - } - if (dflag) - fsrprintf(_("%s set temp attr\n"), tname); - } - - /* 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 = wc_b4; - 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; -} - -/* - * emulate getmntany - */ -static int -getmntany(FILE *fp, struct mntent *mp, struct mntent *mpref, struct stat64 *s) -{ - struct mntent *t; - struct stat64 ms; - - while ((t = getmntent(fp))) { - if (mpref->mnt_fsname) { /* device */ - if (stat64(t->mnt_fsname, &ms) < 0) - continue; - if (s->st_rdev != ms.st_rdev) - continue; - } - if (mpref->mnt_dir) { /* mount point */ - if (stat64(t->mnt_dir, &ms) < 0) - continue; - if (s->st_ino != ms.st_ino || s->st_dev != ms.st_dev) - continue; - } - *mp = *t; - break; - } - return (t != NULL); -} - - -/* - * 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, 0777) < 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)); - } - } -} diff --git a/man/man8/xfs_estimate.8 b/man/man8/xfs_estimate.8 deleted file mode 100644 index 70a2ac6c..00000000 --- a/man/man8/xfs_estimate.8 +++ /dev/null @@ -1,104 +0,0 @@ -.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 -.Ee diff --git a/man/man8/xfs_fsr.8 b/man/man8/xfs_fsr.8 deleted file mode 100644 index bf5e9425..00000000 --- a/man/man8/xfs_fsr.8 +++ /dev/null @@ -1,171 +0,0 @@ -.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. diff --git a/po/Makefile b/po/Makefile index 193ad2f5..07495a9d 100644 --- a/po/Makefile +++ b/po/Makefile @@ -31,7 +31,6 @@ XGETTEXTFILES = \ $(TOPDIR)/dump/content.c \ $(TOPDIR)/dump/inomap.c \ $(TOPDIR)/dump/var.c \ - $(TOPDIR)/fsr/xfs_fsr.c \ $(TOPDIR)/inventory/inv_api.c \ $(TOPDIR)/inventory/inv_core.c \ $(TOPDIR)/inventory/inv_fstab.c \ |