[Ocfs2-devel] ocfs2 quota/reflink bug?
Darrick J. Wong
darrick.wong at oracle.com
Thu Jan 28 21:34:24 PST 2016
Hi there,
This might sound a little funny coming from me, but I think I found a quota bug
in ocfs2. The user quota isn't charged when creating a reflink copy, but
chowning the file credits the old owner and charges the new owner, resulting in
an integer underflow in block usage accounting. ocfs2-tools is 1.6.4 and the
kernel is 4.5-rc1.
Comments during the terminal transcript will be in [brackets].
# mkfs.ocfs2 --fs-features=local,refcount,usrquota /dev/sda
mkfs.ocfs2 1.6.4
Label:
Features: local sparse backup-super unwritten inline-data strict-journal-super xattr usrquota refcount
Block size: 4096 (12 bits)
Cluster size: 4096 (12 bits)
Volume size: 1667567616 (407121 clusters) (407121 blocks)
Cluster groups: 13 (tail covers 20049 clusters, rest cover 32256 clusters)
Extent allocator size: 4194304 (1 groups)
Journal size: 67108864
Node slots: 1
Creating bitmaps: done
Initializing superblock: done
Writing system files: done
Writing superblock: done
Writing backup superblock: 1 block(s)
Formatting Journals: done
Growing extent allocator: done
Formatting slot map: done
Formatting quota files: done
Writing lost+found: done
mkfs.ocfs2 successful
# mount /dev/sda /mnt -o usrquota
# dd if=/dev/zero of=/mnt/a bs=65536k count=1
1+0 records in
1+0 records out
67108864 bytes (67 MB) copied, 0.751677 s, 89.3 MB/s
# repquota /mnt
*** Report for user quotas on device /dev/sda
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
root -- 65536 0 0 2 0 0
# reflink -p /mnt/a /mnt/b
# repquota /mnt
*** Report for user quotas on device /dev/sda
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
root -- 65536 0 0 3 0 0
[Hey, look! Reflinks are free!]
# chown nobody /mnt/a
# repquota /mnt
*** Report for user quotas on device /dev/sda
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
root -- 0 0 0 2 0 0
nobody -- 65536 0 0 1 0 0
[Hey, I still own /mnt/b! Free quota for me!]
# chown nobody /mnt/b
# repquota /mnt
*** Report for user quotas on device /dev/sda
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
root -- 18446744073709486080 0 0 1 0 0
nobody -- 131072 0 0 2 0 0
[Oh no.]
[Hmm, will fsck repair this?]
# fsck.ocfs2 /dev/sda
fsck.ocfs2 1.6.4
Checking OCFS2 filesystem in /dev/sda:
Label: <NONE>
UUID: B35A5046EB1B4ACEBE522473EA73FB0F
Number of blocks: 407121
Block size: 4096
Number of clusters: 407121
Cluster size: 4096
Number of slots: 1
/dev/sda is clean. It will be checked after 20 additional mounts.
[Uh.....]
# mount /dev/sda
# repquota /mnt
*** Report for user quotas on device /dev/sda
Block grace time: 7days; Inode grace time: 7days
Block limits File limits
User used soft hard grace used soft hard grace
----------------------------------------------------------------------
root -- 18446744073709486080 0 0 1 0 0
[D'oh]
The simple solution is to charge quota blocks for reflinks, though it is a
little galling to charge users for a supposedly zero-space "copy". I suppose
if the FS keeps track of who got charged for a given (possibly shared) block,
one could determine the amount that gets credited during a chown or charged
during a CoW, etc. Sadly I'm not familiar enough with ocfs2 to know which it
is or how to change the code. :(
--D
More information about the Ocfs2-devel
mailing list