diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2011-10-29 09:05:00 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2011-10-29 09:05:00 -0400 |
commit | 5cb81dabcc28863e7d04e6fd9ede154bd8459c14 (patch) | |
tree | 704df9fffdc243449dc5eba697cec133162ee1bf /fs/ext4 | |
parent | fba90ffee813e2425feb9a57c532b3d297af18c3 (diff) |
ext4: fix quota accounting during migration
The tmp_inode should have same uid/gid as the original inode.
Otherwise new metadata blocks will be accounted to wrong quota-id,
which will result in a quota leak after the inode migration is
completed.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/ext4.h | 3 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 9 | ||||
-rw-r--r-- | fs/ext4/migrate.c | 7 | ||||
-rw-r--r-- | fs/ext4/namei.c | 8 |
4 files changed, 17 insertions, 10 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 3647ae0b21ab..657e82649fa5 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1811,7 +1811,8 @@ extern int ext4fs_dirhash(const char *name, int len, struct | |||
1811 | 1811 | ||
1812 | /* ialloc.c */ | 1812 | /* ialloc.c */ |
1813 | extern struct inode *ext4_new_inode(handle_t *, struct inode *, int, | 1813 | extern struct inode *ext4_new_inode(handle_t *, struct inode *, int, |
1814 | const struct qstr *qstr, __u32 goal); | 1814 | const struct qstr *qstr, __u32 goal, |
1815 | uid_t *owner); | ||
1815 | extern void ext4_free_inode(handle_t *, struct inode *); | 1816 | extern void ext4_free_inode(handle_t *, struct inode *); |
1816 | extern struct inode * ext4_orphan_get(struct super_block *, unsigned long); | 1817 | extern struct inode * ext4_orphan_get(struct super_block *, unsigned long); |
1817 | extern unsigned long ext4_count_free_inodes(struct super_block *); | 1818 | extern unsigned long ext4_count_free_inodes(struct super_block *); |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index e007fecdaedc..acdde93b74d7 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -691,7 +691,7 @@ err_ret: | |||
691 | * group to find a free inode. | 691 | * group to find a free inode. |
692 | */ | 692 | */ |
693 | struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode, | 693 | struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode, |
694 | const struct qstr *qstr, __u32 goal) | 694 | const struct qstr *qstr, __u32 goal, uid_t *owner) |
695 | { | 695 | { |
696 | struct super_block *sb; | 696 | struct super_block *sb; |
697 | struct buffer_head *inode_bitmap_bh = NULL; | 697 | struct buffer_head *inode_bitmap_bh = NULL; |
@@ -852,8 +852,11 @@ got: | |||
852 | flex_group = ext4_flex_group(sbi, group); | 852 | flex_group = ext4_flex_group(sbi, group); |
853 | atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes); | 853 | atomic_dec(&sbi->s_flex_groups[flex_group].free_inodes); |
854 | } | 854 | } |
855 | 855 | if (owner) { | |
856 | if (test_opt(sb, GRPID)) { | 856 | inode->i_mode = mode; |
857 | inode->i_uid = owner[0]; | ||
858 | inode->i_gid = owner[1]; | ||
859 | } else if (test_opt(sb, GRPID)) { | ||
857 | inode->i_mode = mode; | 860 | inode->i_mode = mode; |
858 | inode->i_uid = current_fsuid(); | 861 | inode->i_uid = current_fsuid(); |
859 | inode->i_gid = dir->i_gid; | 862 | inode->i_gid = dir->i_gid; |
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c index 8a9a0912fdae..f729377bf043 100644 --- a/fs/ext4/migrate.c +++ b/fs/ext4/migrate.c | |||
@@ -439,6 +439,7 @@ int ext4_ext_migrate(struct inode *inode) | |||
439 | struct migrate_struct lb; | 439 | struct migrate_struct lb; |
440 | unsigned long max_entries; | 440 | unsigned long max_entries; |
441 | __u32 goal; | 441 | __u32 goal; |
442 | uid_t owner[2]; | ||
442 | 443 | ||
443 | /* | 444 | /* |
444 | * If the filesystem does not support extents, or the inode | 445 | * If the filesystem does not support extents, or the inode |
@@ -466,10 +467,12 @@ int ext4_ext_migrate(struct inode *inode) | |||
466 | } | 467 | } |
467 | goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) * | 468 | goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) * |
468 | EXT4_INODES_PER_GROUP(inode->i_sb)) + 1; | 469 | EXT4_INODES_PER_GROUP(inode->i_sb)) + 1; |
470 | owner[0] = inode->i_uid; | ||
471 | owner[1] = inode->i_gid; | ||
469 | tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode, | 472 | tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode, |
470 | S_IFREG, NULL, goal); | 473 | S_IFREG, NULL, goal, owner); |
471 | if (IS_ERR(tmp_inode)) { | 474 | if (IS_ERR(tmp_inode)) { |
472 | retval = -ENOMEM; | 475 | retval = PTR_ERR(inode); |
473 | ext4_journal_stop(handle); | 476 | ext4_journal_stop(handle); |
474 | return retval; | 477 | return retval; |
475 | } | 478 | } |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 4a550aa07614..f73d582e89f9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1754,7 +1754,7 @@ retry: | |||
1754 | if (IS_DIRSYNC(dir)) | 1754 | if (IS_DIRSYNC(dir)) |
1755 | ext4_handle_sync(handle); | 1755 | ext4_handle_sync(handle); |
1756 | 1756 | ||
1757 | inode = ext4_new_inode(handle, dir, mode, &dentry->d_name, 0); | 1757 | inode = ext4_new_inode(handle, dir, mode, &dentry->d_name, 0, NULL); |
1758 | err = PTR_ERR(inode); | 1758 | err = PTR_ERR(inode); |
1759 | if (!IS_ERR(inode)) { | 1759 | if (!IS_ERR(inode)) { |
1760 | inode->i_op = &ext4_file_inode_operations; | 1760 | inode->i_op = &ext4_file_inode_operations; |
@@ -1790,7 +1790,7 @@ retry: | |||
1790 | if (IS_DIRSYNC(dir)) | 1790 | if (IS_DIRSYNC(dir)) |
1791 | ext4_handle_sync(handle); | 1791 | ext4_handle_sync(handle); |
1792 | 1792 | ||
1793 | inode = ext4_new_inode(handle, dir, mode, &dentry->d_name, 0); | 1793 | inode = ext4_new_inode(handle, dir, mode, &dentry->d_name, 0, NULL); |
1794 | err = PTR_ERR(inode); | 1794 | err = PTR_ERR(inode); |
1795 | if (!IS_ERR(inode)) { | 1795 | if (!IS_ERR(inode)) { |
1796 | init_special_inode(inode, inode->i_mode, rdev); | 1796 | init_special_inode(inode, inode->i_mode, rdev); |
@@ -1830,7 +1830,7 @@ retry: | |||
1830 | ext4_handle_sync(handle); | 1830 | ext4_handle_sync(handle); |
1831 | 1831 | ||
1832 | inode = ext4_new_inode(handle, dir, S_IFDIR | mode, | 1832 | inode = ext4_new_inode(handle, dir, S_IFDIR | mode, |
1833 | &dentry->d_name, 0); | 1833 | &dentry->d_name, 0, NULL); |
1834 | err = PTR_ERR(inode); | 1834 | err = PTR_ERR(inode); |
1835 | if (IS_ERR(inode)) | 1835 | if (IS_ERR(inode)) |
1836 | goto out_stop; | 1836 | goto out_stop; |
@@ -2277,7 +2277,7 @@ retry: | |||
2277 | ext4_handle_sync(handle); | 2277 | ext4_handle_sync(handle); |
2278 | 2278 | ||
2279 | inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO, | 2279 | inode = ext4_new_inode(handle, dir, S_IFLNK|S_IRWXUGO, |
2280 | &dentry->d_name, 0); | 2280 | &dentry->d_name, 0, NULL); |
2281 | err = PTR_ERR(inode); | 2281 | err = PTR_ERR(inode); |
2282 | if (IS_ERR(inode)) | 2282 | if (IS_ERR(inode)) |
2283 | goto out_stop; | 2283 | goto out_stop; |