aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2011-10-29 09:05:00 -0400
committerTheodore Ts'o <tytso@mit.edu>2011-10-29 09:05:00 -0400
commit5cb81dabcc28863e7d04e6fd9ede154bd8459c14 (patch)
tree704df9fffdc243449dc5eba697cec133162ee1bf /fs/ext4
parentfba90ffee813e2425feb9a57c532b3d297af18c3 (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.h3
-rw-r--r--fs/ext4/ialloc.c9
-rw-r--r--fs/ext4/migrate.c7
-rw-r--r--fs/ext4/namei.c8
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 */
1813extern struct inode *ext4_new_inode(handle_t *, struct inode *, int, 1813extern 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);
1815extern void ext4_free_inode(handle_t *, struct inode *); 1816extern void ext4_free_inode(handle_t *, struct inode *);
1816extern struct inode * ext4_orphan_get(struct super_block *, unsigned long); 1817extern struct inode * ext4_orphan_get(struct super_block *, unsigned long);
1817extern unsigned long ext4_count_free_inodes(struct super_block *); 1818extern 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 */
693struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode, 693struct 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;