2007-07-24 16:08:02 +00:00
|
|
|
/*
|
2007-10-30 03:07:42 +00:00
|
|
|
* $Id: bulkstat_unlink_test.c,v 1.3 2007/10/30 03:07:42 mohamedb.longdrop.melbourne.sgi.com Exp $
|
2007-07-24 16:08:02 +00:00
|
|
|
* Test bulkstat doesn't returned unlinked inodes.
|
|
|
|
|
* Mark Goodwin <markgw@sgi.com> Fri Jul 20 09:13:57 EST 2007
|
|
|
|
|
*/
|
2015-08-04 16:34:42 +10:00
|
|
|
#include <stdlib.h>
|
2007-07-24 16:08:02 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <xfs/xfs.h>
|
|
|
|
|
#include <unistd.h>
|
2007-10-26 16:05:04 +00:00
|
|
|
#include <getopt.h>
|
2015-08-04 16:34:42 +10:00
|
|
|
#include <string.h>
|
2007-07-24 16:08:02 +00:00
|
|
|
|
|
|
|
|
int
|
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
|
{
|
2007-10-26 16:05:04 +00:00
|
|
|
int e;
|
|
|
|
|
int i;
|
|
|
|
|
int j;
|
|
|
|
|
int k;
|
|
|
|
|
int nfiles;
|
|
|
|
|
int stride;
|
2007-07-24 16:08:02 +00:00
|
|
|
|
2007-10-26 16:05:04 +00:00
|
|
|
int c;
|
2007-07-24 16:08:02 +00:00
|
|
|
|
2007-10-26 16:05:04 +00:00
|
|
|
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;
|
2007-07-24 16:08:02 +00:00
|
|
|
|
2007-10-26 16:05:04 +00:00
|
|
|
while ((c = getopt(argc, argv, "r")) != -1) {
|
|
|
|
|
switch(c) {
|
|
|
|
|
case 'r':
|
|
|
|
|
chknb = 1;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2007-07-24 16:08:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-10-26 16:05:04 +00:00
|
|
|
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);
|
|
|
|
|
}
|
2007-07-24 16:08:02 +00:00
|
|
|
|
|
|
|
|
|
2007-10-26 16:05:04 +00:00
|
|
|
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));
|
2010-01-21 08:53:44 +11:00
|
|
|
a.lastip = (__u64 *)&last_inode;
|
2007-10-26 16:05:04 +00:00
|
|
|
a.icount = nfiles;
|
|
|
|
|
a.ubuffer = ret;
|
|
|
|
|
a.ocount = &count;
|
|
|
|
|
|
|
|
|
|
if (mkdir(dirname, 0755) < 0) {
|
2007-10-30 03:07:42 +00:00
|
|
|
printf("Warning (%s,%d), mkdir(%s) failed.\n", __FILE__, __LINE__, dirname);
|
2007-10-26 16:05:04 +00:00
|
|
|
perror(dirname);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((fd[nfiles] = open(dirname, O_RDONLY)) < 0) {
|
2007-10-30 03:07:42 +00:00
|
|
|
printf("Warning (%s,%d), open(%s) failed.\n", __FILE__, __LINE__, dirname);
|
2007-10-26 16:05:04 +00:00
|
|
|
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) {
|
2007-10-30 03:07:42 +00:00
|
|
|
printf("Warning (%s,%d), open(%s) failed.\n", __FILE__, __LINE__, fname);
|
2007-10-26 16:05:04 +00:00
|
|
|
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 ... */
|
2008-12-31 12:52:05 +01:00
|
|
|
printf("failed. Unlinked inode %llu returned by bulkstat\n", (unsigned long long)inodelist[j]);
|
2007-10-26 16:05:04 +00:00
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
close(fd[nfiles]);
|
|
|
|
|
sprintf(fname, "rm -rf %s\n", dirname);
|
|
|
|
|
system(fname);
|
|
|
|
|
|
|
|
|
|
sync();
|
|
|
|
|
sleep(2);
|
|
|
|
|
printf("passed\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exit(0);
|
2007-07-24 16:08:02 +00:00
|
|
|
}
|