On Jul 4, 2017, at 1:42 AM, Wang Shilong <wangshilong1991@xxxxxxxxx> wrote: > > when upgrading from old format, try to set project id > to old file first time, it will return EOVERFLOW, but if > that file is dirtied(touch etc), changing project id will > be allowed, this might be confusing for users, we could > try to expand @i_extra_iszie here too. > > Reported-by: zhangyi(F) <yi.zhang@xxxxxxxxxx> > Signed-off-by: Wang Shilong <wshilong@xxxxxxx> Reviewed-by: Andreas Dilger <adilger@xxxxxxxxx> > --- > v1->v2: > ext4_expand_extra_isize should be invoked after ext4_reserve_inode_write > --- > fs/ext4/ext4.h | 3 +++ > fs/ext4/inode.c | 8 ++++---- > fs/ext4/ioctl.c | 17 +++++++++++++++-- > 3 files changed, 22 insertions(+), 6 deletions(-) > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index 3219154..640f006 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -2453,6 +2453,9 @@ int ext4_walk_page_buffers(handle_t *handle, > int *partial, > int (*fn)(handle_t *handle, > struct buffer_head *bh)); > +int ext4_expand_extra_isize(struct inode *inode, > + unsigned int new_extra_isize, > + struct ext4_iloc iloc, handle_t *handle); > int do_journal_get_write_access(handle_t *handle, > struct buffer_head *bh); > #define FALL_BACK_TO_NONDELALLOC 1 > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index 5cf82d0..9d07554 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -5632,10 +5632,10 @@ ext4_reserve_inode_write(handle_t *handle, struct inode *inode, > * Expand an inode by new_extra_isize bytes. > * Returns 0 on success or negative error number on failure. > */ > -static int ext4_expand_extra_isize(struct inode *inode, > - unsigned int new_extra_isize, > - struct ext4_iloc iloc, > - handle_t *handle) > +int ext4_expand_extra_isize(struct inode *inode, > + unsigned int new_extra_isize, > + struct ext4_iloc iloc, > + handle_t *handle) > { > struct ext4_inode *raw_inode; > struct ext4_xattr_ibody_header *header; > diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c > index 0c21e22..d413008 100644 > --- a/fs/ext4/ioctl.c > +++ b/fs/ext4/ioctl.c > @@ -319,6 +319,7 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid) > struct ext4_iloc iloc; > struct ext4_inode *raw_inode; > struct dquot *transfer_to[MAXQUOTAS] = { }; > + bool need_expand = false; > > if (!ext4_has_feature_project(sb)) { > if (projid != EXT4_DEF_PROJID) > @@ -350,7 +351,10 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid) > goto out_unlock; > > raw_inode = ext4_raw_inode(&iloc); > - if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) { > + if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid) && > + !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) { > + need_expand = true; > + } else if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) { > err = -EOVERFLOW; > brelse(iloc.bh); > goto out_unlock; > @@ -361,7 +365,8 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid) > > handle = ext4_journal_start(inode, EXT4_HT_QUOTA, > EXT4_QUOTA_INIT_BLOCKS(sb) + > - EXT4_QUOTA_DEL_BLOCKS(sb) + 3); > + EXT4_QUOTA_DEL_BLOCKS(sb) + 3 + > + need_expand ? EXT4_DATA_TRANS_BLOCKS(sb) : 0); > if (IS_ERR(handle)) { > err = PTR_ERR(handle); > goto out_unlock; > @@ -371,6 +376,14 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid) > if (err) > goto out_stop; > > + if (need_expand) { > + err = ext4_expand_extra_isize(inode, > + EXT4_SB(sb)->s_want_extra_isize, > + iloc, handle); > + if (err) > + goto out_stop; > + } > + > transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid)); > if (!IS_ERR(transfer_to[PRJQUOTA])) { > err = __dquot_transfer(inode, transfer_to); > -- > 2.9.3 > Cheers, Andreas
Attachment:
signature.asc
Description: Message signed with OpenPGP