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/

Reply via email to