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