Hi, > The attached patch converts the GFP mask for kmallocs within ext3 to > GFP_NOFS whenever they are called with an active journal handle. > <snip> > * Fix the kmalloc flags used from within ext3, when we have an active journal > handle > > If we do a kmalloc with GFP_KERNEL on system running low on memory, > with an active journal handle, we might end up in cleaning up the fs cache > flushing dirty inodes for some other filesystem. This would cause hitting a > J_ASSERT() in : > > handle_t *journal_start(journal_t *journal, int nblocks) > { > handle_t *handle = journal_current_handle(); > int err; > [...] > > if (handle) { > J_ASSERT(handle->h_transaction->t_journal == journal); As I've looked at your trace your analysis seems to be correct and the patch is fine too. It's just sad that we have to do GFP_NOFS allocation at so many places... You can add: Signed-off-by: Jan Kara <[EMAIL PROTECTED]>
<snip> > Signed-off-by: Suzuki K P <[EMAIL PROTECTED]> > > Index: linux-2.6.20-rc1/fs/ext3/xattr.c > =================================================================== > --- linux-2.6.20-rc1.orig/fs/ext3/xattr.c 2006-12-13 17:14:23.000000000 > -0800 > +++ linux-2.6.20-rc1/fs/ext3/xattr.c 2006-12-19 11:41:35.000000000 -0800 > @@ -718,7 +718,7 @@ > ce = NULL; > } > ea_bdebug(bs->bh, "cloning"); > - s->base = kmalloc(bs->bh->b_size, GFP_KERNEL); > + s->base = kmalloc(bs->bh->b_size, GFP_NOFS); > error = -ENOMEM; > if (s->base == NULL) > goto cleanup; > @@ -730,7 +730,7 @@ > } > } else { > /* Allocate a buffer where we construct the new block. */ > - s->base = kmalloc(sb->s_blocksize, GFP_KERNEL); > + s->base = kmalloc(sb->s_blocksize, GFP_NOFS); > /* assert(header == s->base) */ > error = -ENOMEM; > if (s->base == NULL) > Index: linux-2.6.20-rc1/fs/ext3/resize.c > =================================================================== > --- linux-2.6.20-rc1.orig/fs/ext3/resize.c 2006-12-13 17:14:23.000000000 > -0800 > +++ linux-2.6.20-rc1/fs/ext3/resize.c 2006-12-19 11:42:39.000000000 -0800 > @@ -440,7 +440,7 @@ > goto exit_dindj; > > n_group_desc = kmalloc((gdb_num + 1) * sizeof(struct buffer_head *), > - GFP_KERNEL); > + GFP_NOFS); > if (!n_group_desc) { > err = -ENOMEM; > ext3_warning (sb, __FUNCTION__, > @@ -524,7 +524,7 @@ > int res, i; > int err; > > - primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_KERNEL); > + primary = kmalloc(reserved_gdb * sizeof(*primary), GFP_NOFS); > if (!primary) > return -ENOMEM; > > Index: linux-2.6.20-rc1/fs/ext3/acl.c > =================================================================== > --- linux-2.6.20-rc1.orig/fs/ext3/acl.c 2006-12-13 17:14:23.000000000 > -0800 > +++ linux-2.6.20-rc1/fs/ext3/acl.c 2006-12-19 11:45:35.000000000 -0800 > @@ -37,7 +37,7 @@ > return ERR_PTR(-EINVAL); > if (count == 0) > return NULL; > - acl = posix_acl_alloc(count, GFP_KERNEL); > + acl = posix_acl_alloc(count, GFP_NOFS); > if (!acl) > return ERR_PTR(-ENOMEM); > for (n=0; n < count; n++) { > @@ -91,7 +91,7 @@ > > *size = ext3_acl_size(acl->a_count); > ext_acl = kmalloc(sizeof(ext3_acl_header) + acl->a_count * > - sizeof(ext3_acl_entry), GFP_KERNEL); > + sizeof(ext3_acl_entry), GFP_NOFS); > if (!ext_acl) > return ERR_PTR(-ENOMEM); > ext_acl->a_version = cpu_to_le32(EXT3_ACL_VERSION); > @@ -187,7 +187,7 @@ > } > retval = ext3_xattr_get(inode, name_index, "", NULL, 0); > if (retval > 0) { > - value = kmalloc(retval, GFP_KERNEL); > + value = kmalloc(retval, GFP_NOFS); > if (!value) > return ERR_PTR(-ENOMEM); > retval = ext3_xattr_get(inode, name_index, "", value, retval); > @@ -335,7 +335,7 @@ > if (error) > goto cleanup; > } > - clone = posix_acl_clone(acl, GFP_KERNEL); > + clone = posix_acl_clone(acl, GFP_NOFS); > error = -ENOMEM; > if (!clone) > goto cleanup; Honza -- Jan Kara <[EMAIL PROTECTED]> SuSE CR Labs - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/