aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/fs.h
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2011-07-26 18:25:49 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-08-19 13:25:34 -0400
commit778fc546f749c588aa2f6cd50215d2715c374252 (patch)
treeb3ffa04327884cd0491c3ee1677f0ffc589ebe9c /include/linux/fs.h
parent710b7216964d6455cf1b215c43b03a1a79008c7d (diff)
locks: fix tracking of inprogress lease breaks
We currently use a bit in fl_flags to record whether a lease is being broken, and set fl_type to the type (RDLCK or UNLCK) that it will eventually have. This means that once the lease break starts, we forget what the lease's type *used* to be. Breaking a read lease will then result in blocking read opens, even though there's no conflict--because the lease type is now F_UNLCK and we can no longer tell whether it was previously a read or write lease. So, instead keep fl_type as the original type (the type which we enforce), and keep track of whether we're unlocking or merely downgrading by replacing the single FL_INPROGRESS flag by FL_UNLOCK_PENDING and FL_DOWNGRADE_PENDING flags. To get this right we also need to track separate downgrade and break times, to handle the case where a write-leased file gets conflicting opens first for read, then later for write. (I first considered just eliminating the downgrade behavior completely--nfsv4 doesn't need it, and nobody as far as I can tell actually uses it currently--but Jeremy Allison tells me that Windows oplocks do behave this way, so Samba will probably use this some day.) Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'include/linux/fs.h')
-rw-r--r--include/linux/fs.h7
1 files changed, 5 insertions, 2 deletions
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 327fdd4de85f..76460edf1648 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1065,7 +1065,8 @@ static inline int file_check_writeable(struct file *filp)
1065#define FL_LEASE 32 /* lease held on this file */ 1065#define FL_LEASE 32 /* lease held on this file */
1066#define FL_CLOSE 64 /* unlock on close */ 1066#define FL_CLOSE 64 /* unlock on close */
1067#define FL_SLEEP 128 /* A blocking lock */ 1067#define FL_SLEEP 128 /* A blocking lock */
1068#define FL_INPROGRESS 256 /* Lease is being broken */ 1068#define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */
1069#define FL_UNLOCK_PENDING 512 /* Lease is being broken */
1069 1070
1070/* 1071/*
1071 * Special return value from posix_lock_file() and vfs_lock_file() for 1072 * Special return value from posix_lock_file() and vfs_lock_file() for
@@ -1122,7 +1123,9 @@ struct file_lock {
1122 loff_t fl_end; 1123 loff_t fl_end;
1123 1124
1124 struct fasync_struct * fl_fasync; /* for lease break notifications */ 1125 struct fasync_struct * fl_fasync; /* for lease break notifications */
1125 unsigned long fl_break_time; /* for nonblocking lease breaks */ 1126 /* for lease breaks: */
1127 unsigned long fl_break_time;
1128 unsigned long fl_downgrade_time;
1126 1129
1127 const struct file_lock_operations *fl_ops; /* Callbacks for filesystems */ 1130 const struct file_lock_operations *fl_ops; /* Callbacks for filesystems */
1128 const struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */ 1131 const struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */