#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/vfs.h>
+#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int bufsize = 0;
sem_t sem;
#define ALIGN 65535
+#define MAX_SHIFT 4096
char usage[] =
"Usage: %s filename command-sequence\n"
" command-sequence items:\n"
+" b[num] write optional length from random in-memory offset\n"
" c close\n"
" C[num] create with optional stripes\n"
" d mkdir\n"
/* use sigaction instead of signal to avoid SA_ONESHOT semantics */
sigaction(SIGUSR1, &(const struct sigaction){.sa_handler = &usr1_handler},
NULL);
+ srandom(time(NULL));
+
fname = argv[1];
for (commands = argv[2]; *commands; commands++) {
case 'v':
verbose = 1;
break;
+ case 'b':
case 'w':
len = atoi(commands+1);
if (len <= 0)
len = 1;
if (bufsize < len) {
- buf = realloc(buf, len + ALIGN);
+ int shift = (*commands == 'b') ?
+ (random() % MAX_SHIFT) : 0;
+ buf = realloc(buf, len + ALIGN + shift);
if (buf == NULL) {
save_errno = errno;
perror("allocating buf for write\n");
}
bufsize = len;
buf_align = (char *)((long)(buf + ALIGN) &
- ~ALIGN);
+ ~ALIGN) + shift;
strncpy(buf_align, msg, bufsize);
}
while (len > 0) {
kill -USR1 $MULTIPID
nr_files=`lfs find $DIR1/$tdir -type f | wc -l`
[ $nr_files -eq 10000 ] || error "$nr_files != 10000 truncated directory?"
-
}
run_test 37 "check i_size is not updated for directory on close (bug 18695) =============="
+test_38() { # bug 18801, based on the code of test_32b
+ remote_ost_nodsh && skip "remote OST with nodsh" && return
+
+ local node
+ local p="$TMP/sanityN-$TESTNAME.parameters"
+ local random="$TMP/sanityN-$TESTNAME.random"
+ # 1. locked unaligned non-DIRECT_IO write of 8192 bytes to file A
+ # 2a. locked unaligned DIRECT_IO write of 4000 bytes to file B
+ # 2b. locked unaligned DIRECT_IO write of 4000 bytes to file B
+ # 3. unaligned "lockless DIRECT_IO" write of 192 bytes in the end of file B
+ # 4. compare A and B
+ log "creating the initial file"
+ multiop $random Ob4000b4000b192c || error "failed creating random file"
+ log "creating a file with the same contents"
+ multiop $DIR1/$tfile oO_CREAT:O_DIRECT:O_RDWR:b4000c || error "first multiop failed"
+ multiop $DIR1/$tfile oO_CREAT:O_DIRECT:O_RDWR:z4000b4000c || error "second multiop failed"
+ save_lustre_params $HOSTNAME "llite.*.contention_seconds" > $p
+ for node in $(osts_nodes); do
+ save_lustre_params $node "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
+ save_lustre_params $node "ldlm.namespaces.filter-*.contended_locks" >> $p
+ save_lustre_params $node "ldlm.namespaces.filter-*.contention_seconds" >> $p
+ done
+ log "enforcing lockless I/O"
+ clear_llite_stats
+ # agressive lockless i/o settings
+ for node in $(osts_nodes); do
+ do_node $node 'lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes 2000000; lctl set_param -n ldlm.namespaces.filter-*.contended_locks 0; lctl set_param -n ldlm.namespaces.filter-*.contention_seconds 60'
+ done
+ lctl set_param -n llite.*.contention_seconds 60
+ multiop $DIR2/$tfile oO_DIRECT:O_RDWR:z8000b192c || error "the last multiop failed"
+ [ $(calc_llite_stats lockless_write_bytes) -ne 0 ] || error "lockless i/o was not triggered"
+ restore_lustre_params <$p
+ log "comparing"
+ cmp $DIR1/$tfile $random || error "O_DIRECT+lockless results do not match the original file"
+ rm -f $DIR1/$tfile
+ rm -f $p
+ rm -f $random
+}
+run_test 38 "lockless i/o with O_DIRECT and unaligned writes"
+
log "cleanup: ======================================================"
check_and_cleanup_lustre