From e9aa3b80e7230bf3aa475f95e5e5a8562e4bcefb Mon Sep 17 00:00:00 2001 From: anserper Date: Wed, 15 Jul 2009 12:47:33 +0000 Subject: [PATCH] b=18801 i=Oleg Drokin i=Alexander Zarochentsev atime, mtime and addition POSIX compliance stuff for direct I/O and lockless I/o --- lustre/llite/file.c | 56 +++++++++++++++++++++++++++++++++++++++++++------ lustre/tests/sanityN.sh | 17 +++++++++++++++ 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index dfdd142e..7d9cb0b 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1649,9 +1649,10 @@ repeat: } else { retval = ll_direct_IO(READ, file, iov_copy, *ppos, nr_segs, 0); if (retval > 0) { - lprocfs_counter_add(sbi->ll_stats, - LPROC_LL_LOCKLESS_READ, - (long)retval); + file_accessed(file); + lprocfs_counter_add(sbi->ll_stats, + LPROC_LL_LOCKLESS_READ, + (long)retval); *ppos += retval; } } @@ -1696,6 +1697,26 @@ static ssize_t ll_file_read(struct file *file, char *buf, size_t count, #endif } +/* iov_shorten from linux kernel */ +static unsigned long ll_iov_shorten(struct iovec *iov, + unsigned long nr_segs, + size_t to) +{ + unsigned long seg = 0; + size_t len = 0; + + while (seg < nr_segs) { + seg++; + if (len + iov->iov_len >= to) { + iov->iov_len = to - len; + break; + } + len += iov->iov_len; + iov++; + } + return seg; +} + /* * Write to a file (through the page cache). */ @@ -1860,11 +1881,34 @@ repeat: *ppos); #endif } else { + size_t ocount, ncount; + + retval = generic_segment_checks(iov_copy, &nrsegs_copy, + &ocount, VERIFY_READ); + if (retval) + GOTO(out, retval); + + retval = generic_write_checks(file, ppos, &ncount, 0); + if (retval) + GOTO(out, retval); + + if (unlikely(ocount != ncount)) { + /* we are allowed to modify the original iov too */ + nrsegs_copy = ll_iov_shorten(iov_copy, nrsegs_copy, + ncount); + chunk = 0; /* no repetition after the short write */ + } + + retval = ll_remove_suid(file, file->f_vfsmnt); + if (retval) + GOTO(out, retval); + + file_update_time(file); retval = ll_direct_IO(WRITE, file, iov_copy, *ppos, nr_segs, 0); if (retval > 0) { - lprocfs_counter_add(sbi->ll_stats, - LPROC_LL_LOCKLESS_WRITE, - (long)retval); + lprocfs_counter_add(sbi->ll_stats, + LPROC_LL_LOCKLESS_WRITE, + (long)retval); *ppos += retval; } } diff --git a/lustre/tests/sanityN.sh b/lustre/tests/sanityN.sh index e3fb5d6..7d42930 100644 --- a/lustre/tests/sanityN.sh +++ b/lustre/tests/sanityN.sh @@ -880,6 +880,23 @@ test_38() { # bug 18801, based on the code of test_32b } run_test 38 "lockless i/o with O_DIRECT and unaligned writes" +test_39() { + local originaltime + local updatedtime + local delay=3 + + touch $DIR1/$tfile + originaltime=$(stat -c %Y $DIR1/$tfile) + log "original modification time is $originaltime" + sleep $delay + multiop $DIR1/$tfile oO_DIRECT:O_WRONLY:w$((10*1048576))c || error "multiop has failed" + updatedtime=$(stat -c %Y $DIR2/$tfile) + log "updated modification time is $updatedtime" + [ $((updatedtime - originaltime)) -ge $delay ] || error "invalid modification time" + rm -rf $DIR/$tfile +} +run_test 39 "direct I/O writes should update mtime =========" + log "cleanup: ======================================================" check_and_cleanup_lustre -- 1.8.3.1