diff options
author | Jan Kara <jack@suse.cz> | 2017-04-06 11:02:09 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2017-04-19 08:21:23 -0400 |
commit | 161f3b74479b1e486fc784111491023a5bc57bf7 (patch) | |
tree | 1c35dd6e5fc58f9d4feb0b4338e2ac56da685ca9 | |
parent | 33eb928a9e21fb32221db4290d579753ecf2b80e (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.c | 78 |
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 | ||
126 | static int ext2_quota_off(struct super_block *sb, int type); | ||
127 | |||
128 | static 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 | ||
136 | static inline void ext2_quota_off_umount(struct super_block *sb) | ||
137 | { | ||
138 | } | ||
139 | #endif | ||
140 | |||
125 | static void ext2_put_super (struct super_block * sb) | 141 | static 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 |
314 | static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off); | 330 | static ssize_t ext2_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off); |
315 | static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); | 331 | static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); |
332 | static int ext2_quota_on(struct super_block *sb, int type, int format_id, | ||
333 | const struct path *path); | ||
316 | static struct dquot **ext2_get_dquots(struct inode *inode) | 334 | static 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 | |||
339 | static 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 | ||
322 | static const struct super_operations ext2_sops = { | 351 | static 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 | ||
1579 | static 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 | |||
1600 | static 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); | ||
1617 | out_put: | ||
1618 | iput(inode); | ||
1619 | return err; | ||
1620 | out: | ||
1621 | return dquot_quota_off(sb, type); | ||
1622 | } | ||
1623 | |||
1550 | #endif | 1624 | #endif |
1551 | 1625 | ||
1552 | static struct file_system_type ext2_fs_type = { | 1626 | static struct file_system_type ext2_fs_type = { |