aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLi Wang <liwang@redhat.com>2018-12-17 15:10:38 +0800
committerPetr Vorel <pvorel@suse.cz>2019-01-28 16:35:36 +0100
commit32c06126f1a444ce21e8464bf3261ad475a52ee0 (patch)
tree9fd896e41a882dff6220bd299fe07c1bc7cece1e /include
parentb5f924a5c029d0bf7e53a93b04b68f83e6aa8215 (diff)
fcntl: fcntl F_SETLEASE return EAGAIN on overlapfs
>From Miklos's words: The F_SETLEASE "failure" is caused by the simplistic way the kernel currently determines if there's a possible local conflict to a write lock: check_conflicting_open(const struct dentry *dentry, const long arg, int flags) { /*...*/ if ((arg == F_WRLCK) && ((d_count(dentry) > 1) || (atomic_read(&inode->i_count) > 1))) ret = -EAGAIN; /*...*/ It reads the dentry count, and if there's any other reference to the dentry or inode as the one held by this file, then it is assumed to come from a conflicting open. Which is not true, dentry references can come from variety of sources (e.g. O_PATH opens are obviously non-conflicting). This causes failure on tmpfs as well, which holds an extra reference on each dentry. The extra ref on the dentry in overlayfs comes from the realfile stored in the overlay file's private_data field. The proper solution to this is probably to have an i_readcount, matching the functionality of i_writecount, which would solve the other problems with the current approach. Note: this is not a failure in the sense that applications must be written with the assumption that F_SETLEASE can fail with -EAGAIN, so this error condition just makes the lease non-useful, but shouldn't break anything. Reviewed-by: Petr Vorel <pvorel@suse.cz> ==== Error log ===== fcntl24 1 TFAIL : fcntl24.c:148: fcntl(tfile_7254, F_SETLEASE, F_WRLCK) Failed, errno=11 : Resource temporarily unavailable fcntl25 1 TFAIL : fcntl25.c:149: fcntl(tfile_7255, F_SETLEASE, F_WRLCK) Failed, errno=11 : Resource temporarily unavailable fcntl26 1 TFAIL : fcntl26.c:149: fcntl(tfile_7256, F_SETLEASE, F_WRLCK) Failed, errno=11 : Resource temporarily unavailable fcntl33.c:118: FAIL: fcntl() failed to set lease: EAGAIN/EWOULDBLOCK fcntl33.c:118: FAIL: fcntl() failed to set lease: EAGAIN/EWOULDBLOCK fcntl33.c:118: FAIL: fcntl() failed to set lease: EAGAIN/EWOULDBLOCK fcntl33.c:118: FAIL: fcntl() failed to set lease: EAGAIN/EWOULDBLOCK Reported-by: Xiong Zhou <xzhou@redhat.com> Signed-off-by: Li Wang <liwang@redhat.com> Cc: Miklos Szeredi <mszeredi@redhat.com> Cc: Ye Chao <cye@redhat.com> Signed-off-by: Petr Vorel <pvorel@suse.cz>
Diffstat (limited to 'include')
-rw-r--r--include/tst_fs.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/tst_fs.h b/include/tst_fs.h
index 8d3f1cfbc..23f139ded 100644
--- a/include/tst_fs.h
+++ b/include/tst_fs.h
@@ -41,6 +41,7 @@
#define TST_F2FS_MAGIC 0xF2F52010
#define TST_NILFS_MAGIC 0x3434
#define TST_EXOFS_MAGIC 0x5DF5
+#define TST_OVERLAYFS_MAGIC 0x794c7630
enum {
TST_BYTES = 1,