#define OBD_FAIL_LLITE_READ_PAUSE 0x1431
#define OBD_FAIL_LLITE_FAULT_PAUSE 0x1432
#define OBD_FAIL_LLITE_STATAHEAD_PAUSE 0x1433
+#define OBD_FAIL_LLITE_STAT_RACE1 0x1434
+#define OBD_FAIL_LLITE_STAT_RACE2 0x1435
#define OBD_FAIL_FID_INDIR 0x1501
#define OBD_FAIL_FID_INLMA 0x1502
if (rc != 0)
GOTO(out, rc = (rc == -ENODATA ? 0 : rc));
+ CFS_RACE(OBD_FAIL_LLITE_STAT_RACE2);
+ /*
+ * let a awaken stat thread a chance to get intermediate
+ * attributes from inode
+ */
+ CFS_FAIL_TIMEOUT(OBD_FAIL_LLITE_STAT_RACE2, 1);
+
if (atime < attr->cat_atime)
atime = attr->cat_atime;
else
stat->mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
+ CFS_FAIL_CHECK_RESET(OBD_FAIL_LLITE_STAT_RACE1,
+ OBD_FAIL_LLITE_STAT_RACE2);
+ /* pause to let other stat to do intermediate changes to inode */
+ CFS_RACE(OBD_FAIL_LLITE_STAT_RACE2);
+
+ /*
+ * ll_merge_attr() (in case of regular files) does not update
+ * inode's timestamps atomically. Protect against intermediate
+ * values
+ */
+ if (!S_ISDIR(inode->i_mode))
+ ll_inode_size_lock(inode);
stat->uid = inode->i_uid;
stat->gid = inode->i_gid;
stat->atime = inode_get_atime(inode);
stat->mtime = inode_get_mtime(inode);
stat->ctime = inode_get_ctime(inode);
+
/* stat->blksize is used to tell about preferred IO size */
if (sbi->ll_stat_blksize)
stat->blksize = sbi->ll_stat_blksize;
stat->size = i_size_read(inode);
stat->blocks = inode->i_blocks;
+ if (!S_ISDIR(inode->i_mode))
+ ll_inode_size_unlock(inode);
+
#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
if (flags & AT_STATX_DONT_SYNC) {
if (stat->size == 0 &&
}
run_test 39s "relatime is supported"
+test_39u() {
+ touch $DIR/$tfile
+ sleep 2
+ dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=notrunc ||
+ error "dd failed"
+
+ #define OBD_FAIL_LLITE_STAT_RACE1 0x1434
+ $LCTL set_param fail_loc=0x80001434
+
+ local mtimes=($(stat -c "%Y" $DIR/$tfile &
+ sleep 1; stat -c "%Y" $DIR/$tfile; wait))
+
+ (( ${mtimes[0]} == ${mtimes[1]} )) ||
+ error "mtime mismatch ${mtimes[0]} != ${mtimes[1]}"
+}
+run_test 39u "stat race"
+
test_40() {
dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
$RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&