Kalpak Shah wrote: > ext4_xattr_set_handle() eventually ends up calling > ext4_mark_inode_dirty() which tries to expand the inode by shifting the > EAs. This leads to the xattr_sem being downed again and leading to a > deadlock. > > This patch makes sure that if ext4_xattr_set_handle() is in the > call-chain, ext4_mark_inode_dirty() will not expand the inode. > > Signed-off-by: Kalpak Shah <kalpak.shah@xxxxxxx> Yes, this fixes my testcase. Thanks, Kalpak. -Eric > Index: linux-2.6.27-rc7/fs/ext4/xattr.c > =================================================================== > --- linux-2.6.27-rc7.orig/fs/ext4/xattr.c > +++ linux-2.6.27-rc7/fs/ext4/xattr.c > @@ -959,6 +959,7 @@ ext4_xattr_set_handle(handle_t *handle, > struct ext4_xattr_block_find bs = { > .s = { .not_found = -ENODATA, }, > }; > + unsigned long no_expand; > int error; > > if (!name) > @@ -966,6 +967,9 @@ ext4_xattr_set_handle(handle_t *handle, > if (strlen(name) > 255) > return -ERANGE; > down_write(&EXT4_I(inode)->xattr_sem); > + no_expand = EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND; > + EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND; > + > error = ext4_get_inode_loc(inode, &is.iloc); > if (error) > goto cleanup; > @@ -1042,6 +1046,8 @@ ext4_xattr_set_handle(handle_t *handle, > cleanup: > brelse(is.iloc.bh); > brelse(bs.bh); > + if (no_expand == 0) > + EXT4_I(inode)->i_state &= ~EXT4_STATE_NO_EXPAND; > up_write(&EXT4_I(inode)->xattr_sem); > return error; > } > > Thanks, > Kalpak > > -- > To unsubscribe from this list: send the line "unsubscribe linux-ext4" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html