/*
 * DF-2763 stress: unprivileged writer hammering rename/create/unlink on
 * the journaled mount (/tmp) while root churns journal install/remove.
 * Race hunted: journal_detach() kfrees mp->mnt_jbitmap (vfs_jops.c:251)
 * while an in-flight VOP's jreclist owns a streamid ->
 *   jreclist_init  :547  reads (possibly NULL/freed) mnt_jbitmap
 *   jreclist_init  :556  sets a bit in freed memory
 *   jreclist_done  :613  clears a bit in freed memory
 * Run: ./df2763 <dir> <seconds>
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>

int
main(int ac, char **av)
{
    const char *dir = av[1];
    long secs = atol(av[2]);
    char a[256], b[256];
    int i = 0;
    time_t t0 = time(NULL);

    snprintf(a, sizeof(a), "%s/w%d_a", dir, (int)getpid());
    snprintf(b, sizeof(b), "%s/w%d_b", dir, (int)getpid());
    while (time(NULL) - t0 < secs) {
        /* small write to force journal_write shim too */
        int fd = open(a, O_RDWR|O_CREAT, 0666);
        if (fd >= 0) { write(fd, "x", 1); close(fd); }
        if (rename(a, b) < 0 && errno != ENOENT) { /* keep going */ }
        if (rename(b, a) < 0 && errno != ENOENT) { /* keep going */ }
        if ((++i & 0x3f) == 0)
            unlink(a), unlink(b);
        usleep(200);
    }
    return 0;
}
