On Sat 20-02-10 06:51:08, Christoph Hellwig wrote: > Currently various places in the VFS call vfs_dq_init directly. This means > we tie the quota code into the VFS. Get rid of that and make the > filesystem responsibly for the initialization. For most metadata operations > this is a straight forward move into the methods, but for truncate and > open it's a bit more complicated. > > For truncate we currently only call vfs_dq_init for the sys_truncate case > because open already takes care of it for ftruncate and open(O_TRUNC) - the > new code causes an additional vfs_dq_init for those which is harmless. > > For open the initialization is moved from do_filp_open into the open method, > which means it happens slightly earlier now, and only for regular files. > The latter is fine because we don't need to initialize it for operations > on special files, and we already do it as part of the namespace operations > for directories. > > Add a dquot_file_open helper that filesystems that support generic quotas > can use to fill in ->open. In principle looks OK but I'm too tired now to check the details so I'll have a next look at it on Monday... Honza > > Signed-off-by: Christoph Hellwig <hch@xxxxxx> > > > Index: linux-2.6/fs/ext2/inode.c > =================================================================== > --- linux-2.6.orig/fs/ext2/inode.c 2010-02-20 11:55:53.772255862 +0100 > +++ linux-2.6/fs/ext2/inode.c 2010-02-20 12:00:45.486253976 +0100 > @@ -58,6 +58,8 @@ static inline int ext2_inode_is_fast_sym > */ > void ext2_delete_inode (struct inode * inode) > { > + if (!is_bad_inode(inode)) > + vfs_dq_init(inode); > truncate_inode_pages(&inode->i_data, 0); > > if (is_bad_inode(inode)) > @@ -1457,6 +1459,9 @@ int ext2_setattr(struct dentry *dentry, > error = inode_change_ok(inode, iattr); > if (error) > return error; > + > + if (iattr->ia_valid & ATTR_SIZE) > + vfs_dq_init(inode); > if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || > (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { > error = dquot_transfer(inode, iattr); > Index: linux-2.6/fs/ext3/inode.c > =================================================================== > --- linux-2.6.orig/fs/ext3/inode.c 2010-02-20 11:55:53.781265570 +0100 > +++ linux-2.6/fs/ext3/inode.c 2010-02-20 12:00:45.488257957 +0100 > @@ -196,6 +196,9 @@ void ext3_delete_inode (struct inode * i > { > handle_t *handle; > > + if (!is_bad_inode(inode)) > + vfs_dq_init(inode); > + > truncate_inode_pages(&inode->i_data, 0); > > if (is_bad_inode(inode)) > @@ -3140,6 +3143,8 @@ int ext3_setattr(struct dentry *dentry, > if (error) > return error; > > + if (ia_valid & ATTR_SIZE) > + vfs_dq_init(inode); > if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || > (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { > handle_t *handle; > Index: linux-2.6/fs/ext4/inode.c > =================================================================== > --- linux-2.6.orig/fs/ext4/inode.c 2010-02-20 11:55:53.804005688 +0100 > +++ linux-2.6/fs/ext4/inode.c 2010-02-20 12:00:45.505255373 +0100 > @@ -170,6 +170,9 @@ void ext4_delete_inode(struct inode *ino > handle_t *handle; > int err; > > + if (!is_bad_inode(inode)) > + vfs_dq_init(inode); > + > if (ext4_should_order_data(inode)) > ext4_begin_ordered_truncate(inode, 0); > truncate_inode_pages(&inode->i_data, 0); > @@ -5249,6 +5252,8 @@ int ext4_setattr(struct dentry *dentry, > if (error) > return error; > > + if (ia_valid & ATTR_SIZE) > + vfs_dq_init(inode); > if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || > (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { > handle_t *handle; > Index: linux-2.6/fs/inode.c > =================================================================== > --- linux-2.6.orig/fs/inode.c 2010-02-20 11:58:09.796005478 +0100 > +++ linux-2.6/fs/inode.c 2010-02-20 12:00:45.538255584 +0100 > @@ -8,7 +8,6 @@ > #include <linux/mm.h> > #include <linux/dcache.h> > #include <linux/init.h> > -#include <linux/quotaops.h> > #include <linux/slab.h> > #include <linux/writeback.h> > #include <linux/module.h> > @@ -1210,8 +1209,6 @@ void generic_delete_inode(struct inode * > > if (op->delete_inode) { > void (*delete)(struct inode *) = op->delete_inode; > - if (!is_bad_inode(inode)) > - vfs_dq_init(inode); > /* Filesystems implementing their own > * s_op->delete_inode are required to call > * truncate_inode_pages and clear_inode() > Index: linux-2.6/fs/jfs/inode.c > =================================================================== > --- linux-2.6.orig/fs/jfs/inode.c 2010-02-20 11:59:10.775005758 +0100 > +++ linux-2.6/fs/jfs/inode.c 2010-02-20 12:00:45.545255374 +0100 > @@ -146,6 +146,9 @@ void jfs_delete_inode(struct inode *inod > { > jfs_info("In jfs_delete_inode, inode = 0x%p", inode); > > + if (!is_bad_inode(inode)) > + vfs_dq_init(inode); > + > if (!is_bad_inode(inode) && > (JFS_IP(inode)->fileset == FILESYSTEM_I)) { > truncate_inode_pages(&inode->i_data, 0); > Index: linux-2.6/fs/ocfs2/inode.c > =================================================================== > --- linux-2.6.orig/fs/ocfs2/inode.c 2010-02-20 11:59:10.860254535 +0100 > +++ linux-2.6/fs/ocfs2/inode.c 2010-02-20 12:00:45.548255793 +0100 > @@ -971,6 +971,8 @@ void ocfs2_delete_inode(struct inode *in > goto bail; > } > > + vfs_dq_init(inode); > + > if (!ocfs2_inode_is_valid_to_delete(inode)) { > /* It's probably not necessary to truncate_inode_pages > * here but we do it for safety anyway (it will most > Index: linux-2.6/fs/reiserfs/inode.c > =================================================================== > --- linux-2.6.orig/fs/reiserfs/inode.c 2010-02-20 11:59:10.802007224 +0100 > +++ linux-2.6/fs/reiserfs/inode.c 2010-02-20 12:00:45.554256073 +0100 > @@ -34,6 +34,9 @@ void reiserfs_delete_inode(struct inode > int depth; > int err; > > + if (!is_bad_inode(inode)) > + vfs_dq_init(inode); > + > truncate_inode_pages(&inode->i_data, 0); > > depth = reiserfs_write_lock_once(inode->i_sb); > @@ -3073,6 +3076,8 @@ int reiserfs_setattr(struct dentry *dent > ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); > > depth = reiserfs_write_lock_once(inode->i_sb); > + if (ia_valid & ATTR_SIZE) > + vfs_dq_init(inode); > if (attr->ia_valid & ATTR_SIZE) { > /* version 2 items will be caught by the s_maxbytes check > ** done for us in vmtruncate > Index: linux-2.6/fs/ufs/inode.c > =================================================================== > --- linux-2.6.orig/fs/ufs/inode.c 2010-02-20 11:40:48.574254465 +0100 > +++ linux-2.6/fs/ufs/inode.c 2010-02-20 12:00:45.560257050 +0100 > @@ -36,6 +36,7 @@ > #include <linux/mm.h> > #include <linux/smp_lock.h> > #include <linux/buffer_head.h> > +#include <linux/quotaops.h> > > #include "ufs_fs.h" > #include "ufs.h" > @@ -908,6 +909,9 @@ void ufs_delete_inode (struct inode * in > { > loff_t old_i_size; > > + if (!is_bad_inode(inode)) > + vfs_dq_init(inode); > + > truncate_inode_pages(&inode->i_data, 0); > if (is_bad_inode(inode)) > goto no_delete; > Index: linux-2.6/fs/namei.c > =================================================================== > --- linux-2.6.orig/fs/namei.c 2010-02-20 11:40:48.597274509 +0100 > +++ linux-2.6/fs/namei.c 2010-02-20 12:00:45.565255863 +0100 > @@ -19,7 +19,6 @@ > #include <linux/slab.h> > #include <linux/fs.h> > #include <linux/namei.h> > -#include <linux/quotaops.h> > #include <linux/pagemap.h> > #include <linux/fsnotify.h> > #include <linux/personality.h> > @@ -1451,7 +1450,6 @@ int vfs_create(struct inode *dir, struct > error = security_inode_create(dir, dentry, mode); > if (error) > return error; > - vfs_dq_init(dir); > error = dir->i_op->create(dir, dentry, mode, nd); > if (!error) > fsnotify_create(dir, dentry); > @@ -1803,9 +1801,6 @@ ok: > } > } > if (!IS_ERR(filp)) { > - if (acc_mode & MAY_WRITE) > - vfs_dq_init(nd.path.dentry->d_inode); > - > if (will_truncate) { > error = handle_truncate(&nd.path); > if (error) { > @@ -1986,7 +1981,6 @@ int vfs_mknod(struct inode *dir, struct > if (error) > return error; > > - vfs_dq_init(dir); > error = dir->i_op->mknod(dir, dentry, mode, dev); > if (!error) > fsnotify_create(dir, dentry); > @@ -2085,7 +2079,6 @@ int vfs_mkdir(struct inode *dir, struct > if (error) > return error; > > - vfs_dq_init(dir); > error = dir->i_op->mkdir(dir, dentry, mode); > if (!error) > fsnotify_mkdir(dir, dentry); > @@ -2171,8 +2164,6 @@ int vfs_rmdir(struct inode *dir, struct > if (!dir->i_op->rmdir) > return -EPERM; > > - vfs_dq_init(dir); > - > mutex_lock(&dentry->d_inode->i_mutex); > dentry_unhash(dentry); > if (d_mountpoint(dentry)) > @@ -2258,8 +2249,6 @@ int vfs_unlink(struct inode *dir, struct > if (!dir->i_op->unlink) > return -EPERM; > > - vfs_dq_init(dir); > - > mutex_lock(&dentry->d_inode->i_mutex); > if (d_mountpoint(dentry)) > error = -EBUSY; > @@ -2369,7 +2358,6 @@ int vfs_symlink(struct inode *dir, struc > if (error) > return error; > > - vfs_dq_init(dir); > error = dir->i_op->symlink(dir, dentry, oldname); > if (!error) > fsnotify_create(dir, dentry); > @@ -2453,7 +2441,6 @@ int vfs_link(struct dentry *old_dentry, > return error; > > mutex_lock(&inode->i_mutex); > - vfs_dq_init(dir); > error = dir->i_op->link(old_dentry, dir, new_dentry); > mutex_unlock(&inode->i_mutex); > if (!error) > @@ -2652,9 +2639,6 @@ int vfs_rename(struct inode *old_dir, st > if (!old_dir->i_op->rename) > return -EPERM; > > - vfs_dq_init(old_dir); > - vfs_dq_init(new_dir); > - > old_name = fsnotify_oldname_init(old_dentry->d_name.name); > > if (is_dir) > Index: linux-2.6/fs/ext2/namei.c > =================================================================== > --- linux-2.6.orig/fs/ext2/namei.c 2010-02-20 11:40:48.390272694 +0100 > +++ linux-2.6/fs/ext2/namei.c 2010-02-20 12:00:45.577006037 +0100 > @@ -31,6 +31,7 @@ > */ > > #include <linux/pagemap.h> > +#include <linux/quotaops.h> > #include "ext2.h" > #include "xattr.h" > #include "acl.h" > @@ -99,24 +100,27 @@ struct dentry *ext2_get_parent(struct de > */ > static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd) > { > - struct inode * inode = ext2_new_inode (dir, mode); > - int err = PTR_ERR(inode); > - if (!IS_ERR(inode)) { > - inode->i_op = &ext2_file_inode_operations; > - if (ext2_use_xip(inode->i_sb)) { > - inode->i_mapping->a_ops = &ext2_aops_xip; > - inode->i_fop = &ext2_xip_file_operations; > - } else if (test_opt(inode->i_sb, NOBH)) { > - inode->i_mapping->a_ops = &ext2_nobh_aops; > - inode->i_fop = &ext2_file_operations; > - } else { > - inode->i_mapping->a_ops = &ext2_aops; > - inode->i_fop = &ext2_file_operations; > - } > - mark_inode_dirty(inode); > - err = ext2_add_nondir(dentry, inode); > + struct inode *inode; > + > + vfs_dq_init(dir); > + > + inode = ext2_new_inode(dir, mode); > + if (IS_ERR(inode)) > + return PTR_ERR(inode); > + > + inode->i_op = &ext2_file_inode_operations; > + if (ext2_use_xip(inode->i_sb)) { > + inode->i_mapping->a_ops = &ext2_aops_xip; > + inode->i_fop = &ext2_xip_file_operations; > + } else if (test_opt(inode->i_sb, NOBH)) { > + inode->i_mapping->a_ops = &ext2_nobh_aops; > + inode->i_fop = &ext2_file_operations; > + } else { > + inode->i_mapping->a_ops = &ext2_aops; > + inode->i_fop = &ext2_file_operations; > } > - return err; > + mark_inode_dirty(inode); > + return ext2_add_nondir(dentry, inode); > } > > static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev) > @@ -127,6 +131,8 @@ static int ext2_mknod (struct inode * di > if (!new_valid_dev(rdev)) > return -EINVAL; > > + vfs_dq_init(dir); > + > inode = ext2_new_inode (dir, mode); > err = PTR_ERR(inode); > if (!IS_ERR(inode)) { > @@ -151,6 +157,8 @@ static int ext2_symlink (struct inode * > if (l > sb->s_blocksize) > goto out; > > + vfs_dq_init(dir); > + > inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO); > err = PTR_ERR(inode); > if (IS_ERR(inode)) > @@ -194,6 +202,8 @@ static int ext2_link (struct dentry * ol > if (inode->i_nlink >= EXT2_LINK_MAX) > return -EMLINK; > > + vfs_dq_init(dir); > + > inode->i_ctime = CURRENT_TIME_SEC; > inode_inc_link_count(inode); > atomic_inc(&inode->i_count); > @@ -216,6 +226,8 @@ static int ext2_mkdir(struct inode * dir > if (dir->i_nlink >= EXT2_LINK_MAX) > goto out; > > + vfs_dq_init(dir); > + > inode_inc_link_count(dir); > > inode = ext2_new_inode (dir, S_IFDIR | mode); > @@ -262,6 +274,8 @@ static int ext2_unlink(struct inode * di > struct page * page; > int err = -ENOENT; > > + vfs_dq_init(dir); > + > de = ext2_find_entry (dir, &dentry->d_name, &page); > if (!de) > goto out; > @@ -304,6 +318,9 @@ static int ext2_rename (struct inode * o > struct ext2_dir_entry_2 * old_de; > int err = -ENOENT; > > + vfs_dq_init(old_dir); > + vfs_dq_init(new_dir); > + > old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page); > if (!old_de) > goto out; > Index: linux-2.6/fs/ext3/namei.c > =================================================================== > --- linux-2.6.orig/fs/ext3/namei.c 2010-02-20 11:40:48.419254255 +0100 > +++ linux-2.6/fs/ext3/namei.c 2010-02-20 12:00:45.584007015 +0100 > @@ -1696,6 +1696,8 @@ static int ext3_create (struct inode * d > struct inode * inode; > int err, retries = 0; > > + vfs_dq_init(dir); > + > retry: > handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + > EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + > @@ -1730,6 +1732,8 @@ static int ext3_mknod (struct inode * di > if (!new_valid_dev(rdev)) > return -EINVAL; > > + vfs_dq_init(dir); > + > retry: > handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + > EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + > @@ -1766,6 +1770,8 @@ static int ext3_mkdir(struct inode * dir > if (dir->i_nlink >= EXT3_LINK_MAX) > return -EMLINK; > > + vfs_dq_init(dir); > + > retry: > handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + > EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + > @@ -2060,7 +2066,9 @@ static int ext3_rmdir (struct inode * di > > /* Initialize quotas before so that eventual writes go in > * separate transaction */ > + vfs_dq_init(dir); > vfs_dq_init(dentry->d_inode); > + > handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); > if (IS_ERR(handle)) > return PTR_ERR(handle); > @@ -2119,7 +2127,9 @@ static int ext3_unlink(struct inode * di > > /* Initialize quotas before so that eventual writes go > * in separate transaction */ > + vfs_dq_init(dir); > vfs_dq_init(dentry->d_inode); > + > handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); > if (IS_ERR(handle)) > return PTR_ERR(handle); > @@ -2174,6 +2184,8 @@ static int ext3_symlink (struct inode * > if (l > dir->i_sb->s_blocksize) > return -ENAMETOOLONG; > > + vfs_dq_init(dir); > + > retry: > handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + > EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 + > @@ -2228,6 +2240,9 @@ static int ext3_link (struct dentry * ol > > if (inode->i_nlink >= EXT3_LINK_MAX) > return -EMLINK; > + > + vfs_dq_init(dir); > + > /* > * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing > * otherwise has the potential to corrupt the orphan inode list. > @@ -2278,6 +2293,9 @@ static int ext3_rename (struct inode * o > struct ext3_dir_entry_2 * old_de, * new_de; > int retval, flush_file = 0; > > + vfs_dq_init(old_dir); > + vfs_dq_init(new_dir); > + > old_bh = new_bh = dir_bh = NULL; > > /* Initialize quotas before so that eventual writes go > Index: linux-2.6/fs/ext4/namei.c > =================================================================== > --- linux-2.6.orig/fs/ext4/namei.c 2010-02-20 11:40:48.450275138 +0100 > +++ linux-2.6/fs/ext4/namei.c 2010-02-20 12:00:45.602005827 +0100 > @@ -1766,6 +1766,8 @@ static int ext4_create(struct inode *dir > struct inode *inode; > int err, retries = 0; > > + vfs_dq_init(dir); > + > retry: > handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + > EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 + > @@ -1800,6 +1802,8 @@ static int ext4_mknod(struct inode *dir, > if (!new_valid_dev(rdev)) > return -EINVAL; > > + vfs_dq_init(dir); > + > retry: > handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + > EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 + > @@ -1837,6 +1841,8 @@ static int ext4_mkdir(struct inode *dir, > if (EXT4_DIR_LINK_MAX(dir)) > return -EMLINK; > > + vfs_dq_init(dir); > + > retry: > handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + > EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 + > @@ -2136,7 +2142,9 @@ static int ext4_rmdir(struct inode *dir, > > /* Initialize quotas before so that eventual writes go in > * separate transaction */ > + vfs_dq_init(dir); > vfs_dq_init(dentry->d_inode); > + > handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); > if (IS_ERR(handle)) > return PTR_ERR(handle); > @@ -2195,7 +2203,9 @@ static int ext4_unlink(struct inode *dir > > /* Initialize quotas before so that eventual writes go > * in separate transaction */ > + vfs_dq_init(dir); > vfs_dq_init(dentry->d_inode); > + > handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); > if (IS_ERR(handle)) > return PTR_ERR(handle); > @@ -2250,6 +2260,8 @@ static int ext4_symlink(struct inode *di > if (l > dir->i_sb->s_blocksize) > return -ENAMETOOLONG; > > + vfs_dq_init(dir); > + > retry: > handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + > EXT4_INDEX_EXTRA_TRANS_BLOCKS + 5 + > @@ -2308,6 +2320,8 @@ static int ext4_link(struct dentry *old_ > if (inode->i_nlink >= EXT4_LINK_MAX) > return -EMLINK; > > + vfs_dq_init(dir); > + > /* > * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing > * otherwise has the potential to corrupt the orphan inode list. > @@ -2358,6 +2372,9 @@ static int ext4_rename(struct inode *old > struct ext4_dir_entry_2 *old_de, *new_de; > int retval, force_da_alloc = 0; > > + vfs_dq_init(old_dir); > + vfs_dq_init(new_dir); > + > old_bh = new_bh = dir_bh = NULL; > > /* Initialize quotas before so that eventual writes go > Index: linux-2.6/fs/jfs/namei.c > =================================================================== > --- linux-2.6.orig/fs/jfs/namei.c 2010-02-20 11:53:51.140254046 +0100 > +++ linux-2.6/fs/jfs/namei.c 2010-02-20 12:00:45.617005478 +0100 > @@ -85,6 +85,8 @@ static int jfs_create(struct inode *dip, > > jfs_info("jfs_create: dip:0x%p name:%s", dip, dentry->d_name.name); > > + vfs_dq_init(dip); > + > /* > * search parent directory for entry/freespace > * (dtSearch() returns parent directory page pinned) > @@ -215,6 +217,8 @@ static int jfs_mkdir(struct inode *dip, > > jfs_info("jfs_mkdir: dip:0x%p name:%s", dip, dentry->d_name.name); > > + vfs_dq_init(dip); > + > /* link count overflow on parent directory ? */ > if (dip->i_nlink == JFS_LINK_MAX) { > rc = -EMLINK; > @@ -356,6 +360,7 @@ static int jfs_rmdir(struct inode *dip, > jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); > > /* Init inode for quota operations. */ > + vfs_dq_init(dip); > vfs_dq_init(ip); > > /* directory must be empty to be removed */ > @@ -483,6 +488,7 @@ static int jfs_unlink(struct inode *dip, > jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name); > > /* Init inode for quota operations. */ > + vfs_dq_init(dip); > vfs_dq_init(ip); > > if ((rc = get_UCSname(&dname, dentry))) > @@ -805,6 +811,8 @@ static int jfs_link(struct dentry *old_d > if (ip->i_nlink == 0) > return -ENOENT; > > + vfs_dq_init(dir); > + > tid = txBegin(ip->i_sb, 0); > > mutex_lock_nested(&JFS_IP(dir)->commit_mutex, COMMIT_MUTEX_PARENT); > @@ -896,6 +904,8 @@ static int jfs_symlink(struct inode *dip > > jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name); > > + vfs_dq_init(dip); > + > ssize = strlen(name) + 1; > > /* > @@ -1087,6 +1097,9 @@ static int jfs_rename(struct inode *old_ > jfs_info("jfs_rename: %s %s", old_dentry->d_name.name, > new_dentry->d_name.name); > > + vfs_dq_init(old_dir); > + vfs_dq_init(new_dir); > + > old_ip = old_dentry->d_inode; > new_ip = new_dentry->d_inode; > > @@ -1360,6 +1373,8 @@ static int jfs_mknod(struct inode *dir, > > jfs_info("jfs_mknod: %s", dentry->d_name.name); > > + vfs_dq_init(dir); > + > if ((rc = get_UCSname(&dname, dentry))) > goto out; > > Index: linux-2.6/fs/ocfs2/namei.c > =================================================================== > --- linux-2.6.orig/fs/ocfs2/namei.c 2010-02-20 11:48:48.651005199 +0100 > +++ linux-2.6/fs/ocfs2/namei.c 2010-02-20 12:00:45.625285195 +0100 > @@ -244,6 +244,8 @@ static int ocfs2_mknod(struct inode *dir > (unsigned long)dev, dentry->d_name.len, > dentry->d_name.name); > > + vfs_dq_init(dir); > + > /* get our super block */ > osb = OCFS2_SB(dir->i_sb); > > @@ -633,6 +635,8 @@ static int ocfs2_link(struct dentry *old > if (S_ISDIR(inode->i_mode)) > return -EPERM; > > + vfs_dq_init(dir); > + > err = ocfs2_inode_lock_nested(dir, &parent_fe_bh, 1, OI_LS_PARENT); > if (err < 0) { > if (err != -ENOENT) > @@ -788,6 +792,8 @@ static int ocfs2_unlink(struct inode *di > mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry, > dentry->d_name.len, dentry->d_name.name); > > + vfs_dq_init(dir); > + > BUG_ON(dentry->d_parent->d_inode != dir); > > mlog(0, "ino = %llu\n", (unsigned long long)OCFS2_I(inode)->ip_blkno); > @@ -1048,6 +1054,9 @@ static int ocfs2_rename(struct inode *ol > old_dentry->d_name.len, old_dentry->d_name.name, > new_dentry->d_name.len, new_dentry->d_name.name); > > + vfs_dq_init(old_dir); > + vfs_dq_init(new_dir); > + > osb = OCFS2_SB(old_dir->i_sb); > > if (new_inode) { > @@ -1596,6 +1605,8 @@ static int ocfs2_symlink(struct inode *d > mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir, > dentry, symname, dentry->d_name.len, dentry->d_name.name); > > + vfs_dq_init(dir); > + > sb = dir->i_sb; > osb = OCFS2_SB(sb); > > Index: linux-2.6/fs/reiserfs/namei.c > =================================================================== > --- linux-2.6.orig/fs/reiserfs/namei.c 2010-02-20 11:59:10.814006596 +0100 > +++ linux-2.6/fs/reiserfs/namei.c 2010-02-20 12:00:45.631256001 +0100 > @@ -594,6 +594,8 @@ static int reiserfs_create(struct inode > struct reiserfs_transaction_handle th; > struct reiserfs_security_handle security; > > + vfs_dq_init(dir); > + > if (!(inode = new_inode(dir->i_sb))) { > return -ENOMEM; > } > @@ -666,6 +668,8 @@ static int reiserfs_mknod(struct inode * > if (!new_valid_dev(rdev)) > return -EINVAL; > > + vfs_dq_init(dir); > + > if (!(inode = new_inode(dir->i_sb))) { > return -ENOMEM; > } > @@ -739,6 +743,8 @@ static int reiserfs_mkdir(struct inode * > 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + > REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); > > + vfs_dq_init(dir); > + > #ifdef DISPLACE_NEW_PACKING_LOCALITIES > /* set flag that new packing locality created and new blocks for the content * of that directory are not displaced yet */ > REISERFS_I(dir)->new_packing_locality = 1; > @@ -842,6 +848,8 @@ static int reiserfs_rmdir(struct inode * > JOURNAL_PER_BALANCE_CNT * 2 + 2 + > 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); > > + vfs_dq_init(dir); > + > reiserfs_write_lock(dir->i_sb); > retval = journal_begin(&th, dir->i_sb, jbegin_count); > if (retval) > @@ -923,6 +931,8 @@ static int reiserfs_unlink(struct inode > unsigned long savelink; > int depth; > > + vfs_dq_init(dir); > + > inode = dentry->d_inode; > > /* in this transaction we can be doing at max two balancings and update > @@ -1024,6 +1034,8 @@ static int reiserfs_symlink(struct inode > 2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) + > REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb)); > > + vfs_dq_init(parent_dir); > + > if (!(inode = new_inode(parent_dir->i_sb))) { > return -ENOMEM; > } > @@ -1111,6 +1123,8 @@ static int reiserfs_link(struct dentry * > JOURNAL_PER_BALANCE_CNT * 3 + > 2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); > > + vfs_dq_init(dir); > + > reiserfs_write_lock(dir->i_sb); > if (inode->i_nlink >= REISERFS_LINK_MAX) { > //FIXME: sd_nlink is 32 bit for new files > @@ -1235,6 +1249,9 @@ static int reiserfs_rename(struct inode > JOURNAL_PER_BALANCE_CNT * 3 + 5 + > 4 * REISERFS_QUOTA_TRANS_BLOCKS(old_dir->i_sb); > > + vfs_dq_init(old_dir); > + vfs_dq_init(new_dir); > + > old_inode = old_dentry->d_inode; > new_dentry_inode = new_dentry->d_inode; > > Index: linux-2.6/fs/reiserfs/xattr.c > =================================================================== > --- linux-2.6.orig/fs/reiserfs/xattr.c 2010-02-20 11:40:48.552254116 +0100 > +++ linux-2.6/fs/reiserfs/xattr.c 2010-02-20 12:00:45.635255512 +0100 > @@ -61,7 +61,6 @@ > static int xattr_create(struct inode *dir, struct dentry *dentry, int mode) > { > BUG_ON(!mutex_is_locked(&dir->i_mutex)); > - vfs_dq_init(dir); > return dir->i_op->create(dir, dentry, mode, NULL); > } > #endif > @@ -69,7 +68,6 @@ static int xattr_create(struct inode *di > static int xattr_mkdir(struct inode *dir, struct dentry *dentry, int mode) > { > BUG_ON(!mutex_is_locked(&dir->i_mutex)); > - vfs_dq_init(dir); > return dir->i_op->mkdir(dir, dentry, mode); > } > > @@ -81,7 +79,6 @@ static int xattr_unlink(struct inode *di > { > int error; > BUG_ON(!mutex_is_locked(&dir->i_mutex)); > - vfs_dq_init(dir); > > reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, > I_MUTEX_CHILD, dir->i_sb); > @@ -97,7 +94,6 @@ static int xattr_rmdir(struct inode *dir > { > int error; > BUG_ON(!mutex_is_locked(&dir->i_mutex)); > - vfs_dq_init(dir); > > reiserfs_mutex_lock_nested_safe(&dentry->d_inode->i_mutex, > I_MUTEX_CHILD, dir->i_sb); > Index: linux-2.6/fs/ufs/namei.c > =================================================================== > --- linux-2.6.orig/fs/ufs/namei.c 2010-02-20 11:40:48.582254325 +0100 > +++ linux-2.6/fs/ufs/namei.c 2010-02-20 12:00:45.638255862 +0100 > @@ -30,6 +30,7 @@ > #include <linux/time.h> > #include <linux/fs.h> > #include <linux/smp_lock.h> > +#include <linux/quotaops.h> > > #include "ufs_fs.h" > #include "ufs.h" > @@ -84,6 +85,9 @@ static int ufs_create (struct inode * di > int err; > > UFSD("BEGIN\n"); > + > + vfs_dq_init(dir); > + > inode = ufs_new_inode(dir, mode); > err = PTR_ERR(inode); > > @@ -107,6 +111,9 @@ static int ufs_mknod (struct inode * dir > > if (!old_valid_dev(rdev)) > return -EINVAL; > + > + vfs_dq_init(dir); > + > inode = ufs_new_inode(dir, mode); > err = PTR_ERR(inode); > if (!IS_ERR(inode)) { > @@ -131,6 +138,8 @@ static int ufs_symlink (struct inode * d > if (l > sb->s_blocksize) > goto out_notlocked; > > + vfs_dq_init(dir); > + > lock_kernel(); > inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); > err = PTR_ERR(inode); > @@ -176,6 +185,8 @@ static int ufs_link (struct dentry * old > return -EMLINK; > } > > + vfs_dq_init(dir); > + > inode->i_ctime = CURRENT_TIME_SEC; > inode_inc_link_count(inode); > atomic_inc(&inode->i_count); > @@ -193,6 +204,8 @@ static int ufs_mkdir(struct inode * dir, > if (dir->i_nlink >= UFS_LINK_MAX) > goto out; > > + vfs_dq_init(dir); > + > lock_kernel(); > inode_inc_link_count(dir); > > @@ -237,6 +250,8 @@ static int ufs_unlink(struct inode *dir, > struct page *page; > int err = -ENOENT; > > + vfs_dq_init(dir); > + > de = ufs_find_entry(dir, &dentry->d_name, &page); > if (!de) > goto out; > @@ -281,6 +296,9 @@ static int ufs_rename(struct inode *old_ > struct ufs_dir_entry *old_de; > int err = -ENOENT; > > + vfs_dq_init(old_dir); > + vfs_dq_init(new_dir); > + > old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); > if (!old_de) > goto out; > Index: linux-2.6/fs/nfsd/vfs.c > =================================================================== > --- linux-2.6.orig/fs/nfsd/vfs.c 2010-02-20 11:40:48.611254535 +0100 > +++ linux-2.6/fs/nfsd/vfs.c 2010-02-20 12:00:45.641255652 +0100 > @@ -20,7 +20,6 @@ > #include <linux/fcntl.h> > #include <linux/namei.h> > #include <linux/delay.h> > -#include <linux/quotaops.h> > #include <linux/fsnotify.h> > #include <linux/posix_acl_xattr.h> > #include <linux/xattr.h> > @@ -377,7 +376,6 @@ nfsd_setattr(struct svc_rqst *rqstp, str > put_write_access(inode); > goto out_nfserr; > } > - vfs_dq_init(inode); > } > > /* sanitize the mode change */ > @@ -745,8 +743,6 @@ nfsd_open(struct svc_rqst *rqstp, struct > flags = O_RDWR|O_LARGEFILE; > else > flags = O_WRONLY|O_LARGEFILE; > - > - vfs_dq_init(inode); > } > *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt), > flags, current_cred()); > Index: linux-2.6/fs/ocfs2/file.c > =================================================================== > --- linux-2.6.orig/fs/ocfs2/file.c 2010-02-20 11:55:53.836005270 +0100 > +++ linux-2.6/fs/ocfs2/file.c 2010-02-20 12:00:45.648255722 +0100 > @@ -107,6 +107,9 @@ static int ocfs2_file_open(struct inode > mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file, > file->f_path.dentry->d_name.len, file->f_path.dentry->d_name.name); > > + if (file->f_mode & FMODE_WRITE) > + vfs_dq_init(inode); > + > spin_lock(&oi->ip_lock); > > /* Check that the inode hasn't been wiped from disk by another > @@ -976,6 +979,9 @@ int ocfs2_setattr(struct dentry *dentry, > if (status) > return status; > > + if (attr->ia_valid & ATTR_SIZE) > + vfs_dq_init(inode); > + > size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE; > if (size_change) { > status = ocfs2_rw_lock(inode, 1); > Index: linux-2.6/fs/open.c > =================================================================== > --- linux-2.6.orig/fs/open.c 2010-02-20 11:40:48.619003522 +0100 > +++ linux-2.6/fs/open.c 2010-02-20 12:00:45.664005758 +0100 > @@ -8,7 +8,6 @@ > #include <linux/mm.h> > #include <linux/file.h> > #include <linux/fdtable.h> > -#include <linux/quotaops.h> > #include <linux/fsnotify.h> > #include <linux/module.h> > #include <linux/slab.h> > @@ -278,10 +277,8 @@ static long do_sys_truncate(const char _ > error = locks_verify_truncate(inode, NULL, length); > if (!error) > error = security_path_truncate(&path, length, 0); > - if (!error) { > - vfs_dq_init(inode); > + if (!error) > error = do_truncate(path.dentry, length, 0, NULL); > - } > > put_write_and_out: > put_write_access(inode); > Index: linux-2.6/fs/jfs/file.c > =================================================================== > --- linux-2.6.orig/fs/jfs/file.c 2010-02-20 11:55:53.857256072 +0100 > +++ linux-2.6/fs/jfs/file.c 2010-02-20 12:00:45.672027269 +0100 > @@ -48,7 +48,7 @@ static int jfs_open(struct inode *inode, > { > int rc; > > - if ((rc = generic_file_open(inode, file))) > + if ((rc = dquot_file_open(inode, file))) > return rc; > > /* > @@ -98,6 +98,8 @@ int jfs_setattr(struct dentry *dentry, s > if (rc) > return rc; > > + if (iattr->ia_valid & ATTR_SIZE) > + vfs_dq_init(inode); > if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || > (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { > rc = dquot_transfer(inode, iattr); > Index: linux-2.6/fs/ext2/file.c > =================================================================== > --- linux-2.6.orig/fs/ext2/file.c 2010-02-20 11:40:48.399254325 +0100 > +++ linux-2.6/fs/ext2/file.c 2010-02-20 12:00:45.675031669 +0100 > @@ -70,7 +70,7 @@ const struct file_operations ext2_file_o > .compat_ioctl = ext2_compat_ioctl, > #endif > .mmap = generic_file_mmap, > - .open = generic_file_open, > + .open = dquot_file_open, > .release = ext2_release_file, > .fsync = ext2_fsync, > .splice_read = generic_file_splice_read, > @@ -87,7 +87,7 @@ const struct file_operations ext2_xip_fi > .compat_ioctl = ext2_compat_ioctl, > #endif > .mmap = xip_file_mmap, > - .open = generic_file_open, > + .open = dquot_file_open, > .release = ext2_release_file, > .fsync = ext2_fsync, > }; > Index: linux-2.6/fs/ext3/file.c > =================================================================== > --- linux-2.6.orig/fs/ext3/file.c 2010-02-20 11:40:48.431254674 +0100 > +++ linux-2.6/fs/ext3/file.c 2010-02-20 12:00:45.679005408 +0100 > @@ -62,7 +62,7 @@ const struct file_operations ext3_file_o > .compat_ioctl = ext3_compat_ioctl, > #endif > .mmap = generic_file_mmap, > - .open = generic_file_open, > + .open = dquot_file_open, > .release = ext3_release_file, > .fsync = ext3_sync_file, > .splice_read = generic_file_splice_read, > Index: linux-2.6/fs/ext4/file.c > =================================================================== > --- linux-2.6.orig/fs/ext4/file.c 2010-02-20 11:40:48.461254604 +0100 > +++ linux-2.6/fs/ext4/file.c 2010-02-20 12:00:45.682007294 +0100 > @@ -127,7 +127,7 @@ static int ext4_file_open(struct inode * > sb->s_dirt = 1; > } > } > - return generic_file_open(inode, filp); > + return dquot_file_open(inode, filp); > } > > const struct file_operations ext4_file_operations = { > Index: linux-2.6/fs/quota/dquot.c > =================================================================== > --- linux-2.6.orig/fs/quota/dquot.c 2010-02-20 11:59:10.787005967 +0100 > +++ linux-2.6/fs/quota/dquot.c 2010-02-20 12:00:45.687005339 +0100 > @@ -1821,6 +1821,20 @@ const struct dquot_operations dquot_oper > }; > > /* > + * Generic helper for ->open on filesystems supporting disk quotas. > + */ > +int dquot_file_open(struct inode *inode, struct file *file) > +{ > + int error; > + > + error = generic_file_open(inode, file); > + if (!error && (file->f_mode & FMODE_WRITE)) > + vfs_dq_init(inode); > + return error; > +} > +EXPORT_SYMBOL(dquot_file_open); > + > +/* > * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) > */ > int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) > Index: linux-2.6/fs/reiserfs/file.c > =================================================================== > --- linux-2.6.orig/fs/reiserfs/file.c 2010-02-20 11:40:48.561275487 +0100 > +++ linux-2.6/fs/reiserfs/file.c 2010-02-20 12:00:45.697024196 +0100 > @@ -289,7 +289,7 @@ const struct file_operations reiserfs_fi > .compat_ioctl = reiserfs_compat_ioctl, > #endif > .mmap = reiserfs_file_mmap, > - .open = generic_file_open, > + .open = dquot_file_open, > .release = reiserfs_file_release, > .fsync = reiserfs_sync_file, > .aio_read = generic_file_aio_read, > Index: linux-2.6/fs/ufs/file.c > =================================================================== > --- linux-2.6.orig/fs/ufs/file.c 2010-02-20 11:40:48.590259424 +0100 > +++ linux-2.6/fs/ufs/file.c 2010-02-20 12:00:45.699274231 +0100 > @@ -40,7 +40,7 @@ const struct file_operations ufs_file_op > .write = do_sync_write, > .aio_write = generic_file_aio_write, > .mmap = generic_file_mmap, > - .open = generic_file_open, > + .open = dquot_file_open, > .fsync = simple_fsync, > .splice_read = generic_file_splice_read, > }; > Index: linux-2.6/include/linux/quotaops.h > =================================================================== > --- linux-2.6.orig/include/linux/quotaops.h 2010-02-20 11:59:10.821253697 +0100 > +++ linux-2.6/include/linux/quotaops.h 2010-02-20 12:00:45.701253558 +0100 > @@ -23,7 +23,7 @@ void inode_add_rsv_space(struct inode *i > void inode_claim_rsv_space(struct inode *inode, qsize_t number); > void inode_sub_rsv_space(struct inode *inode, qsize_t number); > > -int dquot_initialize(struct inode *inode, int type); > +void dquot_initialize(struct inode *inode); > void dquot_drop(struct inode *inode); > struct dquot *dqget(struct super_block *sb, unsigned int id, int type); > void dqput(struct dquot *dquot); > @@ -48,6 +48,8 @@ int dquot_release(struct dquot *dquot); > int dquot_commit_info(struct super_block *sb, int type); > int dquot_mark_dquot_dirty(struct dquot *dquot); > > +int dquot_file_open(struct inode *inode, struct file *file); > + > int vfs_quota_on(struct super_block *sb, int type, int format_id, > char *path, int remount); > int vfs_quota_enable(struct inode *inode, int type, int format_id, > @@ -137,15 +139,6 @@ extern const struct quotactl_ops vfs_quo > #define sb_dquot_ops (&dquot_operations) > #define sb_quotactl_ops (&vfs_quotactl_ops) > > -/* It is better to call this function outside of any transaction as it might > - * need a lot of space in journal for dquot structure allocation. */ > -static inline void vfs_dq_init(struct inode *inode) > -{ > - BUG_ON(!inode->i_sb); > - if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) > - inode->i_sb->dq_op->initialize(inode, -1); > -} > - > /* Cannot be called inside a transaction */ > static inline int vfs_dq_off(struct super_block *sb, int remount) > { > @@ -205,7 +198,7 @@ static inline int sb_any_quota_active(st > #define sb_dquot_ops (NULL) > #define sb_quotactl_ops (NULL) > > -static inline void vfs_dq_init(struct inode *inode) > +static inline void dquot_initialize(struct inode *inode) > { > } > > @@ -342,4 +335,6 @@ static inline void dquot_release_reserva > __dquot_free_space(inode, nr << inode->i_blkbits, 1); > } > > +#define dquot_file_open generic_file_open > + > #endif /* _LINUX_QUOTAOPS_ */ > -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html