Messages in this thread Patch in this message | | | Date | Tue, 09 Sep 1997 09:24:17 -0400 | From | Bill Hawes <> | Subject | patch for 2.1.55 pre-1 minix/sysv/affs |
| |
The attached patch takes care of some additional mark_inode_dirty ordering problems in the minix, sysv, and affs code. I also moved some error cleanup code out the the main flow of control.
Regards, Bill--- linux-2.1.54/fs/minix/bitmap.c.old Thu Jul 24 17:36:07 1997 +++ linux-2.1.54/fs/minix/bitmap.c Mon Sep 8 22:49:34 1997 @@ -227,7 +227,7 @@ int i,j; if (!dir || !(inode = get_empty_inode())) - return NULL; + goto out; sb = dir->i_sb; inode->i_sb = sb; inode->i_flags = inode->i_sb->s_flags; @@ -236,32 +236,33 @@ if ((bh = inode->i_sb->u.minix_sb.s_imap[i]) != NULL) if ((j=minix_find_first_zero_bit(bh->b_data, 8192)) < 8192) break; - if (!bh || j >= 8192) { - iput(inode); - return NULL; - } - if (minix_set_bit(j,bh->b_data)) { /* shouldn't happen */ - printk("new_inode: bit already set"); - iput(inode); - return NULL; - } + if (!bh || j >= 8192) + goto iput_and_out; + if (minix_set_bit(j,bh->b_data)) + goto complain_and_out; mark_buffer_dirty(bh, 1); j += i*8192; - if (!j || j >= inode->i_sb->u.minix_sb.s_ninodes) { - iput(inode); - return NULL; - } + /* N.B. should this test precede minix_set_bit? */ + if (!j || j >= inode->i_sb->u.minix_sb.s_ninodes) + goto iput_and_out; inode->i_nlink = 1; inode->i_dev = sb->s_dev; inode->i_uid = current->fsuid; inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; - mark_inode_dirty(inode); inode->i_ino = j; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_op = NULL; inode->i_blocks = inode->i_blksize = 0; insert_inode_hash(inode); + mark_inode_dirty(inode); return inode; + +complain_and_out: + printk("new_inode: bit already set"); +iput_and_out: + iput(inode); +out: + return NULL; } unsigned long minix_count_free_inodes(struct super_block *sb) --- linux-2.1.54/fs/sysv/ialloc.c.old Sat Jul 19 08:17:14 1997 +++ linux-2.1.54/fs/sysv/ialloc.c Mon Sep 8 22:55:45 1997 @@ -154,12 +154,12 @@ inode->i_dev = sb->s_dev; inode->i_uid = current->fsuid; inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; - mark_inode_dirty(inode); inode->i_ino = ino; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_op = NULL; inode->i_blocks = inode->i_blksize = 0; insert_inode_hash(inode); + mark_inode_dirty(inode); /* Change directory entry: */ inode->i_mode = 0; /* for sysv_write_inode() */ inode->i_size = 0; /* ditto */ --- linux-2.1.54/fs/affs/inode.c.old Wed Sep 3 17:57:46 1997 +++ linux-2.1.54/fs/affs/inode.c Mon Sep 8 23:09:29 1997 @@ -864,6 +864,9 @@ return 0; } +/* + * N.B. This code must be split into put_inode and delete_inode operations + */ static void affs_put_inode(struct inode *inode) { @@ -892,23 +895,20 @@ s32 block; if (!dir || !(inode = get_empty_inode())) - return NULL; + goto out; sb = dir->i_sb; inode->i_sb = sb; inode->i_flags = sb->s_flags; - if (!(block = affs_new_header((struct inode *)dir))) { - iput(inode); - return NULL; - } + if (!(block = affs_new_header((struct inode *)dir))) + goto iput_and_out; inode->i_count = 1; inode->i_nlink = 1; inode->i_dev = sb->s_dev; inode->i_uid = current->fsuid; inode->i_gid = current->fsgid; - mark_inode_dirty(inode); inode->i_ino = block; inode->i_op = NULL; inode->i_blocks = 0; @@ -928,8 +928,14 @@ inode->u.affs_i.i_lastblock = -1; insert_inode_hash(inode); + mark_inode_dirty(inode); return inode; + +iput_and_out: + iput(inode); +out: + return NULL; } int | |