* For other inodes, search forward from the parent directory\'s block
* group to find a free inode.
*/
-#if 0
-
-static int find_group_dir(struct super_block *sb, int parent_group)
+static int find_group_dir(struct super_block *sb, struct inode *parent)
{
struct ext2_super_block * es = EXT2_SB(sb)->s_es;
int ngroups = EXT2_SB(sb)->s_groups_count;
mark_buffer_dirty(best_bh);
return best_group;
}
-#endif
/*
* Orlov's allocator for directories.
struct ext2_group_desc *desc;
struct buffer_head *bh;
- if (parent == sb->s_root->d_inode) {
+ if ((parent == sb->s_root->d_inode) ||
+ (parent->i_flags & EXT2_TOPDIR_FL)) {
struct ext2_group_desc *best_desc = NULL;
struct buffer_head *best_bh = NULL;
int best_ndir = inodes_per_group;
desc = ext2_get_group_desc (sb, group, &bh);
if (!desc || !desc->bg_free_inodes_count)
continue;
- if (sbi->debts[group] >= max_debt)
+ if (sbi->s_debts[group] >= max_debt)
continue;
if (le16_to_cpu(desc->bg_used_dirs_count) >= max_dirs)
continue;
lock_super (sb);
es = EXT2_SB(sb)->s_es;
repeat:
- if (S_ISDIR(mode))
- group = find_group_orlov(sb, dir);
- else
+ if (S_ISDIR(mode)) {
+ if (test_opt (sb, OLDALLOC))
+ group = find_group_dir(sb, dir);
+ else
+ group = find_group_orlov(sb, dir);
+ } else
group = find_group_other(sb, dir);
err = -ENOSPC;
cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1);
if (S_ISDIR(mode)) {
- if (EXT2_SB(sb)->debts[group] < 255)
- EXT2_SB(sb)->debts[group]++;
+ if (EXT2_SB(sb)->s_debts[group] < 255)
+ EXT2_SB(sb)->s_debts[group]++;
} else {
- if (EXT2_SB(sb)->debts[group])
- EXT2_SB(sb)->debts[group]--;
+ if (EXT2_SB(sb)->s_debts[group])
+ EXT2_SB(sb)->s_debts[group]--;
}
mark_buffer_dirty(EXT2_SB(sb)->s_sbh);
if (sbi->s_group_desc[i])
brelse (sbi->s_group_desc[i]);
kfree(sbi->s_group_desc);
+ kfree(sbi->s_debts);
brelse (sbi->s_sbh);
sb->s_fs_info = NULL;
kfree(sbi);
return 0;
sbi->s_resuid = v;
}
+ else if (!strcmp (this_char, "oldalloc"))
+ set_opt (sbi->s_mount_opt, OLDALLOC);
+ else if (!strcmp (this_char, "orlov"))
+ clear_opt (sbi->s_mount_opt, OLDALLOC);
/* Silently ignore the quota options */
else if (!strcmp (this_char, "grpquota")
|| !strcmp (this_char, "noquota")
printk ("EXT2-fs: not enough memory\n");
goto failed_mount;
}
- sbi->debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->debts),
- GFP_KERNEL);
- if (!sbi->debts) {
+ sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts),
+ GFP_KERNEL);
+ if (!sbi->s_debts) {
printk ("EXT2-fs: not enough memory\n");
goto failed_mount_group_desc;
}
- memset(sbi->debts, 0, sbi->s_groups_count * sizeof(*sbi->debts));
+ memset(sbi->s_debts, 0, sbi->s_groups_count * sizeof(*sbi->s_debts));
for (i = 0; i < db_count; i++) {
block = descriptor_loc(sb, logic_sb_block, i);
sbi->s_group_desc[i] = sb_bread(sb, block);
brelse (sbi->s_group_desc[j]);
kfree(sbi->s_group_desc);
printk ("EXT2-fs: unable to read group descriptors\n");
- goto failed_mount;
+ goto failed_mount_group_desc;
}
}
if (!ext2_check_descriptors (sb)) {
brelse(sbi->s_group_desc[i]);
failed_mount_group_desc:
kfree(sbi->s_group_desc);
+ if (sbi->s_debts)
+ kfree(sbi->s_debts);
failed_mount:
brelse(bh);
failed_sbi:
#define EXT2_JOURNAL_DATA_FL 0x00004000 /* Reserved for ext3 */
#define EXT2_NOTAIL_FL 0x00008000 /* file tail should not be merged */
#define EXT2_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
+#define EXT2_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
-#define EXT2_FL_USER_VISIBLE 0x00011FFF /* User visible flags */
-#define EXT2_FL_USER_MODIFIABLE 0x000100FF /* User modifiable flags */
+#define EXT2_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
+#define EXT2_FL_USER_MODIFIABLE 0x000380FF /* User modifiable flags */
/*
* ioctl commands
* Mount flags
*/
#define EXT2_MOUNT_CHECK 0x0001 /* Do mount-time checks */
+#define EXT2_MOUNT_OLDALLOC 0x0002 /* Don't use the new Orlov allocator */
#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */
#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */
#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
int s_first_ino;
u32 s_next_generation;
unsigned long s_dir_count;
- u8 *debts;
+ u8 *s_debts;
};
#endif /* _LINUX_EXT2_FS_SB */