@@ -4237,6 +4237,10 @@ int ext4_break_layouts(struct inode *inode)
if (WARN_ON_ONCE(!rwsem_is_locked(&ei->i_mmap_sem)))
return -EINVAL;
+ /* Break longterm leases */
+ if (dax_mapping_is_dax(inode->i_mapping))
+ break_longterm(inode);
+
do {
page = dax_layout_busy_page(inode->i_mapping);
if (!page)
@@ -1580,6 +1580,7 @@ static void time_out_leases(struct inode *inode, struct list_head *dispose)
{
struct file_lock_context *ctx = inode->i_flctx;
struct file_lock *fl, *tmp;
+ struct task_struct *tsk;
lockdep_assert_held(&ctx->flc_lock);
@@ -1587,8 +1588,16 @@ static void time_out_leases(struct inode *inode, struct list_head *dispose)
trace_time_out_leases(inode, fl);
if (past_time(fl->fl_downgrade_time))
lease_modify(fl, F_RDLCK, dispose);
- if (past_time(fl->fl_break_time))
- lease_modify(fl, F_UNLCK, dispose);
+ if (past_time(fl->fl_break_time)) {
+ if (fl->fl_flags & FL_LONGTERM) {
+ tsk = find_task_by_vpid(fl->fl_pid);
+ fl->fl_break_time = 1 + jiffies + lease_break_time * HZ;
+ lease_modify_longterm(fl, F_UNLCK, dispose);
+ kill_pid(tsk->thread_pid, SIGBUS, 0);
+ } else {
+ lease_modify(fl, F_UNLCK, dispose);
+ }
+ }
}
}
@@ -739,6 +739,10 @@ xfs_break_dax_layouts(
ASSERT(xfs_isilocked(XFS_I(inode), XFS_MMAPLOCK_EXCL));
+ /* Break longterm leases */
+ if (dax_mapping_is_dax(inode->i_mapping))
+ break_longterm(inode);
+
page = dax_layout_busy_page(inode->i_mapping);
if (!page)
return 0;
@@ -2459,6 +2459,14 @@ static inline int break_layout(struct inode *inode, bool wait)
return 0;
}
+static inline int break_longterm(struct inode *inode)
+{
+ smp_mb();
+ if (inode->i_flctx && !list_empty_careful(&inode->i_flctx->flc_lease))
+ return __break_lease(inode, O_WRONLY, FL_LONGTERM);
+ return 0;
+}
+
#else /* !CONFIG_FILE_LOCKING */
static inline int break_lease(struct inode *inode, unsigned int mode)
{
@@ -2486,6 +2494,11 @@ static inline int break_layout(struct inode *inode, bool wait)
return 0;
}
+static inline int break_longterm(struct inode *inode, bool wait)
+{
+ return 0;
+}
+
#endif /* CONFIG_FILE_LOCKING */
/* fs/open.c */
From: Ira Weiny <ira.weiny@intel.com> Now that the taking of LONGTERM leases is in place we can now facilitate sending a SIGBUS to process if a file truncate or hole punch is performed and they do not respond by releasing the lease. The standard file lease_break_time is used to time out the LONGTERM lease which is in place on the inode. --- fs/ext4/inode.c | 4 ++++ fs/locks.c | 13 +++++++++++-- fs/xfs/xfs_file.c | 4 ++++ include/linux/fs.h | 13 +++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-)