Messages in this thread Patch in this message |  | | From | Andreas Dilger <> | Subject | Re: Small bugfix in ext2/namei.c | Date | Fri, 1 Sep 2000 14:20:00 -0600 (MDT) |
| |
Theodore Ts'o writes: > Dr. Michael Weller writes: > > Sorry, I've no idea about the ext2 and fs implementation. > > However did you read the comment below and convince yourself that 'err' is > > always set correctly? > > I looked at it and was convinced.
Ted and I submitted patches to this effect some months ago after I went through all of the code paths for ext2_new_inode(), and I even thought we removed all the comments about ext2_new_inode() not setting err. See thread http://kernelnotes.org/lnxlists/linux-kernel/lk_0005_05/msg00090.html for more information.
It looks like it made it into test1-ac4 but was lost in test2... Some of the older patch is now irrelevant because ext2_getblk() was rewritten, so here is a newer version of the patch to fix the error return codes.
Ted, please have a look (it is basically the same as the old patch), and send it on to Linus.
Cheers, Andreas ---- cut here ---- diff -u linux/fs/ext2/balloc.c~ linux/fs/ext2/balloc.c --- linux/fs/ext2/balloc.c~ Mon May 29 20:05:45 2000 +++ linux/fs/ext2/balloc.c Fri Sep 01 13:42:21 2000 @@ -470,10 +470,8 @@ if (i >= sb->u.ext2_sb.s_groups_count) i = 0; gdp = ext2_get_group_desc (sb, i, &bh2); - if (!gdp) { - *err = -EIO; - goto out; - } + if (!gdp) + goto io_error; if (le16_to_cpu(gdp->bg_free_blocks_count) > 0) break; } diff -u linux/fs/ext2/ialloc.c~ linux/fs/ext2/ialloc.c --- linux/fs/ext2/ialloc.c~ Mon May 29 20:05:45 2000 +++ linux/fs/ext2/ialloc.c Fri Sep 01 13:42:21 2000 @@ -286,8 +286,7 @@ es = sb->u.ext2_sb.s_es; repeat: gdp = NULL; i=0; - - *err = -ENOSPC; + if (S_ISDIR(mode)) { avefreei = le32_to_cpu(es->s_free_inodes_count) / sb->u.ext2_sb.s_groups_count; @@ -369,6 +368,7 @@ if (!gdp) { unlock_super (sb); iput(inode); + *err = -ENOSPC; return NULL; } bitmap_nr = load_inode_bitmap (sb, i); @@ -416,9 +416,8 @@ ext2_error (sb, "ext2_new_inode", "Free inodes count corrupted in group %d", i); - unlock_super (sb); - iput (inode); - return NULL; + /* If we continue recover from this case */ + gdp->bg_free_inodes_count = 0; } goto repeat; } @@ -429,6 +428,7 @@ "block_group = %d,inode=%d", i, j); unlock_super (sb); iput (inode); + *err = -EIO; /* Should never happen */ return NULL; } gdp->bg_free_inodes_count = diff -u linux/fs/ext2/inode.c~ linux/fs/ext2/inode.c --- linux/fs/ext2/inode.c~ Sun Mar 26 21:34:49 2000 +++ linux/fs/ext2/inode.c Mon May 29 10:36:34 2000 @@ -117,7 +117,7 @@ inode->u.ext2_i.i_prealloc_count--; ext2_debug ("preallocation hit (%lu/%lu).\n", ++alloc_hits, ++alloc_attempts); - + *err = 0; } else { ext2_discard_prealloc (inode); ext2_debug ("preallocation miss (%lu/%lu).\n", @@ -606,13 +606,11 @@ struct buffer_head * ext2_getblk(struct inode * inode, long block, int create, int * err) { struct buffer_head dummy; - int error; dummy.b_state = 0; dummy.b_blocknr = -1000; - error = ext2_get_block(inode, block, &dummy, create); - *err = error; - if (!error && buffer_mapped(&dummy)) { + *err = ext2_get_block(inode, block, &dummy, create); + if (!*err && buffer_mapped(&dummy)) { struct buffer_head *bh; bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize); if (buffer_new(&dummy)) { @@ -940,8 +938,23 @@ raw_inode->i_file_acl = cpu_to_le32(inode->u.ext2_i.i_file_acl); if (S_ISDIR(inode->i_mode)) raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext2_i.i_dir_acl); - else + else { raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32); + if (inode->i_size >> 31) { + struct super_block *sb = inode->i_sb; + struct ext2_super_block *es = sb->u.ext2_sb.s_es; + if (!(es->s_feature_ro_compat & cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE))) { + /* If this is the first large file + * created, add a flag to the superblock + * SMP Note: we're currently protected by the + * big kernel lock here, so this will need + * to be changed if that's no longer true. + */ + es->s_feature_ro_compat |= cpu_to_le32(EXT2_FEATURE_RO_COMPAT_LARGE_FILE); + ext2_write_super(sb); + } + } + } raw_inode->i_generation = cpu_to_le32(inode->i_generation); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) diff -u linux/fs/ext2/namei.c~ linux/fs/ext2/namei.c --- linux/fs/ext2/namei.c~ Thu Apr 27 22:42:20 2000 +++ linux/fs/ext2/namei.c Fri Sep 01 09:30:51 2000 @@ -366,12 +366,9 @@ struct inode * inode; int err; - /* - * N.B. Several error exits in ext2_new_inode don't set err. - */ inode = ext2_new_inode (dir, mode, &err); if (!inode) - return -EIO; + return err; inode->i_op = &ext2_file_inode_operations; inode->i_fop = &ext2_file_operations; @@ -397,7 +394,7 @@ inode = ext2_new_inode (dir, mode, &err); if (!inode) - return -EIO; + return err; inode->i_uid = current->fsuid; init_special_inode(inode, mode, rdev); @@ -428,7 +428,7 @@ inode = ext2_new_inode (dir, S_IFDIR, &err); if (!inode) - return -EIO; + return err; inode->i_op = &ext2_dir_inode_operations; inode->i_fop = &ext2_dir_operations; @@ -439,7 +439,7 @@ inode->i_nlink--; /* is this nlink == 0? */ mark_inode_dirty(inode); iput (inode); - return -EIO; + return err; } de = (struct ext2_dir_entry_2 *) dir_block->b_data; de->inode = cpu_to_le32(inode->i_ino); @@ -634,7 +631,7 @@ return -ENAMETOOLONG; if (!(inode = ext2_new_inode (dir, S_IFLNK, &err))) - return -EIO; + return err; inode->i_mode = S_IFLNK | S_IRWXUGO; ---- cut here ---- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
|  |