1 * directory tree quota design and implementation
3 V0.07 :: I've succeed in testing journalled tree-quota. At least it survived
4 in fsstress and other manual tests.
7 This document contains basic introduction to directory tree
8 quota for dedicated trees. Currently Linux support many
9 virtualization extensions. One of approaches is containers.
10 Containers is OS level paravirtualization like jail in BSD.
11 In two words container is a set of process isolated from
12 other system. Each process has it's own name-spaces for
13 network,fs,ipc,etc. You may think of container as secure chroot.
15 ** Containers fs root requirement
16 Container's root are independent tree or several trees.
17 usually they organized like follows */ct-root/CT${ID\}/${tree-content}*
18 There are many reasons to keep this trees separate one from another
20 If inode has links in A and B trees. And A-user call chown() for
21 this inode, then B's owner will be surprised.
22 The only way to overcome this is to virtualize inode attributes
23 (for each tree) which is madness IMHO.
24 - checkpoint/restore/online-backup ::
25 This is like suspend resume for VM, but in this case only
26 container's process are stopped(freezed) for some time. After CT's
27 process are stopped we may create backup CT's tree without freezing
30 As I already say there are many way to isolate per-container fs-tree.
31 But everyone has strong disadvantages:
32 - Virtual block devices(qemu-like) :: problems with consistency and performance
33 - ext3/4 + stack-fs(unionfs) :: Bad failure resistance. It is impossible to support jorunalling quota file on stack-fs level.
34 - XFS with proj quota :: Lack of quota file journalling.
36 So the only way to implement journalled quota for containers is to
37 implement it on native fs level.
39 ** Containers directory tree-id assumptions
40 1) Tree id is embedded inside inode
41 2) Tree id is inherent from parent dir
42 3) Inode can not belongs to different directory trees
44 Default directory tree (with id == 0) has special meaning.
45 directory which belongs to default tree may contains roots of
46 other trees. Default tree is used for subtree manipulation.
47 *** ->rename() restriction
49 if (S_ISDIR(old_inode->i_mode)) {
50 if ((new_dir->i_tree_id == 0) || /* move to default tree */
51 (new_dir->i_tree_id == old_inode->i_tree_id)) /*same tree */
55 /* If entry have more than one link then it is bad idea to allow
56 rename it to different (even if it's default tree) tree,
57 because this result in rule (3) violation.
59 if (old_inode->i_nlink > 1) &&
60 (new_dir->i_tree_id != old_inode->i_tree_id)
65 *** ->link restriction
67 /* Links may belongs to only one tree */
68 if(new_dir->i_tree_id != old_inode->i_tree_id)
72 I've prepare proof of concept patch queue.
73 [[http://www.2ka.mipt.ru/~mov/tree-quota.tgz][patch-queue]]
75 This part contain some tips of tree-quota usage. Assume you have kernel
76 with tree-quota patch applied.
77 *** Enabling tree quota an Easy way
78 You may download small file-system image with tree-quota enabled.
79 [[http://www.2ka.mipt.ru/~mov/fs-trquota.img.gz][fs-trquota.img.gz(3Mb)]]
80 mount /test/fs.img /mnt -oloop,quota,grpquota,treeid,trquota
81 *NOTE in order to use journalling quota use following mount options*
83 jqfmt=vfsv0,treeid,trjquota=aquota.tree
86 Currently quota-tools has no tree-quota support. So you have to manually
87 create aquota.tree file. Just copy quota-tree/tool/aquota.tree to the root
89 mount /test/fs.img /mnt -oloop,quota,grpquota,treeid,trquota
90 cp quota-tree/tool/aquota.tree /mnt/
92 quota-tree/tool/quotactl --on --all --path /mnt --dev /dev/loop0
93 # show quotas type ==0 -> usrquota, type == 2 -> trqota
94 quota-tree/tool/quotactl --get --all --type 2 --dev /dev/loop0
96 *** Enabling tree quota from very beginning
98 Currently quota-tools has no tree-quota support. So you have to manually
99 create aquota.tree file. Just copy quota-tree/tool/aquota.tree to the root
101 mount /test/fs.img /mnt -oloop,quota,grpquota,treeid,trquota
102 cp quota-tree/tool/aquota.tree /mnt/
104 quota-tree/tool/quotactl --on --all --path /mnt --dev /dev/loop0
105 # show quotas type ==0 -> usrquota, type == 2 -> trqota
106 quota-tree/tool/quotactl --get --all --type 2 --dev /dev/loop0
108 *** Creating containers tree
110 # create root dir for directory-tree
112 # Assign id for the root
113 ./chattr -Q 1 /mnt/ct-root-1
114 # set quota limits for tree
115 quota-tree/tool/quotactl --set --type 2 --id 1 --bsoft 100000 --bhard 110000 --dev /dev/loop0
117 quota-tree/tool/quotactl --get --all --type 2 --dev /dev/loop0
118 # Populate root with content, it will be accounted in to
119 # tree-quota with id "1"
120 tar zxf root.tar -C /mnt/ct-root-1
122 quota-tree/tool/quotactl --get --all --type 2 --dev /dev/loop0