Hi All:
I find a problem when I use project quota, my base environment is
radhat7.2 (kernel-3.10.y + e2fsprogs-1.42.9).
It will be reproduced with the following steps:
1. mkfs.ext4 /dev/vdb1
2. mount /dev/vdb1 /mnt
3. touch /mnt/testfile
4. umount /mnt
5. Update kernel and e2fsprogs to *upstream stable version*
6. tune2fs -O quota,project /dev/vdb1
7. mount /dev/vdb1 /mnt
8. chattr -p 123 /mnt/testfile
Execute fail and output:
/bin/chattr: Value too large for defined data type while setting project on /mnt/aa
The immediate reason is the following check, i_extra_isize is not updated.
static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
{
...
raw_inode = ext4_raw_inode(&iloc);
if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
err = -EOVERFLOW;
brelse(iloc.bh);
goto out_unlock;
}
...
}
So if I write something to testfile before "step 8" ,the chattr will execute
successfully, because it trigger ext4_expand_extra_isize() to update
i_extra_isize. So is this a BUG or I miss something?
On Jun 29, 2017, at 4:46 AM, zhangyi (F) <[email protected]> wrote:
>
> Hi All:
>
> I find a problem when I use project quota, my base environment is
> radhat7.2 (kernel-3.10.y + e2fsprogs-1.42.9).
>
> It will be reproduced with the following steps:
> 1. mkfs.ext4 /dev/vdb1
> 2. mount /dev/vdb1 /mnt
> 3. touch /mnt/testfile
> 4. umount /mnt
> 5. Update kernel and e2fsprogs to *upstream stable version*
> 6. tune2fs -O quota,project /dev/vdb1
> 7. mount /dev/vdb1 /mnt
> 8. chattr -p 123 /mnt/testfile
>
> Execute fail and output:
> /bin/chattr: Value too large for defined data type while setting project on /mnt/aa
>
> The immediate reason is the following check, i_extra_isize is not updated.
> static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
> {
> ...
> raw_inode = ext4_raw_inode(&iloc);
> if (!EXT4_FITS_IN_INODE(raw_inode, ei, i_projid)) {
> err = -EOVERFLOW;
> brelse(iloc.bh);
> goto out_unlock;
> }
> ...
> }
>
> So if I write something to testfile before "step 8" ,the chattr will execute
> successfully, because it trigger ext4_expand_extra_isize() to update
> i_extra_isize. So is this a BUG or I miss something?
It looks like this code path should also try to expand i_extra_isize if possible,
and only return an error if that fails.
Li Xi, would you be able to look into that?
Cheers, Andreas