On Thu 08-04-10 22:04:20, Dmitry Monakhov wrote: > 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. Dmitry, I'm fixing some OCFS2 quota bugs and this patch helps it as well so I took it into my tree. Honza > > Signed-off-by: Dmitry Monakhov <dmonakhov@xxxxxxxxxx> > --- > fs/ext2/inode.c | 2 +- > fs/ext3/inode.c | 2 +- > fs/ext4/inode.c | 2 +- > fs/jfs/file.c | 2 +- > fs/ocfs2/file.c | 4 ++-- > fs/quota/dquot.c | 5 ++--- > fs/reiserfs/inode.c | 3 ++- > fs/udf/file.c | 2 +- > fs/ufs/truncate.c | 8 ++++---- > include/linux/quotaops.h | 8 ++++++++ > 10 files changed, 23 insertions(+), 15 deletions(-) > > diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c > index 45ff49f..445f08a 100644 > --- a/fs/ext2/inode.c > +++ b/fs/ext2/inode.c > @@ -1460,7 +1460,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr) > 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 ffbbc65..0981a27 100644 > --- a/fs/ext3/inode.c > +++ b/fs/ext3/inode.c > @@ -3151,7 +3151,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) > 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 4a91225..b812655 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -5255,7 +5255,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) > 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 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) > 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 3641052..b26df86 100644 > --- a/fs/ocfs2/file.c > +++ b/fs/ocfs2/file.c > @@ -978,10 +978,10 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) > 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 8a2f0cb..a168189 100644 > --- a/fs/quota/dquot.c > +++ b/fs/quota/dquot.c > @@ -1801,10 +1801,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) > 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 b8671a5..0bf5324 100644 > --- a/fs/reiserfs/inode.c > +++ b/fs/reiserfs/inode.c > @@ -3075,9 +3075,10 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) > 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 @@ int udf_setattr(struct dentry *dentry, struct iattr *iattr) > 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 @@ int ufs_setattr(struct dentry *dentry, struct iattr *attr) > 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 e6fa7ac..fd8f70b 100644 > --- a/include/linux/quotaops.h > +++ b/include/linux/quotaops.h > @@ -14,6 +14,14 @@ static inline struct quota_info *sb_dqopt(struct super_block *sb) > 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) > > /* > -- > 1.6.6.1 > -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html