diff mbox

[08/11] ext4: introduce subtree logic

Message ID 1265635693-12182-9-git-send-email-dmonakhov@openvz.org
State Not Applicable, archived
Headers show

Commit Message

Dmitry Monakhov Feb. 8, 2010, 1:28 p.m. UTC
* Abstract
  A subtree of a directory tree T is a tree consisting of a directory
  (the subtree root) in T and all of its descendants in T.

  Subtree feature allows to create an isolated (from user point of view)
  trees.

  Subtree assumptions:
  (1) Each inode has subtree id. This id is persistently stored inside
      inode (xattr, usually inside ibody)
  (2) Subtree id is inherent from parent directory
  (3) Inode can not belongs to different subtree
      Otherwise changes in one subtree result in changes in other subtree
      which contradict to isolation criteria.

  This feature is similar to project-id in XFS. One may assign some id to
  a subtree. Each entry from the subtree may be accounted in directory
  subtree quota. Will appear in later patches.

* Disk layout
  Subtree id is stored on disk inside xattr usually inside ibody.
  Xattr is used only as a data storage, It has not user visiable xattr
  interface.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 fs/ext4/subtree.c |  292 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/ext4/subtree.h |   60 +++++++++++
 fs/ext4/xattr.h   |    1 +
 3 files changed, 353 insertions(+), 0 deletions(-)
 create mode 100644 fs/ext4/subtree.c
 create mode 100644 fs/ext4/subtree.h

Comments

Greg Freemyer Feb. 8, 2010, 11:54 p.m. UTC | #1
On Mon, Feb 8, 2010 at 8:28 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
> * Abstract
>  A subtree of a directory tree T is a tree consisting of a directory
>  (the subtree root) in T and all of its descendants in T.
>
>  Subtree feature allows to create an isolated (from user point of view)
>  trees.
>
>  Subtree assumptions:
>  (1) Each inode has subtree id. This id is persistently stored inside
>      inode (xattr, usually inside ibody)
>  (2) Subtree id is inherent from parent directory
>  (3) Inode can not belongs to different subtree
>      Otherwise changes in one subtree result in changes in other subtree
>      which contradict to isolation criteria.
>
>  This feature is similar to project-id in XFS. One may assign some id to
>  a subtree. Each entry from the subtree may be accounted in directory
>  subtree quota. Will appear in later patches.
>
> * Disk layout
>  Subtree id is stored on disk inside xattr usually inside ibody.
>  Xattr is used only as a data storage, It has not user visiable xattr
>  interface.
>
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>

Dmitry,

I think the idea of subtrees is useful, but I'm curious about other
use cases than just quota.

At first glance you are attempting to create a generic subtree
functionality for ext4, but criteria 3) above says a inode can only be
in one subtree at a time.

Thus if quota utilizes subtrees and another future feature were to use
subtrees and the layout of the subtree details were not identical,
they would collide.  Thus with the current patch you can only have one
subtree dependent feature at a time for a given filesystem.

It seems you need something along the lines of a subtree name space
etc. in order to allow orthogonal service users to create orthogonal
subtrees.

Also, I can envision use cases where you have subtrees within subtrees.

Envision a projects folder that forms one subtree, but one specific
project within that folder needs to be in its own subtree.  If I read
your patch description right, that is not allowed because only
directories of subtree 0 are allowed to contain diverging subtrees.

ie.  A directory of subtree 0 can contain a directory of subtrees 1
and 2, but a directory of subtree 10 is not allowed to contain
subtrees 11 and 12.

Just food for thought.

Greg
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Andreas Dilger Feb. 9, 2010, 12:49 a.m. UTC | #2
On 2010-02-08, at 06:28, Dmitry Monakhov wrote:
>  A subtree of a directory tree T is a tree consisting of a directory
>  (the subtree root) in T and all of its descendants in T.
>
>  Subtree feature allows to create an isolated (from user point of  
> view)
>  trees.
>
>  Subtree assumptions:
>  (1) Each inode has subtree id. This id is persistently stored inside
>      inode (xattr, usually inside ibody)
>  (2) Subtree id is inherent from parent directory
>  (3) Inode can not belongs to different subtree
>      Otherwise changes in one subtree result in changes in other  
> subtree
>      which contradict to isolation criteria.
>
>  This feature is similar to project-id in XFS. One may assign some  
> id to
>  a subtree. Each entry from the subtree may be accounted in directory
>  subtree quota. Will appear in later patches.
>
> * Disk layout
>  Subtree id is stored on disk inside xattr usually inside ibody.
>  Xattr is used only as a data storage, It has not user visiable xattr
>  interface.


Presumably this would need e2fsck support, in order to ensure that  
inodes in a given directory have the same subtree ID as the parent  
directory.

Also, how are the subtree IDs generated, to ensure that they are  
unique between subtrees?

Cheers, Andreas
--
Andreas Dilger
Sr. Staff Engineer, Lustre Group
Sun Microsystems of Canada, Inc.

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Monakhov Feb. 9, 2010, 9:29 a.m. UTC | #3
Andreas Dilger <adilger@sun.com> writes:

> On 2010-02-08, at 06:28, Dmitry Monakhov wrote:
>>  A subtree of a directory tree T is a tree consisting of a directory
>>  (the subtree root) in T and all of its descendants in T.
>>
>>  Subtree feature allows to create an isolated (from user point of
>> view)
>>  trees.
>>
>>  Subtree assumptions:
>>  (1) Each inode has subtree id. This id is persistently stored inside
>>      inode (xattr, usually inside ibody)
>>  (2) Subtree id is inherent from parent directory
>>  (3) Inode can not belongs to different subtree
>>      Otherwise changes in one subtree result in changes in other
>> subtree
>>      which contradict to isolation criteria.
>>
>>  This feature is similar to project-id in XFS. One may assign some
>> id to
>>  a subtree. Each entry from the subtree may be accounted in directory
>>  subtree quota. Will appear in later patches.
>>
>> * Disk layout
>>  Subtree id is stored on disk inside xattr usually inside ibody.
>>  Xattr is used only as a data storage, It has not user visiable xattr
>>  interface.
>
>
> Presumably this would need e2fsck support, in order to ensure that
> inodes in a given directory have the same subtree ID as the parent
> directory.
Yes i'm working on this, I've already prepared ioctl support
for chattr/lsattr.
> Also, how are the subtree IDs generated, to ensure that they are
> unique between subtrees?
This is user responsibility. There is possible situation where 
set of subtrees may has same ID. The main idea it that each of
such subtrees is a *full* subtree (it includes all nodes starting
from the subtree root)
About isolation: currently there is a discussion about this feature
some people state that subtrees may exist without a isolation
requirement. Let's wait where it goes.
>
> Cheers, Andreas
> --
> Andreas Dilger
> Sr. Staff Engineer, Lustre Group
> Sun Microsystems of Canada, Inc.
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Monakhov Feb. 9, 2010, 10:06 a.m. UTC | #4
Greg Freemyer <greg.freemyer@gmail.com> writes:

> On Mon, Feb 8, 2010 at 8:28 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>> * Abstract
>>  A subtree of a directory tree T is a tree consisting of a directory
>>  (the subtree root) in T and all of its descendants in T.
>>
>>  Subtree feature allows to create an isolated (from user point of view)
>>  trees.
>>
>>  Subtree assumptions:
>>  (1) Each inode has subtree id. This id is persistently stored inside
>>      inode (xattr, usually inside ibody)
>>  (2) Subtree id is inherent from parent directory
>>  (3) Inode can not belongs to different subtree
>>      Otherwise changes in one subtree result in changes in other subtree
>>      which contradict to isolation criteria.
>>
>>  This feature is similar to project-id in XFS. One may assign some id to
>>  a subtree. Each entry from the subtree may be accounted in directory
>>  subtree quota. Will appear in later patches.
>>
>> * Disk layout
>>  Subtree id is stored on disk inside xattr usually inside ibody.
>>  Xattr is used only as a data storage, It has not user visiable xattr
>>  interface.
>>
>> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
>
> Dmitry,
>
> I think the idea of subtrees is useful, but I'm curious about other
> use cases than just quota.
>
> At first glance you are attempting to create a generic subtree
> functionality for ext4, but criteria 3) above says a inode can only be
> in one subtree at a time.
Theoretically this is possible, but this dramatically complicate things
Just think about this. If inode belongs to different subtrees then
it must have several tree-dquota objects attached to it. This means
that quota require great quota redesign. 
Obviously i don't know any use case for this feature. do you know any?
IMHO isolated subtrees has well defined use-cases. Wat's why two
independent teams (xfs-team and openvz) implemented this feature
in semantically identical way.
>
> Thus if quota utilizes subtrees and another future feature were to use
> subtrees and the layout of the subtree details were not identical,
> they would collide.  Thus with the current patch you can only have one
> subtree dependent feature at a time for a given filesystem.
>
> It seems you need something along the lines of a subtree name space
> etc. in order to allow orthogonal service users to create orthogonal
> subtrees.
>
> Also, I can envision use cases where you have subtrees within subtrees.
>
> Envision a projects folder that forms one subtree, but one specific
> project within that folder needs to be in its own subtree.  If I read
> your patch description right, that is not allowed because only
> directories of subtree 0 are allowed to contain diverging subtrees.
Default tree (ID == 0) is just analog of common space.
where other subrees exist. It is used for subtree manipulation.
>
> ie.  A directory of subtree 0 can contain a directory of subtrees 1
> and 2, but a directory of subtree 10 is not allowed to contain
> subtrees 11 and 12.
>
> Just food for thought.
>
> Greg
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Greg Freemyer Feb. 9, 2010, 1:36 p.m. UTC | #5
On Tue, Feb 9, 2010 at 5:06 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
> Greg Freemyer <greg.freemyer@gmail.com> writes:
>
>> On Mon, Feb 8, 2010 at 8:28 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>> * Abstract
>>>  A subtree of a directory tree T is a tree consisting of a directory
>>>  (the subtree root) in T and all of its descendants in T.
>>>
>>>  Subtree feature allows to create an isolated (from user point of view)
>>>  trees.
>>>
>>>  Subtree assumptions:
>>>  (1) Each inode has subtree id. This id is persistently stored inside
>>>      inode (xattr, usually inside ibody)
>>>  (2) Subtree id is inherent from parent directory
>>>  (3) Inode can not belongs to different subtree
>>>      Otherwise changes in one subtree result in changes in other subtree
>>>      which contradict to isolation criteria.
>>>
>>>  This feature is similar to project-id in XFS. One may assign some id to
>>>  a subtree. Each entry from the subtree may be accounted in directory
>>>  subtree quota. Will appear in later patches.
>>>
>>> * Disk layout
>>>  Subtree id is stored on disk inside xattr usually inside ibody.
>>>  Xattr is used only as a data storage, It has not user visiable xattr
>>>  interface.
>>>
>>> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
>>
>> Dmitry,
>>
>> I think the idea of subtrees is useful, but I'm curious about other
>> use cases than just quota.
>>
>> At first glance you are attempting to create a generic subtree
>> functionality for ext4, but criteria 3) above says a inode can only be
>> in one subtree at a time.
> Theoretically this is possible, but this dramatically complicate things
> Just think about this. If inode belongs to different subtrees then
> it must have several tree-dquota objects attached to it. This means
> that quota require great quota redesign.
> Obviously i don't know any use case for this feature. do you know any?

Maybe we're talking about different things.  I working with the OHSM
project <http://ohsm.sourceforge.net/>

We haven't submitted any patches yet, but for one of our features we
have something fairly close to your subtree patch.  If we were to
leverage your patch and drop that part of ours we would be in the
unhappy situation that quota and ohsm could not both be enabled on the
same filesystem because the ohsm subtree geography is not likely to be
consistent with the quota subtree geography.

If we call quota and ohsm services then my desire would be to see your
subtree patches support orthoganal subtree groups.  One group per
service.

I haven't looked into the actual implementation, but from an API
perspective it is just a matter of adding a service parameter to the
various calls.  For a given subtree service group, a given inode could
only be part of one subtree, but a single inode could participate in
multiple subtree service groups.

Greg
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Monakhov Feb. 9, 2010, 1:53 p.m. UTC | #6
Greg Freemyer <greg.freemyer@gmail.com> writes:

> On Tue, Feb 9, 2010 at 5:06 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>> Greg Freemyer <greg.freemyer@gmail.com> writes:
>>
>>> On Mon, Feb 8, 2010 at 8:28 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>>> * Abstract
>>>>  A subtree of a directory tree T is a tree consisting of a directory
>>>>  (the subtree root) in T and all of its descendants in T.
>>>>
>>>>  Subtree feature allows to create an isolated (from user point of view)
>>>>  trees.
>>>>
>>>>  Subtree assumptions:
>>>>  (1) Each inode has subtree id. This id is persistently stored inside
>>>>      inode (xattr, usually inside ibody)
>>>>  (2) Subtree id is inherent from parent directory
>>>>  (3) Inode can not belongs to different subtree
>>>>      Otherwise changes in one subtree result in changes in other subtree
>>>>      which contradict to isolation criteria.
>>>>
>>>>  This feature is similar to project-id in XFS. One may assign some id to
>>>>  a subtree. Each entry from the subtree may be accounted in directory
>>>>  subtree quota. Will appear in later patches.
>>>>
>>>> * Disk layout
>>>>  Subtree id is stored on disk inside xattr usually inside ibody.
>>>>  Xattr is used only as a data storage, It has not user visiable xattr
>>>>  interface.
>>>>
>>>> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
>>>
>>> Dmitry,
>>>
>>> I think the idea of subtrees is useful, but I'm curious about other
>>> use cases than just quota.
>>>
>>> At first glance you are attempting to create a generic subtree
>>> functionality for ext4, but criteria 3) above says a inode can only be
>>> in one subtree at a time.
>> Theoretically this is possible, but this dramatically complicate things
>> Just think about this. If inode belongs to different subtrees then
>> it must have several tree-dquota objects attached to it. This means
>> that quota require great quota redesign.
>> Obviously i don't know any use case for this feature. do you know any?
>
> Maybe we're talking about different things.  I working with the OHSM
> project <http://ohsm.sourceforge.net/>
>
> We haven't submitted any patches yet, but for one of our features we
> have something fairly close to your subtree patch.  If we were to
> leverage your patch and drop that part of ours we would be in the
> unhappy situation that quota and ohsm could not both be enabled on the
> same filesystem because the ohsm subtree geography is not likely to be
> consistent with the quota subtree geography.
>
> If we call quota and ohsm services then my desire would be to see your
> subtree patches support orthoganal subtree groups.  One group per
> service.
>
> I haven't looked into the actual implementation, but from an API
> perspective it is just a matter of adding a service parameter to the
> various calls.  For a given subtree service group, a given inode could
> only be part of one subtree, but a single inode could participate in
> multiple subtree service groups.
Ok now i think i understand what you are talking about.
one subtree <=> one service is the main rule i'm standing.
If you wan to support several services, no problem
I can easily extend xattr to support different services
something like this
subtree_entry
{
        __le16 sbe_flags /* entry flags */
        __le16 sbe_type  /* service type */
        __le32 sbe_id    /* subtree id */
}
/* subtree entry flags
enum {
     SUBTREE_FL_VALID           = 1, /* entry contains valid data */
     SUBTREE_FL_INHERENT        = 2, /* inherent id from parent on
                                                            create *
     SUBTREE_FL_ISOLATE         = 4  /* Isolated subtree */
    /* and soon */
};

>
> Greg
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Greg Freemyer Feb. 9, 2010, 2:29 p.m. UTC | #7
On Tue, Feb 9, 2010 at 8:53 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
> Greg Freemyer <greg.freemyer@gmail.com> writes:
>
>> On Tue, Feb 9, 2010 at 5:06 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>> Greg Freemyer <greg.freemyer@gmail.com> writes:
>>>
>>>> On Mon, Feb 8, 2010 at 8:28 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>>>> * Abstract
>>>>>  A subtree of a directory tree T is a tree consisting of a directory
>>>>>  (the subtree root) in T and all of its descendants in T.
>>>>>
>>>>>  Subtree feature allows to create an isolated (from user point of view)
>>>>>  trees.
>>>>>
>>>>>  Subtree assumptions:
>>>>>  (1) Each inode has subtree id. This id is persistently stored inside
>>>>>      inode (xattr, usually inside ibody)
>>>>>  (2) Subtree id is inherent from parent directory
>>>>>  (3) Inode can not belongs to different subtree
>>>>>      Otherwise changes in one subtree result in changes in other subtree
>>>>>      which contradict to isolation criteria.
>>>>>
>>>>>  This feature is similar to project-id in XFS. One may assign some id to
>>>>>  a subtree. Each entry from the subtree may be accounted in directory
>>>>>  subtree quota. Will appear in later patches.
>>>>>
>>>>> * Disk layout
>>>>>  Subtree id is stored on disk inside xattr usually inside ibody.
>>>>>  Xattr is used only as a data storage, It has not user visiable xattr
>>>>>  interface.
>>>>>
>>>>> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
>>>>
>>>> Dmitry,
>>>>
>>>> I think the idea of subtrees is useful, but I'm curious about other
>>>> use cases than just quota.
>>>>
>>>> At first glance you are attempting to create a generic subtree
>>>> functionality for ext4, but criteria 3) above says a inode can only be
>>>> in one subtree at a time.
>>> Theoretically this is possible, but this dramatically complicate things
>>> Just think about this. If inode belongs to different subtrees then
>>> it must have several tree-dquota objects attached to it. This means
>>> that quota require great quota redesign.
>>> Obviously i don't know any use case for this feature. do you know any?
>>
>> Maybe we're talking about different things.  I working with the OHSM
>> project <http://ohsm.sourceforge.net/>
>>
>> We haven't submitted any patches yet, but for one of our features we
>> have something fairly close to your subtree patch.  If we were to
>> leverage your patch and drop that part of ours we would be in the
>> unhappy situation that quota and ohsm could not both be enabled on the
>> same filesystem because the ohsm subtree geography is not likely to be
>> consistent with the quota subtree geography.
>>
>> If we call quota and ohsm services then my desire would be to see your
>> subtree patches support orthoganal subtree groups.  One group per
>> service.
>>
>> I haven't looked into the actual implementation, but from an API
>> perspective it is just a matter of adding a service parameter to the
>> various calls.  For a given subtree service group, a given inode could
>> only be part of one subtree, but a single inode could participate in
>> multiple subtree service groups.
> Ok now i think i understand what you are talking about.
> one subtree <=> one service is the main rule i'm standing.
> If you wan to support several services, no problem
> I can easily extend xattr to support different services
> something like this
> subtree_entry
> {
>        __le16 sbe_flags /* entry flags */
>        __le16 sbe_type  /* service type */
>        __le32 sbe_id    /* subtree id */
> }

Conceptually agreed.

But you'd still be limited to one subtree_entry per inode with that right?

Another option would be more like

#define EXT4_SUBTREE_MAX_SERVICE_GROUPS 1
#define EXT4_SUBTREE_MAX_SERVICE_GROUP_QUOTA 0

// OHSM would patch the above when its ready to submit

subtree_entry[EXT4_SUBTREE_MAX_SERVICE_GROUPS]
{
       __le16 sbe_flags /* entry flags */
       __le32 sbe_id    /* subtree id */
}

(Clearly that won't actually work as is, but you get the idea.  Each
service group gets its own flags and id.)

Another option would be separate xattr entries for each subtree group.

Regardless, it looks very doable and its just a matter of figuring out
the best way to support multiple subtree service groups.

Greg
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Monakhov Feb. 9, 2010, 2:48 p.m. UTC | #8
Greg Freemyer <greg.freemyer@gmail.com> writes:

> On Tue, Feb 9, 2010 at 8:53 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>> Greg Freemyer <greg.freemyer@gmail.com> writes:
>>
>>> On Tue, Feb 9, 2010 at 5:06 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>>> Greg Freemyer <greg.freemyer@gmail.com> writes:
>>>>
>>>>> On Mon, Feb 8, 2010 at 8:28 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>>>>> * Abstract
>>>>>>  A subtree of a directory tree T is a tree consisting of a directory
>>>>>>  (the subtree root) in T and all of its descendants in T.
>>>>>>
>>>>>>  Subtree feature allows to create an isolated (from user point of view)
>>>>>>  trees.
>>>>>>
>>>>>>  Subtree assumptions:
>>>>>>  (1) Each inode has subtree id. This id is persistently stored inside
>>>>>>      inode (xattr, usually inside ibody)
>>>>>>  (2) Subtree id is inherent from parent directory
>>>>>>  (3) Inode can not belongs to different subtree
>>>>>>      Otherwise changes in one subtree result in changes in other subtree
>>>>>>      which contradict to isolation criteria.
>>>>>>
>>>>>>  This feature is similar to project-id in XFS. One may assign some id to
>>>>>>  a subtree. Each entry from the subtree may be accounted in directory
>>>>>>  subtree quota. Will appear in later patches.
>>>>>>
>>>>>> * Disk layout
>>>>>>  Subtree id is stored on disk inside xattr usually inside ibody.
>>>>>>  Xattr is used only as a data storage, It has not user visiable xattr
>>>>>>  interface.
>>>>>>
>>>>>> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
>>>>>
>>>>> Dmitry,
>>>>>
>>>>> I think the idea of subtrees is useful, but I'm curious about other
>>>>> use cases than just quota.
>>>>>
>>>>> At first glance you are attempting to create a generic subtree
>>>>> functionality for ext4, but criteria 3) above says a inode can only be
>>>>> in one subtree at a time.
>>>> Theoretically this is possible, but this dramatically complicate things
>>>> Just think about this. If inode belongs to different subtrees then
>>>> it must have several tree-dquota objects attached to it. This means
>>>> that quota require great quota redesign.
>>>> Obviously i don't know any use case for this feature. do you know any?
>>>
>>> Maybe we're talking about different things.  I working with the OHSM
>>> project <http://ohsm.sourceforge.net/>
>>>
>>> We haven't submitted any patches yet, but for one of our features we
>>> have something fairly close to your subtree patch.  If we were to
>>> leverage your patch and drop that part of ours we would be in the
>>> unhappy situation that quota and ohsm could not both be enabled on the
>>> same filesystem because the ohsm subtree geography is not likely to be
>>> consistent with the quota subtree geography.
>>>
>>> If we call quota and ohsm services then my desire would be to see your
>>> subtree patches support orthoganal subtree groups.  One group per
>>> service.
>>>
>>> I haven't looked into the actual implementation, but from an API
>>> perspective it is just a matter of adding a service parameter to the
>>> various calls.  For a given subtree service group, a given inode could
>>> only be part of one subtree, but a single inode could participate in
>>> multiple subtree service groups.
>> Ok now i think i understand what you are talking about.
>> one subtree <=> one service is the main rule i'm standing.
>> If you wan to support several services, no problem
>> I can easily extend xattr to support different services
>> something like this
>> subtree_entry
>> {
>>        __le16 sbe_flags /* entry flags */
>>        __le16 sbe_type  /* service type */
>>        __le32 sbe_id    /* subtree id */
>> }
>
> Conceptually agreed.
>
> But you'd still be limited to one subtree_entry per inode with that right?
>
> Another option would be more like
>
> #define EXT4_SUBTREE_MAX_SERVICE_GROUPS 1
> #define EXT4_SUBTREE_MAX_SERVICE_GROUP_QUOTA 0
>
> // OHSM would patch the above when its ready to submit
>
> subtree_entry[EXT4_SUBTREE_MAX_SERVICE_GROUPS]
> {
>        __le16 sbe_flags /* entry flags */
>        __le32 sbe_id    /* subtree id */
> }
>
> (Clearly that won't actually work as is, but you get the idea.  Each
> service group gets its own flags and id.)
>
> Another option would be separate xattr entries for each subtree group.
>
> Regardless, it looks very doable and its just a matter of figuring out
> the best way to support multiple subtree service groups.
Off course i mean that. In fact i'm plan to pack entries in to one
xattr data block because each xattr has significant space overhead.
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Greg Freemyer Feb. 9, 2010, 2:52 p.m. UTC | #9
On Tue, Feb 9, 2010 at 9:48 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
> Greg Freemyer <greg.freemyer@gmail.com> writes:
>
>> On Tue, Feb 9, 2010 at 8:53 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>> Greg Freemyer <greg.freemyer@gmail.com> writes:
>>>
>>>> On Tue, Feb 9, 2010 at 5:06 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>>>> Greg Freemyer <greg.freemyer@gmail.com> writes:
>>>>>
>>>>>> On Mon, Feb 8, 2010 at 8:28 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>>>>>> * Abstract
>>>>>>>  A subtree of a directory tree T is a tree consisting of a directory
>>>>>>>  (the subtree root) in T and all of its descendants in T.
>>>>>>>
>>>>>>>  Subtree feature allows to create an isolated (from user point of view)
>>>>>>>  trees.
>>>>>>>
>>>>>>>  Subtree assumptions:
>>>>>>>  (1) Each inode has subtree id. This id is persistently stored inside
>>>>>>>      inode (xattr, usually inside ibody)
>>>>>>>  (2) Subtree id is inherent from parent directory
>>>>>>>  (3) Inode can not belongs to different subtree
>>>>>>>      Otherwise changes in one subtree result in changes in other subtree
>>>>>>>      which contradict to isolation criteria.
>>>>>>>
>>>>>>>  This feature is similar to project-id in XFS. One may assign some id to
>>>>>>>  a subtree. Each entry from the subtree may be accounted in directory
>>>>>>>  subtree quota. Will appear in later patches.
>>>>>>>
>>>>>>> * Disk layout
>>>>>>>  Subtree id is stored on disk inside xattr usually inside ibody.
>>>>>>>  Xattr is used only as a data storage, It has not user visiable xattr
>>>>>>>  interface.
>>>>>>>
>>>>>>> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
>>>>>>
>>>>>> Dmitry,
>>>>>>
>>>>>> I think the idea of subtrees is useful, but I'm curious about other
>>>>>> use cases than just quota.
>>>>>>
>>>>>> At first glance you are attempting to create a generic subtree
>>>>>> functionality for ext4, but criteria 3) above says a inode can only be
>>>>>> in one subtree at a time.
>>>>> Theoretically this is possible, but this dramatically complicate things
>>>>> Just think about this. If inode belongs to different subtrees then
>>>>> it must have several tree-dquota objects attached to it. This means
>>>>> that quota require great quota redesign.
>>>>> Obviously i don't know any use case for this feature. do you know any?
>>>>
>>>> Maybe we're talking about different things.  I working with the OHSM
>>>> project <http://ohsm.sourceforge.net/>
>>>>
>>>> We haven't submitted any patches yet, but for one of our features we
>>>> have something fairly close to your subtree patch.  If we were to
>>>> leverage your patch and drop that part of ours we would be in the
>>>> unhappy situation that quota and ohsm could not both be enabled on the
>>>> same filesystem because the ohsm subtree geography is not likely to be
>>>> consistent with the quota subtree geography.
>>>>
>>>> If we call quota and ohsm services then my desire would be to see your
>>>> subtree patches support orthoganal subtree groups.  One group per
>>>> service.
>>>>
>>>> I haven't looked into the actual implementation, but from an API
>>>> perspective it is just a matter of adding a service parameter to the
>>>> various calls.  For a given subtree service group, a given inode could
>>>> only be part of one subtree, but a single inode could participate in
>>>> multiple subtree service groups.
>>> Ok now i think i understand what you are talking about.
>>> one subtree <=> one service is the main rule i'm standing.
>>> If you wan to support several services, no problem
>>> I can easily extend xattr to support different services
>>> something like this
>>> subtree_entry
>>> {
>>>        __le16 sbe_flags /* entry flags */
>>>        __le16 sbe_type  /* service type */
>>>        __le32 sbe_id    /* subtree id */
>>> }
>>
>> Conceptually agreed.
>>
>> But you'd still be limited to one subtree_entry per inode with that right?
>>
>> Another option would be more like
>>
>> #define EXT4_SUBTREE_MAX_SERVICE_GROUPS 1
>> #define EXT4_SUBTREE_MAX_SERVICE_GROUP_QUOTA 0
>>
>> // OHSM would patch the above when its ready to submit
>>
>> subtree_entry[EXT4_SUBTREE_MAX_SERVICE_GROUPS]
>> {
>>        __le16 sbe_flags /* entry flags */
>>        __le32 sbe_id    /* subtree id */
>> }
>>
>> (Clearly that won't actually work as is, but you get the idea.  Each
>> service group gets its own flags and id.)
>>
>> Another option would be separate xattr entries for each subtree group.
>>
>> Regardless, it looks very doable and its just a matter of figuring out
>> the best way to support multiple subtree service groups.
> Off course i mean that. In fact i'm plan to pack entries in to one
> xattr data block because each xattr has significant space overhead.
>

Sounds great.  Does xfs support multiple service groups with its
current offering?

Greg
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dmitry Monakhov Feb. 9, 2010, 3:21 p.m. UTC | #10
Greg Freemyer <greg.freemyer@gmail.com> writes:

> On Tue, Feb 9, 2010 at 9:48 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>> Greg Freemyer <greg.freemyer@gmail.com> writes:
>>
>>> On Tue, Feb 9, 2010 at 8:53 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>>> Greg Freemyer <greg.freemyer@gmail.com> writes:
>>>>
>>>>> On Tue, Feb 9, 2010 at 5:06 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>>>>> Greg Freemyer <greg.freemyer@gmail.com> writes:
>>>>>>
>>>>>>> On Mon, Feb 8, 2010 at 8:28 AM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
>>>>>>>> * Abstract
>>>>>>>>  A subtree of a directory tree T is a tree consisting of a directory
>>>>>>>>  (the subtree root) in T and all of its descendants in T.
>>>>>>>>
>>>>>>>>  Subtree feature allows to create an isolated (from user point of view)
>>>>>>>>  trees.
>>>>>>>>
>>>>>>>>  Subtree assumptions:
>>>>>>>>  (1) Each inode has subtree id. This id is persistently stored inside
>>>>>>>>      inode (xattr, usually inside ibody)
>>>>>>>>  (2) Subtree id is inherent from parent directory
>>>>>>>>  (3) Inode can not belongs to different subtree
>>>>>>>>      Otherwise changes in one subtree result in changes in other subtree
>>>>>>>>      which contradict to isolation criteria.
>>>>>>>>
>>>>>>>>  This feature is similar to project-id in XFS. One may assign some id to
>>>>>>>>  a subtree. Each entry from the subtree may be accounted in directory
>>>>>>>>  subtree quota. Will appear in later patches.
>>>>>>>>
>>>>>>>> * Disk layout
>>>>>>>>  Subtree id is stored on disk inside xattr usually inside ibody.
>>>>>>>>  Xattr is used only as a data storage, It has not user visiable xattr
>>>>>>>>  interface.
>>>>>>>>
>>>>>>>> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
>>>>>>>
>>>>>>> Dmitry,
>>>>>>>
>>>>>>> I think the idea of subtrees is useful, but I'm curious about other
>>>>>>> use cases than just quota.
>>>>>>>
>>>>>>> At first glance you are attempting to create a generic subtree
>>>>>>> functionality for ext4, but criteria 3) above says a inode can only be
>>>>>>> in one subtree at a time.
>>>>>> Theoretically this is possible, but this dramatically complicate things
>>>>>> Just think about this. If inode belongs to different subtrees then
>>>>>> it must have several tree-dquota objects attached to it. This means
>>>>>> that quota require great quota redesign.
>>>>>> Obviously i don't know any use case for this feature. do you know any?
>>>>>
>>>>> Maybe we're talking about different things.  I working with the OHSM
>>>>> project <http://ohsm.sourceforge.net/>
>>>>>
>>>>> We haven't submitted any patches yet, but for one of our features we
>>>>> have something fairly close to your subtree patch.  If we were to
>>>>> leverage your patch and drop that part of ours we would be in the
>>>>> unhappy situation that quota and ohsm could not both be enabled on the
>>>>> same filesystem because the ohsm subtree geography is not likely to be
>>>>> consistent with the quota subtree geography.
>>>>>
>>>>> If we call quota and ohsm services then my desire would be to see your
>>>>> subtree patches support orthoganal subtree groups.  One group per
>>>>> service.
>>>>>
>>>>> I haven't looked into the actual implementation, but from an API
>>>>> perspective it is just a matter of adding a service parameter to the
>>>>> various calls.  For a given subtree service group, a given inode could
>>>>> only be part of one subtree, but a single inode could participate in
>>>>> multiple subtree service groups.
>>>> Ok now i think i understand what you are talking about.
>>>> one subtree <=> one service is the main rule i'm standing.
>>>> If you wan to support several services, no problem
>>>> I can easily extend xattr to support different services
>>>> something like this
>>>> subtree_entry
>>>> {
>>>>        __le16 sbe_flags /* entry flags */
>>>>        __le16 sbe_type  /* service type */
>>>>        __le32 sbe_id    /* subtree id */
>>>> }
>>>
>>> Conceptually agreed.
>>>
>>> But you'd still be limited to one subtree_entry per inode with that right?
>>>
>>> Another option would be more like
>>>
>>> #define EXT4_SUBTREE_MAX_SERVICE_GROUPS 1
>>> #define EXT4_SUBTREE_MAX_SERVICE_GROUP_QUOTA 0
>>>
>>> // OHSM would patch the above when its ready to submit
>>>
>>> subtree_entry[EXT4_SUBTREE_MAX_SERVICE_GROUPS]
>>> {
>>>        __le16 sbe_flags /* entry flags */
>>>        __le32 sbe_id    /* subtree id */
>>> }
>>>
>>> (Clearly that won't actually work as is, but you get the idea.  Each
>>> service group gets its own flags and id.)
>>>
>>> Another option would be separate xattr entries for each subtree group.
>>>
>>> Regardless, it looks very doable and its just a matter of figuring out
>>> the best way to support multiple subtree service groups.
>> Off course i mean that. In fact i'm plan to pack entries in to one
>> xattr data block because each xattr has significant space overhead.
>>
>
> Sounds great.  Does xfs support multiple service groups with its
> current offering?
IFAIK there is only one group, this is because they use it for quota
and for isolation needs. 
In fact due to current linux implementation
the cant use group quota,while project quota is enabled because there
is only two types of types available. This will be fixed by generic
quota improvements see 3-6 patches in the series. 
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/ext4/subtree.c b/fs/ext4/subtree.c
new file mode 100644
index 0000000..40d3d85
--- /dev/null
+++ b/fs/ext4/subtree.c
@@ -0,0 +1,292 @@ 
+/*
+ *  linux/fs/ext4/subtree.c
+ *
+ * Support for subtree quota for ext4 filesystem
+ *
+ * Copyright (C) Parallels Inc, 2010
+ * Dmitry Monakhov <dmonakhov@openvz.org>
+ *
+ */
+
+/*
+ * *Abstract*
+ * A subtree of a directory tree T is a tree consisting of a directory
+ * (the subtree root) in T and all of its descendants in T.
+ *
+ * Subtree feature allows to create an isolated trees.
+ * Isolation means what:
+ *   1) Subtrees has no common inodes (no hadlinks across subtrees)
+ *   2) All descendants belongs to the same subtree.
+ * Such isolated subtrees may be restricted by subtree quota.
+ *
+ * Subtree assumptions:
+ * (1) Each inode has subtree id. This id is persistently stored inside
+ *     inode's xattr, usually inside ibody
+ * (2) Subtree id is inherent from parent directory
+ * (3) Inode can not belongs to different subtree trees
+ *     Otherwise changes in one subtree result in changes in other subtree
+ *     which contradict to isolation criteria.
+ *
+ * Default directory tree (with subtree_id == 0) has special meaning.
+ * directory which belongs to default subtree may contains entries with
+ * other trees. It may be used for renames between different subtrees.
+ */
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/mbcache.h>
+#include <linux/quotaops.h>
+#include <linux/rwsem.h>
+#include "ext4_jbd2.h"
+#include "ext4.h"
+#include "xattr.h"
+#include "acl.h"
+#include "subtree.h"
+enum {
+	EXT4_SUBTREE_SAME = 1,	/* Both nodes belongs to same subtree */
+	EXT4_SUBTREE_COMMON,	/* Ancestor tree includes descent subtree*/
+	EXT4_SUBTREE_CROSS,     /* Nodes belongs to different subtrees */
+};
+
+#define EXT4_I_SUBTREE(inode) (EXT4_I(inode)->i_subtree)
+/**
+   Check ancestor descendant subtree relationship.
+   @ancino: ancestor inode
+   @inode: descendant inode
+ */
+static inline int ext4_which_subtree(struct inode *ancino, struct inode *inode)
+{
+#ifdef EXT4_SUBTREE_DEBUG
+	BUG_ON(EXT4_I_SUBTREE(ancino) > EXT4_SUBTREE_ID_MAX);
+	BUG_ON(EXT4_I_SUBTREE(inode) > EXT4_SUBTREE_ID_MAX);
+#endif
+	if (EXT4_I_SUBTREE(inode) == EXT4_I_SUBTREE(ancino))
+		return EXT4_SUBTREE_SAME;
+		else if (EXT4_I_SUBTREE(ancino) == 0)
+		/*
+		 * Ancestor inode belongs to default tree and it includes
+		 * other subtrees by default
+		*/
+		return EXT4_SUBTREE_COMMON;
+	return EXT4_SUBTREE_CROSS;
+}
+/*
+ * Function is called for new inode before quota init.
+ */
+void ext4_st_inherent_subtree(struct inode *inode, struct inode *dir)
+{
+#ifdef EXT4_SUBTREE_DEBUG
+	BUG_ON(EXT4_I_SUBTREE(dir) > EXT4_SUBTREE_ID_MAX);
+#endif
+	EXT4_I_SUBTREE(inode) = EXT4_I_SUBTREE(dir);
+}
+/*
+ * Initialize directory subtree id of a new inode. Called from ext4_new_inode.
+ *
+ * dir->i_mutex: down
+ * inode->i_mutex: up (access to inode is still exclusive)
+ */
+int ext4_st_init(handle_t *handle, struct inode *inode, struct inode *dir)
+{
+	struct ext4_subtree_entry est;
+	int ret;
+	if (!test_opt(inode->i_sb, SUBTREE))
+		return 0;
+
+	if (EXT4_I_SUBTREE(inode) > EXT4_SUBTREE_ID_MAX)
+		return -EINVAL;
+
+	est.est_id = cpu_to_le32(EXT4_I_SUBTREE(dir));
+	est.est_fl = cpu_to_le16(EXT4_SUBTREE_FL_VALID);
+	ret = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SUBTREE,
+				"", &est, sizeof(est), XATTR_CREATE);
+	return ret;
+}
+
+/*
+ * Read subtree from inode.
+ */
+int ext4_st_read(struct inode *inode)
+{
+	struct ext4_subtree_entry est;
+	int ret;
+	if (!test_opt(inode->i_sb, SUBTREE))
+		return 0;
+
+	ret = ext4_xattr_get(inode, EXT4_XATTR_INDEX_SUBTREE, "",
+			&est, sizeof(est));
+
+	if (ret != -ENODATA && ret != sizeof(est)) {
+		EXT4_I_SUBTREE(inode) = 0;
+		if (ret > 0)
+			/* Index currupted */
+			ret = -EIO;
+		return ret;
+	}
+	if (ret != -ENODATA) {
+		/*
+		 * Inode has not subtree xattr yet. That's ok
+		 * Belongs to default tree.
+		 */
+		EXT4_I_SUBTREE(inode) = 0;
+		return 0;
+	}
+	if (!(le16_to_cpu(est.est_fl) | EXT4_SUBTREE_FL_VALID) ||
+			le32_to_cpu(est.est_id) > EXT4_SUBTREE_ID_MAX) {
+		EXT4_I_SUBTREE(inode) = 0;
+		return -EINVAL;
+	}
+
+	EXT4_I_SUBTREE(inode) = le32_to_cpu(est.est_id);
+	return 0;
+}
+
+/*
+ * Change subtree id for a given inode
+ * ->i_mutex is locked.
+ */
+int ext4_st_change(struct inode *inode, struct inode *dir, int subtree)
+{
+	struct ext4_subtree_entry est;
+	int credits = EXT4_XATTR_TRANS_BLOCKS +
+		EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb);
+	handle_t *handle;
+	int retries = 0;
+	int ret, ret2;
+
+	if (subtree > EXT4_SUBTREE_ID_MAX)
+		return -EINVAL;
+
+	/*
+	 * In order to preserve subtree structure caller must traverse
+	 * hierarchy in following order.
+	 * change from some subtree to default subtree: from parent to child
+	 * change from default subtree to some subtree: from child to parent
+	*/
+	if (dir && (EXT4_I_SUBTREE(dir) != 0 &&
+			EXT4_I_SUBTREE(dir)  != subtree))
+		return -EXDEV;
+
+	if (EXT4_I_SUBTREE(inode) == subtree)
+		return 0;
+retry:
+	handle = ext4_journal_start(inode, credits);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+
+	est.est_id = cpu_to_le32(subtree);
+	est.est_fl = cpu_to_le16(EXT4_SUBTREE_FL_VALID);
+	ret = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SUBTREE,
+				"", &est, sizeof(est), XATTR_REPLACE);
+	if (unlikely(ret == -ENODATA)) {
+		/* Inode has not subtree xattr on disk */
+		BUG_ON(EXT4_I_SUBTREE(inode) != 0);
+		ret = ext4_xattr_set_handle(handle, inode,
+					EXT4_XATTR_INDEX_SUBTREE,
+					"", &est, sizeof(est), XATTR_CREATE);
+	}
+	if (ret) {
+		ret2 = ext4_journal_stop(handle);
+		if (!ret2 && ret == -ENOSPC &&
+			ext4_should_retry_alloc(inode->i_sb, &retries))
+			goto retry;
+		if (ret == 0)
+		ret = ret2;
+	}
+	if (ret)
+		return ret;
+	/*
+	 * Quota transfer only after xattr update. Because it may be
+	 * impossible to roll back quota changed due to -EDQUOT
+	 * TODO: add quota transfer here
+	 */
+	EXT4_I_SUBTREE(inode) = subtree;
+	ret2 = ext4_journal_stop(handle);
+	if (!ret)
+		ret = ret2;
+	return ret;
+
+	/*
+	 * Restore xattr to previous value. Xattr is already allocated, so
+	 * operation may fail only due to some serious error.
+	 */
+	est.est_id = cpu_to_le32(EXT4_I_SUBTREE(inode));
+	est.est_fl = cpu_to_le16(EXT4_SUBTREE_FL_VALID);
+
+	ret2 = ext4_xattr_set_handle(handle, inode, EXT4_XATTR_INDEX_SUBTREE,
+				"", &est, sizeof(est), XATTR_REPLACE);
+	if (ret2)
+		ext4_warning(inode->i_sb, __func__,
+			"Cant restore subtree id err:%d", ret2);
+	ext4_journal_stop(handle);
+	return ret;
+
+}
+/**
+ * Check subtree assumptions on ext4_link()
+ * @tdir:   target directory inode
+ * @inode:  inode in question
+ * @return: true if link is possible, zero otherwise
+ */
+inline int ext4_st_may_link(struct inode *tdir, struct inode *inode)
+{
+	if (!test_opt(inode->i_sb, SUBTREE))
+		return 1;
+	/*
+	 * According to subtree quota assumptions inode can not belongs to
+	 * different quota trees.
+	 */
+	if(ext4_which_subtree(tdir, inode) != EXT4_SUBTREE_SAME)
+		return 0;
+	return 1;
+}
+
+/**
+ * Check for directory subtree assumptions on ext4_rename()
+ * @new_dir: new directory inode
+ * @inode:   inode in question
+ * @return:  true if rename is possible, zero otherwise.
+ */
+inline int ext4_st_may_rename(struct inode *new_dir, struct inode *inode)
+{
+	int same;
+	// XXX: Seems what i_nlink check is racy
+	// Is it possible to get inode->i_mutex here?
+	if (!test_opt(inode->i_sb, SUBTREE))
+		return 1;
+	same = ext4_which_subtree(new_dir, inode);
+	if (S_ISDIR(inode->i_mode)) {
+		if (same == EXT4_SUBTREE_CROSS)
+			return 0;
+	} else {
+		if (inode->i_nlink > 1) {
+			/*
+			 * If we allow to move any dentry of inode which has
+			 * more than one link between subtrees then we end up
+			 * with inode which belongs to different subtrees.
+			 */
+			if (same != EXT4_SUBTREE_SAME)
+				return 0;
+		} else {
+			if (same == EXT4_SUBTREE_CROSS)
+				return 0;
+		}
+	}
+	return 1;
+}
+
+/**
+ * Check subtree  parent/child relationship assumptions.
+ */
+inline void ext4_st_check_parent(struct inode *dir, struct inode *inode)
+{
+	if (!test_opt(dir->i_sb, SUBTREE))
+		return;
+	if (ext4_which_subtree(dir, inode) == EXT4_SUBTREE_CROSS) {
+		ext4_warning(inode->i_sb, __func__,
+			"Bad subtree hierarchy: directory{ino:%lu, sbtr:%u}"
+			"inoode{ino:%lu, sbtr:%u}\n",
+			dir->i_ino, EXT4_I_SUBTREE(dir),
+			inode->i_ino, EXT4_I_SUBTREE(inode));
+		}
+}
diff --git a/fs/ext4/subtree.h b/fs/ext4/subtree.h
new file mode 100644
index 0000000..83583c7
--- /dev/null
+++ b/fs/ext4/subtree.h
@@ -0,0 +1,60 @@ 
+/*
+ *  linux/fs/ext4/subtree.h
+ *
+ * Support for subtree quota for ext4 filesystem
+ *
+ * Copyright (C) Parallels Inc, 2010
+ * Dmitry Monakhov <dmonakhov@openvz.org>
+ *
+ */
+#ifndef _EXT4_SUBTREE_H
+#define _EXT4_SUBTREE_H
+
+/* On disk data size of subtree entry */
+struct ext4_subtree_entry
+{
+	__le16 est_fl;
+	__le32 est_id;
+	__le16 est_reserved;
+};
+enum {
+	EXT4_SUBTREE_FL_VALID	= 0x1,
+};
+#define EXT4_SUBTREE_ID_MAX	((1UL << 31) -16)
+
+#ifdef CONFIG_EXT4_SUBTREE
+void ext4_st_inherent_subtree(struct inode *inode, struct inode *dir);
+int ext4_st_init(handle_t *h, struct inode *inode, struct inode *dir);
+int ext4_st_read(struct inode *inode);
+int ext4_st_change(struct inode *inode, struct inode *dir, int subtree);
+int ext4_st_may_link(struct inode *dir, struct inode *inode);
+int ext4_st_may_rename(struct inode *dir, struct inode *inode);
+void ext4_st_check_parent(struct inode *dir, struct inode *inode);
+#else
+inline void ext4_st_inherent_subtree(struct inode *inode, struct inode *dir)
+{
+	return 0;
+}
+inline int ext4_st_init(handle_t *, struct inode *, struct inode *)
+{
+	return 0
+}
+inline int ext4_st_read(struct inode *inode)
+{
+	return 0;
+}
+inline int ext4_st_change(struct inode *inode, struct inode *dir, int subtree)
+{
+	return 0;
+}
+inline int ext4_st_may_link(struct inode *dir, struct inode *inode)
+{
+	return 1;
+}
+inline int ext4_st_may_rename(struct inode *dir, struct inode *inode)
+{
+	return 1;
+}
+inline void ext4_st_check_parent(struct inode *dir, struct inode *inode) {}
+#endif /* CONFIG_EXT4_SUBTREE */
+#endif
diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
index 8ede88b..688dde8 100644
--- a/fs/ext4/xattr.h
+++ b/fs/ext4/xattr.h
@@ -21,6 +21,7 @@ 
 #define EXT4_XATTR_INDEX_TRUSTED		4
 #define	EXT4_XATTR_INDEX_LUSTRE			5
 #define EXT4_XATTR_INDEX_SECURITY	        6
+#define EXT4_XATTR_INDEX_SUBTREE		7
 
 struct ext4_xattr_header {
 	__le32	h_magic;	/* magic number for identification */