}
}
+/* For a partial-page punch, flush punch range to disk immediately */
+static void osd_partial_page_flush_punch(struct osd_device *d,
+ struct inode *inode, loff_t start,
+ loff_t end)
+{
+ if (osd_use_page_cache(d)) {
+ filemap_fdatawrite_range(inode->i_mapping, start, end);
+ } else {
+ /* Notice we use "wait" version to ensure I/O is complete */
+ filemap_write_and_wait_range(inode->i_mapping, start,
+ end);
+ invalidate_mapping_pages(inode->i_mapping, start >> PAGE_SHIFT,
+ end >> PAGE_SHIFT);
+ }
+}
+
/*
* For a partial-page truncate, flush the page to disk immediately to
* avoid data corruption during direct disk write. b=17397
struct file *file = osd_quasi_file(env, inode);
file->f_op->fallocate(file, mode, start, end - start);
- osd_partial_page_flush(d, inode, start);
- osd_partial_page_flush(d, inode, end - 1);
+ osd_partial_page_flush_punch(d, inode, start, end - 1);
}
void osd_process_truncates(const struct lu_env *env, struct list_head *list)
}
run_test fsx "fsx"
+test_fsx_partial_punch() {
+ local fsx_count=100000
+ local testfile=$DIR/f0.fsxfile
+ local fsx_size=5407677 # upper bound file size
+ local fsx_seed=7919
+
+ check_set_fallocate
+
+ rm -f $testfile
+ $LFS setstripe -c -1 $testfile
+
+ #
+ # $fsx_seed, $fsx_count and $fsx_size combination almost
+ # always reproduces the LASSERT under LU-14640. Therefore these
+ # constants are used as reproducer vs using a random value and
+ # hoping it hits the error condition
+ #
+ CMD="$FSX -c 50 -p 1000 -S $fsx_seed -P $TMP -l $fsx_size \
+ -N $fsx_count $testfile"
+ echo "Using: $CMD"
+ $CMD || error "fsx failed"
+ rm -f $testfile
+}
+run_test fsx_partial_punch "Verify fsx with partial punch via fallocate"
+
complete $SECONDS
check_and_cleanup_lustre
exit_status