} 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;
}
}
#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).
*/
*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;
}
}
}
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