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-ext4" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html