On Sat 01-06-13 18:47:46, Jonghwan Choi wrote:
> From: Jeff Mahoney <[email protected]>
>
> 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 <[email protected]>"
>
> 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 <[email protected]>
> Signed-off-by: Jan Kara <[email protected]>
> Signed-off-by: Jonghwan Choi <[email protected]>
> ---
> 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 <[email protected]>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html