--- zzzz-none-000/linux-2.4.17/fs/reiserfs/super.c 2001-12-21 17:42:03.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/fs/reiserfs/super.c 2004-11-24 13:22:10.000000000 +0000 @@ -86,7 +86,7 @@ protecting unlink is bigger that a key lf "save link" which protects truncate), so there left no items to make truncate completion on */ -static void remove_save_link_only (struct super_block * s, struct key * key) +static void remove_save_link_only (struct super_block * s, struct key * key, int oid_free) { struct reiserfs_transaction_handle th; @@ -94,7 +94,7 @@ journal_begin (&th, s, JOURNAL_PER_BALANCE_CNT); reiserfs_delete_solid_item (&th, key); - if (is_direct_le_key (KEY_FORMAT_3_5, key)) + if (oid_free) /* removals are protected by direct items */ reiserfs_release_objectid (&th, le32_to_cpu (key->k_objectid)); @@ -167,7 +167,7 @@ "save" link and release objectid */ reiserfs_warning ("vs-2180: finish_unfinished: iget failed for %K\n", &obj_key); - remove_save_link_only (s, &save_link_key); + remove_save_link_only (s, &save_link_key, 1); continue; } @@ -175,9 +175,21 @@ /* file is not unlinked */ reiserfs_warning ("vs-2185: finish_unfinished: file %K is not unlinked\n", &obj_key); - remove_save_link_only (s, &save_link_key); + remove_save_link_only (s, &save_link_key, 0); continue; } + + if (truncate && S_ISDIR (inode->i_mode) ) { + /* We got a truncate request for a dir which is impossible. + The only imaginable way is to execute unfinished truncate request + then boot into old kernel, remove the file and create dir with + the same key. */ + reiserfs_warning("green-2101: impossible truncate on a directory %k. Please report\n", INODE_PKEY (inode)); + remove_save_link_only (s, &save_link_key, 0); + truncate = 0; + iput (inode); + continue; + } if (truncate) { inode -> u.reiserfs_i.i_flags |= i_link_saved_truncate_mask; @@ -195,7 +207,7 @@ } iput (inode); - reiserfs_warning ("done\n"); + printk ("done\n"); done ++; } s -> u.reiserfs_sb.s_is_unlinked_ok = 0; @@ -243,6 +255,8 @@ 4/*length*/, 0xffff/*free space*/); } else { /* truncate */ + if (S_ISDIR (inode->i_mode)) + reiserfs_warning("green-2102: Adding a truncate savelink for a directory %k! Please report\n", INODE_PKEY(inode)); set_cpu_key_k_offset (&key, 1); set_cpu_key_k_type (&key, TYPE_INDIRECT); @@ -500,13 +514,25 @@ struct reiserfs_super_block * rs; struct reiserfs_transaction_handle th ; unsigned long blocks; - unsigned long mount_options; + unsigned long mount_options = 0; rs = SB_DISK_SUPER_BLOCK (s); if (!parse_options(data, &mount_options, &blocks)) return 0; +#define SET_OPT( opt, bits, super ) \ + if( ( bits ) & ( 1 << ( opt ) ) ) \ + ( super ) -> u.reiserfs_sb.s_mount_opt |= ( 1 << ( opt ) ) + + /* set options in the super-block bitmask */ + SET_OPT( NOTAIL, mount_options, s ); + SET_OPT( REISERFS_NO_BORDER, mount_options, s ); + SET_OPT( REISERFS_NO_UNHASHED_RELOCATION, mount_options, s ); + SET_OPT( REISERFS_HASHED_RELOCATION, mount_options, s ); + SET_OPT( REISERFS_TEST4, mount_options, s ); +#undef SET_OPT + if(blocks) { int rc = reiserfs_resize(s, blocks); if (rc != 0)