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 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 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; }
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%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") : "", file->flags & IO_TMPFILE ? _(",tmpfile") : ""); 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; }
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; }
int main(int argc, char **argv) { int fd, i; int64_t x[131072]; for (i = 0; i < 131072; i++) { x[i] = -1; } fd = open(argv[1], O_RDWR | O_CREAT, 0644); #ifdef WRITE f.l_whence = 0; f.l_start = 0; f.l_len = 1048576; xfsctl (argv[1], fd, XFS_IOC_RESVSP, &f); for (i = 0; i < 131072; i++) { x[i] = i; } write(fd, &x, 1048576); #endif #ifdef READ read(fd, &x, 1048576); for (i = 0; i < 131072; i++) { if (x[i] != i) { printf("error: %d %d %lld\n", i ,8 * i, (long long)x[i]); exit(1); } } #endif close(fd); exit(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 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; }
bool XfsPreallocate(int fd, Uint64 size) { if( ! platform_test_xfs_fd(fd) ) { return false; } xfs_flock64_t allocopt; allocopt.l_whence = 0; allocopt.l_start = 0; allocopt.l_len = size; return (! static_cast<bool>(xfsctl(0, fd, XFS_IOC_RESVSP64, &allocopt)) ); }
void fscounts(char *fname, int fsfd) { xfs_fsop_counts_t counts; int ret; ret=xfsctl(fname, fsfd, XFS_IOC_FSCOUNTS, &counts); if (ret) { perror("xfsctl(XFS_IOC_FSCOUNTS)"); exit(1); } printf("XFS_IOC_FSCOUNTS-\n freedata: %lld freertx: %lld freeino: %lld allocino: %lld\n", (long long)counts.freedata, (long long)counts.freertx, (long long)counts.freeino, (long long)counts.allocino); }
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; }
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; }
static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors) { struct xfs_flock64 fl; memset(&fl, 0, sizeof(fl)); fl.l_whence = SEEK_SET; fl.l_start = sector_num << 9; fl.l_len = (int64_t)nb_sectors << 9; if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) { DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno)); return -errno; } return 0; }
static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes) { struct xfs_flock64 fl; memset(&fl, 0, sizeof(fl)); fl.l_whence = SEEK_SET; fl.l_start = offset; fl.l_len = bytes; if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) { DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno)); return -errno; } return 0; }
__u64 getresblks(char *fname, int fsfd) { xfs_fsop_resblks_t res; int ret; ret=xfsctl(fname, fsfd, XFS_IOC_GET_RESBLKS, &res); if (ret) { perror("xfsctl(XFS_IOC_GET_RESBLKS)"); exit(1); } printf("XFS_IOC_GET_RESBLKS-\n resblks: %lld blksavail: %lld\n", (long long)res.resblks, (long long)res.resblks_avail); return res.resblks; }
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 preallocate_xfs(int fd, lock_type * fl) { /* IMPORTANT: We use RESVSP because we want the extents to be * allocated, but we don't want the allocation to show up in * st_size or persist after the close(2). */ #if defined(XFS_IOC_RESVSP64) /* On Linux this comes in via libxfs.h. */ return xfsctl(NULL, fd, XFS_IOC_RESVSP64, &fl); #elif defined(F_RESVSP64) /* On IRIX, this comes from fcntl.h. */ return fcntl(fd, F_RESVSP64, &fl); #else errno = ENOTSUP; return -1; #endif }
static int preallocate_space(int fd, SMB_OFF_T size) { int err; #ifndef HAVE_GPFS lock_type fl = {0}; if (size <= 0) { return 0; } fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = size; /* IMPORTANT: We use RESVSP because we want the extents to be * allocated, but we don't want the allocation to show up in * st_size or persist after the close(2). */ #if defined(XFS_IOC_RESVSP64) /* On Linux this comes in via libxfs.h. */ err = xfsctl(NULL, fd, XFS_IOC_RESVSP64, &fl); #elif defined(F_RESVSP64) /* On IRIX, this comes from fcntl.h. */ err = fcntl(fd, F_RESVSP64, &fl); #else err = -1; errno = ENOSYS; #endif #else /* GPFS uses completely different interface */ err = gpfs_prealloc(fd, (gpfs_off64_t)0, (gpfs_off64_t)size); #endif if (err) { DEBUG(module_debug, ("%s: preallocate failed on fd=%d size=%lld: %s\n", MODULE, fd, (long long)size, strerror(errno))); } return err; }
/* * 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; }
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; }
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); signal_maskfunc(SIGCHLD, SIG_BLOCK); /* 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 <<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); } } /* 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; }
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 bool preallocate_file_full (const char * filename, uint64_t length) { bool success = 0; #ifdef WIN32 HANDLE hFile = CreateFile (filename, GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0); if (hFile != INVALID_HANDLE_VALUE) { LARGE_INTEGER li; li.QuadPart = length; success = SetFilePointerEx (hFile, li, NULL, FILE_BEGIN) && SetEndOfFile (hFile); CloseHandle (hFile); } #else int flags = O_RDWR | O_CREAT | O_LARGEFILE; int fd = open (filename, flags, 0666); if (fd >= 0) { # ifdef HAVE_FALLOCATE64 if (!success) { success = !fallocate64 (fd, 0, 0, length); } # endif # ifdef HAVE_XFS_XFS_H if (!success && platform_test_xfs_fd (fd)) { xfs_flock64_t fl; fl.l_whence = 0; fl.l_start = 0; fl.l_len = length; success = !xfsctl (NULL, fd, XFS_IOC_RESVSP64, &fl); } # endif # ifdef SYS_DARWIN if (!success) { fstore_t fst; fst.fst_flags = F_ALLOCATECONTIG; fst.fst_posmode = F_PEOFPOSMODE; fst.fst_offset = 0; fst.fst_length = length; fst.fst_bytesalloc = 0; success = !fcntl (fd, F_PREALLOCATE, &fst); } # endif #undef HAVE_POSIX_FALLOCATE # ifdef HAVE_POSIX_FALLOCATE if (!success) { success = !posix_fallocate (fd, 0, length); } # endif #define MINSLEEP 3 #define MAXSLEEP 40000 #define INCRFACT 1.9 #define DECRFACT 3 #define BLCKSIZE 32768 #define TSTEVERYBYTES 524288 #define TSTEVERYBLKS TSTEVERYBYTES/BLCKSIZE if (!success) /* if nothing else works, do it the old-fashioned way */ { struct timeval lastTime, thisTime; // Set up buffer with 0s. unsigned int block_size = BLCKSIZE; uint8_t buf[ block_size ]; memset (buf, 0, sizeof (buf)); // Set up speed test counters. unsigned int testEveryBytes = TSTEVERYBYTES; unsigned int testEveryIters = TSTEVERYBLKS; unsigned int itersUntilTest = testEveryIters; long lastTook = 0; long currentTook = 0; gettimeofday(&lastTime, NULL); unsigned int sleep = MINSLEEP; unsigned int lastSlept = 0; unsigned int size=length; success = true; while (success && (length > 0)) { if (itersUntilTest == 0) { gettimeofday(&thisTime, NULL); currentTook = thisTime.tv_sec*1000000 + thisTime.tv_usec - lastTime.tv_sec*1000000 - lastTime.tv_usec - lastSlept; if (currentTook > lastTook) { sleep = MIN(sleep * INCRFACT, MAXSLEEP); } else if (currentTook < lastTook) { sleep = MAX(sleep / DECRFACT, MINSLEEP); } lastSlept = 0; lastTook = currentTook; lastTime = thisTime; itersUntilTest = testEveryIters; fprintf (stderr, "{\"TR_PREALLOC\":%d,\"filename\":\"%s\"}\n", (int)(100.f*(float)(size - length)/(float)size), filename); //fprintf (stderr, "Will sleep %d usec on every write.\n", sleep); } const int thisPass = MIN (length, sizeof (buf)); success = write (fd, buf, thisPass) == thisPass; length -= thisPass; --itersUntilTest; usleep(sleep); lastSlept = lastSlept + sleep; } } /* if (!success) // if nothing else works, do it the old-fashioned way { uint8_t buf[ 32768 ]; memset (buf, 0, sizeof (buf)); success = true; while (success && (length > 0)) { const int thisPass = MIN (length, sizeof (buf)); success = write (fd, buf, thisPass) == thisPass; length -= thisPass; usleep(9000); } } */ close (fd); } #endif return success; }
int main(int argc, char *argv[]) { int e; int fd = 0; int i; int j; int k; int nfiles; int stride; struct stat sbuf; ino_t *inodelist; __u32 *genlist; xfs_fsop_bulkreq_t a; xfs_bstat_t *ret; int iterations; char fname[MAXPATHLEN]; char *dirname; if (argc != 5) { fprintf(stderr, "Usage: %s iterations nfiles stride dir\n", argv[0]); fprintf(stderr, "Create dir with nfiles, unlink each stride'th file, sync, bulkstat\n"); exit(1); } iterations = atoi(argv[1]); nfiles = atoi(argv[2]); stride = atoi(argv[3]); dirname = argv[4]; if (!nfiles || !iterations) { fprintf(stderr, "Iterations and nfiles showld be non zero.\n"); exit(1); } inodelist = (ino_t *)malloc(nfiles * sizeof(ino_t)); genlist = (__u32 *)malloc(nfiles * sizeof(__u32)); ret = (xfs_bstat_t *)malloc(nfiles * sizeof(xfs_bstat_t)); for (k=0; k < iterations; k++) { xfs_ino_t last_inode = 0; int count = 0; int testFiles = 0; printf("Iteration %d ... \n", k); memset(inodelist, 0, nfiles * sizeof(ino_t)); memset(genlist, 0, nfiles * sizeof(__u32)); memset(ret, 0, nfiles * sizeof(xfs_bstat_t)); memset(&a, 0, sizeof(xfs_fsop_bulkreq_t)); a.lastip = (__u64 *)&last_inode; a.icount = nfiles; a.ubuffer = ret; a.ocount = &count; if (mkdir(dirname, 0755) < 0) { perror(dirname); exit(1); } /* create nfiles and store their inode numbers in inodelist */ for (i=0; i < nfiles; i++) { sprintf(fname, "%s/file%06d", dirname, i); if ((fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) { perror(fname); exit(1); } write(fd, fname, sizeof(fname)); if (fstat(fd, &sbuf) < 0) { perror(fname); exit(1); } inodelist[i] = sbuf.st_ino; close(fd); } sync(); /* collect bs_gen for the nfiles files */ if ((fd = open(dirname, O_RDONLY)) < 0) { perror(dirname); exit(1); } testFiles = 0; for (;;) { if ((e = xfsctl(dirname, fd, XFS_IOC_FSBULKSTAT, &a)) < 0) { perror("XFS_IOC_FSBULKSTAT1:"); exit(1); } if (count == 0) break; for (i=0; i < count; i++) { for (j=0; j < nfiles; j += stride) { if (ret[i].bs_ino == inodelist[j]) { genlist[j] = ret[i].bs_gen; testFiles++; } } } } close(fd); printf("testFiles %d ... \n", testFiles); /* remove some of the first set of files */ for (i=0; i < nfiles; i += stride) { sprintf(fname, "%s/file%06d", dirname, i); if (unlink(fname) < 0) { perror(fname); exit(1); } } /* create a new set of files (replacing the unlinked ones) */ for (i=0; i < nfiles; i += stride) { sprintf(fname, "%s/file%06d", dirname, i); if ((fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) { perror(fname); exit(1); } write(fd, fname, sizeof(fname)); close(fd); } sync(); last_inode = 0; count = 0; if ((fd = open(dirname, O_RDONLY)) < 0) { perror(dirname); exit(1); } for (;;) { if ((e = xfsctl(dirname, fd, XFS_IOC_FSBULKSTAT, &a)) < 0) { perror("XFS_IOC_FSBULKSTAT:"); exit(1); } if (count == 0) break; for (i=0; i < count; i++) { for (j=0; j < nfiles; j += stride) { if ((ret[i].bs_ino == inodelist[j]) && (ret[i].bs_gen == genlist[j])) { /* oops, the same inode with old gen number */ printf("Unlinked inode %llu with generation %d " "returned by bulkstat\n", (unsigned long long)inodelist[j], genlist[j]); exit(1); } if (ret[i].bs_ino == inodelist[j] && ret[i].bs_gen != genlist[j] + 1) { /* oops, the new gen number is not 1 bigger than the old */ printf("Inode with old generation %d, new generation %d\n", genlist[j], ret[i].bs_gen); exit(1); } } } } close(fd); sprintf(fname, "rm -rf %s\n", dirname); system(fname); sync(); sleep(2); printf("passed\n"); } exit(0); }
static bool preallocate_file_full( const char * filename, uint64_t length ) { bool success = 0; #ifdef WIN32 HANDLE hFile = CreateFile( filename, GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, 0 ); if( hFile != INVALID_HANDLE_VALUE ) { LARGE_INTEGER li; li.QuadPart = length; success = SetFilePointerEx( hFile, li, NULL, FILE_BEGIN ) && SetEndOfFile( hFile ); CloseHandle( hFile ); } #else int flags = O_RDWR | O_CREAT | O_LARGEFILE; int fd = open( filename, flags, 0666 ); if( fd >= 0 ) { # ifdef HAVE_FALLOCATE64 if( !success ) { success = !fallocate64( fd, 0, 0, length ); } # endif # ifdef HAVE_XFS_XFS_H if( !success && platform_test_xfs_fd( fd ) ) { xfs_flock64_t fl; fl.l_whence = 0; fl.l_start = 0; fl.l_len = length; success = !xfsctl( NULL, fd, XFS_IOC_RESVSP64, &fl ); } # endif # ifdef SYS_DARWIN if( !success ) { fstore_t fst; fst.fst_flags = F_ALLOCATECONTIG; fst.fst_posmode = F_PEOFPOSMODE; fst.fst_offset = 0; fst.fst_length = length; fst.fst_bytesalloc = 0; success = !fcntl( fd, F_PREALLOCATE, &fst ); } # endif # ifdef HAVE_POSIX_FALLOCATE if( !success ) { success = !posix_fallocate( fd, 0, length ); } # endif if( !success ) /* if nothing else works, do it the old-fashioned way */ { uint8_t buf[ 4096 ]; memset( buf, 0, sizeof( buf ) ); success = true; while ( success && ( length > 0 ) ) { const int thisPass = MIN( length, sizeof( buf ) ); success = write( fd, buf, thisPass ) == thisPass; length -= thisPass; } } close( fd ); } #endif return success; }
int main(int argc, char *argv[]) { int e; int i; int j; int k; int nfiles; int stride; int c; struct stat sbuf; ino_t *inodelist; xfs_fsop_bulkreq_t a; xfs_bstat_t *ret; int iterations; char fname[MAXPATHLEN]; char *dirname; int chknb = 0; while ((c = getopt(argc, argv, "r")) != -1) { switch(c) { case 'r': chknb = 1; break; default: break; } } if ((argc - optind) != 4) { fprintf(stderr, "Usage: %s iterations nfiles stride dir [options]\n", argv[0]); fprintf(stderr, "Create dir with nfiles, unlink each stride'th file, sync, bulkstat\n"); exit(1); } iterations = atoi(argv[optind++]); nfiles = atoi(argv[optind++]); stride = atoi(argv[optind++]); dirname = argv[optind++]; if (chknb) printf("Runing extended checks.\n"); inodelist = (ino_t *)malloc(nfiles * sizeof(ino_t)); ret = (xfs_bstat_t *)malloc(nfiles * sizeof(xfs_bstat_t)); for (k=0; k < iterations; k++) { int fd[nfiles + 1]; xfs_ino_t last_inode = 0; int count = 0, scount = -1; printf("Iteration %d ... (%d files)", k, nfiles); memset(&a, 0, sizeof(xfs_fsop_bulkreq_t)); a.lastip = (__u64 *)&last_inode; a.icount = nfiles; a.ubuffer = ret; a.ocount = &count; if (mkdir(dirname, 0755) < 0) { printf("Warning (%s,%d), mkdir(%s) failed.\n", __FILE__, __LINE__, dirname); perror(dirname); exit(1); } if ((fd[nfiles] = open(dirname, O_RDONLY)) < 0) { printf("Warning (%s,%d), open(%s) failed.\n", __FILE__, __LINE__, dirname); perror(dirname); exit(1); } if (chknb) { /* Get the original number of inodes (lazy) */ sync(); if (xfsctl(dirname, fd[nfiles], XFS_IOC_FSBULKSTAT, &a) != 0) { printf("Warning (%s:%d), xfsctl(XFS_IOC_FSBULKSTAT) FAILED.\n", __FILE__, __LINE__); } scount = count; } for (i=0; i < nfiles; i++) { /* Open the files */ sprintf(fname, "%s/file%06d", dirname, i); if ((fd[i] = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) { printf("Warning (%s,%d), open(%s) failed.\n", __FILE__, __LINE__, fname); perror(fname); exit(1); } write(fd[i], fname, sizeof(fname)); if (fstat(fd[i], &sbuf) < 0) { printf("Warning (%s,%d), fstat failed.\n", __FILE__, __LINE__); perror(fname); exit(1); } inodelist[i] = sbuf.st_ino; unlink(fname); } if (chknb) { /* *The files are still opened (but unlink()ed) , * we should have more inodes than before */ sync(); last_inode = 0; if (xfsctl(dirname, fd[nfiles], XFS_IOC_FSBULKSTAT, &a) != 0) { printf("Warning (%s:%d), xfsctl(XFS_IOC_FSBULKSTAT) FAILED.\n", __FILE__, __LINE__); } if (count < scount) { printf("ERROR, count(%d) < scount(%d).\n", count, scount); return -1; } } /* Close all the files */ for (i = 0; i < nfiles; i++) { close(fd[i]); } if (chknb) { /* * The files are now closed, we should be back to our, * previous inode count */ sync(); last_inode = 0; if (xfsctl(dirname, fd[nfiles], XFS_IOC_FSBULKSTAT, &a) != 0) { printf("Warning (%s:%d), xfsctl(XFS_IOC_FSBULKSTAT) FAILED.\n", __FILE__, __LINE__); } if (count != scount) { printf("ERROR, count(%d) != scount(%d).\n", count, scount); return -1; } } sync(); last_inode = 0; for (;;) { if ((e = xfsctl(dirname, fd[nfiles], XFS_IOC_FSBULKSTAT, &a)) < 0) { printf("Warning (%s,%d), xfsctl failed.\n", __FILE__, __LINE__); perror("XFS_IOC_FSBULKSTAT:"); exit(1); } if (count == 0) break; for (i=0; i < count; i++) { for (j=0; j < nfiles; j += stride) { if (ret[i].bs_ino == inodelist[j]) { /* oops ... */ printf("failed. Unlinked inode %llu returned by bulkstat\n", (unsigned long long)inodelist[j]); exit(1); } } } } close(fd[nfiles]); sprintf(fname, "rm -rf %s\n", dirname); system(fname); sync(); sleep(2); printf("passed\n"); } exit(0); }
void AsyncFile::openReq(Request* request) { m_auto_sync_freq = 0; m_write_wo_sync = 0; m_open_flags = request->par.open.flags; // for open.flags, see signal FSOPENREQ #ifdef NDB_WIN32 DWORD dwCreationDisposition; DWORD dwDesiredAccess = 0; DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_NO_BUFFERING; Uint32 flags = request->par.open.flags; // Convert file open flags from Solaris to Windows if ((flags & FsOpenReq::OM_CREATE) && (flags & FsOpenReq::OM_TRUNCATE)){ dwCreationDisposition = CREATE_ALWAYS; } else if (flags & FsOpenReq::OM_TRUNCATE){ dwCreationDisposition = TRUNCATE_EXISTING; } else if (flags & FsOpenReq::OM_CREATE){ dwCreationDisposition = CREATE_NEW; } else { dwCreationDisposition = OPEN_EXISTING; } switch(flags & 3){ case FsOpenReq::OM_READONLY: dwDesiredAccess = GENERIC_READ; break; case FsOpenReq::OM_WRITEONLY: dwDesiredAccess = GENERIC_WRITE; break; case FsOpenReq::OM_READWRITE: dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; break; default: request->error = 1000; break; return; } hFile = CreateFile(theFileName.c_str(), dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0); if(INVALID_HANDLE_VALUE == hFile) { request->error = GetLastError(); if(((ERROR_PATH_NOT_FOUND == request->error) || (ERROR_INVALID_NAME == request->error)) && (flags & FsOpenReq::OM_CREATE)) { createDirectories(); hFile = CreateFile(theFileName.c_str(), dwDesiredAccess, dwShareMode, 0, dwCreationDisposition, dwFlagsAndAttributes, 0); if(INVALID_HANDLE_VALUE == hFile) request->error = GetLastError(); else request->error = 0; return; } } else { request->error = 0; return; } #else Uint32 flags = request->par.open.flags; int new_flags = 0; // Convert file open flags from Solaris to Liux if (flags & FsOpenReq::OM_CREATE) { new_flags |= O_CREAT; } if (flags & FsOpenReq::OM_TRUNCATE){ #if 0 if(Global_unlinkO_CREAT){ unlink(theFileName.c_str()); } else #endif new_flags |= O_TRUNC; } if (flags & FsOpenReq::OM_AUTOSYNC) { m_auto_sync_freq = request->par.open.auto_sync_size; } if (flags & FsOpenReq::OM_APPEND){ new_flags |= O_APPEND; } if (flags & FsOpenReq::OM_DIRECT) #ifdef O_DIRECT { new_flags |= O_DIRECT; } #endif if ((flags & FsOpenReq::OM_SYNC) && ! (flags & FsOpenReq::OM_INIT)) { #ifdef O_SYNC new_flags |= O_SYNC; #endif } const char * rw = ""; switch(flags & 0x3){ case FsOpenReq::OM_READONLY: rw = "r"; new_flags |= O_RDONLY; break; case FsOpenReq::OM_WRITEONLY: rw = "w"; new_flags |= O_WRONLY; break; case FsOpenReq::OM_READWRITE: rw = "rw"; new_flags |= O_RDWR; break; default: request->error = 1000; break; return; } // allow for user to choose any permissionsa with umask const int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; if (flags & FsOpenReq::OM_CREATE_IF_NONE) { Uint32 tmp_flags = new_flags; #ifdef O_DIRECT tmp_flags &= ~O_DIRECT; #endif if ((theFd = ::open(theFileName.c_str(), tmp_flags, mode)) != -1) { close(theFd); request->error = FsRef::fsErrFileExists; return; } new_flags |= O_CREAT; } no_odirect: if (-1 == (theFd = ::open(theFileName.c_str(), new_flags, mode))) { PRINT_ERRORANDFLAGS(new_flags); if ((errno == ENOENT) && (new_flags & O_CREAT)) { createDirectories(); if (-1 == (theFd = ::open(theFileName.c_str(), new_flags, mode))) { #ifdef O_DIRECT if (new_flags & O_DIRECT) { new_flags &= ~O_DIRECT; goto no_odirect; } #endif PRINT_ERRORANDFLAGS(new_flags); request->error = errno; return; } } #ifdef O_DIRECT else if (new_flags & O_DIRECT) { new_flags &= ~O_DIRECT; goto no_odirect; } #endif else { request->error = errno; return; } } if (flags & FsOpenReq::OM_CHECK_SIZE) { struct stat buf; if ((fstat(theFd, &buf) == -1)) { request->error = errno; } else if((Uint64)buf.st_size != request->par.open.file_size) { request->error = FsRef::fsErrInvalidFileSize; } if (request->error) return; } if (flags & FsOpenReq::OM_INIT) { off_t off = 0; const off_t sz = request->par.open.file_size; Uint32 tmp[sizeof(SignalHeader)+25]; Signal * signal = (Signal*)(&tmp[0]); FsReadWriteReq* req = (FsReadWriteReq*)signal->getDataPtrSend(); Uint32 index = 0; Uint32 block = refToBlock(request->theUserReference); #ifdef HAVE_XFS_XFS_H if(platform_test_xfs_fd(theFd)) { ndbout_c("Using xfsctl(XFS_IOC_RESVSP64) to allocate disk space"); xfs_flock64_t fl; fl.l_whence= 0; fl.l_start= 0; fl.l_len= (off64_t)sz; if(xfsctl(NULL, theFd, XFS_IOC_RESVSP64, &fl) < 0) ndbout_c("failed to optimally allocate disk space"); } #endif #ifdef HAVE_POSIX_FALLOCATE posix_fallocate(theFd, 0, sz); #endif while(off < sz) { req->filePointer = 0; // DATA 0 req->userPointer = request->theUserPointer; // DATA 2 req->numberOfPages = 1; // DATA 5 req->varIndex = index++; req->data.pageData[0] = m_page_ptr.i; m_fs.EXECUTE_DIRECT(block, GSN_FSWRITEREQ, signal, FsReadWriteReq::FixedLength + 1); retry: Uint32 size = request->par.open.page_size; char* buf = (char*)m_page_ptr.p; while(size > 0){ const int n = write(theFd, buf, size); if(n == -1 && errno == EINTR) { continue; } if(n == -1 || n == 0) { break; } size -= n; buf += n; } if(size != 0) { int err = errno; #ifdef O_DIRECT if ((new_flags & O_DIRECT) && off == 0) { ndbout_c("error on first write(%d), disable O_DIRECT", err); new_flags &= ~O_DIRECT; close(theFd); theFd = ::open(theFileName.c_str(), new_flags, mode); if (theFd != -1) goto retry; } #endif close(theFd); unlink(theFileName.c_str()); request->error = err; return; } off += request->par.open.page_size; } if(lseek(theFd, 0, SEEK_SET) != 0) request->error = errno; } else if (flags & FsOpenReq::OM_DIRECT) { #ifdef O_DIRECT if (flags & (FsOpenReq::OM_TRUNCATE | FsOpenReq::OM_CREATE)) { request->error = check_odirect_write(flags, new_flags, mode); } else { request->error = check_odirect_read(flags, new_flags, mode); } if (request->error) return; #endif } #ifdef VM_TRACE if (flags & FsOpenReq::OM_DIRECT) { #ifdef O_DIRECT ndbout_c("%s %s O_DIRECT: %d", theFileName.c_str(), rw, !!(new_flags & O_DIRECT)); #else ndbout_c("%s %s O_DIRECT: 0", theFileName.c_str(), rw); #endif } #endif if ((flags & FsOpenReq::OM_SYNC) && (flags & FsOpenReq::OM_INIT)) { #ifdef O_SYNC /** * reopen file with O_SYNC */ close(theFd); new_flags &= ~(O_CREAT | O_TRUNC); new_flags |= O_SYNC; theFd = ::open(theFileName.c_str(), new_flags, mode); if (theFd == -1) { request->error = errno; } #endif } #endif }
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; if (flags & IO_TMPFILE) oflags |= O_TMPFILE; fd = open(path, oflags, mode); if (fd < 0) { if (errno == EISDIR && ((oflags & (O_RDWR|O_TMPFILE)) == 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 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 handle(char *fname, int fsfd, char *path) { xfs_fsop_handlereq_t handle; char buffer[1024]; char link[1024]; int ret; __u32 len; __u32 linklen; int fd; handle.path=path; handle.ohandle=buffer; handle.ohandlen=&len; ret=xfsctl(fname, fsfd, XFS_IOC_PATH_TO_FSHANDLE, &handle); if (ret) { perror("xfsctl(XFS_IOC_PATH_TO_FSHANDLE)"); exit(1); } printf("XFS_IOC_PATH_TO_FSHANDLE-\n handle: "); handle_print(handle.ohandle, *handle.ohandlen); printf("\n"); fd=open(path,O_RDONLY); if (fd<0) { perror("open"); exit(1); } handle.path=NULL; handle.fd=fd; handle.ohandle=buffer; handle.ohandlen=&len; ret=xfsctl(fname, fsfd, XFS_IOC_FD_TO_HANDLE, &handle); if (ret) { perror("ioctl(XFS_IOC_FD_TO_HANDLE)"); exit(1); } printf("XFS_IOC_FD_TO_HANDLE-\n path: %s\n handle: ", path); handle_print(handle.ohandle, *handle.ohandlen); printf("\n"); close(fd); handle.path=NULL; handle.fd=-1; handle.ihandle=buffer; handle.ihandlen=len; handle.ohandle=NULL; handle.ohandlen=NULL; ret=xfsctl(fname, fsfd, XFS_IOC_OPEN_BY_HANDLE, &handle); if (ret<0) { perror("xfsctl(XFS_IOC_OPEN_BY_HANDLE)"); exit(1); } printf("XFS_IOC_OPEN_BY_HANDLE-\n handle: "); handle_print(handle.ihandle, handle.ihandlen); printf("\n fd: %d\n stat- ", ret); stat_print(ret); close(ret); handle.path=path; handle.ohandle=buffer; handle.ohandlen=&len; ret=xfsctl(fname, fsfd, XFS_IOC_PATH_TO_HANDLE, &handle); if (ret) { perror("xfsctl(XFS_IOC_PATH_TO_HANDLE)"); exit(1); } printf("XFS_IOC_PATH_TO_HANDLE-\n path: %s\n handle: ", path); handle_print(handle.ohandle, *handle.ohandlen); printf("\n"); handle.path=NULL; handle.fd=-1; handle.ihandle=buffer; handle.ihandlen=len; handle.ohandle=link; linklen=sizeof(link); handle.ohandlen=&linklen; ret=xfsctl(fname, fsfd, XFS_IOC_READLINK_BY_HANDLE, &handle); if (ret<0) { perror("xfsctl(XFS_IOC_READLINK_BY_HANDLE)"); fprintf(stderr,"ERROR IGNORED\n"); } else { printf("XFS_IOC_READLINK_BY_HANDLE-\n handle: "); handle_print(handle.ihandle, handle.ihandlen); printf("\n link=\"%*.*s\"\n", ret, ret, (char*)handle.ohandle); } }