Commit d9013aae authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] hpfs: deadlock fixes

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).
parent 772fd530
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment