Merge of master-melb:xfs-cmds:26728a by kenmcd.
memset(&xargs, 0, sizeof(xargs));
xargs.notvolmsg = "oh no %s";
+ xargs.isdirect = LIBXFS_DIRECT;
xargs.isreadonly = LIBXFS_ISREADONLY;
xargs.notvolok = 1;
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 */
#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 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 char *libxfs_findrawpath(char *);
/* 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 *);
int
platform_aio_init(int aio_count)
{
- return (0); /* aio/lio_listio not available */
+ return 0; /* aio/lio_listio not available */
}
char *
platform_findrawpath(char *path)
{
- return (path);
+ return path;
}
-size_t
-platform_memalignment(void)
+char *
+platform_findblockpath(char *path)
+{
+ return path;
+}
+
+int
+platform_direct_blockdev(void)
+{
+ return 0;
+}
+
+int
+platform_align_blockdev(void)
{
- return sizeof(void *);
+ return (sizeof(void *));
}
int
platform_aio_init(int aio_count)
{
- return (0); /* aio/lio_listio not available */
+ return 0; /* aio/lio_listio not available */
}
char *
platform_findrawpath(char *path)
{
- return (path);
+ return path;
}
-size_t
-platform_memalignment(void)
+char *
+platform_findblockpath(char *path)
+{
+ return path;
+}
+
+int
+platform_direct_blockdev(void)
+{
+ return 0;
+}
+
+int
+platform_align_blockdev(void)
{
- return sizeof(void *);
+ return (sizeof(void *));
}
#include <sys/stat.h>
#include "init.h"
-#define findrawpath(x) x
-#define findblockpath(x) x
-
char *progname = "libxfs"; /* default, changed by each tool */
struct cache *libxfs_icache; /* global inode cache */
{
dev_t dev;
int fd, d, flags;
- int readonly, excl;
+ 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);
perror(path);
return 0;
}
- if (!(*rawfile = findrawpath(path))) {
+ if (!(*rawfile = platform_findrawpath(path))) {
fprintf(stderr, _("%s: "
"can't find a character device matching %s\n"),
progname, path);
return 0;
}
- if (!(*blockfile = findblockpath(path))) {
+ if (!(*blockfile = platform_findblockpath(path))) {
fprintf(stderr, _("%s: "
"can't find a block device matching %s\n"),
progname, path);
(void)getcwd(curdir,MAXPATHLEN);
needcd = 0;
fd = -1;
- flags = a->isreadonly;
+ flags = (a->isreadonly | a->isdirect);
if (a->volname) {
if(!check_open(a->volname,flags,&rawfile,&blockfile))
cache_destroy(libxfs_bcache);
}
+int
+libxfs_device_alignment(void)
+{
+ return platform_align_blockdev();
+}
+
void
libxfs_report(FILE *fp)
{
c = asctime(localtime(&t));
fprintf(fp, "%s", c);
}
-
-char *
-libxfs_findrawpath(char *path)
-{
- return platform_findrawpath(path);
-}
/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
+ * Copyright (c) 2000-2006 Silicon Graphics, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
extern void platform_set_blocksize (int fd, char *path, int blocksize);
extern void platform_flush_device (int fd, dev_t device);
extern char *platform_findrawpath(char *path);
-extern int platform_aio_init(int aio_count);
-extern size_t platform_memalignment(void);
+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_aio_init (int aio_count);
+
#endif /* LIBXFS_INIT_H */
return findrawpath(path);
}
-size_t
-platform_memalignment(void)
+char *
+platform_findblockpath(char *path)
+{
+ return findblockpath(path);
+}
+
+int
+platform_direct_blockdev(void)
+{
+ return 0;
+}
+
+int
+platform_align_blockdev(void)
{
- return sizeof(void *);
+ return (sizeof(void *));
}
#include <sys/ioctl.h>
extern char *progname;
+static int max_block_alignment;
#ifndef BLKGETSIZE64
# define BLKGETSIZE64 _IOR(0x12,114,size_t)
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;
}
progname, path, strerror(errno));
*bsz = BBSIZE;
}
+ if (*bsz > max_block_alignment)
+ max_block_alignment = *bsz;
}
int
char *
platform_findrawpath(char *path)
{
- return (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)
+ abort();
+ return max_block_alignment;
}
size_t
#define BDSTRAT_SIZE (256 * 1024)
#define min(x, y) ((x) < (y) ? (x) : (y))
-static inline void *
-libxfs_memalign(size_t size)
-{
- static size_t memalignment;
-
- if (!memalignment)
- memalignment = platform_memalignment();
- return memalign(memalignment, size);
-}
-
void
libxfs_device_zero(dev_t dev, xfs_daddr_t start, uint len)
{
int fd;
zsize = min(BDSTRAT_SIZE, BBTOB(len));
- if ((z = libxfs_memalign(zsize)) == NULL) {
+ 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));
bp->b_blkno = blkno;
bp->b_bcount = bytes;
bp->b_dev = device;
- if (!(bp->b_addr = libxfs_memalign(bytes))) {
+ bp->b_addr = memalign(libxfs_device_alignment(), bytes);
+ if (!bp->b_addr) {
fprintf(stderr,
_("%s: %s can't memalign %d bytes: %s\n"),
progname, __FUNCTION__, (int)bytes,
bzero(&xi, sizeof(xi));
xi.notvolok = 1;
xi.setblksize = 1;
+ xi.isdirect = LIBXFS_DIRECT;
xi.isreadonly = LIBXFS_EXCLUSIVELY;
while ((c = getopt(argc, argv, "b:d:i:l:L:n:Np:qr:s:CfV")) != EOF) {
$(TOPDIR)/repair/incore_ext.c \
$(TOPDIR)/repair/incore_ino.c \
$(TOPDIR)/repair/init.c \
- $(TOPDIR)/repair/io.c \
$(TOPDIR)/repair/phase1.c \
$(TOPDIR)/repair/phase2.c \
$(TOPDIR)/repair/phase3.c \
CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c dino_chunks.c \
dinode.c dir.c dir2.c dir_stack.c globals.c incore.c \
- incore_bmc.c init.c incore_ext.c incore_ino.c io.c phase1.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 rt.c sb.c \
prefetch.c scan.c versions.c xfs_repair.c
#define NUM_SBS 8 /* max # of sbs to verify */
#define NUM_AGH_SECTS 4 /* # of components in an ag header */
-#define MEM_ALIGN 128 /* I/O buf alignment - a cache line */
-
/*
* secondary sb mask -- if the secondary sb feature bits has a
* the partial sb mask bit set, then you depend on the fields
args->notvolok = 1;
args->setblksize = !dangerously;
+ args->isdirect = LIBXFS_DIRECT;
if (no_modify)
args->isreadonly = (LIBXFS_ISREADONLY | LIBXFS_ISINACTIVE);
else if (dangerously)
+++ /dev/null
-/*
- * 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 <libxfs.h>
-#include "globals.h"
-#include "agheader.h"
-#include "protos.h"
-#include "err_protos.h"
-
-void
-io_init(void)
-{
- /* open up filesystem device */
-
- ASSERT(fs_name != NULL && *fs_name != '\0');
-
- if ((fs_fd = open (fs_name, (no_modify? O_RDONLY : O_RDWR))) < 0) {
- do_error(_("couldn't open filesystem \"%s\"\n"), fs_name);
- }
-}
{
char *bp;
- bp = (char *)memalign(MEM_ALIGN, size);
+ bp = (char *)memalign(libxfs_device_alignment(), size);
if (!bp)
do_error(_("could not allocate ag header buffer (%d bytes)\n"),
size);
char *ag_bp;
int rval;
- io_init();
-
do_log(_("Phase 1 - find and verify superblock...\n"));
primary_sb_modified = 0;
*/
void xfs_init(libxfs_init_t *args);
-void io_init(void);
int verify_sb(xfs_sb_t *sb,
int is_primary_sb);
*/
#include <libxfs.h>
+#include <libxlog.h>
#include "agheader.h"
#include "globals.h"
#include "protos.h"
do_warn(_("\nattempting to find secondary superblock...\n"));
- sb = (xfs_sb_t *) memalign(MEM_ALIGN, BSIZE);
+ sb = (xfs_sb_t *)memalign(libxfs_device_alignment(), BSIZE);
if (!sb) {
do_error(
_("error finding secondary superblock -- failed to memalign buffer\n"));
/*
* read disk 1 MByte at a time.
*/
- if (lseek64(fs_fd, off, SEEK_SET) != off) {
+ if (lseek64(x.dfd, off, SEEK_SET) != off) {
done = 1;
}
- if (!done && (bsize = read(fs_fd, sb, BSIZE)) == 0) {
+ if (!done && (bsize = read(x.dfd, sb, BSIZE)) == 0) {
done = 1;
}
if (no_modify)
return;
- if ((buf = calloc(size, 1)) == NULL) {
- do_error(_("failed to malloc superblock buffer\n"));
+ if ((buf = memalign(libxfs_device_alignment(), size)) == NULL) {
+ do_error(_("failed to memalign superblock buffer\n"));
return;
}
+ memset(buf, 0, size);
- if (lseek64(fs_fd, 0LL, SEEK_SET) != 0LL) {
+ if (lseek64(x.dfd, 0LL, SEEK_SET) != 0LL) {
free(buf);
do_error(_("couldn't seek to offset 0 in filesystem\n"));
}
libxfs_xlate_sb(buf, sbp, -1, XFS_SB_ALL_BITS);
- if (write(fs_fd, buf, size) != size) {
+ if (write(x.dfd, buf, size) != size) {
free(buf);
do_error(_("primary superblock write failed!\n"));
}
int error, rval;
void *buf;
- if ((buf = calloc(size, 1)) == NULL) {
+ if ((buf = memalign(libxfs_device_alignment(), size)) == NULL) {
do_error(
- _("error reading superblock %u -- failed to malloc buffer\n"),
+ _("error reading superblock %u -- failed to memalign buffer\n"),
agno, off);
exit(1);
}
+ memset(buf, 0, size);
/* try and read it first */
- if (lseek64(fs_fd, off, SEEK_SET) != off) {
+ if (lseek64(x.dfd, off, SEEK_SET) != off) {
do_warn(
_("error reading superblock %u -- seek to offset %lld failed\n"),
agno, off);
return(XR_EOF);
}
- if ((rval = read(fs_fd, buf, size)) != size) {
+ if ((rval = read(x.dfd, buf, size)) != size) {
error = errno;
do_warn(
_("superblock read failed, offset %lld, size %d, ag %u, rval %d\n"),
- off, size, rval, agno);
+ off, size, agno, rval);
do_error("%s\n", strerror(error));
}
libxfs_xlate_sb(buf, sbp, 1, XFS_SB_ALL_BITS);
if ((fs_name = argv[optind]) == NULL)
usage();
-
- if (!isa_file) {
- if ((fs_name = libxfs_findrawpath(fs_name)) == NULL)
- do_error("couldn't find raw device for %s\n", fs_name);
- }
}
void