@@ -369,10 +369,19 @@ locks_dispose_list(struct list_head *dispose)
369369 while (!list_empty (dispose )) {
370370 flc = list_first_entry (dispose , struct file_lock_core , flc_list );
371371 list_del_init (& flc -> flc_list );
372- if (flc -> flc_flags & (FL_LEASE |FL_DELEG |FL_LAYOUT ))
373- locks_free_lease (file_lease (flc ));
374- else
375- locks_free_lock (file_lock (flc ));
372+ locks_free_lock (file_lock (flc ));
373+ }
374+ }
375+
376+ static void
377+ lease_dispose_list (struct list_head * dispose )
378+ {
379+ struct file_lock_core * flc ;
380+
381+ while (!list_empty (dispose )) {
382+ flc = list_first_entry (dispose , struct file_lock_core , flc_list );
383+ list_del_init (& flc -> flc_list );
384+ locks_free_lease (file_lease (flc ));
376385 }
377386}
378387
@@ -576,10 +585,50 @@ lease_setup(struct file_lease *fl, void **priv)
576585 __f_setown (filp , task_pid (current ), PIDTYPE_TGID , 0 );
577586}
578587
588+ /**
589+ * lease_open_conflict - see if the given file points to an inode that has
590+ * an existing open that would conflict with the
591+ * desired lease.
592+ * @filp: file to check
593+ * @arg: type of lease that we're trying to acquire
594+ *
595+ * Check to see if there's an existing open fd on this file that would
596+ * conflict with the lease we're trying to set.
597+ */
598+ static int
599+ lease_open_conflict (struct file * filp , const int arg )
600+ {
601+ struct inode * inode = file_inode (filp );
602+ int self_wcount = 0 , self_rcount = 0 ;
603+
604+ if (arg == F_RDLCK )
605+ return inode_is_open_for_write (inode ) ? - EAGAIN : 0 ;
606+ else if (arg != F_WRLCK )
607+ return 0 ;
608+
609+ /*
610+ * Make sure that only read/write count is from lease requestor.
611+ * Note that this will result in denying write leases when i_writecount
612+ * is negative, which is what we want. (We shouldn't grant write leases
613+ * on files open for execution.)
614+ */
615+ if (filp -> f_mode & FMODE_WRITE )
616+ self_wcount = 1 ;
617+ else if (filp -> f_mode & FMODE_READ )
618+ self_rcount = 1 ;
619+
620+ if (atomic_read (& inode -> i_writecount ) != self_wcount ||
621+ atomic_read (& inode -> i_readcount ) != self_rcount )
622+ return - EAGAIN ;
623+
624+ return 0 ;
625+ }
626+
579627static const struct lease_manager_operations lease_manager_ops = {
580628 .lm_break = lease_break_callback ,
581629 .lm_change = lease_modify ,
582630 .lm_setup = lease_setup ,
631+ .lm_open_conflict = lease_open_conflict ,
583632};
584633
585634/*
@@ -1620,7 +1669,7 @@ int __break_lease(struct inode *inode, unsigned int flags)
16201669 spin_unlock (& ctx -> flc_lock );
16211670 percpu_up_read (& file_rwsem );
16221671
1623- locks_dispose_list (& dispose );
1672+ lease_dispose_list (& dispose );
16241673 error = wait_event_interruptible_timeout (new_fl -> c .flc_wait ,
16251674 list_empty (& new_fl -> c .flc_blocked_member ),
16261675 break_time );
@@ -1643,7 +1692,7 @@ int __break_lease(struct inode *inode, unsigned int flags)
16431692out :
16441693 spin_unlock (& ctx -> flc_lock );
16451694 percpu_up_read (& file_rwsem );
1646- locks_dispose_list (& dispose );
1695+ lease_dispose_list (& dispose );
16471696free_lock :
16481697 locks_free_lease (new_fl );
16491698 return error ;
@@ -1727,7 +1776,7 @@ static int __fcntl_getlease(struct file *filp, unsigned int flavor)
17271776 spin_unlock (& ctx -> flc_lock );
17281777 percpu_up_read (& file_rwsem );
17291778
1730- locks_dispose_list (& dispose );
1779+ lease_dispose_list (& dispose );
17311780 }
17321781 return type ;
17331782}
@@ -1745,52 +1794,6 @@ int fcntl_getdeleg(struct file *filp, struct delegation *deleg)
17451794 return 0 ;
17461795}
17471796
1748- /**
1749- * check_conflicting_open - see if the given file points to an inode that has
1750- * an existing open that would conflict with the
1751- * desired lease.
1752- * @filp: file to check
1753- * @arg: type of lease that we're trying to acquire
1754- * @flags: current lock flags
1755- *
1756- * Check to see if there's an existing open fd on this file that would
1757- * conflict with the lease we're trying to set.
1758- */
1759- static int
1760- check_conflicting_open (struct file * filp , const int arg , int flags )
1761- {
1762- struct inode * inode = file_inode (filp );
1763- int self_wcount = 0 , self_rcount = 0 ;
1764-
1765- if (flags & FL_LAYOUT )
1766- return 0 ;
1767- if (flags & FL_DELEG )
1768- /* We leave these checks to the caller */
1769- return 0 ;
1770-
1771- if (arg == F_RDLCK )
1772- return inode_is_open_for_write (inode ) ? - EAGAIN : 0 ;
1773- else if (arg != F_WRLCK )
1774- return 0 ;
1775-
1776- /*
1777- * Make sure that only read/write count is from lease requestor.
1778- * Note that this will result in denying write leases when i_writecount
1779- * is negative, which is what we want. (We shouldn't grant write leases
1780- * on files open for execution.)
1781- */
1782- if (filp -> f_mode & FMODE_WRITE )
1783- self_wcount = 1 ;
1784- else if (filp -> f_mode & FMODE_READ )
1785- self_rcount = 1 ;
1786-
1787- if (atomic_read (& inode -> i_writecount ) != self_wcount ||
1788- atomic_read (& inode -> i_readcount ) != self_rcount )
1789- return - EAGAIN ;
1790-
1791- return 0 ;
1792- }
1793-
17941797static int
17951798generic_add_lease (struct file * filp , int arg , struct file_lease * * flp , void * * priv )
17961799{
@@ -1827,7 +1830,7 @@ generic_add_lease(struct file *filp, int arg, struct file_lease **flp, void **pr
18271830 percpu_down_read (& file_rwsem );
18281831 spin_lock (& ctx -> flc_lock );
18291832 time_out_leases (inode , & dispose );
1830- error = check_conflicting_open (filp , arg , lease -> c . flc_flags );
1833+ error = lease -> fl_lmops -> lm_open_conflict (filp , arg );
18311834 if (error )
18321835 goto out ;
18331836
@@ -1884,7 +1887,7 @@ generic_add_lease(struct file *filp, int arg, struct file_lease **flp, void **pr
18841887 * precedes these checks.
18851888 */
18861889 smp_mb ();
1887- error = check_conflicting_open (filp , arg , lease -> c . flc_flags );
1890+ error = lease -> fl_lmops -> lm_open_conflict (filp , arg );
18881891 if (error ) {
18891892 locks_unlink_lock_ctx (& lease -> c );
18901893 goto out ;
@@ -1896,7 +1899,7 @@ generic_add_lease(struct file *filp, int arg, struct file_lease **flp, void **pr
18961899out :
18971900 spin_unlock (& ctx -> flc_lock );
18981901 percpu_up_read (& file_rwsem );
1899- locks_dispose_list (& dispose );
1902+ lease_dispose_list (& dispose );
19001903 if (is_deleg )
19011904 inode_unlock (inode );
19021905 if (!error && !my_fl )
@@ -1932,7 +1935,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
19321935 error = fl -> fl_lmops -> lm_change (victim , F_UNLCK , & dispose );
19331936 spin_unlock (& ctx -> flc_lock );
19341937 percpu_up_read (& file_rwsem );
1935- locks_dispose_list (& dispose );
1938+ lease_dispose_list (& dispose );
19361939 return error ;
19371940}
19381941
@@ -2727,7 +2730,7 @@ locks_remove_lease(struct file *filp, struct file_lock_context *ctx)
27272730 spin_unlock (& ctx -> flc_lock );
27282731 percpu_up_read (& file_rwsem );
27292732
2730- locks_dispose_list (& dispose );
2733+ lease_dispose_list (& dispose );
27312734}
27322735
27332736/*
0 commit comments