xfs
[Top] [All Lists]

Re: xfs_repair wipes ACL entries, maybe endian-related?

To: KELEMEN Peter <fuji@xxxxxxx>
Subject: Re: xfs_repair wipes ACL entries, maybe endian-related?
From: Steve Lord <lord@xxxxxxx>
Date: Mon, 26 Mar 2001 09:22:54 -0600
Cc: linux-xfs@xxxxxxxxxxx
In-reply-to: Message from KELEMEN Peter <fuji@xxxxxxx> of "Fri, 23 Mar 2001 20:11:37 +0100." <20010323201137.D19598@xxxxxxxxxxxxxx>
Sender: owner-linux-xfs@xxxxxxxxxxx
> Hello,
> 
> [ I have no access to the test machine, I'm writing from my memory ]
> 
> I've been peeking at ACLs today (CVS tree as of 2001/03/22 ~16:00
> CET).  After setting the ACL on a file, unmounting the filesystem
> and running xfs_repair, it intends to wipe out the ACL entries.
> Looking at the code, xfsprogs/repair/attr_repair.c::valid_acl()
> decides it should be cleared.  Reason: acl_cnt > MAX_ACL_ENTRIES,
> I sniffed around with xfs_db, SGI_ACL_FILE attr with 304 byte
> value is OK, in my case it was \000\000\000\005... (normal u,g,o
> plus one u and a mask); valid_acl thinks that acl_cnt is 83886080,
> which just happens to be 0x5000000.  I somehow suspect that adding
> some INT_GET(..., ARCH_CONVERT) macros around the obvious places
> in valid_acl() is not The Right Thing To Do(tm), hence no patch.
> 
> Peter
> 


Looks like you are about correct, the kernel code has endian conversion for
on disk acls, the repair code does not.

xfs_acl_get_endian needs to be ported to user space I think, try this
change to cmd/xfsprogs/repair/attr_repair.c

Steve

===========================================================================
Index: cmd/xfsprogs/repair/attr_repair.c
===========================================================================

--- /usr/tmp/TmpDir.19411-0/cmd/xfsprogs/repair/attr_repair.c_1.2       Mon Mar 
26 09:22:59 2001
+++ cmd/xfsprogs/repair/attr_repair.c   Mon Mar 26 09:22:10 2001
@@ -921,6 +921,23 @@
        return (err);  /* and repair */
 }
 
+static void
+xfs_acl_get_endian(struct acl *aclp)
+{
+    struct acl_entry *ace, *end;
+
+    /* do the endian conversion */
+    INT_SET(aclp->acl_cnt, ARCH_CONVERT, aclp->acl_cnt);
+
+    /* loop thru ACEs of ACL */
+    end = &aclp->acl_entry[0]+aclp->acl_cnt;
+    for (ace=&aclp->acl_entry[0]; ace < end; ace++) {
+        INT_SET(ace->ae_tag, ARCH_CONVERT, ace->ae_tag);
+        INT_SET(ace->ae_id, ARCH_CONVERT, ace->ae_id);
+        INT_SET(ace->ae_perm, ARCH_CONVERT, ace->ae_perm);
+    }
+}
+
 /* 
  * Validate an ACL
  */
@@ -933,6 +950,8 @@
 
        if (aclp == NULL)
                goto acl_invalid;
+
+       xfs_acl_get_endian(aclp);
 
        if (aclp->acl_cnt > ACL_MAX_ENTRIES)
                goto acl_invalid;



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