printk(KERN_INFO "ext3_inode_cache: not all structures were freed\n");
}
-#ifdef CONFIG_EXT3_FS_POSIX_ACL
-
static void ext3_clear_inode(struct inode *inode)
{
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
if (EXT3_I(inode)->i_acl &&
EXT3_I(inode)->i_acl != EXT3_ACL_NOT_CACHED) {
posix_acl_release(EXT3_I(inode)->i_acl);
posix_acl_release(EXT3_I(inode)->i_default_acl);
EXT3_I(inode)->i_default_acl = EXT3_ACL_NOT_CACHED;
}
-}
-
-#else
-# define ext3_clear_inode NULL
#endif
+ if (!is_bad_inode(inode))
+ ext3_discard_reservation(inode);
+}
#ifdef CONFIG_QUOTA
static int ext3_dquot_initialize(struct inode *inode, int type);
static int ext3_dquot_drop(struct inode *inode);
static int ext3_write_dquot(struct dquot *dquot);
+static int ext3_acquire_dquot(struct dquot *dquot);
+static int ext3_release_dquot(struct dquot *dquot);
static int ext3_mark_dquot_dirty(struct dquot *dquot);
static int ext3_write_info(struct super_block *sb, int type);
static int ext3_quota_on(struct super_block *sb, int type, int format_id, char *path);
.free_inode = dquot_free_inode,
.transfer = dquot_transfer,
.write_dquot = ext3_write_dquot,
+ .acquire_dquot = ext3_acquire_dquot,
+ .release_dquot = ext3_release_dquot,
.mark_dirty = ext3_mark_dquot_dirty,
.write_info = ext3_write_info
};
.read_inode = ext3_read_inode,
.write_inode = ext3_write_inode,
.dirty_inode = ext3_dirty_inode,
- .put_inode = ext3_put_inode,
.delete_inode = ext3_delete_inode,
.put_super = ext3_put_super,
.write_super = ext3_write_super,
Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
- Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_noload,
+ Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
+ Opt_reservation, Opt_noreservation, Opt_noload,
Opt_commit, Opt_journal_update, Opt_journal_inum,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0,
- Opt_ignore, Opt_err,
+ Opt_tagxid, Opt_ignore, Opt_err, Opt_resize,
};
static match_table_t tokens = {
{Opt_nouser_xattr, "nouser_xattr"},
{Opt_acl, "acl"},
{Opt_noacl, "noacl"},
+ {Opt_reservation, "reservation"},
+ {Opt_noreservation, "noreservation"},
{Opt_noload, "noload"},
{Opt_commit, "commit=%u"},
{Opt_journal_update, "journal=update"},
{Opt_grpjquota, "grpjquota=%s"},
{Opt_jqfmt_vfsold, "jqfmt=vfsold"},
{Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
+ {Opt_tagxid, "tagxid"},
{Opt_ignore, "grpquota"},
{Opt_ignore, "noquota"},
{Opt_ignore, "quota"},
{Opt_ignore, "usrquota"},
- {Opt_err, NULL}
+ {Opt_err, NULL},
+ {Opt_resize, "resize"}
+
};
static unsigned long get_sb_block(void **data)
}
static int parse_options (char * options, struct super_block *sb,
- unsigned long * inum, int is_remount)
+ unsigned long * inum, unsigned long *n_blocks_count, int is_remount)
{
struct ext3_sb_info *sbi = EXT3_SB(sb);
char * p;
case Opt_nouid32:
set_opt (sbi->s_mount_opt, NO_UID32);
break;
+#ifndef CONFIG_INOXID_NONE
+ case Opt_tagxid:
+ set_opt (sbi->s_mount_opt, TAG_XID);
+ break;
+#endif
case Opt_check:
#ifdef CONFIG_EXT3_CHECK
set_opt (sbi->s_mount_opt, CHECK);
printk("EXT3 (no)acl options not supported\n");
break;
#endif
+ case Opt_reservation:
+ set_opt(sbi->s_mount_opt, RESERVATION);
+ break;
+ case Opt_noreservation:
+ clear_opt(sbi->s_mount_opt, RESERVATION);
+ break;
case Opt_journal_update:
/* @@@ FIXME */
/* Eventually we will want to be able to create
break;
case Opt_ignore:
break;
+ case Opt_resize:
+ if (!n_blocks_count) {
+ printk("EXT3-fs: resize option only available "
+ "for remount\n");
+ return 0;
+ }
+ match_int(&args[0], &option);
+ *n_blocks_count = option;
+ break;
default:
printk (KERN_ERR
"EXT3-fs: Unrecognized mount option \"%s\" "
sbi->s_resuid = le16_to_cpu(es->s_def_resuid);
sbi->s_resgid = le16_to_cpu(es->s_def_resgid);
- if (!parse_options ((char *) data, sb, &journal_inum, 0))
+ set_opt(sbi->s_mount_opt, RESERVATION);
+
+ if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0))
goto failed_mount;
+ if (EXT3_SB(sb)->s_mount_opt & EXT3_MOUNT_TAG_XID)
+ sb->s_flags |= MS_TAGXID;
sb->s_flags |= MS_ONE_SECOND;
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
sbi->s_gdb_count = db_count;
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
spin_lock_init(&sbi->s_next_gen_lock);
+ /* per fileystem reservation list head & lock */
+ spin_lock_init(&sbi->s_rsv_window_lock);
+ INIT_LIST_HEAD(&sbi->s_rsv_window_head.rsv_list);
+ sbi->s_rsv_window_head.rsv_start = 0;
+ sbi->s_rsv_window_head.rsv_end = 0;
+ sbi->s_rsv_window_head.rsv_alloc_hit = 0;
+ atomic_set(&sbi->s_rsv_window_head.rsv_goal_size, 0);
+
/*
* set up enough so that it can read an inode
*/
struct ext3_super_block * es;
struct ext3_sb_info *sbi = EXT3_SB(sb);
unsigned long tmp;
+ unsigned long n_blocks_count = 0;
/*
* Allow the "check" option to be passed as a remount option.
*/
- if (!parse_options(data, sb, &tmp, 1))
+ if (!parse_options(data, sb, &tmp, &n_blocks_count, 1))
return -EINVAL;
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
ext3_init_journal_params(sbi, sbi->s_journal);
- if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
+ if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
+ n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
return -EROFS;
*/
ext3_clear_journal_err(sb, es);
sbi->s_mount_state = le16_to_cpu(es->s_state);
+ if ((ret = ext3_group_extend(sb, es, n_blocks_count)))
+ return ret;
if (!ext3_setup_super (sb, es, 0))
sb->s_flags &= ~MS_RDONLY;
}
return ret;
}
+static int ext3_acquire_dquot(struct dquot *dquot)
+{
+ int ret, err;
+ handle_t *handle;
+
+ handle = ext3_journal_start(dquot_to_inode(dquot),
+ EXT3_QUOTA_INIT_BLOCKS);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ ret = dquot_acquire(dquot);
+ err = ext3_journal_stop(handle);
+ if (!ret)
+ ret = err;
+ return ret;
+}
+
+static int ext3_release_dquot(struct dquot *dquot)
+{
+ int ret, err;
+ handle_t *handle;
+
+ handle = ext3_journal_start(dquot_to_inode(dquot),
+ EXT3_QUOTA_INIT_BLOCKS);
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ ret = dquot_release(dquot);
+ err = ext3_journal_stop(handle);
+ if (!ret)
+ ret = err;
+ return ret;
+}
+
static int ext3_mark_dquot_dirty(struct dquot *dquot)
{
/* Are we journalling quotas? */