Re: [patch 1/2] reiserfs: locking, handle nested locks properly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 8/6/13 5:10 PM, Jeff Mahoney wrote:
> On 8/6/13 4:46 PM, Jan Kara wrote:
>> On Mon 05-08-13 20:12:17, Jeff Mahoney wrote:
>>> The reiserfs write lock replaced the BKL and uses similar semantics.
>>>
>>> Frederic's locking code makes a distinction between when the lock is nested
>>> and when it's being acquired/released, but I don't think that's the right
>>> distinction to make.
>>>
>>> The right distinction is between the lock being released at end-of-use and
>>> the lock being released for a schedule. The unlock should return the depth
>>> and the lock should restore it, rather than the other way around as it is now.
>>>
>>> This patch implements that and adds a number of places where the lock
>>> should be dropped.
>> ...
>>
>>> --- a/fs/reiserfs/reiserfs.h	2013-08-05 20:08:59.258412220 -0400
>>> +++ b/fs/reiserfs/reiserfs.h	2013-08-05 20:09:52.537601042 -0400
>>> @@ -630,8 +630,8 @@ static inline int __reiserfs_is_journal_
>>>   */
>>>  void reiserfs_write_lock(struct super_block *s);
>>>  void reiserfs_write_unlock(struct super_block *s);
>>> -int reiserfs_write_lock_once(struct super_block *s);
>>> -void reiserfs_write_unlock_once(struct super_block *s, int lock_depth);
>>> +int __must_check reiserfs_write_unlock_nested(struct super_block *s);
>>> +void reiserfs_write_lock_nested(struct super_block *s, int depth);
>>>  
>>>  #ifdef CONFIG_REISERFS_CHECK
>>>  void reiserfs_lock_check_recursive(struct super_block *s);
>>> @@ -666,45 +666,54 @@ static inline void reiserfs_lock_check_r
>>>   * - The journal lock
>>>   * - The inode mutex
>>>   */
>>> -static inline void reiserfs_mutex_lock_safe(struct mutex *m,
>>> -			       struct super_block *s)
>>> +
>>> +#define reiserfs_safe(sb, action)			\
>>> +do {							\
>>> +	struct super_block *__sb = (sb);		\
>>> +	int __depth;					\
>>> +	__depth = reiserfs_write_unlock_nested(__sb);	\
>>> +	(action);					\
>>> +	reiserfs_write_lock_nested(__sb, __depth);	\
>>> +} while(0)
>>> +
>>> +#define reiserfs_mutex_lock_safe(mtx, s) reiserfs_safe(s, mutex_lock(mtx))
>>> +#define reiserfs_mutex_lock_nested_safe(mtx, subclass, s) \
>>> +	reiserfs_safe(s, mutex_lock_nested(mtx, subclass))
>>> +#define reiserfs_down_read_safe(sem, s) reiserfs_safe(s, down_read(sem))
>>> +
>>> +/*
>>> + * When we schedule, we usually want to also release the write lock,
>>> + * according to the previous bkl based locking scheme of reiserfs.
>>> + */
>>> +static inline void reiserfs_cond_resched(struct super_block *s)
>>>  {
>>> -	reiserfs_lock_check_recursive(s);
>>> -	reiserfs_write_unlock(s);
>>> -	mutex_lock(m);
>>> -	reiserfs_write_lock(s);
>>> +	if (need_resched())
>>> +		reiserfs_safe(s, schedule());
>>>  }
>>>  
>>> -static inline void
>>> -reiserfs_mutex_lock_nested_safe(struct mutex *m, unsigned int subclass,
>>> -			       struct super_block *s)
>>> +static inline struct buffer_head *
>>> +reiserfs_safe_sb_bread(struct super_block *s, sector_t block)
>>>  {
>>> -	reiserfs_lock_check_recursive(s);
>>> -	reiserfs_write_unlock(s);
>>> -	mutex_lock_nested(m, subclass);
>>> -	reiserfs_write_lock(s);
>>> +	int depth;
>>> +	struct buffer_head *bh;
>>> +
>>> +	depth = reiserfs_write_unlock_nested(s);
>>> +	bh = sb_bread(s, block);
>>> +	reiserfs_write_lock_nested(s, depth);
>>> +
>>> +	return bh;
>>>  }
>>>
>>> +void reiserfs_safe_lock_buffer(struct buffer_head *bh);
>>> +
>>>  static inline void
>>> -reiserfs_down_read_safe(struct rw_semaphore *sem, struct super_block *s)
>>> +reiserfs_safe_wait_on_buffer(struct buffer_head *bh, struct super_block *s)
>>>  {
>>> -	reiserfs_lock_check_recursive(s);
>>> -	reiserfs_write_unlock(s);
>>> -	down_read(sem);
>>> -	reiserfs_write_lock(s);
>>> -}
>>> +	int depth;
>>>  
>>> -/*
>>> - * When we schedule, we usually want to also release the write lock,
>>> - * according to the previous bkl based locking scheme of reiserfs.
>>> - */
>>> -static inline void reiserfs_cond_resched(struct super_block *s)
>>> -{
>>> -	if (need_resched()) {
>>> -		reiserfs_write_unlock(s);
>>> -		schedule();
>>> -		reiserfs_write_lock(s);
>>> -	}
>>> +	depth = reiserfs_write_unlock_nested(s);
>>> +	__wait_on_buffer(bh);
>>> +	reiserfs_write_lock_nested(s, depth);
>>>  }
>>>  
>>>  struct fid;
>>> @@ -2463,6 +2472,15 @@ int reiserfs_commit_for_inode(struct ino
>>>  int reiserfs_inode_needs_commit(struct inode *);
>>>  void reiserfs_update_inode_transaction(struct inode *);
>>>  void reiserfs_wait_on_write_block(struct super_block *s);
>>> +static inline void reiserfs_safe_wait_on_write_block(struct super_block *s)
>>> +{
>>> +	int depth;
>>> +
>>> +	depth = reiserfs_write_unlock_nested(s);
>>> +	reiserfs_wait_on_write_block(s);
>>> +	reiserfs_write_lock_nested(s, depth);
>>> +}
>>> +
>>   I didn't find where the above 'safe' functions are called...
> 
> Whoa. WTF. Thanks for the review. These aren't the same patches as the
> ones in my repo. No idea why these got sent instead of the right ones!

Actually, they are. The end result is right but the reiserfs_safe()
macro was an idea I had and then decided against it. It shouldn't be in
the final version. I must've accidentally merged the removal in the
wrong patch.

-Jeff


-- 
Jeff Mahoney
SUSE Labs

Attachment: signature.asc
Description: OpenPGP digital signature


[Index of Archives]     [Linux File System Development]     [Linux BTRFS]     [Linux NFS]     [Linux Filesystems]     [Ext4 Filesystem]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Resources]

  Powered by Linux