]> git.hungrycats.org Git - linux/commitdiff
[PATCH] hpfs: deadlock fixes
authorAlexander Viro <viro@www.linux.org.uk>
Thu, 18 Mar 2004 05:24:12 +0000 (21:24 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 18 Mar 2004 05:24:12 +0000 (21:24 -0800)
We used to have GFP_KERNEL kmalloc() done by the code that held hpfs
lock on directory.  That could trigger a call of hpfs_write_inode() and
deadlock; fixed by switch to GFP_NOFS.  Same for hpfs inodes themselves
- hpfs_write_inode() calls iget() and that could trigger both the
deadlocks (avoidable with very baroque locking scheme) and stack
overflows (unavoidable unless we kill potential recursion here).

fs/hpfs/buffer.c
fs/hpfs/dnode.c
fs/hpfs/ea.c
fs/hpfs/super.c

index 65f7e2f1667ee1d811ab8fbfbe1ac3dc98f2a57d..7453c07976e796a5422abdbdfcdfb290e49e80f1 100644 (file)
@@ -88,7 +88,7 @@ void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffe
                return 0;
        }
 
-       qbh->data = data = (char *)kmalloc(2048, GFP_KERNEL);
+       qbh->data = data = (char *)kmalloc(2048, GFP_NOFS);
        if (!data) {
                printk("HPFS: hpfs_map_4sectors: out of memory\n");
                goto bail;
@@ -140,7 +140,7 @@ void *hpfs_get_4sectors(struct super_block *s, unsigned secno,
        }
 
        /*return hpfs_map_4sectors(s, secno, qbh, 0);*/
-       if (!(qbh->data = kmalloc(2048, GFP_KERNEL))) {
+       if (!(qbh->data = kmalloc(2048, GFP_NOFS))) {
                printk("HPFS: hpfs_get_4sectors: out of memory\n");
                return NULL;
        }
index fbe4b03e3ab46b4f7b3f1eed4190fefafd87ab95..fda1505a5717973efe67b8b88b127d8dada4bf07 100644 (file)
@@ -32,7 +32,7 @@ void hpfs_add_pos(struct inode *inode, loff_t *pos)
                for (; hpfs_inode->i_rddir_off[i]; i++)
                        if (hpfs_inode->i_rddir_off[i] == pos) return;
        if (!(i&0x0f)) {
-               if (!(ppos = kmalloc((i+0x11) * sizeof(loff_t*), GFP_KERNEL))) {
+               if (!(ppos = kmalloc((i+0x11) * sizeof(loff_t*), GFP_NOFS))) {
                        printk("HPFS: out of memory for position list\n");
                        return;
                }
@@ -236,7 +236,7 @@ int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, unsigned char *name, uns
        struct buffer_head *bh;
        struct fnode *fnode;
        int c1, c2 = 0;
-       if (!(nname = kmalloc(256, GFP_KERNEL))) {
+       if (!(nname = kmalloc(256, GFP_NOFS))) {
                printk("HPFS: out of memory, can't add to dnode\n");
                return 1;
        }
@@ -273,7 +273,7 @@ int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, unsigned char *name, uns
                kfree(nname);
                return 0;
        }
-       if (!nd) if (!(nd = kmalloc(0x924, GFP_KERNEL))) {
+       if (!nd) if (!(nd = kmalloc(0x924, GFP_NOFS))) {
                /* 0x924 is a max size of dnode after adding a dirent with
                   max name length. We alloc this only once. There must
                   not be any error while splitting dnodes, otherwise the
@@ -478,7 +478,7 @@ static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
        t = get_pos(dnode, de);
        for_all_poss(i, hpfs_pos_subst, t, 4);
        for_all_poss(i, hpfs_pos_subst, t + 1, 5);
-       if (!(nde = kmalloc(de->length, GFP_KERNEL))) {
+       if (!(nde = kmalloc(de->length, GFP_NOFS))) {
                hpfs_error(i->i_sb, "out of memory for dirent - directory will be corrupted");
                hpfs_brelse4(&qbh);
                return 0;
@@ -588,7 +588,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
                struct quad_buffer_head qbh1;
                if (!de_next->down) goto endm;
                ndown = de_down_pointer(de_next);
-               if (!(de_cp = kmalloc(de->length, GFP_KERNEL))) {
+               if (!(de_cp = kmalloc(de->length, GFP_NOFS))) {
                        printk("HPFS: out of memory for dtree balancing\n");
                        goto endm;
                }
@@ -650,7 +650,7 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno)
                        } else if (down)
                                *(dnode_secno *) ((void *) del + del->length - 4) = down;
                } else goto endm;
-               if (!(de_cp = kmalloc(de_prev->length, GFP_KERNEL))) {
+               if (!(de_cp = kmalloc(de_prev->length, GFP_NOFS))) {
                        printk("HPFS: out of memory for dtree balancing\n");
                        hpfs_brelse4(&qbh1);
                        goto endm;
@@ -994,7 +994,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
        int c1, c2 = 0;
        int d1, d2 = 0;
        name1 = f->name;
-       if (!(name2 = kmalloc(256, GFP_KERNEL))) {
+       if (!(name2 = kmalloc(256, GFP_NOFS))) {
                printk("HPFS: out of memory, can't map dirent\n");
                return NULL;
        }
index 831429404b8eeab36990017dc134e7b64b274ebb..39caa7b03403d3d8c23d0165f9b43a377aa4f2df 100644 (file)
@@ -52,7 +52,7 @@ void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
 static char *get_indirect_ea(struct super_block *s, int ano, secno a, int size)
 {
        char *ret;
-       if (!(ret = kmalloc(size + 1, GFP_KERNEL))) {
+       if (!(ret = kmalloc(size + 1, GFP_NOFS))) {
                printk("HPFS: out of memory for EA\n");
                return NULL;
        }
@@ -140,7 +140,7 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
                if (!strcmp(ea->name, key)) {
                        if (ea->indirect)
                                return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
-                       if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_KERNEL))) {
+                       if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) {
                                printk("HPFS: out of memory for EA\n");
                                return NULL;
                        }
@@ -166,7 +166,7 @@ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *si
                if (!strcmp(ea->name, key)) {
                        if (ea->indirect)
                                return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
-                       if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_KERNEL))) {
+                       if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) {
                                printk("HPFS: out of memory for EA\n");
                                return NULL;
                        }
index ff630e40b5902cb17a15d71a9f68b716afd46dd9..886760c4c99913152ed098afaf69cb29fc688a2d 100644 (file)
@@ -165,7 +165,7 @@ static kmem_cache_t * hpfs_inode_cachep;
 static struct inode *hpfs_alloc_inode(struct super_block *sb)
 {
        struct hpfs_inode_info *ei;
-       ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, SLAB_KERNEL);
+       ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, SLAB_NOFS);
        if (!ei)
                return NULL;
        ei->vfs_inode.i_version = 1;