? db-checks.patch
? eattr-callouts.patch
? eattr-callouts2.patch
? eattr-callouts3.patch
? eattr-callouts4.patch
? initialize-dyn.patch
? mount-mem-leaks.patch
? namei.patch
? negative-response-encode-0001.patch
? phil-error-code-fixes.patch
? phil-patches1.patch
? remount.patch
? src/kernel/linux-2.6/.acl.c.swp
? src/server/.pint-eattr.c.swp
Index: src/io/trove/trove-dbpf/dbpf-keyval.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/io/trove/trove-dbpf/dbpf-keyval.c,v
retrieving revision 1.83
diff -u -a -p -r1.83 dbpf-keyval.c
--- src/io/trove/trove-dbpf/dbpf-keyval.c	15 Mar 2007 21:45:23 -0000	1.83
+++ src/io/trove/trove-dbpf/dbpf-keyval.c	28 Mar 2007 21:25:16 -0000
@@ -1623,7 +1623,14 @@ static int dbpf_keyval_iterate_cursor_ge
         key->buffer_sz : DBPF_KEYVAL_DB_ENTRY_KEY_SIZE(db_key.size);
 
     memcpy(key->buffer, key_entry.key, key_sz);
-    key->buffer_sz = DBPF_KEYVAL_DB_ENTRY_KEY_SIZE(db_key.size);
+
+    /* only adjust the buffer size if the key didn't fit into the
+     * buffer
+     */
+    if(key->buffer_sz < DBPF_KEYVAL_DB_ENTRY_KEY_SIZE(db_key.size))
+    {
+        key->buffer_sz = DBPF_KEYVAL_DB_ENTRY_KEY_SIZE(db_key.size);
+    }
 
     key->read_sz = key_sz;
     
Index: src/kernel/linux-2.6/acl.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/acl.c,v
retrieving revision 1.24
diff -u -a -p -r1.24 acl.c
--- src/kernel/linux-2.6/acl.c	20 Sep 2006 22:59:53 -0000	1.24
+++ src/kernel/linux-2.6/acl.c	28 Mar 2007 21:25:16 -0000
@@ -612,10 +612,15 @@ int pvfs2_acl_chmod(struct inode *inode)
         goto out;
     }
     acl = pvfs2_get_acl(inode, ACL_TYPE_ACCESS);
-    if (IS_ERR(acl) || !acl)
+    if (IS_ERR(acl))
     {
         error = PTR_ERR(acl);
         gossip_err("pvfs2_acl_chmod: get acl (access) failed with %d\n", error);
+        goto out;
+    }
+    if(!acl)
+    {
+        error = 0;
         goto out;
     }
     clone = posix_acl_clone(acl, GFP_KERNEL);
Index: src/kernel/linux-2.6/namei.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/namei.c,v
retrieving revision 1.81
diff -u -a -p -r1.81 namei.c
--- src/kernel/linux-2.6/namei.c	20 Sep 2006 22:59:53 -0000	1.81
+++ src/kernel/linux-2.6/namei.c	28 Mar 2007 21:25:16 -0000
@@ -158,76 +158,82 @@ static struct dentry *pvfs2_lookup(
                 llu(new_op->downcall.resp.lookup.refn.handle),
                 new_op->downcall.resp.lookup.refn.fs_id, ret);
 
-    /* lookup inode matching name (or add if not there) */
-    if (ret > -1)
+    if(ret < 0)
     {
-	inode = pvfs2_iget(sb, &new_op->downcall.resp.lookup.refn);
-	if (inode && !is_bad_inode(inode))
-	{
-            struct dentry *res;
-
-	    /* update dentry/inode pair into dcache */
-	    dentry->d_op = &pvfs2_dentry_operations;
-
-            res = pvfs2_d_splice_alias(dentry, inode);
-
-            gossip_debug(GOSSIP_NAME_DEBUG, "Lookup success (inode ct = %d)\n",
-                        (int)atomic_read(&inode->i_count));
-            op_release(new_op);
-            if (res) 
-                res->d_op = &pvfs2_dentry_operations;
-            return res;
-	}
-        else if (inode && is_bad_inode(inode))
+        if(ret == -ENOENT)
         {
-            ret = -EACCES;
-	    found_pvfs2_inode = PVFS2_I(inode);
-            /* look for an error code, possibly set by pvfs2_read_inode(),
-             * otherwise we have to guess EACCES 
+            /*
+             * if no inode was found, add a negative dentry to dcache anyway;
+             * if we don't, we don't hold expected lookup semantics and we most
+             * noticeably break during directory renames.
+             *
+             * however, if the operation failed or exited, do not add the
+             * dentry (e.g. in the case that a touch is issued on a file that
+             * already exists that was interrupted during this lookup -- no
+             * need to add another negative dentry for an existing file)
              */
-            if(found_pvfs2_inode->error_code)
-            {
-                ret = found_pvfs2_inode->error_code;
-            }
-            iput(inode);
+
+            gossip_debug(GOSSIP_NAME_DEBUG, 
+                         "pvfs2_lookup: Adding *negative* dentry %p\n for %s\n",
+                         dentry, dentry->d_name.name);
+
+            /*
+             * make sure to set the pvfs2 specific dentry operations for
+             * the negative dentry that we're adding now so that a
+             * potential future lookup of this cached negative dentry can
+             * be properly revalidated.
+             */
+            dentry->d_op = &pvfs2_dentry_operations;
+            d_add(dentry, inode);
+
             op_release(new_op);
-            return ERR_PTR(ret);
+            return NULL;
         }
-	else
-	{
-            op_release(new_op);
-            gossip_debug(GOSSIP_NAME_DEBUG, "Returning -EACCES\n");
-            return ERR_PTR(-EACCES);
-	}
+
+        /* must be a non-recoverable error */
+        return ERR_PTR(ret);
     }
 
-    /*
-      if no inode was found, add a negative dentry to dcache anyway;
-      if we don't, we don't hold expected lookup semantics and we most
-      noticeably break during directory renames.
-
-      however, if the operation failed or exited, do not add the
-      dentry (e.g. in the case that a touch is issued on a file that
-      already exists that was interrupted during this lookup -- no
-      need to add another negative dentry for an existing file)
-    */
-    if (!inode && op_state_serviced(new_op))
+    inode = pvfs2_iget(sb, &new_op->downcall.resp.lookup.refn);
+    if (inode && !is_bad_inode(inode))
     {
-        /*
-          make sure to set the pvfs2 specific dentry operations for
-          the negative dentry that we're adding now so that a
-          potential future lookup of this cached negative dentry can
-          be properly revalidated.
-        */
-        gossip_debug(GOSSIP_NAME_DEBUG, "pvfs2_lookup: Adding *negative* dentry %p\n  "
-                    "for %s\n", dentry, dentry->d_name.name);
+        struct dentry *res;
 
+        /* update dentry/inode pair into dcache */
         dentry->d_op = &pvfs2_dentry_operations;
-        d_add(dentry, inode);
+
+        res = pvfs2_d_splice_alias(dentry, inode);
+
+        gossip_debug(GOSSIP_NAME_DEBUG, "Lookup success (inode ct = %d)\n",
+                     (int)atomic_read(&inode->i_count));
+        if (res)
+            res->d_op = &pvfs2_dentry_operations;
+
+        op_release(new_op);
+        return res;
+    }
+    else if (inode && is_bad_inode(inode))
+    {
+        ret = -EACCES;
+        found_pvfs2_inode = PVFS2_I(inode);
+        /* look for an error code, possibly set by pvfs2_read_inode(),
+         * otherwise we have to guess EACCES 
+         */
+        if(found_pvfs2_inode->error_code)
+        {
+            ret = found_pvfs2_inode->error_code;
+        }
+        iput(inode);
+        op_release(new_op);
+        return ERR_PTR(ret);
     }
 
+    /* no error was returned from service_operation, but the inode
+     * from pvfs2_iget was null...just return EACCESS
+     */
     op_release(new_op);
-    return NULL;
+    gossip_debug(GOSSIP_NAME_DEBUG, "Returning -EACCES\n");
+    return ERR_PTR(-EACCES);
 }
 
 /* return 0 on success; non-zero otherwise */
Index: src/server/get-eattr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/server/get-eattr.sm,v
retrieving revision 1.15
diff -u -a -p -r1.15 get-eattr.sm
--- src/server/get-eattr.sm	17 Feb 2007 21:16:47 -0000	1.15
+++ src/server/get-eattr.sm	28 Mar 2007 21:25:16 -0000
@@ -23,6 +23,7 @@
 #include "pvfs2-types.h"
 #include "pvfs2-util.h"
 #include "pint-util.h"
+#include "pint-eattr.h"
 
 static int geteattr_setup_resp(
     PINT_server_op *s_op, job_status_s *js_p);
@@ -85,63 +86,32 @@ machine pvfs2_get_eattr_sm
 static int geteattr_setup_resp(PINT_server_op *s_op, job_status_s *js_p)
 {
     int i, tsz;
-    char reserved_prefix[] = "system.pvfs2.";
-    int reserved_prefix_len = strlen("system.pvfs2.");
-    char* tmp_buffer = NULL;
-    int tmp_len = 0;
-    int ret;
 
     gossip_debug(GOSSIP_GETEATTR_DEBUG,"geteattr requesting %d keys\n",
             s_op->req->u.geteattr.nkey);
 
     js_p->error_code = 0;
  
-    tmp_buffer = (char*)malloc(PVFS_REQ_LIMIT_KEY_LEN);
-    if(!tmp_buffer)
-    {
-        js_p->error_code = -PVFS_ENOMEM;
-        return(1);
-    }
-
     /* iterate through the keys and see if they fall into valid name spaces */
     for(i=0; i<s_op->req->u.geteattr.nkey; i++)
     {
         gossip_debug(GOSSIP_GETEATTR_DEBUG, "geteattr key %d : %s\n", i, 
                 (char *) s_op->req->u.geteattr.key[i].buffer);
-        if(!PINT_eattr_is_prefixed(s_op->req->u.geteattr.key[i].buffer))
+
+        js_p->error_code = PINT_eattr_check_access(
+            &s_op->req->u.geteattr.key[i],
+            NULL);
+        if(js_p->error_code != 0)
         {
-            /* not prefixed: treat this as if the key does not exist */
-            free(tmp_buffer);
-            js_p->error_code = -PVFS_ENOENT;
             return(1);
         }
 
-        /* look for keys in the special "system.pvfs2." prefix and strip the
-         * prefix off; they are stored as keyvals with no prefix within
-         * trove.
-         */
-        if(strncmp(s_op->req->u.geteattr.key[i].buffer, reserved_prefix,
-            reserved_prefix_len) == 0)
-        {
-            ret = sscanf(s_op->req->u.geteattr.key[i].buffer,
-                "system.pvfs2.%s", tmp_buffer);
-            if(ret != 1)
-            {
-                free(tmp_buffer);
-                js_p->error_code = -PVFS_ENOENT;
-                return(1);
-            }
-            tmp_len = strlen(tmp_buffer) + 1;
-            memcpy(s_op->req->u.geteattr.key[i].buffer, tmp_buffer, tmp_len);
-            s_op->req->u.geteattr.key[i].buffer_sz = tmp_len;
-        }
     }
 
     s_op->resp.u.geteattr.val =
         malloc(s_op->req->u.geteattr.nkey*sizeof(PVFS_ds_keyval));
     if (!s_op->resp.u.geteattr.val)
     {
-        free(tmp_buffer);
         js_p->error_code = -PVFS_ENOMEM;
         return(1);
     }
@@ -150,7 +120,6 @@ static int geteattr_setup_resp(PINT_serv
     if (!s_op->resp.u.geteattr.err)
     {
         free(s_op->resp.u.geteattr.val);
-        free(tmp_buffer);
         js_p->error_code = -PVFS_ENOMEM;
         return(1);
     }
@@ -163,7 +132,6 @@ static int geteattr_setup_resp(PINT_serv
         s_op->resp.u.geteattr.nkey = 0;
         free (s_op->resp.u.geteattr.val);
         free (s_op->resp.u.geteattr.err);
-        free(tmp_buffer);
         js_p->error_code = -PVFS_ENOMEM;
         return(1);
     }
@@ -177,7 +145,6 @@ static int geteattr_setup_resp(PINT_serv
             (char *) s_op->u.eattr.buffer + tsz;
         tsz += s_op->req->u.geteattr.valsz[i];
     }
-    free(tmp_buffer);
     return 1;
 }
 
Index: src/server/list-eattr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/server/list-eattr.sm,v
retrieving revision 1.9
diff -u -a -p -r1.9 list-eattr.sm
--- src/server/list-eattr.sm	17 Feb 2007 21:16:48 -0000	1.9
+++ src/server/list-eattr.sm	28 Mar 2007 21:25:16 -0000
@@ -23,6 +23,7 @@
 #include "pvfs2-types.h"
 #include "pvfs2-util.h"
 #include "pint-util.h"
+#include "pint-eattr.h"
 
 static int listeattr_setup_resp(
     PINT_server_op *s_op, job_status_s *js_p);
@@ -182,10 +183,6 @@ static int listeattr_check_resp(PINT_ser
 {
     int num_found = 0;
     int i = 0;
-    char* tmp_buffer = NULL;
-    char translate_prefix[] = "system.pvfs2.";
-    int translate_prefix_len = strlen("system.pvfs2.");
-    int ret = 0;
 
     /* Nothing was requested? then fill token to hold the max available keys */
     if (s_op->resp.u.listeattr.nkey == 0)
@@ -212,52 +209,21 @@ static int listeattr_check_resp(PINT_ser
         return(1);
     }
   
-    tmp_buffer = (char*)malloc(PVFS_REQ_LIMIT_KEY_LEN);
-    if(!tmp_buffer)
-    {
-        js_p->error_code = -PVFS_ENOMEM;
-        return(1);
-    }
-
     /* iterate through the keys that we found */
     for(i=0; i<num_found; i++)
     {
-        /* check to see if it is prefixed into a supported name space */
-        if(!PINT_eattr_is_prefixed(s_op->resp.u.listeattr.key[i].buffer))
+        js_p->error_code = PINT_eattr_list_access(
+            &s_op->resp.u.listeattr.key[i],
+            NULL);
+        if(js_p->error_code != 0)
         {
-            /* we need to tack on a "system.pvfs2." prefix */
-
-            /* find out if the key size requested is large enough */
-            if((translate_prefix_len + s_op->resp.u.listeattr.key[i].read_sz) >
-                s_op->req->u.listeattr.keysz[i])
-            {
-                /* NOTE: trying to mimic the semantics of
-                 * trove_keyval_iterate_keys(): it will also report an
-                 * overall error if one of the key buffers is to small,
-                 * though the choice of error code may be different.
-                 */
-                free(tmp_buffer);
-                js_p->error_code = -PVFS_EMSGSIZE;
-                return(1);
-            }
-
-            /* add a prefix onto the key and adjust sizes accordingly */
-            /* NOTE: this will have to change if we ever permit non-string
-             * keys (which would break using them for xattrs anyway)
-             */
-            ret = sprintf(tmp_buffer,
-                "%s%s", translate_prefix,
-                (char*)s_op->resp.u.listeattr.key[i].buffer);
-            memcpy(s_op->resp.u.listeattr.key[i].buffer, tmp_buffer,
-                (ret+1));
-            s_op->resp.u.listeattr.key[i].read_sz += translate_prefix_len;
+            return 1;
         }
 
         s_op->resp.u.listeattr.key[i].buffer_sz =
             s_op->resp.u.listeattr.key[i].read_sz;
     }    
 
-    free(tmp_buffer);
     js_p->error_code = 0;
     return(1);
 }
Index: src/server/module.mk.in
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/server/module.mk.in,v
retrieving revision 1.47
diff -u -a -p -r1.47 module.mk.in
--- src/server/module.mk.in	13 Sep 2006 20:22:58 -0000	1.47
+++ src/server/module.mk.in	28 Mar 2007 21:25:16 -0000
@@ -42,7 +42,8 @@ ifdef BUILD_SERVER
 
 	# c files that should be added to server library
 	SERVERSRC += \
-		$(SERVER_SMCGEN)
+		$(SERVER_SMCGEN) \
+		$(DIR)/pint-eattr.c
 
 	# track generate .c files to remove during dist clean, etc. 
 		SMCGEN += $(SERVER_SMCGEN)
Index: src/server/pint-eattr.c
===================================================================
RCS file: src/server/pint-eattr.c
diff -N src/server/pint-eattr.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/server/pint-eattr.c	28 Mar 2007 21:25:16 -0000
@@ -0,0 +1,265 @@
+/* 
+ * (C) 2001 Clemson University and The University of Chicago 
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "pvfs2.h"
+#include "pint-eattr.h"
+#include "pvfs2-req-proto.h"
+
+#define PVFS_EATTR_NS_SYSTEM_PVFS2 "system.pvfs2."
+
+/* extended attribute name spaces supported in PVFS2 */
+struct PINT_eattr_check
+{
+    const char * ns;
+    int ret;
+    int (* check) (PVFS_ds_keyval *key, PVFS_ds_keyval *val);
+};
+
+/* PINT_eattr_strip_prefix
+ *
+ * Remove the 'system.pvfs2.' prefix from attributes before querying.
+ * These specific attributes are stored without the prefix.
+ */
+static int PINT_eattr_strip_prefix(PVFS_ds_keyval *key, PVFS_ds_keyval *val);
+
+static struct PINT_eattr_check PINT_eattr_access[] =
+{
+    {"system.pvfs2.", 0, PINT_eattr_strip_prefix},
+    {"system.", 0, NULL},
+    {"user.", 0, NULL},
+    {"trusted.", 0, NULL},
+    {"security.", 0, NULL},
+    {NULL, -PVFS_ENOENT, NULL}
+};
+
+/* PINT_eattr_system_verify
+ *
+ * Check the eattrs with system. namespace prefixes.  Right now this
+ * only checks that acls are formatted properly.
+ */
+static int PINT_eattr_system_verify(PVFS_ds_keyval *k, PVFS_ds_keyval *v);
+
+/* We provide namespace structures that include error codes
+ * or checking functions.  For an extended attribute, the
+ * namespace is checked by iterating from top to bottom
+ * through this list.  If a namespace matches and the error
+ * code is non-zero, the error code is returned, otherwise,
+ * the checking function is called (if non-null).  If none of the namespaces
+ * in the list match (or the eattr isn't prefixed with
+ * a namespace, the last entry in the list is triggered,
+ * and EOPNOTSUPP is returned.  Since we don't allow
+ * eattrs with system.pvfs2. prefixes to be set by the
+ * set-eattr operation, we return EINVAL in that case.
+ */
+static struct PINT_eattr_check PINT_eattr_namespaces[] =
+{
+    {"system.pvfs2.", -PVFS_EINVAL, NULL},
+    {"system.", 0, PINT_eattr_system_verify},
+    {"user.", 0, NULL},
+    {"trusted.", 0, NULL},
+    {"security.", 0, NULL},
+    {NULL, -PVFS_EOPNOTSUPP, NULL}
+};
+
+static int PINT_eattr_verify_acl_access(PVFS_ds_keyval *key, PVFS_ds_keyval *val);
+
+/* Used to verify that acls are correctly formatted before plopping
+ * them in storage
+ */
+static struct PINT_eattr_check PINT_eattr_system[] =
+{
+    {"system.posix_acl_access", 0, PINT_eattr_verify_acl_access},
+    {NULL, 0, NULL}};
+
+static int PINT_eattr_add_pvfs_prefix(PVFS_ds_keyval *key, PVFS_ds_keyval *val);
+
+/* check that the eattr in the list matches a valid namespace.  If
+ * it doesn't, assume its in the system.pvfs2. namespace, and tack
+ * on that prefix (using the PINT_eattr_add_pvfs_prefix function).
+ */
+static struct PINT_eattr_check PINT_eattr_list[] =
+{
+    {"system.", 0, NULL},
+    {"user.", 0, NULL},
+    {"trusted.", 0, NULL},
+    {"security.", 0, NULL},
+    {NULL, 0, PINT_eattr_add_pvfs_prefix}
+};
+
+/* PINT_eattr_verify
+ *
+ * Useful as a basic function that does verification given an array of
+ * extended attribute checking structures.  It essentially iterates
+ * through the array and compares the key's buffer with each element.
+ * If one matches, it uses the other fields in that checking structure
+ * to verify the eattr.
+ */
+static inline int PINT_eattr_verify(
+    struct PINT_eattr_check * eattr_array,
+    PVFS_ds_keyval *key, PVFS_ds_keyval *val);
+
+int PINT_eattr_check_access(PVFS_ds_keyval *key, PVFS_ds_keyval *val)
+{
+    return PINT_eattr_verify(PINT_eattr_access, key, val);
+}
+
+static int PINT_eattr_strip_prefix(PVFS_ds_keyval *key, PVFS_ds_keyval *val)
+{
+    char * tmp_buffer = NULL;
+    int tmp_len;
+    int ret;
+
+    tmp_buffer = (char*)malloc(PVFS_REQ_LIMIT_KEY_LEN);
+    if(!tmp_buffer)
+    {
+        return -PVFS_ENOMEM;
+    }
+
+    /* look for keys in the special "system.pvfs2." prefix and strip the
+     * prefix off; they are stored as keyvals with no prefix within
+     * trove.
+     */
+    ret = sscanf(key->buffer,
+                 PVFS_EATTR_NS_SYSTEM_PVFS2 "%s", tmp_buffer);
+    if(ret != 1)
+    {
+        free(tmp_buffer);
+        return -PVFS_ENOENT;
+    }
+
+    tmp_len = strlen(tmp_buffer) + 1;
+    memcpy(key->buffer, tmp_buffer, tmp_len);
+    key->buffer_sz = tmp_len;
+    free(tmp_buffer);
+    return 0;
+}
+
+static inline int PINT_eattr_verify(
+    struct PINT_eattr_check * eattr_array,
+    PVFS_ds_keyval *key, PVFS_ds_keyval *val)
+{
+    int i = 0;
+    while(1)
+    {
+        /* if we get to the NULL ns at the end of the list, return
+         * the error code
+         */
+        if(!eattr_array[i].ns)
+        {
+            if(eattr_array[i].ret == 0 && eattr_array[i].check)
+            {
+                return eattr_array[i].check(key, val);
+            }
+            return eattr_array[i].ret;
+        }
+
+        if(strncmp(eattr_array[i].ns, key->buffer,
+            strlen(eattr_array[i].ns)) == 0)
+        {
+            /* if the return value for this namespace is non-zero,
+             * return that value
+             */
+            if(eattr_array[i].ret != 0)
+            {
+                return eattr_array[i].ret;
+            }
+
+            /* if the checking function for this namespace is non-null,
+             * invoke that checking function and return the result.
+             */
+            if(eattr_array[i].check)
+            {
+                return eattr_array[i].check(key, val);
+            }
+
+            /* looks like the namespace is otherwise acceptable */
+            return 0;
+        }
+        i++;
+    }
+
+    /* this shouldn't be possible */
+    return(0);
+}
+
+int PINT_eattr_system_verify(PVFS_ds_keyval *k, PVFS_ds_keyval *v)
+{
+    return PINT_eattr_verify(PINT_eattr_system, k, v);
+}
+
+int PINT_eattr_namespace_verify(PVFS_ds_keyval *k, PVFS_ds_keyval *v)
+{
+    return PINT_eattr_verify(PINT_eattr_namespaces, k, v);
+}
+
+static int PINT_eattr_verify_acl_access(PVFS_ds_keyval *key, PVFS_ds_keyval *val)
+{
+
+    assert(!strcmp(key->buffer, "system.posix_acl_access"));
+
+    /* verify that the acl is formatted properly.  Right now
+     * all we can do is make sure the size matches a non-zero
+     * number of pvfs acl entries.  The remainder should be 1
+     * because the keyvals are padded with a null terminator
+     */
+    if(val->buffer_sz == 0 || 
+       val->buffer_sz % sizeof(pvfs2_acl_entry) != 1)
+    {
+        return -PVFS_EINVAL;
+    }
+
+    return 0;
+}
+
+int PINT_eattr_list_access(PVFS_ds_keyval *key, PVFS_ds_keyval *val)
+{
+    return PINT_eattr_verify(PINT_eattr_list, key, val);
+}
+
+/* PINT_eattr_add_pvfs_prefix
+ *
+ * Tack on the system.pvfs2. prefix to any eattrs that don't have it.
+ * This is used by the eattr list operation for pvfs specific attributes,
+ * such as 'dh' (datafile handles) or 'md' (metafile distribution).
+ */
+static int PINT_eattr_add_pvfs_prefix(PVFS_ds_keyval *key, PVFS_ds_keyval *val)
+{
+    char * tmp_buffer = NULL;
+    int ret;
+
+    if(key->buffer_sz < (key->read_sz + sizeof(PVFS_EATTR_NS_SYSTEM_PVFS2)))
+    {
+        return -PVFS_EMSGSIZE;
+    }
+
+    tmp_buffer = (char*)malloc(key->read_sz + sizeof(PVFS_EATTR_NS_SYSTEM_PVFS2));
+    if(!tmp_buffer)
+    {
+        return -PVFS_ENOMEM;
+    }
+
+    ret = sprintf(tmp_buffer, "%s%.*s",
+                  PVFS_EATTR_NS_SYSTEM_PVFS2, key->read_sz, (char *)key->buffer);
+    memcpy(key->buffer, tmp_buffer, ret+1);
+    key->read_sz = ret+1;
+
+    free(tmp_buffer);
+    return 0;
+}
+
+/*
+ * Local variables:
+ *  mode: c
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ *
+ * vim: ft=c ts=8 sts=4 sw=4 expandtab
+ */
Index: src/server/pint-eattr.h
===================================================================
RCS file: src/server/pint-eattr.h
diff -N src/server/pint-eattr.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/server/pint-eattr.h	28 Mar 2007 21:25:16 -0000
@@ -0,0 +1,41 @@
+/* 
+ * (C) 2001 Clemson University and The University of Chicago 
+ *
+ * See COPYING in top-level directory.
+ */
+
+/* Extended Attributes
+ *
+ * These functions provide checking of extended attributes formats
+ * and namespaces
+ */
+
+/* PINT_eattr_list_verify
+ *
+ * Verify the extended attribute using the check access structure array
+ */
+int PINT_eattr_list_access(PVFS_ds_keyval *key, PVFS_ds_keyval *val);
+
+/* PINT_eattr_check_access
+ *
+ * Check that a request extended attribute is correctly formatted and
+ * within a valid namespace
+ */
+int PINT_eattr_check_access(PVFS_ds_keyval *key, PVFS_ds_keyval *val);
+
+/* PINT_eattr_namespace_verify
+ *
+ * Checks that the eattr has a valid namespace that PVFS accepts
+ */
+int PINT_eattr_namespace_verify(PVFS_ds_keyval *k, PVFS_ds_keyval *v);
+
+/*
+ * Local variables:
+ *  mode: c
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ *
+ * vim: ft=c ts=8 sts=4 sw=4 expandtab
+ */
+
Index: src/server/pvfs2-server.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/server/pvfs2-server.c,v
retrieving revision 1.234
diff -u -a -p -r1.234 pvfs2-server.c
--- src/server/pvfs2-server.c	12 Mar 2007 22:20:29 -0000	1.234
+++ src/server/pvfs2-server.c	28 Mar 2007 21:25:16 -0000
@@ -123,16 +123,6 @@ PINT_server_trove_keys_s Trove_Common_Ke
     {SYMLINK_TARGET_KEYSTR, SYMLINK_TARGET_KEYLEN}
 };
 
-/* extended attribute name spaces supported in PVFS2 */
-const char *PINT_eattr_namespaces[] =
-{
-    "system.",
-    "user.",
-    "trusted.",
-    "security.",
-    NULL
-};
-
 /* These three are used continuously in our wait loop.  They could be
  * relatively large, so rather than allocate them on the stack, we'll
  * make them dynamically allocated globals.
Index: src/server/pvfs2-server.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/server/pvfs2-server.h,v
retrieving revision 1.145
diff -u -a -p -r1.145 pvfs2-server.h
--- src/server/pvfs2-server.h	21 Mar 2007 15:35:22 -0000	1.145
+++ src/server/pvfs2-server.h	28 Mar 2007 21:25:16 -0000
@@ -104,29 +104,6 @@ extern struct PINT_server_req_params PIN
 
 const char* PINT_map_server_op_to_string(enum PVFS_server_op op);
 
-extern const char *PINT_eattr_namespaces[];
-/* PINT_eattr_is_prefixed()
- *
- * This function will check to see if a given xattr key falls into the set of
- * name spaces that PVFS2 supports
- *
- * returns 1 if the prefix is supported, 0 otherwise
- */
-static inline int PINT_eattr_is_prefixed(char* key_name)
-{
-    int i = 0;
-    while(PINT_eattr_namespaces[i])
-    {
-        if(strncmp(PINT_eattr_namespaces[i], key_name,
-            strlen(PINT_eattr_namespaces[i])) == 0)
-        {
-            return(1);
-        }
-        i++;
-    }
-    return(0);
-}
-
 /* used to keep a random, but handy, list of keys around */
 typedef struct PINT_server_trove_keys
 {
Index: src/server/set-eattr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/server/set-eattr.sm,v
retrieving revision 1.14
diff -u -a -p -r1.14 set-eattr.sm
--- src/server/set-eattr.sm	17 Feb 2007 21:16:48 -0000	1.14
+++ src/server/set-eattr.sm	28 Mar 2007 21:25:16 -0000
@@ -13,6 +13,7 @@
 #include "pvfs2-internal.h"
 #include "pvfs2-util.h"
 #include "pint-util.h"
+#include "pint-eattr.h"
 
 static int seteattr_verify_eattribs(
     PINT_server_op *s_op, job_status_s *js_p);
@@ -68,11 +69,8 @@ static int seteattr_verify_eattribs(
     PINT_server_op *s_op, job_status_s *js_p)
 {
     PVFS_object_attr *a_p = NULL;
-    int i;
-    char reserved_prefix[] = "system.pvfs2.";
-    int reserved_prefix_len = strlen("system.pvfs2.");
-
     a_p = &s_op->attr;
+    int i;
 
     js_p->error_code = 0;
 
@@ -86,25 +84,15 @@ static int seteattr_verify_eattribs(
     /* iterate through the keys that are being written */
     for (i = 0; i < s_op->req->u.seteattr.nkey; i++)
     {
-        /* make sure that they all fall into a supported name space */
-        if(!PINT_eattr_is_prefixed(s_op->req->u.seteattr.key[i].buffer))
-        {
-            /* emulating return code seen on ext3 */
-            js_p->error_code = -PVFS_EOPNOTSUPP;
-            return 1;
-        }
-
-        /* don't allow anyone to set things in the system.pvfs2 name space */
-        if(strncmp(s_op->req->u.seteattr.key[i].buffer, reserved_prefix,
-            reserved_prefix_len) == 0)
+        js_p->error_code = PINT_eattr_namespace_verify(
+            &s_op->req->u.seteattr.key[i],
+            &s_op->req->u.seteattr.val[i]);
+        if(!js_p->error_code)
         {
-            /* what error code make sense here? */
-            js_p->error_code = -PVFS_EINVAL;
             return 1;
         }
     }
 
-    js_p->error_code = 0;
     return 1;
 }
 
Index: test/automated/tacl_xattr.sh
===================================================================
RCS file: /projects/cvsroot/pvfs2/test/automated/tacl_xattr.sh,v
retrieving revision 1.2
diff -u -a -p -r1.2 tacl_xattr.sh
--- test/automated/tacl_xattr.sh	11 Sep 2006 15:42:42 -0000	1.2
+++ test/automated/tacl_xattr.sh	28 Mar 2007 21:25:16 -0000
@@ -90,16 +90,16 @@ fi
 cd $DIR/tacl
 CUR_PATH=`pwd`
 
-/usr/sbin/adduser -d $CUR_PATH/tacluser1 tacluser1
+/usr/sbin/useradd -d $CUR_PATH/tacluser1 tacluser1
 mkdir -p $CUR_PATH/tacluser1
 chown tacluser1 $CUR_PATH/tacluser1
-/usr/sbin/adduser -d $CUR_PATH/tacluser2 tacluser2
+/usr/sbin/useradd -d $CUR_PATH/tacluser2 tacluser2
 mkdir -p $CUR_PATH/tacluser2
 chown tacluser2 $CUR_PATH/tacluser2
-/usr/sbin/adduser -d $CUR_PATH/tacluser3 tacluser3
+/usr/sbin/useradd -d $CUR_PATH/tacluser3 tacluser3
 mkdir -p $CUR_PATH/tacluser3
 chown tacluser3 $CUR_PATH/tacluser3
-/usr/sbin/adduser -d $CUR_PATH/tacluser4 tacluser4
+/usr/sbin/useradd -d $CUR_PATH/tacluser4 tacluser4
 mkdir -p $CUR_PATH/tacluser4
 chown tacluser4 $CUR_PATH/tacluser4
 
@@ -287,7 +287,6 @@ su - tacluser3 << TACL_USER3
 	fi
 
 TACL_USER3
-
 
 setfacl -m mask:--- shared/team1
 
