xfs
[Top] [All Lists]

Re: How does linux-xfs list extended attributes by namespace?

To: Craig Rodrigues <rodrigc@xxxxxxxxxxxxxx>
Subject: Re: How does linux-xfs list extended attributes by namespace?
From: Tim Shimmin <tes@xxxxxxx>
Date: Fri, 1 Apr 2005 11:35:31 +1000
Cc: linux-xfs@xxxxxxxxxxx
In-reply-to: <20050331173543.GA77406@xxxxxxxxxxxxxx>; from rodrigc@xxxxxxxxxxxxxx on Thu, Mar 31, 2005 at 12:35:43PM -0500
References: <20050331173543.GA77406@xxxxxxxxxxxxxx>
Sender: linux-xfs-bounce@xxxxxxxxxxx
User-agent: Mutt/1.2.5.1i
Hi Craig,

On Thu, Mar 31, 2005 at 12:35:43PM -0500, Craig Rodrigues wrote:
> Hi,
> 
> I am helping with the port of XFS to FreeBSD, based on
> the Linux-XFS codebase.
> 
> Can someone explain to me how listing of extended attributes works?
> 
> If I understand things correctly, on Linux, the call path is:
> 
> linvfs_listxattr()  
>  ->  attr_generic_list() 
>   -> XVOP_ATTR_LIST() (which is xfs_attr_list() )
>   -> attr_system_list()
>     -> attr_generic_listadd()
> 
> 
> My question is, how does the existing system call
> list extended attributes by attribute namespace?
> XVOP_ATTR_LIST() doesn't take in any parameters which would
> indicate that it could list attributes in a specific attribute namespace.
> Does it list all the EA for a file?
> 

It's been a while since I looked at this but I'm going to
probably be looking more closely at it in the near future.
Below is a bit of an explanation; Nathan S. can correct me where
I've made some mistakes ;-)

A bit of background.
The original XFS/IRIX EAs used bits set in the flags to indicate
which namespace was used. Originally this was either the ROOT namespace
or USER namespace. The flags were passed as arguments and the flags
were stored on disk. The flags as arguments encoded more than the namespace.
The EA interface on Linux (as started by Andreas G.) encoded the namespace
as a string prefix to the EA name - _not_ as any flags or bitset.
On the Linux EA list interface, one could just ask for all the EA names
and it would return them all prefixed by the namespace strings.
I don't believe one could list all the EAs for a particular namespace.
On IRIX, as we passed in flags to the attr list call, one could ask for
all the names for a particular namespace (e.g. just list the USER EAs).

So on Linux/XFS we have a couple of layers.
At the higher level we have as you mentioned:
linvfs_listxattr() -> attr_generic_list().
In this func, it will set xflags to:
  ATTR_KERNAMELS | ATTR_KERNFULLS
or
  ATTR_KERNAMELS | ATTR_KERNORMALS
and possibly could add in ATTR_KERNOVAL as well.

From xfs_attr.h:
    #define ATTR_KERNOVAL   0x2000  /* [kernel] get attr size only, not value */
    #define ATTR_KERNAMELS  0x4000  /* [kernel] list attr names (simple list) */

    #define ATTR_KERNORMALS 0x0800  /* [kernel] normal attr list: user+secure */
    #define ATTR_KERNROOTLS 0x8000  /* [kernel] include root in the attr list */
    #define ATTR_KERNFULLS  (ATTR_KERNORMALS|ATTR_KERNROOTLS)

So you can see we ask for listings of "user+secure" namespace or 
"user+secure+root".
I believe root has been given the string name of "trusted".
So that is a listing of "user+security" or "user+security+trusted".
We only get the latter if we have CAP_SYS_ADMIN capability by the looks of it.

So we call VOP_ATTR_LIST -> xfs_attr_list with these ls-namespace bits in the 
flags.
And after this call we call attr_system_list() to add to the list with the 
system namespace EAs.

i.e. 
attr_generic_list
    1. VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error)
    2. attr_system_list(vp, data, size, result)

1. xfs_attr_list will go onto call the various format list functions.
Take the shortform format as an example: xfs_attr_shortform_list.

Normally this goes thru the EAs and checks to see if we have a matching 
namespace.
            if (((context->flags & ATTR_SECURE) != 0) !=
                ((sfe->flags & XFS_ATTR_SECURE) != 0) &&
                !(context->flags & ATTR_KERNORMALS)) {
                    sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
                    continue;
            }
            if (((context->flags & ATTR_ROOT) != 0) !=
                ((sfe->flags & XFS_ATTR_ROOT) != 0) &&
                !(context->flags & ATTR_KERNROOTLS)) {
                    sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
                    continue;
            }
Note that it doesn't work the way of asking "for this namespace or this
other namespace." Intead the listing has used an overriding kind of 
macro (ATTR_KERN*LS macros).

It says 
  "if we don't match on secure namespace AND we are not asked for
   a user+secure listing" then go onto next EA.
So one shouldn't ask to list "ATTR_SECURE|ATTR_ROOT" as that won't work
(the way we have this implemented - could have done it differently I guess).
Instead one has to ask for "ATTR_KERNORMALS|ATTR_KERNROOTLS" for the listing
to override the namespace macro tests.

2. We then go onto add "system" namespace EAs. 
These do not come out of XFS ondisk EAs.
Looking at the code these are for ACLs. Notably, "posix_acl_access"
and "posix_acl_default". These are represented on disk by the ROOT or trusted
namespace EAs for "SGI_ACL_FILE" and "SGI_ACL_DEFAULT"
I presume these would be listed earlier as "trusted.SGI_ACL_FILE" and
"trusted.SGI_ACL_DEFAULT".
Or something like that :)
I would guess that the "posix_acl_access" and "posix_acl_default" names
are there to match up with Andreas G.'s acl/EA interface which expects
these names. 

So back to the question.
The linux interface of listing attributes will always list _all_ of
the EAs for all the namespaces.
The lower level xfs listing code (VOP_ATTR_LIST or xfs_attr_list)
can handle listing of EAs for a particular namespace (by specifying
the namespace bit in the passed in xflags).

--Tim


<Prev in Thread] Current Thread [Next in Thread>