From 5dd4056db84387975140ff2568eaa0406f07985e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Mar 2010 09:05:00 -0500 Subject: dquot: cleanup space allocation / freeing routines Get rid of the alloc_space, free_space, reserve_space, claim_space and release_rsv dquot operations - they are always called from the filesystem and if a filesystem really needs their own (which none currently does) it can just call into it's own routine directly. Move shared logic into the common __dquot_alloc_space, dquot_claim_space_nodirty and __dquot_free_space low-level methods, and rationalize the wrappers around it to move as much as possible code into the common block for CONFIG_QUOTA vs not. Also rename all these helpers to be named dquot_* instead of vfs_dq_*. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/jfs/jfs_dtree.c | 28 +++++++++++++++------------- fs/jfs/jfs_extent.c | 16 +++++++++------- fs/jfs/jfs_xtree.c | 21 +++++++++++---------- fs/jfs/xattr.c | 17 +++++++++-------- 4 files changed, 44 insertions(+), 38 deletions(-) (limited to 'fs/jfs') diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index 925871e9887b..0e4623be70ce 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c @@ -381,10 +381,10 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) * It's time to move the inline table to an external * page and begin to build the xtree */ - if (vfs_dq_alloc_block(ip, sbi->nbperpage)) + if (dquot_alloc_block(ip, sbi->nbperpage)) goto clean_up; if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) { - vfs_dq_free_block(ip, sbi->nbperpage); + dquot_free_block(ip, sbi->nbperpage); goto clean_up; } @@ -408,7 +408,7 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) memcpy(&jfs_ip->i_dirtable, temp_table, sizeof (temp_table)); dbFree(ip, xaddr, sbi->nbperpage); - vfs_dq_free_block(ip, sbi->nbperpage); + dquot_free_block(ip, sbi->nbperpage); goto clean_up; } ip->i_size = PSIZE; @@ -1027,10 +1027,9 @@ static int dtSplitUp(tid_t tid, n = xlen; /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, n)) { - rc = -EDQUOT; + rc = dquot_alloc_block(ip, n); + if (rc) goto extendOut; - } quota_allocation += n; if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen, @@ -1308,7 +1307,7 @@ static int dtSplitUp(tid_t tid, /* Rollback quota allocation */ if (rc && quota_allocation) - vfs_dq_free_block(ip, quota_allocation); + dquot_free_block(ip, quota_allocation); dtSplitUp_Exit: @@ -1369,9 +1368,10 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, return -EIO; /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) { + rc = dquot_alloc_block(ip, lengthPXD(pxd)); + if (rc) { release_metapage(rmp); - return -EDQUOT; + return rc; } jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp); @@ -1892,6 +1892,7 @@ static int dtSplitRoot(tid_t tid, struct dt_lock *dtlck; struct tlock *tlck; struct lv *lv; + int rc; /* get split root page */ smp = split->mp; @@ -1916,9 +1917,10 @@ static int dtSplitRoot(tid_t tid, rp = rmp->data; /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) { + rc = dquot_alloc_block(ip, lengthPXD(pxd)); + if (rc) { release_metapage(rmp); - return -EDQUOT; + return rc; } BT_MARK_DIRTY(rmp, ip); @@ -2287,7 +2289,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, xlen = lengthPXD(&fp->header.self); /* Free quota allocation. */ - vfs_dq_free_block(ip, xlen); + dquot_free_block(ip, xlen); /* free/invalidate its buffer page */ discard_metapage(fmp); @@ -2363,7 +2365,7 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, xlen = lengthPXD(&p->header.self); /* Free quota allocation */ - vfs_dq_free_block(ip, xlen); + dquot_free_block(ip, xlen); /* free/invalidate its buffer page */ discard_metapage(mp); diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c index 41d6045dbeb0..5d3bbd10f8db 100644 --- a/fs/jfs/jfs_extent.c +++ b/fs/jfs/jfs_extent.c @@ -141,10 +141,11 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) } /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, nxlen)) { + rc = dquot_alloc_block(ip, nxlen); + if (rc) { dbFree(ip, nxaddr, (s64) nxlen); mutex_unlock(&JFS_IP(ip)->commit_mutex); - return -EDQUOT; + return rc; } /* determine the value of the extent flag */ @@ -164,7 +165,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr) */ if (rc) { dbFree(ip, nxaddr, nxlen); - vfs_dq_free_block(ip, nxlen); + dquot_free_block(ip, nxlen); mutex_unlock(&JFS_IP(ip)->commit_mutex); return (rc); } @@ -256,10 +257,11 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) goto exit; /* Allocat blocks to quota. */ - if (vfs_dq_alloc_block(ip, nxlen)) { + rc = dquot_alloc_block(ip, nxlen); + if (rc) { dbFree(ip, nxaddr, (s64) nxlen); mutex_unlock(&JFS_IP(ip)->commit_mutex); - return -EDQUOT; + return rc; } delta = nxlen - xlen; @@ -297,7 +299,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) /* extend the extent */ if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) { dbFree(ip, xaddr + xlen, delta); - vfs_dq_free_block(ip, nxlen); + dquot_free_block(ip, nxlen); goto exit; } } else { @@ -308,7 +310,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, bool abnr) */ if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) { dbFree(ip, nxaddr, nxlen); - vfs_dq_free_block(ip, nxlen); + dquot_free_block(ip, nxlen); goto exit; } } diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index d654a6458648..6c50871e6220 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c @@ -585,10 +585,10 @@ int xtInsert(tid_t tid, /* transaction id */ hint = addressXAD(xad) + lengthXAD(xad) - 1; } else hint = 0; - if ((rc = vfs_dq_alloc_block(ip, xlen))) + if ((rc = dquot_alloc_block(ip, xlen))) goto out; if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) { - vfs_dq_free_block(ip, xlen); + dquot_free_block(ip, xlen); goto out; } } @@ -617,7 +617,7 @@ int xtInsert(tid_t tid, /* transaction id */ /* undo data extent allocation */ if (*xaddrp == 0) { dbFree(ip, xaddr, (s64) xlen); - vfs_dq_free_block(ip, xlen); + dquot_free_block(ip, xlen); } return rc; } @@ -985,10 +985,9 @@ xtSplitPage(tid_t tid, struct inode *ip, rbn = addressPXD(pxd); /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) { - rc = -EDQUOT; + rc = dquot_alloc_block(ip, lengthPXD(pxd)); + if (rc) goto clean_up; - } quota_allocation += lengthPXD(pxd); @@ -1195,7 +1194,7 @@ xtSplitPage(tid_t tid, struct inode *ip, /* Rollback quota allocation. */ if (quota_allocation) - vfs_dq_free_block(ip, quota_allocation); + dquot_free_block(ip, quota_allocation); return (rc); } @@ -1235,6 +1234,7 @@ xtSplitRoot(tid_t tid, struct pxdlist *pxdlist; struct tlock *tlck; struct xtlock *xtlck; + int rc; sp = &JFS_IP(ip)->i_xtroot; @@ -1252,9 +1252,10 @@ xtSplitRoot(tid_t tid, return -EIO; /* Allocate blocks to quota. */ - if (vfs_dq_alloc_block(ip, lengthPXD(pxd))) { + rc = dquot_alloc_block(ip, lengthPXD(pxd)); + if (rc) { release_metapage(rmp); - return -EDQUOT; + return rc; } jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp); @@ -3680,7 +3681,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) ip->i_size = newsize; /* update quota allocation to reflect freed blocks */ - vfs_dq_free_block(ip, nfreed); + dquot_free_block(ip, nfreed); /* * free tlock of invalidated pages diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index fad364548bc9..1f594ab21895 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -260,14 +260,14 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size, nblocks = (size + (sb->s_blocksize - 1)) >> sb->s_blocksize_bits; /* Allocate new blocks to quota. */ - if (vfs_dq_alloc_block(ip, nblocks)) { - return -EDQUOT; - } + rc = dquot_alloc_block(ip, nblocks); + if (rc) + return rc; rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno); if (rc) { /*Rollback quota allocation. */ - vfs_dq_free_block(ip, nblocks); + dquot_free_block(ip, nblocks); return rc; } @@ -332,7 +332,7 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size, failed: /* Rollback quota allocation. */ - vfs_dq_free_block(ip, nblocks); + dquot_free_block(ip, nblocks); dbFree(ip, blkno, nblocks); return rc; @@ -538,7 +538,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) if (blocks_needed > current_blocks) { /* Allocate new blocks to quota. */ - if (vfs_dq_alloc_block(inode, blocks_needed)) + rc = dquot_alloc_block(inode, blocks_needed); + if (rc) return -EDQUOT; quota_allocation = blocks_needed; @@ -602,7 +603,7 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) clean_up: /* Rollback quota allocation */ if (quota_allocation) - vfs_dq_free_block(inode, quota_allocation); + dquot_free_block(inode, quota_allocation); return (rc); } @@ -677,7 +678,7 @@ static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, /* If old blocks exist, they must be removed from quota allocation. */ if (old_blocks) - vfs_dq_free_block(inode, old_blocks); + dquot_free_block(inode, old_blocks); inode->i_ctime = CURRENT_TIME; -- cgit v1.2.3 From 63936ddaa16b9486e2d426ed7b09f559a5c60f87 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Mar 2010 09:05:01 -0500 Subject: dquot: cleanup inode allocation / freeing routines Get rid of the alloc_inode and free_inode dquot operations - they are always called from the filesystem and if a filesystem really needs their own (which none currently does) it can just call into it's own routine directly. Also get rid of the vfs_dq_alloc/vfs_dq_free wrappers and always call the lowlevel dquot_alloc_inode / dqout_free_inode routines directly, which now lose the number argument which is always 1. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- Documentation/filesystems/Locking | 8 -------- fs/ext2/ialloc.c | 10 +++++----- fs/ext3/ialloc.c | 10 +++++----- fs/ext3/super.c | 2 -- fs/ext4/ialloc.c | 10 +++++----- fs/ext4/super.c | 2 -- fs/jfs/inode.c | 2 +- fs/jfs/jfs_inode.c | 6 +++--- fs/ocfs2/inode.c | 2 +- fs/ocfs2/namei.c | 30 +++++++++--------------------- fs/ocfs2/quota_global.c | 2 -- fs/quota/dquot.c | 29 +++++++++++++---------------- fs/reiserfs/inode.c | 10 +++++----- fs/reiserfs/super.c | 2 -- fs/udf/ialloc.c | 10 ++++++---- fs/ufs/ialloc.c | 7 ++++--- include/linux/quota.h | 2 -- include/linux/quotaops.h | 24 ++++-------------------- 18 files changed, 61 insertions(+), 107 deletions(-) (limited to 'fs/jfs') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 1192fde11638..4428f55f2131 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -462,8 +462,6 @@ in sys_read() and friends. prototypes: int (*initialize) (struct inode *, int); int (*drop) (struct inode *); - int (*alloc_inode) (const struct inode *, unsigned long); - int (*free_inode) (const struct inode *, unsigned long); int (*transfer) (struct inode *, struct iattr *); int (*write_dquot) (struct dquot *); int (*acquire_dquot) (struct dquot *); @@ -479,8 +477,6 @@ What filesystem should expect from the generic quota functions: FS recursion Held locks when called initialize: yes maybe dqonoff_sem drop: yes - -alloc_inode: ->mark_dirty() - -free_inode: ->mark_dirty() - transfer: yes - write_dquot: yes dqonoff_sem or dqptr_sem acquire_dquot: yes dqonoff_sem or dqptr_sem @@ -491,10 +487,6 @@ write_info: yes dqonoff_sem FS recursion means calling ->quota_read() and ->quota_write() from superblock operations. -->alloc_inode(), ->free_inode() are called -only directly by the filesystem and do not call any fs functions only -the ->mark_dirty() operation. - More details about quota locking can be found in fs/dquot.c. --------------------------- vm_operations_struct ----------------------------- diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 15387c9c17d8..d12f9809559c 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -121,7 +121,7 @@ void ext2_free_inode (struct inode * inode) if (!is_bad_inode(inode)) { /* Quota is already initialized in iput() */ ext2_xattr_delete_inode(inode); - vfs_dq_free_inode(inode); + dquot_free_inode(inode); vfs_dq_drop(inode); } @@ -586,10 +586,10 @@ got: goto fail_drop; } - if (vfs_dq_alloc_inode(inode)) { - err = -EDQUOT; + vfs_dq_init(inode); + err = dquot_alloc_inode(inode); + if (err) goto fail_drop; - } err = ext2_init_acl(inode, dir); if (err) @@ -605,7 +605,7 @@ got: return inode; fail_free_drop: - vfs_dq_free_inode(inode); + dquot_free_inode(inode); fail_drop: vfs_dq_drop(inode); diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index b39991285136..8bf00e997c38 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -125,7 +125,7 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) */ vfs_dq_init(inode); ext3_xattr_delete_inode(handle, inode); - vfs_dq_free_inode(inode); + dquot_free_inode(inode); vfs_dq_drop(inode); is_directory = S_ISDIR(inode->i_mode); @@ -588,10 +588,10 @@ got: sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0; ret = inode; - if (vfs_dq_alloc_inode(inode)) { - err = -EDQUOT; + vfs_dq_init(inode); + err = dquot_alloc_inode(inode); + if (err) goto fail_drop; - } err = ext3_init_acl(handle, inode, dir); if (err) @@ -619,7 +619,7 @@ really_out: return ret; fail_free_drop: - vfs_dq_free_inode(inode); + dquot_free_inode(inode); fail_drop: vfs_dq_drop(inode); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 8c13910a3782..8b8bc4f9cb14 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -752,8 +752,6 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, static const struct dquot_operations ext3_quota_operations = { .initialize = dquot_initialize, .drop = dquot_drop, - .alloc_inode = dquot_alloc_inode, - .free_inode = dquot_free_inode, .transfer = dquot_transfer, .write_dquot = ext3_write_dquot, .acquire_dquot = ext3_acquire_dquot, diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index f3624ead4f6c..b0d744cf8b95 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -219,7 +219,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) */ vfs_dq_init(inode); ext4_xattr_delete_inode(handle, inode); - vfs_dq_free_inode(inode); + dquot_free_inode(inode); vfs_dq_drop(inode); is_directory = S_ISDIR(inode->i_mode); @@ -1034,10 +1034,10 @@ got: ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize; ret = inode; - if (vfs_dq_alloc_inode(inode)) { - err = -EDQUOT; + vfs_dq_init(inode); + err = dquot_alloc_inode(inode); + if (err) goto fail_drop; - } err = ext4_init_acl(handle, inode, dir); if (err) @@ -1074,7 +1074,7 @@ really_out: return ret; fail_free_drop: - vfs_dq_free_inode(inode); + dquot_free_inode(inode); fail_drop: vfs_dq_drop(inode); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index fa8f4deda652..d231da8798e3 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1017,8 +1017,6 @@ static const struct dquot_operations ext4_quota_operations = { #ifdef CONFIG_QUOTA .get_reserved_space = ext4_get_reserved_space, #endif - .alloc_inode = dquot_alloc_inode, - .free_inode = dquot_free_inode, .transfer = dquot_transfer, .write_dquot = ext4_write_dquot, .acquire_dquot = ext4_acquire_dquot, diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index b2ae190a77ba..2562d18988f7 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -159,7 +159,7 @@ void jfs_delete_inode(struct inode *inode) * Free the inode from the quota allocation. */ vfs_dq_init(inode); - vfs_dq_free_inode(inode); + dquot_free_inode(inode); vfs_dq_drop(inode); } diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index dc0e02159ac9..7762f33e062b 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -116,10 +116,10 @@ struct inode *ialloc(struct inode *parent, umode_t mode) /* * Allocate inode to quota. */ - if (vfs_dq_alloc_inode(inode)) { - rc = -EDQUOT; + vfs_dq_init(inode); + rc = dquot_alloc_inode(inode); + if (rc) goto fail_drop; - } inode->i_mode = mode; /* inherit flags from parent */ diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 88459bdd1ff3..cb7f67d8441a 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -665,7 +665,7 @@ static int ocfs2_remove_inode(struct inode *inode, } ocfs2_remove_from_cache(INODE_CACHE(inode), di_bh); - vfs_dq_free_inode(inode); + dquot_free_inode(inode); status = ocfs2_free_dinode(handle, inode_alloc_inode, inode_alloc_bh, di); diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 13adaa1f40cd..99766b6418eb 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -348,13 +348,9 @@ static int ocfs2_mknod(struct inode *dir, goto leave; } - /* We don't use standard VFS wrapper because we don't want vfs_dq_init - * to be called. */ - if (sb_any_quota_active(osb->sb) && - osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) { - status = -EDQUOT; + status = dquot_alloc_inode(inode); + if (status) goto leave; - } did_quota_inode = 1; mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, @@ -431,7 +427,7 @@ static int ocfs2_mknod(struct inode *dir, status = 0; leave: if (status < 0 && did_quota_inode) - vfs_dq_free_inode(inode); + dquot_free_inode(inode); if (handle) ocfs2_commit_trans(osb, handle); @@ -1688,13 +1684,9 @@ static int ocfs2_symlink(struct inode *dir, goto bail; } - /* We don't use standard VFS wrapper because we don't want vfs_dq_init - * to be called. */ - if (sb_any_quota_active(osb->sb) && - osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) { - status = -EDQUOT; + status = dquot_alloc_inode(inode); + if (status) goto bail; - } did_quota_inode = 1; mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry, @@ -1790,7 +1782,7 @@ bail: dquot_free_space_nodirty(inode, ocfs2_clusters_to_bytes(osb->sb, 1)); if (status < 0 && did_quota_inode) - vfs_dq_free_inode(inode); + dquot_free_inode(inode); if (handle) ocfs2_commit_trans(osb, handle); @@ -2098,13 +2090,9 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, goto leave; } - /* We don't use standard VFS wrapper because we don't want vfs_dq_init - * to be called. */ - if (sb_any_quota_active(osb->sb) && - osb->sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) { - status = -EDQUOT; + status = dquot_alloc_inode(inode); + if (status) goto leave; - } did_quota_inode = 1; inode->i_nlink = 0; @@ -2139,7 +2127,7 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, insert_inode_hash(inode); leave: if (status < 0 && did_quota_inode) - vfs_dq_free_inode(inode); + dquot_free_inode(inode); if (handle) ocfs2_commit_trans(osb, handle); diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index aa66fb277225..ed96b3eeb13c 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -853,8 +853,6 @@ static void ocfs2_destroy_dquot(struct dquot *dquot) const struct dquot_operations ocfs2_quota_operations = { .initialize = dquot_initialize, .drop = dquot_drop, - .alloc_inode = dquot_alloc_inode, - .free_inode = dquot_free_inode, .transfer = dquot_transfer, .write_dquot = ocfs2_write_dquot, .acquire_dquot = ocfs2_acquire_dquot, diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index baf202c012cc..ed131318b849 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1531,15 +1531,15 @@ EXPORT_SYMBOL(__dquot_alloc_space); /* * This operation can block, but only after everything is updated */ -int dquot_alloc_inode(const struct inode *inode, qsize_t number) +int dquot_alloc_inode(const struct inode *inode) { - int cnt, ret = NO_QUOTA; + int cnt, ret = -EDQUOT; char warntype[MAXQUOTAS]; /* First test before acquiring mutex - solves deadlocks when we * re-enter the quota code and are already holding the mutex */ - if (IS_NOQUOTA(inode)) - return QUOTA_OK; + if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) + return 0; for (cnt = 0; cnt < MAXQUOTAS; cnt++) warntype[cnt] = QUOTA_NL_NOWARN; down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); @@ -1547,7 +1547,7 @@ int dquot_alloc_inode(const struct inode *inode, qsize_t number) for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (!inode->i_dquot[cnt]) continue; - if (check_idq(inode->i_dquot[cnt], number, warntype+cnt) + if (check_idq(inode->i_dquot[cnt], 1, warntype+cnt) == NO_QUOTA) goto warn_put_all; } @@ -1555,12 +1555,12 @@ int dquot_alloc_inode(const struct inode *inode, qsize_t number) for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (!inode->i_dquot[cnt]) continue; - dquot_incr_inodes(inode->i_dquot[cnt], number); + dquot_incr_inodes(inode->i_dquot[cnt], 1); } - ret = QUOTA_OK; + ret = 0; warn_put_all: spin_unlock(&dq_data_lock); - if (ret == QUOTA_OK) + if (ret == 0) mark_all_dquot_dirty(inode->i_dquot); flush_warnings(inode->i_dquot, warntype); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); @@ -1638,29 +1638,28 @@ EXPORT_SYMBOL(__dquot_free_space); /* * This operation can block, but only after everything is updated */ -int dquot_free_inode(const struct inode *inode, qsize_t number) +void dquot_free_inode(const struct inode *inode) { unsigned int cnt; char warntype[MAXQUOTAS]; /* First test before acquiring mutex - solves deadlocks when we * re-enter the quota code and are already holding the mutex */ - if (IS_NOQUOTA(inode)) - return QUOTA_OK; + if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) + return; down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); spin_lock(&dq_data_lock); for (cnt = 0; cnt < MAXQUOTAS; cnt++) { if (!inode->i_dquot[cnt]) continue; - warntype[cnt] = info_idq_free(inode->i_dquot[cnt], number); - dquot_decr_inodes(inode->i_dquot[cnt], number); + warntype[cnt] = info_idq_free(inode->i_dquot[cnt], 1); + dquot_decr_inodes(inode->i_dquot[cnt], 1); } spin_unlock(&dq_data_lock); mark_all_dquot_dirty(inode->i_dquot); flush_warnings(inode->i_dquot, warntype); up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); - return QUOTA_OK; } EXPORT_SYMBOL(dquot_free_inode); @@ -1815,8 +1814,6 @@ EXPORT_SYMBOL(dquot_commit_info); const struct dquot_operations dquot_operations = { .initialize = dquot_initialize, .drop = dquot_drop, - .alloc_inode = dquot_alloc_inode, - .free_inode = dquot_free_inode, .transfer = dquot_transfer, .write_dquot = dquot_commit, .acquire_dquot = dquot_acquire, diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 2df0f5c7c60b..f56a3d2e6497 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -54,7 +54,7 @@ void reiserfs_delete_inode(struct inode *inode) * after delete_object so that quota updates go into the same transaction as * stat data deletion */ if (!err) - vfs_dq_free_inode(inode); + dquot_free_inode(inode); if (journal_end(&th, inode->i_sb, jbegin_count)) goto out; @@ -1765,10 +1765,10 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, BUG_ON(!th->t_trans_id); - if (vfs_dq_alloc_inode(inode)) { - err = -EDQUOT; + vfs_dq_init(inode); + err = dquot_alloc_inode(inode); + if (err) goto out_end_trans; - } if (!dir->i_nlink) { err = -EPERM; goto out_bad_inode; @@ -1959,7 +1959,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, INODE_PKEY(inode)->k_objectid = 0; /* Quota change must be inside a transaction for journaling */ - vfs_dq_free_inode(inode); + dquot_free_inode(inode); out_end_trans: journal_end(th, th->t_super, th->t_blocks_allocated); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index ea4a77e9d7f5..e942ceecf2b8 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -618,8 +618,6 @@ static int reiserfs_quota_on(struct super_block *, int, int, char *, int); static const struct dquot_operations reiserfs_quota_operations = { .initialize = dquot_initialize, .drop = dquot_drop, - .alloc_inode = dquot_alloc_inode, - .free_inode = dquot_free_inode, .transfer = dquot_transfer, .write_dquot = reiserfs_write_dquot, .acquire_dquot = reiserfs_acquire_dquot, diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index c10fa39f97e2..e1856b89c9c8 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -36,7 +36,7 @@ void udf_free_inode(struct inode *inode) * Note: we must free any quota before locking the superblock, * as writing the quota to disk may need the lock as well. */ - vfs_dq_free_inode(inode); + dquot_free_inode(inode); vfs_dq_drop(inode); clear_inode(inode); @@ -61,7 +61,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) struct super_block *sb = dir->i_sb; struct udf_sb_info *sbi = UDF_SB(sb); struct inode *inode; - int block; + int block, ret; uint32_t start = UDF_I(dir)->i_location.logicalBlockNum; struct udf_inode_info *iinfo; struct udf_inode_info *dinfo = UDF_I(dir); @@ -153,12 +153,14 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) insert_inode_hash(inode); mark_inode_dirty(inode); - if (vfs_dq_alloc_inode(inode)) { + vfs_dq_init(inode); + ret = dquot_alloc_inode(inode); + if (ret) { vfs_dq_drop(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; iput(inode); - *err = -EDQUOT; + *err = ret; return NULL; } diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 3527c00fef0d..02f77882c573 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c @@ -95,7 +95,7 @@ void ufs_free_inode (struct inode * inode) is_directory = S_ISDIR(inode->i_mode); - vfs_dq_free_inode(inode); + dquot_free_inode(inode); vfs_dq_drop(inode); clear_inode (inode); @@ -355,9 +355,10 @@ cg_found: unlock_super (sb); - if (vfs_dq_alloc_inode(inode)) { + vfs_dq_init(inode); + err = dquot_alloc_inode(inode); + if (err) { vfs_dq_drop(inode); - err = -EDQUOT; goto fail_without_unlock; } diff --git a/include/linux/quota.h b/include/linux/quota.h index 1b14ad287fe3..e3b07895d327 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -297,8 +297,6 @@ struct quota_format_ops { struct dquot_operations { int (*initialize) (struct inode *, int); int (*drop) (struct inode *); - int (*alloc_inode) (const struct inode *, qsize_t); - int (*free_inode) (const struct inode *, qsize_t); int (*transfer) (struct inode *, qid_t *, unsigned long); int (*write_dquot) (struct dquot *); /* Ordinary dquot write */ struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */ diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 47e85682e118..9ce7f051a4ba 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -37,10 +37,10 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int warn, int reserve); void __dquot_free_space(struct inode *inode, qsize_t number, int reserve); -int dquot_alloc_inode(const struct inode *inode, qsize_t number); +int dquot_alloc_inode(const struct inode *inode); int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); -int dquot_free_inode(const struct inode *inode, qsize_t number); +void dquot_free_inode(const struct inode *inode); int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask); int dquot_commit(struct dquot *dquot); @@ -148,22 +148,6 @@ static inline void vfs_dq_init(struct inode *inode) inode->i_sb->dq_op->initialize(inode, -1); } -static inline int vfs_dq_alloc_inode(struct inode *inode) -{ - if (sb_any_quota_active(inode->i_sb)) { - vfs_dq_init(inode); - if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA) - return 1; - } - return 0; -} - -static inline void vfs_dq_free_inode(struct inode *inode) -{ - if (sb_any_quota_active(inode->i_sb)) - inode->i_sb->dq_op->free_inode(inode, 1); -} - /* Cannot be called inside a transaction */ static inline int vfs_dq_off(struct super_block *sb, int remount) { @@ -231,12 +215,12 @@ static inline void vfs_dq_drop(struct inode *inode) { } -static inline int vfs_dq_alloc_inode(struct inode *inode) +static inline int dquot_alloc_inode(const struct inode *inode) { return 0; } -static inline void vfs_dq_free_inode(struct inode *inode) +static inline void dquot_free_inode(const struct inode *inode) { } -- cgit v1.2.3 From 759bfee658beab14af7b357156461d0eb852be2c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Mar 2010 09:05:02 -0500 Subject: dquot: move dquot transfer responsibility into the filesystem Currently notify_change calls vfs_dq_transfer directly. This means we tie the quota code into the VFS. Get rid of that and make the filesystem responsible for the transfer. Most filesystems already do this, only ufs and udf need the code added, and for jfs it needs to be enabled unconditionally instead of only when ACLs are enabled. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/attr.c | 11 ++--------- fs/jfs/acl.c | 26 +------------------------- fs/jfs/file.c | 26 +++++++++++++++++++++++++- fs/jfs/jfs_acl.h | 7 ++++++- fs/jfs/jfs_inode.h | 1 + fs/jfs/namei.c | 2 +- fs/udf/file.c | 23 ++++++++++++++++++++++- fs/ufs/truncate.c | 7 +++++++ 8 files changed, 65 insertions(+), 38 deletions(-) (limited to 'fs/jfs') diff --git a/fs/attr.c b/fs/attr.c index 96d394bdaddf..0a6ea54cde7d 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -12,7 +12,6 @@ #include #include #include -#include #include /* Taken over from the old code... */ @@ -212,14 +211,8 @@ int notify_change(struct dentry * dentry, struct iattr * attr) error = inode->i_op->setattr(dentry, attr); } else { error = inode_change_ok(inode, attr); - if (!error) { - if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || - (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) - error = vfs_dq_transfer(inode, attr) ? - -EDQUOT : 0; - if (!error) - error = inode_setattr(inode, attr); - } + if (!error) + error = inode_setattr(inode, attr); } if (ia_valid & ATTR_SIZE) diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index d66477c34306..213169780b6c 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c @@ -20,7 +20,6 @@ #include #include -#include #include #include "jfs_incore.h" #include "jfs_txnmgr.h" @@ -174,7 +173,7 @@ cleanup: return rc; } -static int jfs_acl_chmod(struct inode *inode) +int jfs_acl_chmod(struct inode *inode) { struct posix_acl *acl, *clone; int rc; @@ -205,26 +204,3 @@ static int jfs_acl_chmod(struct inode *inode) posix_acl_release(clone); return rc; } - -int jfs_setattr(struct dentry *dentry, struct iattr *iattr) -{ - struct inode *inode = dentry->d_inode; - int rc; - - rc = inode_change_ok(inode, iattr); - if (rc) - return rc; - - if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || - (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { - if (vfs_dq_transfer(inode, iattr)) - return -EDQUOT; - } - - rc = inode_setattr(inode, iattr); - - if (!rc && (iattr->ia_valid & ATTR_MODE)) - rc = jfs_acl_chmod(inode); - - return rc; -} diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 2b70fa78e4a7..a4229e49330e 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -18,6 +18,7 @@ */ #include +#include #include "jfs_incore.h" #include "jfs_inode.h" #include "jfs_dmap.h" @@ -88,14 +89,37 @@ static int jfs_release(struct inode *inode, struct file *file) return 0; } +int jfs_setattr(struct dentry *dentry, struct iattr *iattr) +{ + struct inode *inode = dentry->d_inode; + int rc; + + rc = inode_change_ok(inode, iattr); + if (rc) + return rc; + + if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || + (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { + if (vfs_dq_transfer(inode, iattr)) + return -EDQUOT; + } + + rc = inode_setattr(inode, iattr); + + if (!rc && (iattr->ia_valid & ATTR_MODE)) + rc = jfs_acl_chmod(inode); + + return rc; +} + const struct inode_operations jfs_file_inode_operations = { .truncate = jfs_truncate, .setxattr = jfs_setxattr, .getxattr = jfs_getxattr, .listxattr = jfs_listxattr, .removexattr = jfs_removexattr, -#ifdef CONFIG_JFS_POSIX_ACL .setattr = jfs_setattr, +#ifdef CONFIG_JFS_POSIX_ACL .check_acl = jfs_check_acl, #endif }; diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h index b07bd417ef85..54e07559878d 100644 --- a/fs/jfs/jfs_acl.h +++ b/fs/jfs/jfs_acl.h @@ -22,7 +22,7 @@ int jfs_check_acl(struct inode *, int); int jfs_init_acl(tid_t, struct inode *, struct inode *); -int jfs_setattr(struct dentry *, struct iattr *); +int jfs_acl_chmod(struct inode *inode); #else @@ -32,5 +32,10 @@ static inline int jfs_init_acl(tid_t tid, struct inode *inode, return 0; } +static inline int jfs_acl_chmod(struct inode *inode) +{ + return 0; +} + #endif #endif /* _H_JFS_ACL */ diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 1eff7db34d63..4b91b2787835 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h @@ -40,6 +40,7 @@ extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type); extern void jfs_set_inode_flags(struct inode *); extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int); +extern int jfs_setattr(struct dentry *, struct iattr *); extern const struct address_space_operations jfs_aops; extern const struct inode_operations jfs_dir_inode_operations; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index c79a4270f083..1d1390afe55e 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -1541,8 +1541,8 @@ const struct inode_operations jfs_dir_inode_operations = { .getxattr = jfs_getxattr, .listxattr = jfs_listxattr, .removexattr = jfs_removexattr, -#ifdef CONFIG_JFS_POSIX_ACL .setattr = jfs_setattr, +#ifdef CONFIG_JFS_POSIX_ACL .check_acl = jfs_check_acl, #endif }; diff --git a/fs/udf/file.c b/fs/udf/file.c index f311d509b6a3..35ca47281faa 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -217,6 +218,26 @@ const struct file_operations udf_file_operations = { .llseek = generic_file_llseek, }; +static int udf_setattr(struct dentry *dentry, struct iattr *iattr) +{ + struct inode *inode = dentry->d_inode; + int error; + + error = inode_change_ok(inode, iattr); + if (error) + return error; + + if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || + (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { + error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0; + if (error) + return error; + } + + return inode_setattr(inode, iattr); +} + const struct inode_operations udf_file_inode_operations = { - .truncate = udf_truncate, + .truncate = udf_truncate, + .setattr = udf_setattr, }; diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 41dd431ce228..56ab31f00bd0 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "ufs_fs.h" #include "ufs.h" @@ -517,6 +518,12 @@ static int ufs_setattr(struct dentry *dentry, struct iattr *attr) if (error) return error; + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || + (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { + error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + if (error) + return error; + } if (ia_valid & ATTR_SIZE && attr->ia_size != i_size_read(inode)) { loff_t old_i_size = inode->i_size; -- cgit v1.2.3 From b43fa8284d7790d9cca32c9c55e24f29be2fa33b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Mar 2010 09:05:03 -0500 Subject: dquot: cleanup dquot transfer routine Get rid of the transfer dquot operation - it is now always called from the filesystem and if a filesystem really needs it's own (which none currently does) it can just call into it's own routine directly. Rename the now static low-level dquot_transfer helper to __dquot_transfer and vfs_dq_transfer to dquot_transfer to have a consistent namespace, and make the new dquot_transfer return a normal negative errno value which all callers expect. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- Documentation/filesystems/Locking | 2 -- drivers/staging/pohmelfs/inode.c | 2 +- fs/ext2/inode.c | 2 +- fs/ext3/inode.c | 2 +- fs/ext3/super.c | 1 - fs/ext4/inode.c | 2 +- fs/ext4/super.c | 1 - fs/jfs/file.c | 5 +++-- fs/ocfs2/file.c | 4 ++-- fs/ocfs2/quota_global.c | 1 - fs/quota/dquot.c | 12 +++++------- fs/reiserfs/inode.c | 3 +-- fs/reiserfs/super.c | 1 - fs/udf/file.c | 2 +- fs/ufs/truncate.c | 2 +- include/linux/quota.h | 1 - include/linux/quotaops.h | 5 ++--- 17 files changed, 19 insertions(+), 29 deletions(-) (limited to 'fs/jfs') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 4428f55f2131..4574e0272bdd 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -462,7 +462,6 @@ in sys_read() and friends. prototypes: int (*initialize) (struct inode *, int); int (*drop) (struct inode *); - int (*transfer) (struct inode *, struct iattr *); int (*write_dquot) (struct dquot *); int (*acquire_dquot) (struct dquot *); int (*release_dquot) (struct dquot *); @@ -477,7 +476,6 @@ What filesystem should expect from the generic quota functions: FS recursion Held locks when called initialize: yes maybe dqonoff_sem drop: yes - -transfer: yes - write_dquot: yes dqonoff_sem or dqptr_sem acquire_dquot: yes dqonoff_sem or dqptr_sem release_dquot: yes dqonoff_sem or dqptr_sem diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c index f69b7783027f..11fc4d5c43e1 100644 --- a/drivers/staging/pohmelfs/inode.c +++ b/drivers/staging/pohmelfs/inode.c @@ -969,7 +969,7 @@ int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr) if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { - err = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + err = dquot_transfer(inode, attr); if (err) goto err_out_exit; } diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 71b032c65a02..3cfcfd9a131a 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -1459,7 +1459,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) return error; if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { - error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0; + error = dquot_transfer(inode, iattr); if (error) return error; } diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 20f02d69365c..14d40a4dd6f0 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -3160,7 +3160,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) error = PTR_ERR(handle); goto err_out; } - error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + error = dquot_transfer(inode, attr); if (error) { ext3_journal_stop(handle); return error; diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 8b8bc4f9cb14..f7d4a2c19dee 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -752,7 +752,6 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, static const struct dquot_operations ext3_quota_operations = { .initialize = dquot_initialize, .drop = dquot_drop, - .transfer = dquot_transfer, .write_dquot = ext3_write_dquot, .acquire_dquot = ext3_acquire_dquot, .release_dquot = ext3_release_dquot, diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 9f607ea411c8..6a002a6d0624 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5263,7 +5263,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) error = PTR_ERR(handle); goto err_out; } - error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + error = dquot_transfer(inode, attr); if (error) { ext4_journal_stop(handle); return error; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index d231da8798e3..b4253fb7bab6 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1017,7 +1017,6 @@ static const struct dquot_operations ext4_quota_operations = { #ifdef CONFIG_QUOTA .get_reserved_space = ext4_get_reserved_space, #endif - .transfer = dquot_transfer, .write_dquot = ext4_write_dquot, .acquire_dquot = ext4_acquire_dquot, .release_dquot = ext4_release_dquot, diff --git a/fs/jfs/file.c b/fs/jfs/file.c index a4229e49330e..2c201783836f 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -100,8 +100,9 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { - if (vfs_dq_transfer(inode, iattr)) - return -EDQUOT; + rc = dquot_transfer(inode, iattr); + if (rc) + return rc; } rc = inode_setattr(inode, iattr); diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 6cf3d8d18369..472e8f8bc892 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1020,7 +1020,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) /* * Gather pointers to quota structures so that allocation / * freeing of quota structures happens here and not inside - * vfs_dq_transfer() where we have problems with lock ordering + * dquot_transfer() where we have problems with lock ordering */ if (attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid && OCFS2_HAS_RO_COMPAT_FEATURE(sb, @@ -1053,7 +1053,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) mlog_errno(status); goto bail_unlock; } - status = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + status = dquot_transfer(inode, attr); if (status < 0) goto bail_commit; } else { diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index ed96b3eeb13c..b654bd103b6f 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -853,7 +853,6 @@ static void ocfs2_destroy_dquot(struct dquot *dquot) const struct dquot_operations ocfs2_quota_operations = { .initialize = dquot_initialize, .drop = dquot_drop, - .transfer = dquot_transfer, .write_dquot = ocfs2_write_dquot, .acquire_dquot = ocfs2_acquire_dquot, .release_dquot = ocfs2_release_dquot, diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index ed131318b849..78ce4c48ad77 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1669,7 +1669,7 @@ EXPORT_SYMBOL(dquot_free_inode); * This operation can block, but only after everything is updated * A transaction must be started when entering this function. */ -int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask) +static int __dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask) { qsize_t space, cur_space; qsize_t rsv_space = 0; @@ -1766,12 +1766,11 @@ over_quota: ret = NO_QUOTA; goto warn_put_all; } -EXPORT_SYMBOL(dquot_transfer); /* Wrapper for transferring ownership of an inode for uid/gid only * Called from FSXXX_setattr() */ -int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) +int dquot_transfer(struct inode *inode, struct iattr *iattr) { qid_t chid[MAXQUOTAS]; unsigned long mask = 0; @@ -1786,12 +1785,12 @@ int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) } if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { vfs_dq_init(inode); - if (inode->i_sb->dq_op->transfer(inode, chid, mask) == NO_QUOTA) - return 1; + if (__dquot_transfer(inode, chid, mask) == NO_QUOTA) + return -EDQUOT; } return 0; } -EXPORT_SYMBOL(vfs_dq_transfer); +EXPORT_SYMBOL(dquot_transfer); /* * Write info of quota file to disk @@ -1814,7 +1813,6 @@ EXPORT_SYMBOL(dquot_commit_info); const struct dquot_operations dquot_operations = { .initialize = dquot_initialize, .drop = dquot_drop, - .transfer = dquot_transfer, .write_dquot = dquot_commit, .acquire_dquot = dquot_acquire, .release_dquot = dquot_release, diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index f56a3d2e6497..99a5e5a8ab5a 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -3134,8 +3134,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) jbegin_count); if (error) goto out; - error = - vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + error = dquot_transfer(inode, attr); if (error) { journal_end(&th, inode->i_sb, jbegin_count); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index e942ceecf2b8..97c3e8ed7db6 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -618,7 +618,6 @@ static int reiserfs_quota_on(struct super_block *, int, int, char *, int); static const struct dquot_operations reiserfs_quota_operations = { .initialize = dquot_initialize, .drop = dquot_drop, - .transfer = dquot_transfer, .write_dquot = reiserfs_write_dquot, .acquire_dquot = reiserfs_acquire_dquot, .release_dquot = reiserfs_release_dquot, diff --git a/fs/udf/file.c b/fs/udf/file.c index 35ca47281faa..2df7fcb677b3 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -229,7 +229,7 @@ static int udf_setattr(struct dentry *dentry, struct iattr *iattr) if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { - error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0; + error = dquot_transfer(inode, iattr); if (error) return error; } diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 56ab31f00bd0..87bbab685901 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -520,7 +520,7 @@ static int ufs_setattr(struct dentry *dentry, struct iattr *attr) if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { - error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; + error = dquot_transfer(inode, attr); if (error) return error; } diff --git a/include/linux/quota.h b/include/linux/quota.h index e3b07895d327..422e6aa78edc 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -297,7 +297,6 @@ struct quota_format_ops { struct dquot_operations { int (*initialize) (struct inode *, int); int (*drop) (struct inode *); - int (*transfer) (struct inode *, qid_t *, unsigned long); int (*write_dquot) (struct dquot *); /* Ordinary dquot write */ struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */ void (*destroy_dquot)(struct dquot *); /* Free memory for dquot */ diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 9ce7f051a4ba..fa27b7218c82 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -42,7 +42,6 @@ int dquot_alloc_inode(const struct inode *inode); int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); void dquot_free_inode(const struct inode *inode); -int dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask); int dquot_commit(struct dquot *dquot); int dquot_acquire(struct dquot *dquot); int dquot_release(struct dquot *dquot); @@ -66,7 +65,7 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di); void vfs_dq_drop(struct inode *inode); -int vfs_dq_transfer(struct inode *inode, struct iattr *iattr); +int dquot_transfer(struct inode *inode, struct iattr *iattr); int vfs_dq_quota_on_remount(struct super_block *sb); static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type) @@ -234,7 +233,7 @@ static inline int vfs_dq_quota_on_remount(struct super_block *sb) return 0; } -static inline int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) +static inline int dquot_transfer(struct inode *inode, struct iattr *iattr) { return 0; } -- cgit v1.2.3 From 257ba15cedf1288f0c96118d7e63947231d27278 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Mar 2010 09:05:04 -0500 Subject: dquot: move dquot drop responsibility into the filesystem Currently clear_inode calls vfs_dq_drop directly. This means we tie the quota code into the VFS. Get rid of that and make the filesystem responsible for the drop inside the ->clear_inode superblock operation. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext2/super.c | 2 ++ fs/ext3/super.c | 2 ++ fs/ext4/super.c | 1 + fs/inode.c | 1 - fs/jfs/super.c | 6 ++++++ fs/ocfs2/inode.c | 2 ++ fs/reiserfs/super.c | 6 ++++++ fs/udf/inode.c | 2 ++ fs/ufs/super.c | 6 ++++++ 9 files changed, 27 insertions(+), 1 deletion(-) (limited to 'fs/jfs') diff --git a/fs/ext2/super.c b/fs/ext2/super.c index f9cb54a585ce..98815d2a5664 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -194,6 +194,8 @@ static void destroy_inodecache(void) static void ext2_clear_inode(struct inode *inode) { struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info; + + vfs_dq_drop(inode); ext2_discard_reservation(inode); EXT2_I(inode)->i_block_alloc_info = NULL; if (unlikely(rsv)) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index f7d4a2c19dee..2277b1a98e62 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -528,6 +528,8 @@ static void destroy_inodecache(void) static void ext3_clear_inode(struct inode *inode) { struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info; + + vfs_dq_drop(inode); ext3_discard_reservation(inode); EXT3_I(inode)->i_block_alloc_info = NULL; if (unlikely(rsv)) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b4253fb7bab6..56554c8850ec 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -761,6 +761,7 @@ static void destroy_inodecache(void) static void ext4_clear_inode(struct inode *inode) { + vfs_dq_drop(inode); ext4_discard_preallocations(inode); if (EXT4_JOURNAL(inode)) jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, diff --git a/fs/inode.c b/fs/inode.c index 03dfeb2e3928..f1aef3482b0e 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -314,7 +314,6 @@ void clear_inode(struct inode *inode) BUG_ON(!(inode->i_state & I_FREEING)); BUG_ON(inode->i_state & I_CLEAR); inode_sync_wait(inode); - vfs_dq_drop(inode); if (inode->i_sb->s_op->clear_inode) inode->i_sb->s_op->clear_inode(inode); if (S_ISBLK(inode->i_mode) && inode->i_bdev) diff --git a/fs/jfs/super.c b/fs/jfs/super.c index d929a822a74e..4086fa593419 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -131,6 +131,11 @@ static void jfs_destroy_inode(struct inode *inode) kmem_cache_free(jfs_inode_cachep, ji); } +static void jfs_clear_inode(struct inode *inode) +{ + vfs_dq_drop(inode); +} + static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct jfs_sb_info *sbi = JFS_SBI(dentry->d_sb); @@ -745,6 +750,7 @@ static const struct super_operations jfs_super_operations = { .dirty_inode = jfs_dirty_inode, .write_inode = jfs_write_inode, .delete_inode = jfs_delete_inode, + .clear_inode = jfs_clear_inode, .put_super = jfs_put_super, .sync_fs = jfs_sync_fs, .freeze_fs = jfs_freeze, diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index cb7f67d8441a..13eb5d467c40 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -1087,6 +1087,8 @@ void ocfs2_clear_inode(struct inode *inode) mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL, "Inode=%lu\n", inode->i_ino); + vfs_dq_drop(inode); + /* To preven remote deletes we hold open lock before, now it * is time to unlock PR and EX open locks. */ ocfs2_open_unlock(inode); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 97c3e8ed7db6..6b24e70e329b 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -578,6 +578,11 @@ out: reiserfs_write_unlock_once(inode->i_sb, lock_depth); } +static void reiserfs_clear_inode(struct inode *inode) +{ + vfs_dq_drop(inode); +} + #ifdef CONFIG_QUOTA static ssize_t reiserfs_quota_write(struct super_block *, int, const char *, size_t, loff_t); @@ -590,6 +595,7 @@ static const struct super_operations reiserfs_sops = { .destroy_inode = reiserfs_destroy_inode, .write_inode = reiserfs_write_inode, .dirty_inode = reiserfs_dirty_inode, + .clear_inode = reiserfs_clear_inode, .delete_inode = reiserfs_delete_inode, .put_super = reiserfs_put_super, .write_super = reiserfs_write_super, diff --git a/fs/udf/inode.c b/fs/udf/inode.c index f90231eb2916..859389a3832b 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -108,6 +108,8 @@ void udf_clear_inode(struct inode *inode) (unsigned long long)inode->i_size, (unsigned long long)iinfo->i_lenExtents); } + + vfs_dq_drop(inode); kfree(iinfo->i_ext.i_data); iinfo->i_ext.i_data = NULL; } diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 143c20bfb04b..95d61cb3a5b8 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1432,6 +1432,11 @@ static void destroy_inodecache(void) kmem_cache_destroy(ufs_inode_cachep); } +static void ufs_clear_inode(struct inode *inode) +{ + vfs_dq_drop(inode); +} + #ifdef CONFIG_QUOTA static ssize_t ufs_quota_read(struct super_block *, int, char *,size_t, loff_t); static ssize_t ufs_quota_write(struct super_block *, int, const char *, size_t, loff_t); @@ -1442,6 +1447,7 @@ static const struct super_operations ufs_super_ops = { .destroy_inode = ufs_destroy_inode, .write_inode = ufs_write_inode, .delete_inode = ufs_delete_inode, + .clear_inode = ufs_clear_inode, .put_super = ufs_put_super, .write_super = ufs_write_super, .sync_fs = ufs_sync_fs, -- cgit v1.2.3 From 9f7547580263d4a55efe06ce5cfd567f568be6e8 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Mar 2010 09:05:05 -0500 Subject: dquot: cleanup dquot drop routine Get rid of the drop dquot operation - it is now always called from the filesystem and if a filesystem really needs it's own (which none currently does) it can just call into it's own routine directly. Rename the now static low-level dquot_drop helper to __dquot_drop and vfs_dq_drop to dquot_drop to have a consistent namespace. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- Documentation/filesystems/Locking | 2 -- fs/ext2/ialloc.c | 4 +-- fs/ext2/super.c | 2 +- fs/ext3/ialloc.c | 4 +-- fs/ext3/super.c | 3 +-- fs/ext4/ialloc.c | 4 +-- fs/ext4/super.c | 3 +-- fs/jfs/inode.c | 2 +- fs/jfs/jfs_inode.c | 2 +- fs/jfs/super.c | 2 +- fs/ocfs2/inode.c | 2 +- fs/ocfs2/quota_global.c | 1 - fs/quota/dquot.c | 52 +++++++++++++++++++-------------------- fs/reiserfs/inode.c | 2 +- fs/reiserfs/namei.c | 2 +- fs/reiserfs/super.c | 3 +-- fs/udf/ialloc.c | 4 +-- fs/udf/inode.c | 2 +- fs/ufs/ialloc.c | 4 +-- fs/ufs/super.c | 2 +- include/linux/quota.h | 1 - include/linux/quotaops.h | 5 ++-- 22 files changed, 49 insertions(+), 59 deletions(-) (limited to 'fs/jfs') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 4574e0272bdd..fa10e4bf8e5e 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -461,7 +461,6 @@ in sys_read() and friends. --------------------------- dquot_operations ------------------------------- prototypes: int (*initialize) (struct inode *, int); - int (*drop) (struct inode *); int (*write_dquot) (struct dquot *); int (*acquire_dquot) (struct dquot *); int (*release_dquot) (struct dquot *); @@ -475,7 +474,6 @@ What filesystem should expect from the generic quota functions: FS recursion Held locks when called initialize: yes maybe dqonoff_sem -drop: yes - write_dquot: yes dqonoff_sem or dqptr_sem acquire_dquot: yes dqonoff_sem or dqptr_sem release_dquot: yes dqonoff_sem or dqptr_sem diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index d12f9809559c..88b71972c626 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -122,7 +122,7 @@ void ext2_free_inode (struct inode * inode) /* Quota is already initialized in iput() */ ext2_xattr_delete_inode(inode); dquot_free_inode(inode); - vfs_dq_drop(inode); + dquot_drop(inode); } es = EXT2_SB(sb)->s_es; @@ -608,7 +608,7 @@ fail_free_drop: dquot_free_inode(inode); fail_drop: - vfs_dq_drop(inode); + dquot_drop(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; unlock_new_inode(inode); diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 98815d2a5664..42e4a303b675 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -195,7 +195,7 @@ static void ext2_clear_inode(struct inode *inode) { struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info; - vfs_dq_drop(inode); + dquot_drop(inode); ext2_discard_reservation(inode); EXT2_I(inode)->i_block_alloc_info = NULL; if (unlikely(rsv)) diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 8bf00e997c38..7d7238f9f6f3 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -126,7 +126,7 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) vfs_dq_init(inode); ext3_xattr_delete_inode(handle, inode); dquot_free_inode(inode); - vfs_dq_drop(inode); + dquot_drop(inode); is_directory = S_ISDIR(inode->i_mode); @@ -622,7 +622,7 @@ fail_free_drop: dquot_free_inode(inode); fail_drop: - vfs_dq_drop(inode); + dquot_drop(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; unlock_new_inode(inode); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 2277b1a98e62..0163d0dae124 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -529,7 +529,7 @@ static void ext3_clear_inode(struct inode *inode) { struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info; - vfs_dq_drop(inode); + dquot_drop(inode); ext3_discard_reservation(inode); EXT3_I(inode)->i_block_alloc_info = NULL; if (unlikely(rsv)) @@ -753,7 +753,6 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, static const struct dquot_operations ext3_quota_operations = { .initialize = dquot_initialize, - .drop = dquot_drop, .write_dquot = ext3_write_dquot, .acquire_dquot = ext3_acquire_dquot, .release_dquot = ext3_release_dquot, diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index b0d744cf8b95..ca8986e4b528 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -220,7 +220,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) vfs_dq_init(inode); ext4_xattr_delete_inode(handle, inode); dquot_free_inode(inode); - vfs_dq_drop(inode); + dquot_drop(inode); is_directory = S_ISDIR(inode->i_mode); @@ -1077,7 +1077,7 @@ fail_free_drop: dquot_free_inode(inode); fail_drop: - vfs_dq_drop(inode); + dquot_drop(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; unlock_new_inode(inode); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 56554c8850ec..035516c80df2 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -761,7 +761,7 @@ static void destroy_inodecache(void) static void ext4_clear_inode(struct inode *inode) { - vfs_dq_drop(inode); + dquot_drop(inode); ext4_discard_preallocations(inode); if (EXT4_JOURNAL(inode)) jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, @@ -1014,7 +1014,6 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, static const struct dquot_operations ext4_quota_operations = { .initialize = dquot_initialize, - .drop = dquot_drop, #ifdef CONFIG_QUOTA .get_reserved_space = ext4_get_reserved_space, #endif diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 2562d18988f7..22fa412c5289 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -160,7 +160,7 @@ void jfs_delete_inode(struct inode *inode) */ vfs_dq_init(inode); dquot_free_inode(inode); - vfs_dq_drop(inode); + dquot_drop(inode); } clear_inode(inode); diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 7762f33e062b..72b30895422c 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -162,7 +162,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) return inode; fail_drop: - vfs_dq_drop(inode); + dquot_drop(inode); inode->i_flags |= S_NOQUOTA; fail_unlock: inode->i_nlink = 0; diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 4086fa593419..266699deb1c6 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -133,7 +133,7 @@ static void jfs_destroy_inode(struct inode *inode) static void jfs_clear_inode(struct inode *inode) { - vfs_dq_drop(inode); + dquot_drop(inode); } static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf) diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 13eb5d467c40..00eb6a095e68 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -1087,7 +1087,7 @@ void ocfs2_clear_inode(struct inode *inode) mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL, "Inode=%lu\n", inode->i_ino); - vfs_dq_drop(inode); + dquot_drop(inode); /* To preven remote deletes we hold open lock before, now it * is time to unlock PR and EX open locks. */ diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index b654bd103b6f..4dca38f487cf 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -852,7 +852,6 @@ static void ocfs2_destroy_dquot(struct dquot *dquot) const struct dquot_operations ocfs2_quota_operations = { .initialize = dquot_initialize, - .drop = dquot_drop, .write_dquot = ocfs2_write_dquot, .acquire_dquot = ocfs2_acquire_dquot, .release_dquot = ocfs2_release_dquot, diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 78ce4c48ad77..cd83c5b871ba 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1358,7 +1358,7 @@ EXPORT_SYMBOL(dquot_initialize); /* * Release all quotas referenced by inode */ -int dquot_drop(struct inode *inode) +static void __dquot_drop(struct inode *inode) { int cnt; struct dquot *put[MAXQUOTAS]; @@ -1370,32 +1370,31 @@ int dquot_drop(struct inode *inode) } up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); dqput_all(put); - return 0; } -EXPORT_SYMBOL(dquot_drop); -/* Wrapper to remove references to quota structures from inode */ -void vfs_dq_drop(struct inode *inode) -{ - /* Here we can get arbitrary inode from clear_inode() so we have - * to be careful. OTOH we don't need locking as quota operations - * are allowed to change only at mount time */ - if (!IS_NOQUOTA(inode) && inode->i_sb && inode->i_sb->dq_op - && inode->i_sb->dq_op->drop) { - int cnt; - /* Test before calling to rule out calls from proc and such - * where we are not allowed to block. Note that this is - * actually reliable test even without the lock - the caller - * must assure that nobody can come after the DQUOT_DROP and - * add quota pointers back anyway */ - for (cnt = 0; cnt < MAXQUOTAS; cnt++) - if (inode->i_dquot[cnt]) - break; - if (cnt < MAXQUOTAS) - inode->i_sb->dq_op->drop(inode); - } -} -EXPORT_SYMBOL(vfs_dq_drop); +void dquot_drop(struct inode *inode) +{ + int cnt; + + if (IS_NOQUOTA(inode)) + return; + + /* + * Test before calling to rule out calls from proc and such + * where we are not allowed to block. Note that this is + * actually reliable test even without the lock - the caller + * must assure that nobody can come after the DQUOT_DROP and + * add quota pointers back anyway. + */ + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + if (inode->i_dquot[cnt]) + break; + } + + if (cnt < MAXQUOTAS) + __dquot_drop(inode); +} +EXPORT_SYMBOL(dquot_drop); /* * inode_reserved_space is managed internally by quota, and protected by @@ -1812,7 +1811,6 @@ EXPORT_SYMBOL(dquot_commit_info); */ const struct dquot_operations dquot_operations = { .initialize = dquot_initialize, - .drop = dquot_drop, .write_dquot = dquot_commit, .acquire_dquot = dquot_acquire, .release_dquot = dquot_release, @@ -2029,7 +2027,7 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, * When S_NOQUOTA is set, remove dquot references as no more * references can be added */ - sb->dq_op->drop(inode); + __dquot_drop(inode); } error = -EIO; diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 99a5e5a8ab5a..f07c3b69247d 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1964,7 +1964,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, out_end_trans: journal_end(th, th->t_super, th->t_blocks_allocated); /* Drop can be outside and it needs more credits so it's better to have it outside */ - vfs_dq_drop(inode); + dquot_drop(inode); inode->i_flags |= S_NOQUOTA; make_bad_inode(inode); diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 9d4dcf0b07cb..9dea84e8a79a 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -546,7 +546,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th, */ static int drop_new_inode(struct inode *inode) { - vfs_dq_drop(inode); + dquot_drop(inode); make_bad_inode(inode); inode->i_flags |= S_NOQUOTA; iput(inode); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 6b24e70e329b..34f7cd0cb02d 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -580,7 +580,7 @@ out: static void reiserfs_clear_inode(struct inode *inode) { - vfs_dq_drop(inode); + dquot_drop(inode); } #ifdef CONFIG_QUOTA @@ -623,7 +623,6 @@ static int reiserfs_quota_on(struct super_block *, int, int, char *, int); static const struct dquot_operations reiserfs_quota_operations = { .initialize = dquot_initialize, - .drop = dquot_drop, .write_dquot = reiserfs_write_dquot, .acquire_dquot = reiserfs_acquire_dquot, .release_dquot = reiserfs_release_dquot, diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index e1856b89c9c8..15c6e992e587 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -37,7 +37,7 @@ void udf_free_inode(struct inode *inode) * as writing the quota to disk may need the lock as well. */ dquot_free_inode(inode); - vfs_dq_drop(inode); + dquot_drop(inode); clear_inode(inode); @@ -156,7 +156,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) vfs_dq_init(inode); ret = dquot_alloc_inode(inode); if (ret) { - vfs_dq_drop(inode); + dquot_drop(inode); inode->i_flags |= S_NOQUOTA; inode->i_nlink = 0; iput(inode); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 859389a3832b..1199e8e21ee2 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -109,7 +109,7 @@ void udf_clear_inode(struct inode *inode) (unsigned long long)iinfo->i_lenExtents); } - vfs_dq_drop(inode); + dquot_drop(inode); kfree(iinfo->i_ext.i_data); iinfo->i_ext.i_data = NULL; } diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 02f77882c573..67b4bdb056fb 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c @@ -96,7 +96,7 @@ void ufs_free_inode (struct inode * inode) is_directory = S_ISDIR(inode->i_mode); dquot_free_inode(inode); - vfs_dq_drop(inode); + dquot_drop(inode); clear_inode (inode); @@ -358,7 +358,7 @@ cg_found: vfs_dq_init(inode); err = dquot_alloc_inode(inode); if (err) { - vfs_dq_drop(inode); + dquot_drop(inode); goto fail_without_unlock; } diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 95d61cb3a5b8..66b63a751615 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1434,7 +1434,7 @@ static void destroy_inodecache(void) static void ufs_clear_inode(struct inode *inode) { - vfs_dq_drop(inode); + dquot_drop(inode); } #ifdef CONFIG_QUOTA diff --git a/include/linux/quota.h b/include/linux/quota.h index 422e6aa78edc..aec2e9dac2d7 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -296,7 +296,6 @@ struct quota_format_ops { /* Operations working with dquots */ struct dquot_operations { int (*initialize) (struct inode *, int); - int (*drop) (struct inode *); int (*write_dquot) (struct dquot *); /* Ordinary dquot write */ struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */ void (*destroy_dquot)(struct dquot *); /* Free memory for dquot */ diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index fa27b7218c82..a5ebd1abccd8 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -24,7 +24,7 @@ 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); -int dquot_drop(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); int dquot_scan_active(struct super_block *sb, @@ -64,7 +64,6 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di); int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di); -void vfs_dq_drop(struct inode *inode); int dquot_transfer(struct inode *inode, struct iattr *iattr); int vfs_dq_quota_on_remount(struct super_block *sb); @@ -210,7 +209,7 @@ static inline void vfs_dq_init(struct inode *inode) { } -static inline void vfs_dq_drop(struct inode *inode) +static inline void dquot_drop(struct inode *inode) { } -- cgit v1.2.3 From 907f4554e2521cb28b0009d17167760650a9561c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Mar 2010 09:05:06 -0500 Subject: dquot: move dquot initialization responsibility into the filesystem 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 responsible 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. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext2/file.c | 4 ++-- fs/ext2/inode.c | 5 +++++ fs/ext2/namei.c | 51 ++++++++++++++++++++++++++++++++---------------- fs/ext3/file.c | 2 +- fs/ext3/inode.c | 5 +++++ fs/ext3/namei.c | 18 +++++++++++++++++ fs/ext4/file.c | 2 +- fs/ext4/inode.c | 5 +++++ fs/ext4/namei.c | 17 ++++++++++++++++ fs/inode.c | 3 --- fs/jfs/file.c | 4 +++- fs/jfs/inode.c | 3 +++ fs/jfs/namei.c | 15 ++++++++++++++ fs/namei.c | 16 --------------- fs/nfsd/vfs.c | 4 ---- fs/ocfs2/file.c | 5 +++++ fs/ocfs2/inode.c | 2 ++ fs/ocfs2/namei.c | 11 +++++++++++ fs/open.c | 5 +---- fs/quota/dquot.c | 14 +++++++++++++ fs/reiserfs/file.c | 2 +- fs/reiserfs/inode.c | 5 +++++ fs/reiserfs/namei.c | 17 ++++++++++++++++ fs/reiserfs/xattr.c | 4 ---- fs/udf/file.c | 5 ++++- fs/udf/inode.c | 4 ++++ fs/udf/namei.c | 17 ++++++++++++++++ fs/ufs/file.c | 2 +- fs/ufs/inode.c | 4 ++++ fs/ufs/namei.c | 18 +++++++++++++++++ fs/ufs/truncate.c | 3 +++ include/linux/quotaops.h | 4 ++++ 32 files changed, 220 insertions(+), 56 deletions(-) (limited to 'fs/jfs') diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 586e3589d4c2..d11f6e484519 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -70,7 +70,7 @@ const struct file_operations ext2_file_operations = { .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_file_operations = { .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, }; diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 3cfcfd9a131a..c87840c33e17 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -58,6 +58,8 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode) */ 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, struct iattr *iattr) 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); diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index dd7175ce5606..5923df7b22af 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -31,6 +31,7 @@ */ #include +#include #include "ext2.h" #include "xattr.h" #include "acl.h" @@ -99,24 +100,27 @@ struct dentry *ext2_get_parent(struct dentry *child) */ 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 * dir, struct dentry *dentry, int mode, dev_ 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 * dir, struct dentry * dentry, 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 * old_dentry, struct inode * dir, 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, struct dentry * dentry, int mode) 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 * dir, struct dentry *dentry) 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 * old_dir, struct dentry * old_dentry, 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; diff --git a/fs/ext3/file.c b/fs/ext3/file.c index a86d3302cdc2..3c7fb11a3b29 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -62,7 +62,7 @@ const struct file_operations ext3_file_operations = { .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, diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 14d40a4dd6f0..d7962b0c57b3 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -196,6 +196,9 @@ void ext3_delete_inode (struct inode * inode) { handle_t *handle; + if (!is_bad_inode(inode)) + vfs_dq_init(inode); + truncate_inode_pages(&inode->i_data, 0); if (is_bad_inode(inode)) @@ -3148,6 +3151,8 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) 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; diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 7b0e44f7d66f..a492b371b134 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1696,6 +1696,8 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode, 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 * dir, struct dentry *dentry, 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, struct dentry * dentry, int mode) 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 * dir, struct dentry *dentry) /* 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 * dir, struct dentry *dentry) /* 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 * dir, 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 * old_dentry, 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 * old_dir, struct dentry *old_dentry, 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 diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 9630583cef28..85fa464a24ad 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -127,7 +127,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp) sb->s_dirt = 1; } } - return generic_file_open(inode, filp); + return dquot_file_open(inode, filp); } const struct file_operations ext4_file_operations = { diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 6a002a6d0624..eaa22ae9f1f6 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -170,6 +170,9 @@ void ext4_delete_inode(struct inode *inode) 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); @@ -5251,6 +5254,8 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) 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; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 17a17e10dd60..20f55c2e7571 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1766,6 +1766,8 @@ static int ext4_create(struct inode *dir, struct dentry *dentry, int mode, 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, struct dentry *dentry, 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, struct dentry *dentry, int mode) 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, struct dentry *dentry) /* 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, struct dentry *dentry) /* 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 *dir, 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_dentry, 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_dir, struct dentry *old_dentry, 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 diff --git a/fs/inode.c b/fs/inode.c index f1aef3482b0e..407bf392e20a 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -1210,8 +1209,6 @@ void generic_delete_inode(struct inode *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() diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 2c201783836f..f19bb33eb1eb 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -48,7 +48,7 @@ static int jfs_open(struct inode *inode, struct file *file) { 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, struct iattr *iattr) 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); diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 22fa412c5289..1aa2dda16590 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -146,6 +146,9 @@ void jfs_delete_inode(struct inode *inode) { 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); diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 1d1390afe55e..b7cc29da50b4 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -85,6 +85,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, 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, struct dentry *dentry, int mode) 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, struct dentry *dentry) 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, struct dentry *dentry) 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_dentry, 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, struct dentry *dentry, 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_dir, struct dentry *old_dentry, 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, struct dentry *dentry, jfs_info("jfs_mknod: %s", dentry->d_name.name); + vfs_dq_init(dir); + if ((rc = get_UCSname(&dname, dentry))) goto out; diff --git a/fs/namei.c b/fs/namei.c index a4855af776a8..06abd2bf473c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -1461,7 +1460,6 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, 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); @@ -1813,9 +1811,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) { @@ -1996,7 +1991,6 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) if (error) return error; - vfs_dq_init(dir); error = dir->i_op->mknod(dir, dentry, mode, dev); if (!error) fsnotify_create(dir, dentry); @@ -2095,7 +2089,6 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (error) return error; - vfs_dq_init(dir); error = dir->i_op->mkdir(dir, dentry, mode); if (!error) fsnotify_mkdir(dir, dentry); @@ -2181,8 +2174,6 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) 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)) @@ -2268,8 +2259,6 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) if (!dir->i_op->unlink) return -EPERM; - vfs_dq_init(dir); - mutex_lock(&dentry->d_inode->i_mutex); if (d_mountpoint(dentry)) error = -EBUSY; @@ -2379,7 +2368,6 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) if (error) return error; - vfs_dq_init(dir); error = dir->i_op->symlink(dir, dentry, oldname); if (!error) fsnotify_create(dir, dentry); @@ -2463,7 +2451,6 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de 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) @@ -2662,9 +2649,6 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, 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) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 8715d194561a..09e9fc043600 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -377,7 +376,6 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, 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 svc_fh *fhp, int type, 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()); diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 472e8f8bc892..126198f5a67c 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -107,6 +107,9 @@ static int ocfs2_file_open(struct inode *inode, struct file *file) 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 @@ -977,6 +980,8 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE; if (size_change) { + vfs_dq_init(inode); + status = ocfs2_rw_lock(inode, 1); if (status < 0) { mlog_errno(status); diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 00eb6a095e68..77681a690d16 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -971,6 +971,8 @@ void ocfs2_delete_inode(struct inode *inode) 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 diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 99766b6418eb..8b5b142eb638 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -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); @@ -632,6 +634,8 @@ static int ocfs2_link(struct dentry *old_dentry, 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) @@ -787,6 +791,8 @@ static int ocfs2_unlink(struct inode *dir, 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); @@ -1047,6 +1053,9 @@ static int ocfs2_rename(struct inode *old_dir, 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) { @@ -1595,6 +1604,8 @@ static int ocfs2_symlink(struct inode *dir, 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); diff --git a/fs/open.c b/fs/open.c index 040cef72bc00..b740c4244833 100644 --- a/fs/open.c +++ b/fs/open.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -278,10 +277,8 @@ static long do_sys_truncate(const char __user *pathname, loff_t length) 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); diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index cd83c5b871ba..6244bca45c9d 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1820,6 +1820,20 @@ const struct dquot_operations dquot_operations = { .destroy_dquot = dquot_destroy, }; +/* + * 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) */ diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index da2dba082e2d..1d9c12714c5c 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -289,7 +289,7 @@ const struct file_operations reiserfs_file_operations = { .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, diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index f07c3b69247d..06995cb48e39 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -34,6 +34,9 @@ void reiserfs_delete_inode(struct inode *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 *dentry, struct iattr *attr) depth = reiserfs_write_lock_once(inode->i_sb); if (attr->ia_valid & ATTR_SIZE) { + vfs_dq_init(inode); + /* version 2 items will be caught by the s_maxbytes check ** done for us in vmtruncate */ diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 9dea84e8a79a..c55e1b9fee5f 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -594,6 +594,8 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, 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 *dir, struct dentry *dentry, int mode, 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 *dir, struct dentry *dentry, int mode) 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 *dir, struct dentry *dentry) 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 *dir, struct dentry *dentry) 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 *parent_dir, 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 *old_dentry, struct inode *dir, 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 *old_dir, struct dentry *old_dentry, 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; diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 81f09fab8ae4..37d034ca7d99 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -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 *dir, struct dentry *dentry, int mode) 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 *dir, struct dentry *dentry) { 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, struct dentry *dentry) { 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); diff --git a/fs/udf/file.c b/fs/udf/file.c index 2df7fcb677b3..013fa44d9a5e 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -208,7 +208,7 @@ const struct file_operations udf_file_operations = { .read = do_sync_read, .aio_read = generic_file_aio_read, .ioctl = udf_ioctl, - .open = generic_file_open, + .open = dquot_file_open, .mmap = generic_file_mmap, .write = do_sync_write, .aio_write = udf_file_aio_write, @@ -227,6 +227,9 @@ static int udf_setattr(struct dentry *dentry, struct iattr *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); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 1199e8e21ee2..f19520268404 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -70,6 +71,9 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); void udf_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)) diff --git a/fs/udf/namei.c b/fs/udf/namei.c index cd2115060fdc..e360c3fc4ae4 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -563,6 +563,8 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, int err; struct udf_inode_info *iinfo; + vfs_dq_init(dir); + lock_kernel(); inode = udf_new_inode(dir, mode, &err); if (!inode) { @@ -616,6 +618,8 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, if (!old_valid_dev(rdev)) return -EINVAL; + vfs_dq_init(dir); + lock_kernel(); err = -EIO; inode = udf_new_inode(dir, mode, &err); @@ -662,6 +666,8 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) struct udf_inode_info *dinfo = UDF_I(dir); struct udf_inode_info *iinfo; + vfs_dq_init(dir); + lock_kernel(); err = -EMLINK; if (dir->i_nlink >= (256 << sizeof(dir->i_nlink)) - 1) @@ -799,6 +805,8 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) struct fileIdentDesc *fi, cfi; struct kernel_lb_addr tloc; + vfs_dq_init(dir); + retval = -ENOENT; lock_kernel(); fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); @@ -845,6 +853,8 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) struct fileIdentDesc cfi; struct kernel_lb_addr tloc; + vfs_dq_init(dir); + retval = -ENOENT; lock_kernel(); fi = udf_find_entry(dir, &dentry->d_name, &fibh, &cfi); @@ -899,6 +909,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, struct buffer_head *bh; struct udf_inode_info *iinfo; + vfs_dq_init(dir); + lock_kernel(); inode = udf_new_inode(dir, S_IFLNK, &err); if (!inode) @@ -1069,6 +1081,8 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, int err; struct buffer_head *bh; + vfs_dq_init(dir); + lock_kernel(); if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { unlock_kernel(); @@ -1131,6 +1145,9 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, struct kernel_lb_addr tloc; struct udf_inode_info *old_iinfo = UDF_I(old_inode); + vfs_dq_init(old_dir); + vfs_dq_init(new_dir); + lock_kernel(); ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); if (ofi) { diff --git a/fs/ufs/file.c b/fs/ufs/file.c index 73655c61240a..d84762f3028e 100644 --- a/fs/ufs/file.c +++ b/fs/ufs/file.c @@ -40,7 +40,7 @@ const struct file_operations ufs_file_operations = { .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, }; diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 7cf33379fd46..fff8edab382f 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "ufs_fs.h" #include "ufs.h" @@ -908,6 +909,9 @@ void ufs_delete_inode (struct inode * inode) { 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; diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 4c26d9e8bc94..c33cb90c516d 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "ufs_fs.h" #include "ufs.h" @@ -84,6 +85,9 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, 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, struct dentry *dentry, int mode, dev_t 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 * dir, struct dentry * dentry, 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_dentry, struct inode * dir, 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, struct dentry * dentry, int mode) 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 dentry *dentry) 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_dir, struct dentry *old_dentry, 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; diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 87bbab685901..e5ef8a3ec230 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -527,6 +527,9 @@ static int ufs_setattr(struct dentry *dentry, struct iattr *attr) if (ia_valid & ATTR_SIZE && attr->ia_size != i_size_read(inode)) { loff_t old_i_size = inode->i_size; + + vfs_dq_init(inode); + error = vmtruncate(inode, attr->ia_size); if (error) return error; diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index a5ebd1abccd8..93ac788345e2 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -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, @@ -342,4 +344,6 @@ static inline void dquot_release_reservation_block(struct inode *inode, __dquot_free_space(inode, nr << inode->i_blkbits, 1); } +#define dquot_file_open generic_file_open + #endif /* _LINUX_QUOTAOPS_ */ -- cgit v1.2.3 From 871a293155a24554e153538d36e3a80fa169aefb Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 3 Mar 2010 09:05:07 -0500 Subject: dquot: cleanup dquot initialize routine Get rid of the initialize dquot operation - it is now always called from the filesystem and if a filesystem really needs it's own (which none currently does) it can just call into it's own routine directly. Rename the now static low-level dquot_initialize helper to __dquot_initialize and vfs_dq_init to dquot_initialize to have a consistent namespace. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- Documentation/filesystems/Locking | 2 -- fs/ext2/file.c | 1 + fs/ext2/ialloc.c | 2 +- fs/ext2/inode.c | 4 ++-- fs/ext2/namei.c | 16 ++++++++-------- fs/ext3/file.c | 1 + fs/ext3/ialloc.c | 4 ++-- fs/ext3/inode.c | 6 +++--- fs/ext3/namei.c | 24 ++++++++++++------------ fs/ext3/super.c | 5 ++--- fs/ext4/file.c | 1 + fs/ext4/ialloc.c | 4 ++-- fs/ext4/inode.c | 4 ++-- fs/ext4/namei.c | 24 ++++++++++++------------ fs/ext4/super.c | 5 ++--- fs/jfs/file.c | 2 +- fs/jfs/inode.c | 4 ++-- fs/jfs/jfs_inode.c | 2 +- fs/jfs/namei.c | 24 ++++++++++++------------ fs/ocfs2/file.c | 4 ++-- fs/ocfs2/inode.c | 2 +- fs/ocfs2/namei.c | 14 +++++++------- fs/ocfs2/quota_global.c | 1 - fs/ocfs2/refcounttree.c | 2 +- fs/quota/dquot.c | 32 ++++++++++++++++++++------------ fs/reiserfs/inode.c | 6 +++--- fs/reiserfs/namei.c | 22 +++++++++++----------- fs/reiserfs/super.c | 3 +-- fs/udf/file.c | 2 +- fs/udf/ialloc.c | 2 +- fs/udf/inode.c | 2 +- fs/udf/namei.c | 18 +++++++++--------- fs/ufs/file.c | 1 + fs/ufs/ialloc.c | 2 +- fs/ufs/inode.c | 2 +- fs/ufs/namei.c | 16 ++++++++-------- fs/ufs/truncate.c | 2 +- include/linux/quota.h | 1 - include/linux/quotaops.h | 17 ++++------------- 39 files changed, 141 insertions(+), 145 deletions(-) (limited to 'fs/jfs') diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index fa10e4bf8e5e..06bbbed71206 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -460,7 +460,6 @@ in sys_read() and friends. --------------------------- dquot_operations ------------------------------- prototypes: - int (*initialize) (struct inode *, int); int (*write_dquot) (struct dquot *); int (*acquire_dquot) (struct dquot *); int (*release_dquot) (struct dquot *); @@ -473,7 +472,6 @@ a proper locking wrt the filesystem and call the generic quota operations. What filesystem should expect from the generic quota functions: FS recursion Held locks when called -initialize: yes maybe dqonoff_sem write_dquot: yes dqonoff_sem or dqptr_sem acquire_dquot: yes dqonoff_sem or dqptr_sem release_dquot: yes dqonoff_sem or dqptr_sem diff --git a/fs/ext2/file.c b/fs/ext2/file.c index d11f6e484519..5d198d0697fb 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -20,6 +20,7 @@ #include #include +#include #include "ext2.h" #include "xattr.h" #include "acl.h" diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 88b71972c626..ad7d572ee8dc 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -586,7 +586,7 @@ got: goto fail_drop; } - vfs_dq_init(inode); + dquot_initialize(inode); err = dquot_alloc_inode(inode); if (err) goto fail_drop; diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index c87840c33e17..45ff49f0a4b5 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -59,7 +59,7 @@ static inline int ext2_inode_is_fast_symlink(struct inode *inode) void ext2_delete_inode (struct inode * inode) { if (!is_bad_inode(inode)) - vfs_dq_init(inode); + dquot_initialize(inode); truncate_inode_pages(&inode->i_data, 0); if (is_bad_inode(inode)) @@ -1461,7 +1461,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) return error; if (iattr->ia_valid & ATTR_SIZE) - vfs_dq_init(inode); + dquot_initialize(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); diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 5923df7b22af..71efb0e9a3f2 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -102,7 +102,7 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, st { struct inode *inode; - vfs_dq_init(dir); + dquot_initialize(dir); inode = ext2_new_inode(dir, mode); if (IS_ERR(inode)) @@ -131,7 +131,7 @@ static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_ if (!new_valid_dev(rdev)) return -EINVAL; - vfs_dq_init(dir); + dquot_initialize(dir); inode = ext2_new_inode (dir, mode); err = PTR_ERR(inode); @@ -157,7 +157,7 @@ static int ext2_symlink (struct inode * dir, struct dentry * dentry, if (l > sb->s_blocksize) goto out; - vfs_dq_init(dir); + dquot_initialize(dir); inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO); err = PTR_ERR(inode); @@ -202,7 +202,7 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir, if (inode->i_nlink >= EXT2_LINK_MAX) return -EMLINK; - vfs_dq_init(dir); + dquot_initialize(dir); inode->i_ctime = CURRENT_TIME_SEC; inode_inc_link_count(inode); @@ -226,7 +226,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode) if (dir->i_nlink >= EXT2_LINK_MAX) goto out; - vfs_dq_init(dir); + dquot_initialize(dir); inode_inc_link_count(dir); @@ -274,7 +274,7 @@ static int ext2_unlink(struct inode * dir, struct dentry *dentry) struct page * page; int err = -ENOENT; - vfs_dq_init(dir); + dquot_initialize(dir); de = ext2_find_entry (dir, &dentry->d_name, &page); if (!de) @@ -318,8 +318,8 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry, struct ext2_dir_entry_2 * old_de; int err = -ENOENT; - vfs_dq_init(old_dir); - vfs_dq_init(new_dir); + dquot_initialize(old_dir); + dquot_initialize(new_dir); old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page); if (!old_de) diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 3c7fb11a3b29..f55df0e61cbd 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include "xattr.h" diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 7d7238f9f6f3..ef9008b885b5 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -123,7 +123,7 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) * Note: we must free any quota before locking the superblock, * as writing the quota to disk may need the lock as well. */ - vfs_dq_init(inode); + dquot_initialize(inode); ext3_xattr_delete_inode(handle, inode); dquot_free_inode(inode); dquot_drop(inode); @@ -588,7 +588,7 @@ got: sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0; ret = inode; - vfs_dq_init(inode); + dquot_initialize(inode); err = dquot_alloc_inode(inode); if (err) goto fail_drop; diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index d7962b0c57b3..ffbbc65e3f68 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c @@ -197,7 +197,7 @@ void ext3_delete_inode (struct inode * inode) handle_t *handle; if (!is_bad_inode(inode)) - vfs_dq_init(inode); + dquot_initialize(inode); truncate_inode_pages(&inode->i_data, 0); @@ -3152,7 +3152,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) return error; if (ia_valid & ATTR_SIZE) - vfs_dq_init(inode); + dquot_initialize(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; @@ -3250,7 +3250,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode) ret = 2 * (bpp + indirects) + 2; #ifdef CONFIG_QUOTA - /* We know that structure was already allocated during vfs_dq_init so + /* We know that structure was already allocated during dquot_initialize so * we will be updating only the data blocks + inodes */ ret += EXT3_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb); #endif diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index a492b371b134..ee184084ca42 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1696,7 +1696,7 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode, struct inode * inode; int err, retries = 0; - vfs_dq_init(dir); + dquot_initialize(dir); retry: handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + @@ -1732,7 +1732,7 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry, if (!new_valid_dev(rdev)) return -EINVAL; - vfs_dq_init(dir); + dquot_initialize(dir); retry: handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + @@ -1770,7 +1770,7 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode) if (dir->i_nlink >= EXT3_LINK_MAX) return -EMLINK; - vfs_dq_init(dir); + dquot_initialize(dir); retry: handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + @@ -2066,8 +2066,8 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry) /* Initialize quotas before so that eventual writes go in * separate transaction */ - vfs_dq_init(dir); - vfs_dq_init(dentry->d_inode); + dquot_initialize(dir); + dquot_initialize(dentry->d_inode); handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) @@ -2127,8 +2127,8 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry) /* Initialize quotas before so that eventual writes go * in separate transaction */ - vfs_dq_init(dir); - vfs_dq_init(dentry->d_inode); + dquot_initialize(dir); + dquot_initialize(dentry->d_inode); handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) @@ -2184,7 +2184,7 @@ static int ext3_symlink (struct inode * dir, if (l > dir->i_sb->s_blocksize) return -ENAMETOOLONG; - vfs_dq_init(dir); + dquot_initialize(dir); retry: handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + @@ -2241,7 +2241,7 @@ static int ext3_link (struct dentry * old_dentry, if (inode->i_nlink >= EXT3_LINK_MAX) return -EMLINK; - vfs_dq_init(dir); + dquot_initialize(dir); /* * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing @@ -2293,15 +2293,15 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, struct ext3_dir_entry_2 * old_de, * new_de; int retval, flush_file = 0; - vfs_dq_init(old_dir); - vfs_dq_init(new_dir); + dquot_initialize(old_dir); + dquot_initialize(new_dir); old_bh = new_bh = dir_bh = NULL; /* Initialize quotas before so that eventual writes go * in separate transaction */ if (new_dentry->d_inode) - vfs_dq_init(new_dentry->d_inode); + dquot_initialize(new_dentry->d_inode); handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) + EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 0163d0dae124..e844accbf55d 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -752,7 +752,6 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); static const struct dquot_operations ext3_quota_operations = { - .initialize = dquot_initialize, .write_dquot = ext3_write_dquot, .acquire_dquot = ext3_acquire_dquot, .release_dquot = ext3_release_dquot, @@ -1480,7 +1479,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, } list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); - vfs_dq_init(inode); + dquot_initialize(inode); if (inode->i_nlink) { printk(KERN_DEBUG "%s: truncating inode %lu to %Ld bytes\n", @@ -2736,7 +2735,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) * Process 1 Process 2 * ext3_create() quota_sync() * journal_start() write_dquot() - * vfs_dq_init() down(dqio_mutex) + * dquot_initialize() down(dqio_mutex) * down(dqio_mutex) journal_start() * */ diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 85fa464a24ad..a08a12998c49 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "ext4.h" #include "ext4_jbd2.h" #include "xattr.h" diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index ca8986e4b528..9bb2bb9f67ad 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -217,7 +217,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) * Note: we must free any quota before locking the superblock, * as writing the quota to disk may need the lock as well. */ - vfs_dq_init(inode); + dquot_initialize(inode); ext4_xattr_delete_inode(handle, inode); dquot_free_inode(inode); dquot_drop(inode); @@ -1034,7 +1034,7 @@ got: ei->i_extra_isize = EXT4_SB(sb)->s_want_extra_isize; ret = inode; - vfs_dq_init(inode); + dquot_initialize(inode); err = dquot_alloc_inode(inode); if (err) goto fail_drop; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index eaa22ae9f1f6..bec222ca9ba4 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -171,7 +171,7 @@ void ext4_delete_inode(struct inode *inode) int err; if (!is_bad_inode(inode)) - vfs_dq_init(inode); + dquot_initialize(inode); if (ext4_should_order_data(inode)) ext4_begin_ordered_truncate(inode, 0); @@ -5255,7 +5255,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) return error; if (ia_valid & ATTR_SIZE) - vfs_dq_init(inode); + dquot_initialize(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; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 20f55c2e7571..7f3d2d75a0dc 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1766,7 +1766,7 @@ static int ext4_create(struct inode *dir, struct dentry *dentry, int mode, struct inode *inode; int err, retries = 0; - vfs_dq_init(dir); + dquot_initialize(dir); retry: handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + @@ -1802,7 +1802,7 @@ static int ext4_mknod(struct inode *dir, struct dentry *dentry, if (!new_valid_dev(rdev)) return -EINVAL; - vfs_dq_init(dir); + dquot_initialize(dir); retry: handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + @@ -1841,7 +1841,7 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode) if (EXT4_DIR_LINK_MAX(dir)) return -EMLINK; - vfs_dq_init(dir); + dquot_initialize(dir); retry: handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + @@ -2142,8 +2142,8 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry) /* Initialize quotas before so that eventual writes go in * separate transaction */ - vfs_dq_init(dir); - vfs_dq_init(dentry->d_inode); + dquot_initialize(dir); + dquot_initialize(dentry->d_inode); handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) @@ -2203,8 +2203,8 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry) /* Initialize quotas before so that eventual writes go * in separate transaction */ - vfs_dq_init(dir); - vfs_dq_init(dentry->d_inode); + dquot_initialize(dir); + dquot_initialize(dentry->d_inode); handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb)); if (IS_ERR(handle)) @@ -2260,7 +2260,7 @@ static int ext4_symlink(struct inode *dir, if (l > dir->i_sb->s_blocksize) return -ENAMETOOLONG; - vfs_dq_init(dir); + dquot_initialize(dir); retry: handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) + @@ -2320,7 +2320,7 @@ static int ext4_link(struct dentry *old_dentry, if (inode->i_nlink >= EXT4_LINK_MAX) return -EMLINK; - vfs_dq_init(dir); + dquot_initialize(dir); /* * Return -ENOENT if we've raced with unlink and i_nlink is 0. Doing @@ -2372,15 +2372,15 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, 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); + dquot_initialize(old_dir); + dquot_initialize(new_dir); old_bh = new_bh = dir_bh = NULL; /* Initialize quotas before so that eventual writes go * in separate transaction */ if (new_dentry->d_inode) - vfs_dq_init(new_dentry->d_inode); + dquot_initialize(new_dentry->d_inode); handle = ext4_journal_start(old_dir, 2 * EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) + EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 035516c80df2..edcf3b0239d1 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1013,7 +1013,6 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, const char *data, size_t len, loff_t off); static const struct dquot_operations ext4_quota_operations = { - .initialize = dquot_initialize, #ifdef CONFIG_QUOTA .get_reserved_space = ext4_get_reserved_space, #endif @@ -1931,7 +1930,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, } list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); - vfs_dq_init(inode); + dquot_initialize(inode); if (inode->i_nlink) { ext4_msg(sb, KERN_DEBUG, "%s: truncating inode %lu to %lld bytes", @@ -3700,7 +3699,7 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) * Process 1 Process 2 * ext4_create() quota_sync() * jbd2_journal_start() write_dquot() - * vfs_dq_init() down(dqio_mutex) + * dquot_initialize() down(dqio_mutex) * down(dqio_mutex) jbd2_journal_start() * */ diff --git a/fs/jfs/file.c b/fs/jfs/file.c index f19bb33eb1eb..14ba982b3f24 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -99,7 +99,7 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) return rc; if (iattr->ia_valid & ATTR_SIZE) - vfs_dq_init(inode); + dquot_initialize(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); diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 1aa2dda16590..c694a5f15380 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -147,7 +147,7 @@ void jfs_delete_inode(struct inode *inode) jfs_info("In jfs_delete_inode, inode = 0x%p", inode); if (!is_bad_inode(inode)) - vfs_dq_init(inode); + dquot_initialize(inode); if (!is_bad_inode(inode) && (JFS_IP(inode)->fileset == FILESYSTEM_I)) { @@ -161,7 +161,7 @@ void jfs_delete_inode(struct inode *inode) /* * Free the inode from the quota allocation. */ - vfs_dq_init(inode); + dquot_initialize(inode); dquot_free_inode(inode); dquot_drop(inode); } diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index 72b30895422c..829921b67765 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c @@ -116,7 +116,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) /* * Allocate inode to quota. */ - vfs_dq_init(inode); + dquot_initialize(inode); rc = dquot_alloc_inode(inode); if (rc) goto fail_drop; diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index b7cc29da50b4..4a3e9f39c21d 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -85,7 +85,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, jfs_info("jfs_create: dip:0x%p name:%s", dip, dentry->d_name.name); - vfs_dq_init(dip); + dquot_initialize(dip); /* * search parent directory for entry/freespace @@ -217,7 +217,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) jfs_info("jfs_mkdir: dip:0x%p name:%s", dip, dentry->d_name.name); - vfs_dq_init(dip); + dquot_initialize(dip); /* link count overflow on parent directory ? */ if (dip->i_nlink == JFS_LINK_MAX) { @@ -360,8 +360,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) 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); + dquot_initialize(dip); + dquot_initialize(ip); /* directory must be empty to be removed */ if (!dtEmpty(ip)) { @@ -488,8 +488,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) 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); + dquot_initialize(dip); + dquot_initialize(ip); if ((rc = get_UCSname(&dname, dentry))) goto out; @@ -811,7 +811,7 @@ static int jfs_link(struct dentry *old_dentry, if (ip->i_nlink == 0) return -ENOENT; - vfs_dq_init(dir); + dquot_initialize(dir); tid = txBegin(ip->i_sb, 0); @@ -904,7 +904,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, jfs_info("jfs_symlink: dip:0x%p name:%s", dip, name); - vfs_dq_init(dip); + dquot_initialize(dip); ssize = strlen(name) + 1; @@ -1097,8 +1097,8 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, 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); + dquot_initialize(old_dir); + dquot_initialize(new_dir); old_ip = old_dentry->d_inode; new_ip = new_dentry->d_inode; @@ -1149,7 +1149,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, } else if (new_ip) { IWRITE_LOCK(new_ip, RDWRLOCK_NORMAL); /* Init inode for quota operations. */ - vfs_dq_init(new_ip); + dquot_initialize(new_ip); } /* @@ -1373,7 +1373,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, jfs_info("jfs_mknod: %s", dentry->d_name.name); - vfs_dq_init(dir); + dquot_initialize(dir); if ((rc = get_UCSname(&dname, dentry))) goto out; diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 126198f5a67c..364105291282 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -108,7 +108,7 @@ static int ocfs2_file_open(struct inode *inode, struct file *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); + dquot_initialize(inode); spin_lock(&oi->ip_lock); @@ -980,7 +980,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE; if (size_change) { - vfs_dq_init(inode); + dquot_initialize(inode); status = ocfs2_rw_lock(inode, 1); if (status < 0) { diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 77681a690d16..278a223aae14 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -971,7 +971,7 @@ void ocfs2_delete_inode(struct inode *inode) goto bail; } - vfs_dq_init(inode); + dquot_initialize(inode); if (!ocfs2_inode_is_valid_to_delete(inode)) { /* It's probably not necessary to truncate_inode_pages diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 8b5b142eb638..d9cd4e373a53 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -212,7 +212,7 @@ static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode) } else inode->i_gid = current_fsgid(); inode->i_mode = mode; - vfs_dq_init(inode); + dquot_initialize(inode); return inode; } @@ -244,7 +244,7 @@ static int ocfs2_mknod(struct inode *dir, (unsigned long)dev, dentry->d_name.len, dentry->d_name.name); - vfs_dq_init(dir); + dquot_initialize(dir); /* get our super block */ osb = OCFS2_SB(dir->i_sb); @@ -634,7 +634,7 @@ static int ocfs2_link(struct dentry *old_dentry, if (S_ISDIR(inode->i_mode)) return -EPERM; - vfs_dq_init(dir); + dquot_initialize(dir); err = ocfs2_inode_lock_nested(dir, &parent_fe_bh, 1, OI_LS_PARENT); if (err < 0) { @@ -791,7 +791,7 @@ static int ocfs2_unlink(struct inode *dir, mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry, dentry->d_name.len, dentry->d_name.name); - vfs_dq_init(dir); + dquot_initialize(dir); BUG_ON(dentry->d_parent->d_inode != dir); @@ -1053,8 +1053,8 @@ static int ocfs2_rename(struct inode *old_dir, 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); + dquot_initialize(old_dir); + dquot_initialize(new_dir); osb = OCFS2_SB(old_dir->i_sb); @@ -1604,7 +1604,7 @@ static int ocfs2_symlink(struct inode *dir, 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); + dquot_initialize(dir); sb = dir->i_sb; osb = OCFS2_SB(sb); diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 4dca38f487cf..355f41d1d520 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c @@ -851,7 +851,6 @@ static void ocfs2_destroy_dquot(struct dquot *dquot) } const struct dquot_operations ocfs2_quota_operations = { - .initialize = dquot_initialize, .write_dquot = ocfs2_write_dquot, .acquire_dquot = ocfs2_acquire_dquot, .release_dquot = ocfs2_release_dquot, diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 8ae65c9c020c..f3ae10cde841 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -4390,7 +4390,7 @@ static int ocfs2_vfs_reflink(struct dentry *old_dentry, struct inode *dir, } mutex_lock(&inode->i_mutex); - vfs_dq_init(dir); + dquot_initialize(dir); error = ocfs2_reflink(old_dentry, dir, new_dentry, preserve); mutex_unlock(&inode->i_mutex); if (!error) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 6244bca45c9d..3c0a7e0dff78 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -230,6 +230,7 @@ struct dqstats dqstats; EXPORT_SYMBOL(dqstats); static qsize_t inode_get_rsv_space(struct inode *inode); +static void __dquot_initialize(struct inode *inode, int type); static inline unsigned int hashfn(const struct super_block *sb, unsigned int id, int type) @@ -890,7 +891,7 @@ static void add_dquot_ref(struct super_block *sb, int type) spin_unlock(&inode_lock); iput(old_inode); - sb->dq_op->initialize(inode, type); + __dquot_initialize(inode, type); /* We hold a reference to 'inode' so it couldn't have been * removed from s_inodes list while we dropped the inode_lock. * We cannot iput the inode now as we can be holding the last @@ -1293,22 +1294,26 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space) } /* - * Initialize quota pointers in inode - * We do things in a bit complicated way but by that we avoid calling - * dqget() and thus filesystem callbacks under dqptr_sem. + * Initialize quota pointers in inode + * + * We do things in a bit complicated way but by that we avoid calling + * dqget() and thus filesystem callbacks under dqptr_sem. + * + * 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. */ -int dquot_initialize(struct inode *inode, int type) +static void __dquot_initialize(struct inode *inode, int type) { unsigned int id = 0; - int cnt, ret = 0; + int cnt; struct dquot *got[MAXQUOTAS]; struct super_block *sb = inode->i_sb; qsize_t rsv; /* First test before acquiring mutex - solves deadlocks when we * re-enter the quota code and are already holding the mutex */ - if (IS_NOQUOTA(inode)) - return 0; + if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) + return; /* First get references to structures we might need. */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { @@ -1351,7 +1356,11 @@ out_err: up_write(&sb_dqopt(sb)->dqptr_sem); /* Drop unused references */ dqput_all(got); - return ret; +} + +void dquot_initialize(struct inode *inode) +{ + __dquot_initialize(inode, -1); } EXPORT_SYMBOL(dquot_initialize); @@ -1783,7 +1792,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) chid[GRPQUOTA] = iattr->ia_gid; } if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { - vfs_dq_init(inode); + dquot_initialize(inode); if (__dquot_transfer(inode, chid, mask) == NO_QUOTA) return -EDQUOT; } @@ -1810,7 +1819,6 @@ EXPORT_SYMBOL(dquot_commit_info); * Definitions of diskquota operations. */ const struct dquot_operations dquot_operations = { - .initialize = dquot_initialize, .write_dquot = dquot_commit, .acquire_dquot = dquot_acquire, .release_dquot = dquot_release, @@ -1829,7 +1837,7 @@ int dquot_file_open(struct inode *inode, struct file *file) error = generic_file_open(inode, file); if (!error && (file->f_mode & FMODE_WRITE)) - vfs_dq_init(inode); + dquot_initialize(inode); return error; } EXPORT_SYMBOL(dquot_file_open); diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 06995cb48e39..b8671a54e8ed 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -35,7 +35,7 @@ void reiserfs_delete_inode(struct inode *inode) int err; if (!is_bad_inode(inode)) - vfs_dq_init(inode); + dquot_initialize(inode); truncate_inode_pages(&inode->i_data, 0); @@ -1768,7 +1768,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, BUG_ON(!th->t_trans_id); - vfs_dq_init(inode); + dquot_initialize(inode); err = dquot_alloc_inode(inode); if (err) goto out_end_trans; @@ -3076,7 +3076,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) depth = reiserfs_write_lock_once(inode->i_sb); if (attr->ia_valid & ATTR_SIZE) { - vfs_dq_init(inode); + dquot_initialize(inode); /* version 2 items will be caught by the s_maxbytes check ** done for us in vmtruncate diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index c55e1b9fee5f..96e4cbbfaa18 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -554,7 +554,7 @@ static int drop_new_inode(struct inode *inode) } /* utility function that does setup for reiserfs_new_inode. -** vfs_dq_init needs lots of credits so it's better to have it +** dquot_initialize needs lots of credits so it's better to have it ** outside of a transaction, so we had to pull some bits of ** reiserfs_new_inode out into this func. */ @@ -577,7 +577,7 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) } else { inode->i_gid = current_fsgid(); } - vfs_dq_init(inode); + dquot_initialize(inode); return 0; } @@ -594,7 +594,7 @@ static int reiserfs_create(struct inode *dir, struct dentry *dentry, int mode, struct reiserfs_transaction_handle th; struct reiserfs_security_handle security; - vfs_dq_init(dir); + dquot_initialize(dir); if (!(inode = new_inode(dir->i_sb))) { return -ENOMEM; @@ -668,7 +668,7 @@ static int reiserfs_mknod(struct inode *dir, struct dentry *dentry, int mode, if (!new_valid_dev(rdev)) return -EINVAL; - vfs_dq_init(dir); + dquot_initialize(dir); if (!(inode = new_inode(dir->i_sb))) { return -ENOMEM; @@ -743,7 +743,7 @@ static int reiserfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 2 * (REISERFS_QUOTA_INIT_BLOCKS(dir->i_sb) + REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb)); - vfs_dq_init(dir); + dquot_initialize(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 */ @@ -848,7 +848,7 @@ static int reiserfs_rmdir(struct inode *dir, struct dentry *dentry) JOURNAL_PER_BALANCE_CNT * 2 + 2 + 4 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); - vfs_dq_init(dir); + dquot_initialize(dir); reiserfs_write_lock(dir->i_sb); retval = journal_begin(&th, dir->i_sb, jbegin_count); @@ -931,7 +931,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry) unsigned long savelink; int depth; - vfs_dq_init(dir); + dquot_initialize(dir); inode = dentry->d_inode; @@ -1034,7 +1034,7 @@ static int reiserfs_symlink(struct inode *parent_dir, 2 * (REISERFS_QUOTA_INIT_BLOCKS(parent_dir->i_sb) + REISERFS_QUOTA_TRANS_BLOCKS(parent_dir->i_sb)); - vfs_dq_init(parent_dir); + dquot_initialize(parent_dir); if (!(inode = new_inode(parent_dir->i_sb))) { return -ENOMEM; @@ -1123,7 +1123,7 @@ static int reiserfs_link(struct dentry *old_dentry, struct inode *dir, JOURNAL_PER_BALANCE_CNT * 3 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(dir->i_sb); - vfs_dq_init(dir); + dquot_initialize(dir); reiserfs_write_lock(dir->i_sb); if (inode->i_nlink >= REISERFS_LINK_MAX) { @@ -1249,8 +1249,8 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry, 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); + dquot_initialize(old_dir); + dquot_initialize(new_dir); old_inode = old_dentry->d_inode; new_dentry_inode = new_dentry->d_inode; diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 34f7cd0cb02d..04bf5d791bda 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -246,7 +246,7 @@ static int finish_unfinished(struct super_block *s) retval = remove_save_link_only(s, &save_link_key, 0); continue; } - vfs_dq_init(inode); + dquot_initialize(inode); if (truncate && S_ISDIR(inode->i_mode)) { /* We got a truncate request for a dir which is impossible. @@ -622,7 +622,6 @@ static int reiserfs_write_info(struct super_block *, int); static int reiserfs_quota_on(struct super_block *, int, int, char *, int); static const struct dquot_operations reiserfs_quota_operations = { - .initialize = dquot_initialize, .write_dquot = reiserfs_write_dquot, .acquire_dquot = reiserfs_acquire_dquot, .release_dquot = reiserfs_release_dquot, diff --git a/fs/udf/file.c b/fs/udf/file.c index 013fa44d9a5e..1eb06774ed90 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -228,7 +228,7 @@ static int udf_setattr(struct dentry *dentry, struct iattr *iattr) return error; if (iattr->ia_valid & ATTR_SIZE) - vfs_dq_init(inode); + dquot_initialize(inode); if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 15c6e992e587..fb68c9cd0c3e 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -153,7 +153,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) insert_inode_hash(inode); mark_inode_dirty(inode); - vfs_dq_init(inode); + dquot_initialize(inode); ret = dquot_alloc_inode(inode); if (ret) { dquot_drop(inode); diff --git a/fs/udf/inode.c b/fs/udf/inode.c index f19520268404..c7da1a32b364 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -72,7 +72,7 @@ static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); void udf_delete_inode(struct inode *inode) { if (!is_bad_inode(inode)) - vfs_dq_init(inode); + dquot_initialize(inode); truncate_inode_pages(&inode->i_data, 0); diff --git a/fs/udf/namei.c b/fs/udf/namei.c index e360c3fc4ae4..96757e3e3e04 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -563,7 +563,7 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, int err; struct udf_inode_info *iinfo; - vfs_dq_init(dir); + dquot_initialize(dir); lock_kernel(); inode = udf_new_inode(dir, mode, &err); @@ -618,7 +618,7 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, if (!old_valid_dev(rdev)) return -EINVAL; - vfs_dq_init(dir); + dquot_initialize(dir); lock_kernel(); err = -EIO; @@ -666,7 +666,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) struct udf_inode_info *dinfo = UDF_I(dir); struct udf_inode_info *iinfo; - vfs_dq_init(dir); + dquot_initialize(dir); lock_kernel(); err = -EMLINK; @@ -805,7 +805,7 @@ static int udf_rmdir(struct inode *dir, struct dentry *dentry) struct fileIdentDesc *fi, cfi; struct kernel_lb_addr tloc; - vfs_dq_init(dir); + dquot_initialize(dir); retval = -ENOENT; lock_kernel(); @@ -853,7 +853,7 @@ static int udf_unlink(struct inode *dir, struct dentry *dentry) struct fileIdentDesc cfi; struct kernel_lb_addr tloc; - vfs_dq_init(dir); + dquot_initialize(dir); retval = -ENOENT; lock_kernel(); @@ -909,7 +909,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, struct buffer_head *bh; struct udf_inode_info *iinfo; - vfs_dq_init(dir); + dquot_initialize(dir); lock_kernel(); inode = udf_new_inode(dir, S_IFLNK, &err); @@ -1081,7 +1081,7 @@ static int udf_link(struct dentry *old_dentry, struct inode *dir, int err; struct buffer_head *bh; - vfs_dq_init(dir); + dquot_initialize(dir); lock_kernel(); if (inode->i_nlink >= (256 << sizeof(inode->i_nlink)) - 1) { @@ -1145,8 +1145,8 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry, struct kernel_lb_addr tloc; struct udf_inode_info *old_iinfo = UDF_I(old_inode); - vfs_dq_init(old_dir); - vfs_dq_init(new_dir); + dquot_initialize(old_dir); + dquot_initialize(new_dir); lock_kernel(); ofi = udf_find_entry(old_dir, &old_dentry->d_name, &ofibh, &ocfi); diff --git a/fs/ufs/file.c b/fs/ufs/file.c index d84762f3028e..a8962cecde5b 100644 --- a/fs/ufs/file.c +++ b/fs/ufs/file.c @@ -24,6 +24,7 @@ */ #include +#include #include "ufs_fs.h" #include "ufs.h" diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index 67b4bdb056fb..230ecf608026 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c @@ -355,7 +355,7 @@ cg_found: unlock_super (sb); - vfs_dq_init(inode); + dquot_initialize(inode); err = dquot_alloc_inode(inode); if (err) { dquot_drop(inode); diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index fff8edab382f..09aef49beedb 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -910,7 +910,7 @@ void ufs_delete_inode (struct inode * inode) loff_t old_i_size; if (!is_bad_inode(inode)) - vfs_dq_init(inode); + dquot_initialize(inode); truncate_inode_pages(&inode->i_data, 0); if (is_bad_inode(inode)) diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index c33cb90c516d..118556243e7a 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -86,7 +86,7 @@ static int ufs_create (struct inode * dir, struct dentry * dentry, int mode, UFSD("BEGIN\n"); - vfs_dq_init(dir); + dquot_initialize(dir); inode = ufs_new_inode(dir, mode); err = PTR_ERR(inode); @@ -112,7 +112,7 @@ static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t if (!old_valid_dev(rdev)) return -EINVAL; - vfs_dq_init(dir); + dquot_initialize(dir); inode = ufs_new_inode(dir, mode); err = PTR_ERR(inode); @@ -138,7 +138,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, if (l > sb->s_blocksize) goto out_notlocked; - vfs_dq_init(dir); + dquot_initialize(dir); lock_kernel(); inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); @@ -185,7 +185,7 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir, return -EMLINK; } - vfs_dq_init(dir); + dquot_initialize(dir); inode->i_ctime = CURRENT_TIME_SEC; inode_inc_link_count(inode); @@ -204,7 +204,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode) if (dir->i_nlink >= UFS_LINK_MAX) goto out; - vfs_dq_init(dir); + dquot_initialize(dir); lock_kernel(); inode_inc_link_count(dir); @@ -250,7 +250,7 @@ static int ufs_unlink(struct inode *dir, struct dentry *dentry) struct page *page; int err = -ENOENT; - vfs_dq_init(dir); + dquot_initialize(dir); de = ufs_find_entry(dir, &dentry->d_name, &page); if (!de) @@ -296,8 +296,8 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry, struct ufs_dir_entry *old_de; int err = -ENOENT; - vfs_dq_init(old_dir); - vfs_dq_init(new_dir); + dquot_initialize(old_dir); + dquot_initialize(new_dir); old_de = ufs_find_entry(old_dir, &old_dentry->d_name, &old_page); if (!old_de) diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index e5ef8a3ec230..d3b6270cb377 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -528,7 +528,7 @@ static int ufs_setattr(struct dentry *dentry, struct iattr *attr) attr->ia_size != i_size_read(inode)) { loff_t old_i_size = inode->i_size; - vfs_dq_init(inode); + dquot_initialize(inode); error = vmtruncate(inode, attr->ia_size); if (error) diff --git a/include/linux/quota.h b/include/linux/quota.h index aec2e9dac2d7..4aa93554f0eb 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -295,7 +295,6 @@ struct quota_format_ops { /* Operations working with dquots */ struct dquot_operations { - int (*initialize) (struct inode *, int); int (*write_dquot) (struct dquot *); /* Ordinary dquot write */ struct dquot *(*alloc_dquot)(struct super_block *, int); /* Allocate memory for new dquot */ void (*destroy_dquot)(struct dquot *); /* Free memory for dquot */ diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 93ac788345e2..e6fa7acce290 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -23,7 +23,7 @@ void inode_add_rsv_space(struct inode *inode, qsize_t number); 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); @@ -139,15 +139,6 @@ extern const struct quotactl_ops vfs_quotactl_ops; #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) { @@ -207,7 +198,7 @@ static inline int sb_any_quota_active(struct super_block *sb) #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) { } @@ -260,6 +251,8 @@ static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) return 0; } +#define dquot_file_open generic_file_open + #endif /* CONFIG_QUOTA */ static inline int dquot_alloc_space_nodirty(struct inode *inode, qsize_t nr) @@ -344,6 +337,4 @@ static inline void dquot_release_reservation_block(struct inode *inode, __dquot_free_space(inode, nr << inode->i_blkbits, 1); } -#define dquot_file_open generic_file_open - #endif /* _LINUX_QUOTAOPS_ */ -- cgit v1.2.3