aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2017-04-06 11:02:09 -0400
committerJan Kara <jack@suse.cz>2017-04-19 08:21:23 -0400
commit161f3b74479b1e486fc784111491023a5bc57bf7 (patch)
tree1c35dd6e5fc58f9d4feb0b4338e2ac56da685ca9
parent33eb928a9e21fb32221db4290d579753ecf2b80e (diff)
ext2: Set flags on quota files directly
Currently immutable and noatime flags on quota files are set by quota code which requires us to copy inode->i_flags to our on disk version of quota flags in GETFLAGS ioctl and __ext2_write_inode(). Move to setting / clearing these on-disk flags directly to save that copying. Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/ext2/super.c78
1 files changed, 76 insertions, 2 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index b3090416a936..8ac673c71a36 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -122,13 +122,29 @@ void ext2_update_dynamic_rev(struct super_block *sb)
122 */ 122 */
123} 123}
124 124
125#ifdef CONFIG_QUOTA
126static int ext2_quota_off(struct super_block *sb, int type);
127
128static void ext2_quota_off_umount(struct super_block *sb)
129{
130 int type;
131
132 for (type = 0; type < MAXQUOTAS; type++)
133 ext2_quota_off(sb, type);
134}
135#else
136static inline void ext2_quota_off_umount(struct super_block *sb)
137{
138}
139#endif
140
125static void ext2_put_super (struct super_block * sb) 141static void ext2_put_super (struct super_block * sb)
126{ 142{
127 int db_count; 143 int db_count;
128 int i; 144 int i;
129 struct ext2_sb_info *sbi = EXT2_SB(sb); 145 struct ext2_sb_info *sbi = EXT2_SB(sb);
130 146
131 dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); 147 ext2_quota_off_umount(sb);
132 148
133 if (sbi->s_mb_cache) { 149 if (sbi->s_mb_cache) {
134 ext2_xattr_destroy_cache(sbi->s_mb_cache); 150 ext2_xattr_destroy_cache(sbi->s_mb_cache);
@@ -313,10 +329,23 @@ static int ext2_show_options(struct seq_file *seq, struct dentry *root)
313#ifdef CONFIG_QUOTA 329#ifdef CONFIG_QUOTA
314static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off); 330static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off);
315static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); 331static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off);
332static int ext2_quota_on(struct super_block *sb, int type, int format_id,
333 const struct path *path);
316static struct dquot **ext2_get_dquots(struct inode *inode) 334static struct dquot **ext2_get_dquots(struct inode *inode)
317{ 335{
318 return EXT2_I(inode)->i_dquot; 336 return EXT2_I(inode)->i_dquot;
319} 337}
338
339static const struct quotactl_ops ext2_quotactl_ops = {
340 .quota_on = ext2_quota_on,
341 .quota_off = ext2_quota_off,
342 .quota_sync = dquot_quota_sync,
343 .get_state = dquot_get_state,
344 .set_info = dquot_set_dqinfo,
345 .get_dqblk = dquot_get_dqblk,
346 .set_dqblk = dquot_set_dqblk,
347 .get_nextdqblk = dquot_get_next_dqblk,
348};
320#endif 349#endif
321 350
322static const struct super_operations ext2_sops = { 351static const struct super_operations ext2_sops = {
@@ -1116,7 +1145,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
1116 1145
1117#ifdef CONFIG_QUOTA 1146#ifdef CONFIG_QUOTA
1118 sb->dq_op = &dquot_operations; 1147 sb->dq_op = &dquot_operations;
1119 sb->s_qcop = &dquot_quotactl_ops; 1148 sb->s_qcop = &ext2_quotactl_ops;
1120 sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP; 1149 sb->s_quota_types = QTYPE_MASK_USR | QTYPE_MASK_GRP;
1121#endif 1150#endif
1122 1151
@@ -1547,6 +1576,51 @@ out:
1547 return len - towrite; 1576 return len - towrite;
1548} 1577}
1549 1578
1579static int ext2_quota_on(struct super_block *sb, int type, int format_id,
1580 const struct path *path)
1581{
1582 int err;
1583 struct inode *inode;
1584
1585 err = dquot_quota_on(sb, type, format_id, path);
1586 if (err)
1587 return err;
1588
1589 inode = d_inode(path->dentry);
1590 inode_lock(inode);
1591 EXT2_I(inode)->i_flags |= EXT2_NOATIME_FL | EXT2_IMMUTABLE_FL;
1592 inode_set_flags(inode, S_NOATIME | S_IMMUTABLE,
1593 S_NOATIME | S_IMMUTABLE);
1594 inode_unlock(inode);
1595 mark_inode_dirty(inode);
1596
1597 return 0;
1598}
1599
1600static int ext2_quota_off(struct super_block *sb, int type)
1601{
1602 struct inode *inode = sb_dqopt(sb)->files[type];
1603 int err;
1604
1605 if (!inode || !igrab(inode))
1606 goto out;
1607
1608 err = dquot_quota_off(sb, type);
1609 if (err)
1610 goto out_put;
1611
1612 inode_lock(inode);
1613 EXT2_I(inode)->i_flags &= ~(EXT2_NOATIME_FL | EXT2_IMMUTABLE_FL);
1614 inode_set_flags(inode, 0, S_NOATIME | S_IMMUTABLE);
1615 inode_unlock(inode);
1616 mark_inode_dirty(inode);
1617out_put:
1618 iput(inode);
1619 return err;
1620out:
1621 return dquot_quota_off(sb, type);
1622}
1623
1550#endif 1624#endif
1551 1625
1552static struct file_system_type ext2_fs_type = { 1626static struct file_system_type ext2_fs_type = {