Re: [PATCH 3.9-stable] reiserfs: fix deadlock with nfs racing on create/lookup

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

 



On Sat 01-06-13 18:47:46, Jonghwan Choi wrote:
> From: Jeff Mahoney <jeffm@xxxxxxxx>
> 
> This patch looks like it should be in the 3.9-stable tree, should we apply
> it?
  Yes, please do. Thanks!

								Honza
> 
> ------------------
> 
> From: "Jeff Mahoney <jeffm@xxxxxxxx>"
> 
> commit a1457c0ce976bad1356b9b0437f2a5c3ab8a9cfc upstream
> 
> Reiserfs is currently able to be deadlocked by having two NFS clients
> where one has removed and recreated a file and another is accessing the
> file with an open file handle.
> 
> If one client deletes and recreates a file with timing such that the
> recreated file obtains the same [dirid, objectid] pair as the original
> file while another client accesses the file via file handle, the create
> and lookup can race and deadlock if the lookup manages to create the
> in-memory inode first.
> 
> The create thread, in insert_inode_locked4, will hold the write lock
> while waiting on the other inode to be unlocked. The lookup thread,
> anywhere in the iget path, will release and reacquire the write lock while
> it schedules. If it needs to reacquire the lock while the create thread
> has it, it will never be able to make forward progress because it needs
> to reacquire the lock before ultimately unlocking the inode.
> 
> This patch drops the write lock across the insert_inode_locked4 call so
> that the ordering of inode_wait -> write lock is retained. Since this
> would have been the case before the BKL push-down, this is safe.
> 
> Signed-off-by: Jeff Mahoney <jeffm@xxxxxxxx>
> Signed-off-by: Jan Kara <jack@xxxxxxx>
> Signed-off-by: Jonghwan Choi <jhbird.choi@xxxxxxxxxxx>
> ---
>  fs/reiserfs/inode.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
> index ea5061f..c3a9de6 100644
> --- a/fs/reiserfs/inode.c
> +++ b/fs/reiserfs/inode.c
> @@ -1810,11 +1810,16 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
>  				  TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
>  	memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE);
>  	args.dirid = le32_to_cpu(ih.ih_key.k_dir_id);
> -	if (insert_inode_locked4(inode, args.objectid,
> -			     reiserfs_find_actor, &args) < 0) {
> +
> +	reiserfs_write_unlock(inode->i_sb);
> +	err = insert_inode_locked4(inode, args.objectid,
> +			     reiserfs_find_actor, &args);
> +	reiserfs_write_lock(inode->i_sb);
> +	if (err) {
>  		err = -EINVAL;
>  		goto out_bad_inode;
>  	}
> +
>  	if (old_format_only(sb))
>  		/* not a perfect generation count, as object ids can be reused, but
>  		 ** this is as good as reiserfs can do right now.
> -- 
> 1.8.1.2
> 
-- 
Jan Kara <jack@xxxxxxx>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]