Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] quota: ext3: Improve quota credit estimates

Use improved credits estimates for quota operations. Also reserve a space
for a quota operation in a transaction only if filesystem was mounted with
some quota options.

Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Jan Kara and committed by
Linus Torvalds
1f54587b 4e5117ba

+60 -36
+3 -2
fs/ext3/acl.c
··· 393 393 int retries = 0; 394 394 395 395 retry: 396 - handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS); 396 + handle = ext3_journal_start(inode, 397 + EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); 397 398 if (IS_ERR(handle)) { 398 399 error = PTR_ERR(handle); 399 400 ext3_std_error(inode->i_sb, error); ··· 504 503 acl = NULL; 505 504 506 505 retry: 507 - handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS); 506 + handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); 508 507 if (IS_ERR(handle)) 509 508 return PTR_ERR(handle); 510 509 error = ext3_set_acl(handle, inode, type, acl);
+4 -3
fs/ext3/inode.c
··· 128 128 if (needed > EXT3_MAX_TRANS_DATA) 129 129 needed = EXT3_MAX_TRANS_DATA; 130 130 131 - return EXT3_DATA_TRANS_BLOCKS + needed; 131 + return EXT3_DATA_TRANS_BLOCKS(inode->i_sb) + needed; 132 132 } 133 133 134 134 /* ··· 2763 2763 2764 2764 /* (user+group)*(old+new) structure, inode write (sb, 2765 2765 * inode block, ? - but truncate inode update has it) */ 2766 - handle = ext3_journal_start(inode, 4*EXT3_QUOTA_INIT_BLOCKS+3); 2766 + handle = ext3_journal_start(inode, 2*(EXT3_QUOTA_INIT_BLOCKS(inode->i_sb)+ 2767 + EXT3_QUOTA_DEL_BLOCKS(inode->i_sb))+3); 2767 2768 if (IS_ERR(handle)) { 2768 2769 error = PTR_ERR(handle); 2769 2770 goto err_out; ··· 2862 2861 #ifdef CONFIG_QUOTA 2863 2862 /* We know that structure was already allocated during DQUOT_INIT so 2864 2863 * we will be updating only the data blocks + inodes */ 2865 - ret += 2*EXT3_QUOTA_TRANS_BLOCKS; 2864 + ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb); 2866 2865 #endif 2867 2866 2868 2867 return ret;
+13 -12
fs/ext3/namei.c
··· 1645 1645 int err, retries = 0; 1646 1646 1647 1647 retry: 1648 - handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 1648 + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + 1649 1649 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + 1650 - 2*EXT3_QUOTA_INIT_BLOCKS); 1650 + 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); 1651 1651 if (IS_ERR(handle)) 1652 1652 return PTR_ERR(handle); 1653 1653 ··· 1679 1679 return -EINVAL; 1680 1680 1681 1681 retry: 1682 - handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 1682 + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + 1683 1683 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + 1684 - 2*EXT3_QUOTA_INIT_BLOCKS); 1684 + 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); 1685 1685 if (IS_ERR(handle)) 1686 1686 return PTR_ERR(handle); 1687 1687 ··· 1715 1715 return -EMLINK; 1716 1716 1717 1717 retry: 1718 - handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 1718 + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + 1719 1719 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + 1720 - 2*EXT3_QUOTA_INIT_BLOCKS); 1720 + 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); 1721 1721 if (IS_ERR(handle)) 1722 1722 return PTR_ERR(handle); 1723 1723 ··· 2006 2006 /* Initialize quotas before so that eventual writes go in 2007 2007 * separate transaction */ 2008 2008 DQUOT_INIT(dentry->d_inode); 2009 - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); 2009 + handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); 2010 2010 if (IS_ERR(handle)) 2011 2011 return PTR_ERR(handle); 2012 2012 ··· 2065 2065 /* Initialize quotas before so that eventual writes go 2066 2066 * in separate transaction */ 2067 2067 DQUOT_INIT(dentry->d_inode); 2068 - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); 2068 + handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); 2069 2069 if (IS_ERR(handle)) 2070 2070 return PTR_ERR(handle); 2071 2071 ··· 2120 2120 return -ENAMETOOLONG; 2121 2121 2122 2122 retry: 2123 - handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 2123 + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + 2124 2124 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 + 2125 - 2*EXT3_QUOTA_INIT_BLOCKS); 2125 + 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); 2126 2126 if (IS_ERR(handle)) 2127 2127 return PTR_ERR(handle); 2128 2128 ··· 2174 2174 return -EMLINK; 2175 2175 2176 2176 retry: 2177 - handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 2177 + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + 2178 2178 EXT3_INDEX_EXTRA_TRANS_BLOCKS); 2179 2179 if (IS_ERR(handle)) 2180 2180 return PTR_ERR(handle); ··· 2216 2216 * in separate transaction */ 2217 2217 if (new_dentry->d_inode) 2218 2218 DQUOT_INIT(new_dentry->d_inode); 2219 - handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2219 + handle = ext3_journal_start(old_dir, 2 * 2220 + EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) + 2220 2221 EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); 2221 2222 if (IS_ERR(handle)) 2222 2223 return PTR_ERR(handle);
+27 -10
fs/ext3/super.c
··· 589 589 Opt_commit, Opt_journal_update, Opt_journal_inum, 590 590 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 591 591 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 592 - Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, 592 + Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 593 593 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, 594 594 }; 595 595 ··· 634 634 {Opt_grpjquota, "grpjquota=%s"}, 635 635 {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, 636 636 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, 637 - {Opt_ignore, "grpquota"}, 638 - {Opt_ignore, "noquota"}, 639 - {Opt_ignore, "quota"}, 640 - {Opt_ignore, "usrquota"}, 637 + {Opt_quota, "grpquota"}, 638 + {Opt_noquota, "noquota"}, 639 + {Opt_quota, "quota"}, 640 + {Opt_quota, "usrquota"}, 641 641 {Opt_barrier, "barrier=%u"}, 642 642 {Opt_err, NULL}, 643 643 {Opt_resize, "resize"}, ··· 876 876 sbi->s_qf_names[qtype] = NULL; 877 877 return 0; 878 878 } 879 + set_opt(sbi->s_mount_opt, QUOTA); 879 880 break; 880 881 case Opt_offusrjquota: 881 882 qtype = USRQUOTA; ··· 899 898 case Opt_jqfmt_vfsv0: 900 899 sbi->s_jquota_fmt = QFMT_VFS_V0; 901 900 break; 901 + case Opt_quota: 902 + set_opt(sbi->s_mount_opt, QUOTA); 903 + break; 904 + case Opt_noquota: 905 + if (sb_any_quota_enabled(sb)) { 906 + printk(KERN_ERR "EXT3-fs: Cannot change quota " 907 + "options when quota turned on.\n"); 908 + return 0; 909 + } 910 + clear_opt(sbi->s_mount_opt, QUOTA); 911 + break; 902 912 #else 903 913 case Opt_usrjquota: 904 914 case Opt_grpjquota: ··· 920 908 printk(KERN_ERR 921 909 "EXT3-fs: journalled quota options not " 922 910 "supported.\n"); 911 + break; 912 + case Opt_quota: 913 + case Opt_noquota: 923 914 break; 924 915 #endif 925 916 case Opt_abort: ··· 2253 2238 int ret, err; 2254 2239 2255 2240 /* We may create quota structure so we need to reserve enough blocks */ 2256 - handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS); 2241 + handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb)); 2257 2242 if (IS_ERR(handle)) 2258 2243 return PTR_ERR(handle); 2259 2244 ret = dquot_initialize(inode, type); ··· 2269 2254 int ret, err; 2270 2255 2271 2256 /* We may delete quota structure so we need to reserve enough blocks */ 2272 - handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS); 2257 + handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb)); 2273 2258 if (IS_ERR(handle)) 2274 2259 return PTR_ERR(handle); 2275 2260 ret = dquot_drop(inode); ··· 2287 2272 2288 2273 inode = dquot_to_inode(dquot); 2289 2274 handle = ext3_journal_start(inode, 2290 - EXT3_QUOTA_TRANS_BLOCKS); 2275 + EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); 2291 2276 if (IS_ERR(handle)) 2292 2277 return PTR_ERR(handle); 2293 2278 ret = dquot_commit(dquot); ··· 2303 2288 handle_t *handle; 2304 2289 2305 2290 handle = ext3_journal_start(dquot_to_inode(dquot), 2306 - EXT3_QUOTA_INIT_BLOCKS); 2291 + EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb)); 2307 2292 if (IS_ERR(handle)) 2308 2293 return PTR_ERR(handle); 2309 2294 ret = dquot_acquire(dquot); ··· 2319 2304 handle_t *handle; 2320 2305 2321 2306 handle = ext3_journal_start(dquot_to_inode(dquot), 2322 - EXT3_QUOTA_INIT_BLOCKS); 2307 + EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb)); 2323 2308 if (IS_ERR(handle)) 2324 2309 return PTR_ERR(handle); 2325 2310 ret = dquot_release(dquot); ··· 2376 2361 int err; 2377 2362 struct nameidata nd; 2378 2363 2364 + if (!test_opt(sb, QUOTA)) 2365 + return -EINVAL; 2379 2366 /* Not journalling quota? */ 2380 2367 if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] && 2381 2368 !EXT3_SB(sb)->s_qf_names[GRPQUOTA])
+1 -1
fs/ext3/xattr.c
··· 1044 1044 int error, retries = 0; 1045 1045 1046 1046 retry: 1047 - handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS); 1047 + handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb)); 1048 1048 if (IS_ERR(handle)) { 1049 1049 error = PTR_ERR(handle); 1050 1050 } else {
+1
include/linux/ext3_fs.h
··· 358 358 #define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */ 359 359 #define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */ 360 360 #define EXT3_MOUNT_NOBH 0x40000 /* No bufferheads */ 361 + #define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ 361 362 362 363 /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ 363 364 #ifndef _LINUX_EXT2_FS_H
+11 -8
include/linux/ext3_jbd.h
··· 42 42 * superblock only gets updated once, of course, so don't bother 43 43 * counting that again for the quota updates. */ 44 44 45 - #define EXT3_DATA_TRANS_BLOCKS (EXT3_SINGLEDATA_TRANS_BLOCKS + \ 45 + #define EXT3_DATA_TRANS_BLOCKS(sb) (EXT3_SINGLEDATA_TRANS_BLOCKS + \ 46 46 EXT3_XATTR_TRANS_BLOCKS - 2 + \ 47 - 2*EXT3_QUOTA_TRANS_BLOCKS) 47 + 2*EXT3_QUOTA_TRANS_BLOCKS(sb)) 48 48 49 49 /* Delete operations potentially hit one directory's namespace plus an 50 50 * entire inode, plus arbitrary amounts of bitmap/indirection data. Be 51 51 * generous. We can grow the delete transaction later if necessary. */ 52 52 53 - #define EXT3_DELETE_TRANS_BLOCKS (2 * EXT3_DATA_TRANS_BLOCKS + 64) 53 + #define EXT3_DELETE_TRANS_BLOCKS(sb) (2 * EXT3_DATA_TRANS_BLOCKS(sb) + 64) 54 54 55 55 /* Define an arbitrary limit for the amount of data we will anticipate 56 56 * writing to any given transaction. For unbounded transactions such as ··· 74 74 #ifdef CONFIG_QUOTA 75 75 /* Amount of blocks needed for quota update - we know that the structure was 76 76 * allocated so we need to update only inode+data */ 77 - #define EXT3_QUOTA_TRANS_BLOCKS 2 77 + #define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0) 78 78 /* Amount of blocks needed for quota insert/delete - we do some block writes 79 79 * but inode, sb and group updates are done only once */ 80 - #define EXT3_QUOTA_INIT_BLOCKS (DQUOT_MAX_WRITES*\ 81 - (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3) 80 + #define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\ 81 + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0) 82 + #define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\ 83 + (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0) 82 84 #else 83 - #define EXT3_QUOTA_TRANS_BLOCKS 0 84 - #define EXT3_QUOTA_INIT_BLOCKS 0 85 + #define EXT3_QUOTA_TRANS_BLOCKS(sb) 0 86 + #define EXT3_QUOTA_INIT_BLOCKS(sb) 0 87 + #define EXT3_QUOTA_DEL_BLOCKS(sb) 0 85 88 #endif 86 89 87 90 int