STATIC int xfs_ioc_bulkstat( xfs_mount_t *mp, unsigned int cmd, void __user *arg) { xfs_fsop_bulkreq_t bulkreq; int count; /* # of records returned */ xfs_ino_t inlast; /* last inode number */ int done; int error; /* done = 1 if there are more stats to get and if bulkstat */ /* should be called again (unused here, but used in dmapi) */ if (!capable(CAP_SYS_ADMIN)) return -EPERM; if (XFS_FORCED_SHUTDOWN(mp)) return -XFS_ERROR(EIO); if (copy_from_user(&bulkreq, arg, sizeof(xfs_fsop_bulkreq_t))) return -XFS_ERROR(EFAULT); if (copy_from_user(&inlast, bulkreq.lastip, sizeof(__s64))) return -XFS_ERROR(EFAULT); if ((count = bulkreq.icount) <= 0) return -XFS_ERROR(EINVAL); if (bulkreq.ubuffer == NULL) return -XFS_ERROR(EINVAL); if (cmd == XFS_IOC_FSINUMBERS) error = xfs_inumbers(mp, &inlast, &count, bulkreq.ubuffer, xfs_inumbers_fmt); else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE) error = xfs_bulkstat_single(mp, &inlast, bulkreq.ubuffer, &done); else /* XFS_IOC_FSBULKSTAT */ error = xfs_bulkstat(mp, &inlast, &count, (bulkstat_one_pf)xfs_bulkstat_one, NULL, sizeof(xfs_bstat_t), bulkreq.ubuffer, BULKSTAT_FG_QUICK, &done); if (error) return -error; if (bulkreq.ocount != NULL) { if (copy_to_user(bulkreq.lastip, &inlast, sizeof(xfs_ino_t))) return -XFS_ERROR(EFAULT); if (copy_to_user(bulkreq.ocount, &count, sizeof(count))) return -XFS_ERROR(EFAULT); } return 0; }
/* * 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; }