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

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

 



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...

								Honza
-- 
Jan Kara <jack@xxxxxxx>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe reiserfs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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