quota: unify quota init condition in setattr Quota must being initialized if size or uid/git changes requested. But initialization performed in two different places: in case of i_size file system is responsible for dquot init , but in case of uid/gid init will be called internally in dquot_transfer(). This ambiguity makes code harder to understand. Let's move this logic to one common helper function. Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: Jan Kara <jack@suse.cz>
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index b90c3bf..527c46d 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c
@@ -1466,7 +1466,7 @@ if (error) return error; - if (iattr->ia_valid & ATTR_SIZE) + if (is_quota_modification(inode, iattr)) 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/ext3/inode.c b/fs/ext3/inode.c index ea33bdf..735f019 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c
@@ -3151,7 +3151,7 @@ if (error) return error; - if (ia_valid & ATTR_SIZE) + if (is_quota_modification(inode, attr)) dquot_initialize(inode); if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 81d6054..3e0f6af 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c
@@ -5425,7 +5425,7 @@ if (error) return error; - if (ia_valid & ATTR_SIZE) + if (is_quota_modification(inode, attr)) dquot_initialize(inode); if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 14ba982..85d9ec6 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c
@@ -98,7 +98,7 @@ if (rc) return rc; - if (iattr->ia_valid & ATTR_SIZE) + if (is_quota_modification(inode, iattr)) 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/ocfs2/file.c b/fs/ocfs2/file.c index f74f140..e127c53 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c
@@ -966,10 +966,10 @@ if (status) return status; + if (is_quota_modification(inode, attr)) + dquot_initialize(inode); size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE; if (size_change) { - dquot_initialize(inode); - status = ocfs2_rw_lock(inode, 1); if (status < 0) { mlog_errno(status);
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index b1a5036..1056a21 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c
@@ -1822,10 +1822,9 @@ mask |= 1 << GRPQUOTA; chid[GRPQUOTA] = iattr->ia_gid; } - if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { - dquot_initialize(inode); + if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) return __dquot_transfer(inode, chid, mask); - } + return 0; } EXPORT_SYMBOL(dquot_transfer);
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index dc2c65e..0f22fda 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c
@@ -3076,9 +3076,10 @@ ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); depth = reiserfs_write_lock_once(inode->i_sb); - if (attr->ia_valid & ATTR_SIZE) { + if (is_quota_modification(inode, attr)) dquot_initialize(inode); + if (attr->ia_valid & ATTR_SIZE) { /* version 2 items will be caught by the s_maxbytes check ** done for us in vmtruncate */
diff --git a/fs/udf/file.c b/fs/udf/file.c index 4b6a46c..6ebc043 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c
@@ -227,7 +227,7 @@ if (error) return error; - if (iattr->ia_valid & ATTR_SIZE) + if (is_quota_modification(inode, iattr)) dquot_initialize(inode); if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index ee8db3e..f294c44 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c
@@ -518,18 +518,18 @@ if (error) return error; + if (is_quota_modification(inode, attr)) + dquot_initialize(inode); + if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { error = dquot_transfer(inode, attr); if (error) return error; } - if (ia_valid & ATTR_SIZE && - attr->ia_size != i_size_read(inode)) { + if (ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) { loff_t old_i_size = inode->i_size; - dquot_initialize(inode); - error = vmtruncate(inode, attr->ia_size); if (error) return error;
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 82c70c4..8a78187 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h
@@ -14,6 +14,14 @@ return &sb->s_dquot; } +/* i_mutex must being held */ +static inline bool is_quota_modification(struct inode *inode, struct iattr *ia) +{ + return (ia->ia_valid & ATTR_SIZE && ia->ia_size != inode->i_size) || + (ia->ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) || + (ia->ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid); +} + #if defined(CONFIG_QUOTA) /*