[Pvfs2-cvs] commit by aching in pvfs2-1/src/server: check.c check.h list-attr.sm pvfs2-server-req.c unexpected.sm chdirent.sm crdirent.sm create.sm del-eattr.sm event-mon.sm final-response.sm flush.sm get-attr.sm get-config.sm get-eattr.sm io.sm iterate-handles.sm job-timer.sm list-eattr.sm lock.sm lookup.sm mgmt-get-dirdata-handle.sm mgmt-remove-dirent.sm mgmt-remove-object.sm mkdir.sm module.mk.in noop.sm perf-mon.sm perf-update.sm prelude.sm proto-error.sm pvfs2-server.c pvfs2-server.h readdir.sm remove.sm rmdirent.sm set-attr.sm set-eattr.sm setparam.sm small-io.sm statfs.sm truncate.sm

CVS commit program cvs at parl.clemson.edu
Mon Jul 21 14:18:15 EDT 2008


Update of /projects/cvsroot/pvfs2-1/src/server
In directory parlweb1:/tmp/cvs-serv19597

Modified Files:
      Tag: locking-branch
	chdirent.sm crdirent.sm create.sm del-eattr.sm event-mon.sm 
	final-response.sm flush.sm get-attr.sm get-config.sm 
	get-eattr.sm io.sm iterate-handles.sm job-timer.sm 
	list-eattr.sm lock.sm lookup.sm mgmt-get-dirdata-handle.sm 
	mgmt-remove-dirent.sm mgmt-remove-object.sm mkdir.sm 
	module.mk.in noop.sm perf-mon.sm perf-update.sm prelude.sm 
	proto-error.sm pvfs2-server.c pvfs2-server.h readdir.sm 
	remove.sm rmdirent.sm set-attr.sm set-eattr.sm setparam.sm 
	small-io.sm statfs.sm truncate.sm 
Added Files:
      Tag: locking-branch
	check.c check.h list-attr.sm pvfs2-server-req.c unexpected.sm 
Log Message:

Reverse merged and ported to HEAD.


--- /dev/null	2004-06-24 14:04:38.000000000 -0400
+++ check.c	2008-07-21 14:18:15.000000000 -0400
@@ -0,0 +1,445 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * Changes by Acxiom Corporation to add PINT_check_mode() helper function
+ * as a replacement for check_mode() in permission checking, also added
+ * PINT_check_group() for supplimental group support 
+ * Copyright © Acxiom Corporation, 2005.
+ *
+ * See COPYING in top-level directory.
+ */
+
+/*
+ * Server-specific utility functions, to check modes and ACLs.
+ */
+#include <string.h>
+#include <assert.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "pvfs2-debug.h"
+#include "gen-locks.h"
+#include "gossip.h"
+#include "bmi-byteswap.h"
+#include "check.h"
+
+static gen_mutex_t check_group_mutex = GEN_MUTEX_INITIALIZER;
+static char* check_group_pw_buffer = NULL;
+static long check_group_pw_buffer_size = 0;
+static char* check_group_gr_buffer = NULL;
+static long check_group_gr_buffer_size = 0;
+static int PINT_check_group(uid_t uid, gid_t gid);
+
+/* PINT_check_mode()
+ *
+ * checks to see if the type of access described by "access_type" is permitted 
+ * for user "uid" of group "gid" on the object with attributes "attr"
+ *
+ * returns 0 on success, -PVFS_EACCES if permission is not granted
+ */
+int PINT_check_mode(
+    PVFS_object_attr *attr,
+    PVFS_uid uid, PVFS_gid gid,
+    enum PINT_access_type access_type)
+{
+    int in_group_flag = 0;
+    int ret = 0;
+
+    /* if we don't have masks for the permission information that we
+     * need, then the system is broken
+     */
+    assert(attr->mask & PVFS_ATTR_COMMON_UID &&
+           attr->mask & PVFS_ATTR_COMMON_GID &&
+           attr->mask & PVFS_ATTR_COMMON_PERM);
+
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - check_mode called --- "
+                 "(uid=%d,gid=%d,access_type=%d)\n", uid, gid, access_type);
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - object attributes --- "
+                 "(uid=%d,gid=%d,mode=%d)\n", attr->owner, attr->group,
+                 attr->perms);
+
+    /* give root permission, no matter what */
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG,
+                 " - checking if uid (%d) is root ...\n", uid);
+    if (uid == 0)
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        return 0;
+    }
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+
+    /* see if uid matches object owner */
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if owner (%d) "
+        "matches uid (%d)...\n", attr->owner, uid);
+    if(attr->owner == uid)
+    {
+        /* see if object user permissions match access type */
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
+            "(%d) allows access type (%d) for user...\n", attr->perms, access_type);
+        if(access_type == PINT_ACCESS_READABLE && (attr->perms &
+            PVFS_U_READ))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
+            PVFS_U_WRITE))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
+            PVFS_U_EXECUTE))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+    }
+    else
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+    }
+
+    /* see if other bits allow access */
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
+        "(%d) allows access type (%d) by others...\n", attr->perms, access_type);
+    if(access_type == PINT_ACCESS_READABLE && (attr->perms &
+        PVFS_O_READ))
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        return(0);
+    }
+    if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
+        PVFS_O_WRITE))
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        return(0);
+    }
+    if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
+        PVFS_O_EXECUTE))
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        return(0);
+    }
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+
+    /* see if gid matches object group */
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if group (%d) "
+        "matches gid (%d)...\n", attr->group, gid);
+    if(attr->group == gid)
+    {
+        /* default group match */
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+        in_group_flag = 1;
+    }
+    else
+    {
+        /* no default group match, check supplementary groups */
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking for"
+            " supplementary group match...\n");
+        ret = PINT_check_group(uid, attr->group);
+        if(ret == 0)
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            in_group_flag = 1;
+        }
+        else
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+            if(ret != -PVFS_ENOENT)
+            {
+                /* system error; not just failed match */
+                return(ret);
+            }
+        }
+    }
+
+    if(in_group_flag)
+    {
+        /* see if object group permissions match access type */
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - checking if permissions "
+            "(%d) allows access type (%d) for group...\n", attr->perms, access_type);
+        if(access_type == PINT_ACCESS_READABLE && (attr->perms &
+            PVFS_G_READ))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        if(access_type == PINT_ACCESS_WRITABLE && (attr->perms &
+            PVFS_G_WRITE))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        if(access_type == PINT_ACCESS_EXECUTABLE && (attr->perms &
+            PVFS_G_EXECUTE))
+        {
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - yes\n");
+            return(0);
+        }
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, " - no\n");
+    }
+  
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "******PINT_check_mode: denying access\n");
+    /* default case: access denied */
+    return -PVFS_EACCES;
+}
+
+/* PINT_check_group()
+ *
+ * checks to see if uid is a member of gid
+ * 
+ * returns 0 on success, -PVFS_ENOENT if not a member, other PVFS error codes
+ * on system failure
+ */
+static int PINT_check_group(uid_t uid, gid_t gid)
+{
+    struct passwd pwd;
+    struct passwd* pwd_p = NULL;
+    struct group grp;
+    struct group* grp_p = NULL;
+    int i = 0;
+    int ret = -1;
+
+    /* Explanation: 
+     *
+     * We use the _r variants of getpwuid and getgrgid in order to insure
+     * thread safety; particularly if this function ever gets called in a
+     * client side situation in which we can't prevent the application from
+     * making conflicting calls.
+     *
+     * These _r functions require that a buffer be supplied for the user and
+     * group information, however.  These buffers may be unconfortably large
+     * for the stack, so we malloc them on a static pointer and then mutex
+     * lock this function so that it can still be reentrant.
+     */
+
+    gen_mutex_lock(&check_group_mutex);
+
+    if(!check_group_pw_buffer)
+    {
+        /* need to create a buffer for pw and grp entries */
+#if defined(_SC_GETGR_R_SIZE_MAX) && defined(_SC_GETPW_R_SIZE_MAX)
+        /* newish posix systems can tell us what the max buffer size is */
+        check_group_gr_buffer_size = sysconf(_SC_GETGR_R_SIZE_MAX);
+        check_group_pw_buffer_size = sysconf(_SC_GETPW_R_SIZE_MAX);
+#else
+        /* fall back for older systems */
+        check_group_pw_buffer_size = 1024;
+        check_group_gr_buffer_size = 1024;
+#endif
+        check_group_pw_buffer = (char*)malloc(check_group_pw_buffer_size);
+        check_group_gr_buffer = (char*)malloc(check_group_gr_buffer_size);
+        if(!check_group_pw_buffer || !check_group_gr_buffer)
+        {
+            if(check_group_pw_buffer)
+            {
+                free(check_group_pw_buffer);
+                check_group_pw_buffer = NULL;
+            }
+            if(check_group_gr_buffer)
+            {
+                free(check_group_gr_buffer);
+                check_group_gr_buffer = NULL;
+            }
+            gen_mutex_unlock(&check_group_mutex);
+            return(-PVFS_ENOMEM);
+        }
+    }
+
+    /* get user information */
+    ret = getpwuid_r(uid, &pwd, check_group_pw_buffer,
+        check_group_pw_buffer_size,
+        &pwd_p);
+    if(ret != 0 || pwd_p == NULL)
+    {
+        gen_mutex_unlock(&check_group_mutex);
+        return(-PVFS_EINVAL);
+    }
+
+    /* check primary group */
+    if(pwd.pw_gid == gid)
+    {
+        gen_mutex_unlock(&check_group_mutex);
+        return 0;
+    }
+
+    /* get other group information */
+    ret = getgrgid_r(gid, &grp, check_group_gr_buffer,
+        check_group_gr_buffer_size,
+        &grp_p);
+    if(ret != 0)
+    {
+        gen_mutex_unlock(&check_group_mutex);
+        return(-PVFS_EINVAL);
+    }
+
+    if(grp_p == NULL)
+    { 
+	gen_mutex_unlock(&check_group_mutex);
+	gossip_err("User (uid=%d) isn't in group %d on storage node.\n",
+		   uid, gid);
+        return(-PVFS_EACCES);
+    }
+
+    for(i = 0; grp.gr_mem[i] != NULL; i++)
+    {
+        if(0 == strcmp(pwd.pw_name, grp.gr_mem[i]) )
+        {
+            gen_mutex_unlock(&check_group_mutex);
+            return 0;
+        } 
+    }
+
+    gen_mutex_unlock(&check_group_mutex);
+    return(-PVFS_ENOENT);
+}
+
+/* Checks if a given user is part of any groups that matches the file gid */
+static int in_group_p(PVFS_uid uid, PVFS_gid gid, PVFS_gid attr_group)
+{
+    if (attr_group == gid)
+        return 1;
+    if (PINT_check_group(uid, attr_group) == 0)
+        return 1;
+    return 0;
+}
+
+/*
+ * Return 0 if requesting clients is granted want access to the object
+ * by the acl. Returns -PVFS_E... otherwise.
+ */
+int PINT_check_acls(void *acl_buf, size_t acl_size, 
+    PVFS_object_attr *attr,
+    PVFS_uid uid, PVFS_gid gid, int want)
+{
+    pvfs2_acl_entry pe, *pa;
+    int i = 0, found = 0, count = 0;
+    assert(attr->mask & PVFS_ATTR_COMMON_UID &&
+           attr->mask & PVFS_ATTR_COMMON_GID &&
+           attr->mask & PVFS_ATTR_COMMON_PERM);
+
+    if (acl_size == 0)
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "no acl's present.. denying access\n");
+        return -PVFS_EACCES;
+    }
+
+    /* keyval for ACLs includes a \0. so subtract the thingie */
+    acl_size--;
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "PINT_check_acls: read keyval size "
+    " %d (%d acl entries)\n",
+        (int) acl_size, 
+        (int) (acl_size / sizeof(pvfs2_acl_entry)));
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "uid = %d, gid = %d, want = %d\n",
+        uid, gid, want);
+
+    assert(acl_buf);
+    /* if the acl format doesn't look valid, then return an error rather than
+     * asserting; we don't want the server to crash due to an invalid keyval
+     */
+    if((acl_size % sizeof(pvfs2_acl_entry)) != 0)
+    {
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "invalid acls on object\n");
+        return(-PVFS_EACCES);
+    }
+    count = acl_size / sizeof(pvfs2_acl_entry);
+
+    for (i = 0; i < count; i++)
+    {
+        pa = (pvfs2_acl_entry *) acl_buf + i;
+        /* 
+           NOTE: Remember that keyval is encoded as lebf, so convert it 
+           to host representation 
+        */
+        pe.p_tag  = bmitoh32(pa->p_tag);
+        pe.p_perm = bmitoh32(pa->p_perm);
+        pe.p_id   = bmitoh32(pa->p_id);
+        pa = &pe;
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "Decoded ACL entry %d "
+            "(p_tag %d, p_perm %d, p_id %d)\n",
+            i, pa->p_tag, pa->p_perm, pa->p_id);
+        switch(pa->p_tag) 
+        {
+            case PVFS2_ACL_USER_OBJ:
+                /* (May have been checked already) */
+                if (attr->owner == uid)
+                    goto check_perm;
+                break;
+            case PVFS2_ACL_USER:
+                if (pa->p_id == uid)
+                    goto mask;
+                break;
+            case PVFS2_ACL_GROUP_OBJ:
+                if (in_group_p(uid, gid, attr->group)) 
+                {
+                    found = 1;
+                    if ((pa->p_perm & want) == want)
+                        goto mask;
+                }
+                break;
+            case PVFS2_ACL_GROUP:
+                if (in_group_p(uid, gid, pa->p_id)) {
+                    found = 1;
+                    if ((pa->p_perm & want) == want)
+                        goto mask;
+                }
+                break;
+            case PVFS2_ACL_MASK:
+                break;
+            case PVFS2_ACL_OTHER:
+                if (found)
+                {
+                    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(1) PINT_check_acls:"
+                        "returning access denied\n");
+                    return -PVFS_EACCES;
+                }
+                else
+                    goto check_perm;
+            default:
+                gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(2) PINT_check_acls: "
+                        "returning EIO\n");
+                return -PVFS_EIO;
+        }
+    }
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(3) PINT_check_acls: returning EIO\n");
+    return -PVFS_EIO;
+mask:
+    /* search the remaining entries */
+    i = i + 1;
+    for (; i < count; i++)
+    {
+        pvfs2_acl_entry me, *mask_obj = (pvfs2_acl_entry *) acl_buf + i;
+        
+        /* 
+          NOTE: Again, since pvfs2_acl_entry is in lebf, we need to
+          convert it to host endian format
+         */
+        me.p_tag  = bmitoh32(mask_obj->p_tag);
+        me.p_perm = bmitoh32(mask_obj->p_perm);
+        me.p_id   = bmitoh32(mask_obj->p_id);
+        mask_obj = &me;
+        gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "Decoded (mask) ACL entry %d "
+            "(p_tag %d, p_perm %d, p_id %d)\n",
+            i, mask_obj->p_tag, mask_obj->p_perm, mask_obj->p_id);
+        if (mask_obj->p_tag == PVFS2_ACL_MASK) 
+        {
+            if ((pa->p_perm & mask_obj->p_perm & want) == want)
+                return 0;
+            gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(4) PINT_check_acls:"
+                "returning access denied (mask)\n");
+            return -PVFS_EACCES;
+        }
+    }
+
+check_perm:
+    if ((pa->p_perm & want) == want)
+        return 0;
+    gossip_debug(GOSSIP_PERMISSIONS_DEBUG, "(5) PINT_check_acls: returning"
+            "access denied\n");
+    return -PVFS_EACCES;
+}
+

--- /dev/null	2004-06-24 14:04:38.000000000 -0400
+++ check.h	2008-07-21 14:18:15.000000000 -0400
@@ -0,0 +1,25 @@
+
+#ifndef __CHECK_H
+#define __CHECK_H
+
+#include "pvfs2-types.h"
+#include "pvfs2-attr.h"
+
+enum PINT_access_type
+{
+    PINT_ACCESS_EXECUTABLE = 1,
+    PINT_ACCESS_WRITABLE = 2,
+    PINT_ACCESS_READABLE = 4,
+};
+
+int PINT_check_mode(
+    PVFS_object_attr *attr,
+    PVFS_uid uid, PVFS_gid gid,
+    enum PINT_access_type access_type);
+
+int PINT_check_acls(void *acl_buf, size_t acl_size, 
+    PVFS_object_attr *attr,
+    PVFS_uid uid, PVFS_gid gid, int want);
+
+#endif  /* __CHECK_H */
+

--- /dev/null	2004-06-24 14:04:38.000000000 -0400
+++ list-attr.sm	2008-07-21 14:18:15.000000000 -0400
@@ -0,0 +1,304 @@
+/* 
+ * (C) 2001 Clemson University and The University of Chicago 
+ *
+ * See COPYING in top-level directory.
+ *
+ */
+
+/* pvfs2_list_attr_sm
+ *
+ * This state machine handles incoming server listattr operations for a list of handles.  These
+ * are the operations sent by PVFS_sys_readdirplus().
+ *
+ */
+
+#include <string.h>
+#include <assert.h>
+
+#include "server-config.h"
+#include "pvfs2-server.h"
+#include "pvfs2-attr.h"
+#include "pvfs2-types.h"
+#include "pvfs2-types-debug.h"
+#include "pvfs2-util.h"
+#include "pint-util.h"
+#include "pvfs2-internal.h"
+
+%%
+
+
+machine pvfs2_list_attr_sm
+{
+    state prelude
+    {
+        jump pvfs2_prelude_sm;
+        success => read_basic_attrs;
+        default => final_response;
+    }
+
+    state read_basic_attrs
+    {
+        run listattr_read_basic_attrs;
+        success => setup_getattr; 
+        default => final_response;
+    }
+    
+    state setup_getattr
+    {
+        pjmp listattr_setup_getattr
+        {
+            success => pvfs2_get_attr_work_sm;
+        }
+        success => interpret_getattrs;
+        default => final_response;
+    }
+
+    state interpret_getattrs
+    {
+        run listattr_interpret_getattrs;
+        default => final_response;
+    }
+
+    state final_response
+    {
+        jump pvfs2_final_response_sm;
+        default => cleanup;
+    }
+
+    state cleanup
+    {
+        run listattr_cleanup;
+        default => terminate;
+    }
+}
+
+%%
+
+static PINT_sm_action listattr_read_basic_attrs(
+    struct PINT_smcb *smcb, job_status_s *js_p)
+{    
+    int ret;
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+    job_id_t tmp_id;
+
+    s_op->u.listattr.ds_attr_a = (PVFS_ds_attributes *) 
+        calloc(s_op->req->u.listattr.nhandles * sizeof(PVFS_ds_attributes), 1);
+    if (s_op->u.listattr.ds_attr_a == NULL) {
+        js_p->error_code = -PVFS_ENOMEM;
+        return SM_ACTION_COMPLETE;
+    }
+
+    s_op->u.listattr.errors = (PVFS_error *)
+        calloc(s_op->req->u.listattr.nhandles * sizeof(PVFS_error), 1);
+    if (s_op->u.listattr.errors == NULL) {
+        js_p->error_code = -PVFS_ENOMEM;
+        return SM_ACTION_COMPLETE;
+    }
+    s_op->u.listattr.attr_a = (PVFS_object_attr *)
+        calloc(s_op->req->u.listattr.nhandles * sizeof(PVFS_object_attr), 1);
+    if (s_op->u.listattr.attr_a == NULL) {
+        js_p->error_code = -PVFS_ENOMEM;
+        return SM_ACTION_COMPLETE;
+    }
+
+    js_p->error_code = 0;
+    /* initiate retrieval of the attributes from the dspace */
+    ret = job_trove_dspace_getattr_list(
+            s_op->req->u.listattr.fs_id,
+            s_op->req->u.listattr.nhandles,
+            s_op->req->u.listattr.handles,
+            smcb,
+            s_op->u.listattr.errors,
+            s_op->u.listattr.ds_attr_a,
+            0,
+            js_p,
+            &tmp_id,
+            server_job_context);
+
+    return ret;
+}
+
+
+static PINT_sm_action listattr_setup_getattr(
+    struct PINT_smcb *smcb, job_status_s *js_p)
+{    
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+    struct PINT_server_op *getattr_op;
+    int ret;
+    int i;
+
+    s_op->u.listattr.parallel_sms = 0;
+    js_p->error_code = 0;
+
+    for(i=0; i<s_op->req->u.listattr.nhandles; i++)
+    {
+        if(s_op->u.listattr.errors[i])
+        {
+            gossip_debug(GOSSIP_SERVER_DEBUG, 
+                "listattr: dspace_getattr_list failed to get attrs for handle: %llu\n", 
+                llu(s_op->req->u.listattr.handles[i]));
+            /* skip nested machine for this handle */
+            continue;
+        }
+
+        getattr_op = malloc(sizeof(*getattr_op));
+        if(!getattr_op)
+        {
+            s_op->u.listattr.errors[i] = -PVFS_ENOMEM;
+            gossip_debug(GOSSIP_SERVER_DEBUG, 
+                "listattr: failed to setup nested sm for handle: %llu\n", 
+                llu(s_op->req->u.listattr.handles[i]));
+            continue;
+        }
+        memset(getattr_op, 0, sizeof(*getattr_op));
+
+        /* TODO: need a way to explicitly set the right inputs to the
+         * getattr nested sm.  This code block is very fragile.
+         */
+
+        /* need attrs that the prelude would have read normally */
+        PVFS_ds_attr_to_object_attr(&s_op->u.listattr.ds_attr_a[i],
+            &getattr_op->attr);
+        getattr_op->attr.mask = PVFS_ATTR_COMMON_ALL;
+        getattr_op->ds_attr = s_op->u.listattr.ds_attr_a[i];
+        /* need a valid request structure for some generic features like access
+         * logging 
+         */
+        getattr_op->req = s_op->req;
+        /* need to fill in the input parameters to the getattr nested machine */
+        getattr_op->u.getattr.fs_id = s_op->req->u.listattr.fs_id;
+        getattr_op->u.getattr.handle = s_op->req->u.listattr.handles[i];
+        getattr_op->u.getattr.attrmask = s_op->req->u.listattr.attrmask;
+
+        ret = PINT_sm_push_frame(smcb, 0, getattr_op);
+        if(ret < 0)
+        {
+            s_op->u.listattr.errors[i] = -PVFS_ENOMEM;
+            gossip_debug(GOSSIP_SERVER_DEBUG, 
+                "listattr: failed to setup nested sm for handle: %llu\n", 
+                llu(s_op->req->u.listattr.handles[i]));
+            continue;
+        }
+
+        s_op->u.listattr.parallel_sms++;
+    }
+
+    gossip_debug(GOSSIP_SERVER_DEBUG, 
+        "listattr: set up %d parallel nested getattr machines.\n", 
+        s_op->u.listattr.parallel_sms);
+
+    if(s_op->u.listattr.parallel_sms > 0)
+    {
+        js_p->error_code = 0;
+        return SM_ACTION_COMPLETE;
+    }
+    else
+    {
+        /* we didn't kick off any parallel machines.  Pick an error code and
+         * move along...
+         */
+        js_p->error_code = s_op->u.listattr.errors[0];
+        return SM_ACTION_COMPLETE;
+    }
+}
+
+static PINT_sm_action listattr_interpret_getattrs(struct PINT_smcb *smcb, 
+    job_status_s *js_p)
+{    
+    struct PINT_server_op *getattr_op;
+    /* note: this gives us a pointer to the base frame (list_attr), 
+     * _not_ the getattr frames that were previously pushed.
+     */
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+    int task_id;
+    int remaining;
+    PVFS_error tmp_err;
+    int i, j;
+
+    assert(s_op);
+    assert(s_op->op == PVFS_SERV_LISTATTR);
+
+    gossip_debug(GOSSIP_SERVER_DEBUG, 
+        "listattr: trying to interpret results from %d nested parallel getattr machines.\n", 
+        s_op->u.listattr.parallel_sms);
+
+    /* gather results */
+    for(i=0; i<s_op->u.listattr.parallel_sms; i++)
+    {
+        getattr_op = PINT_sm_pop_frame(smcb, &task_id, &tmp_err, 
+            &remaining);
+        gossip_debug(GOSSIP_SERVER_DEBUG, "listattr: nested sm returned error code: %d\n", tmp_err);
+        /* match it up with the correct array entry */
+        for(j=0; j<s_op->req->u.listattr.nhandles; j++)
+        {
+            if(s_op->req->u.listattr.handles[j] == getattr_op->u.getattr.handle)
+            {
+                s_op->u.listattr.attr_a[j] = getattr_op->resp.u.getattr.attr;
+                s_op->u.listattr.errors[j] = tmp_err;
+                free(getattr_op);
+                break;
+            }
+        }
+    }
+
+    /* if we reached this point, then we have a successful ack to send back;
+     * set remaining response fields
+     */
+    s_op->resp.u.listattr.attr = s_op->u.listattr.attr_a;
+    s_op->resp.u.listattr.error = s_op->u.listattr.errors;
+    s_op->resp.u.listattr.nhandles = s_op->req->u.listattr.nhandles;
+
+    js_p->error_code = 0;
+    return SM_ACTION_COMPLETE;
+}
+
+static PINT_sm_action listattr_cleanup(struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    int i;
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+
+    if (s_op->u.listattr.attr_a)
+    {
+        for (i = 0; i < s_op->req->u.listattr.nhandles; i++) 
+        {
+            PINT_free_object_attr(&s_op->u.listattr.attr_a[i]);
+        }
+        free(s_op->u.listattr.attr_a);
+    }
+    if (s_op->u.listattr.ds_attr_a)
+        free(s_op->u.listattr.ds_attr_a);
+    if (s_op->u.listattr.errors)
+        free(s_op->u.listattr.errors);
+
+    return(server_state_machine_complete(smcb));
+}
+
+
+static inline int PINT_get_object_ref_listattr(
+    struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
+{
+    *fs_id = req->u.listattr.fs_id;
+    *handle = PVFS_HANDLE_NULL;
+    return 0;
+};
+
+struct PINT_server_req_params pvfs2_list_attr_params =
+{
+    .string_name = "list_attr",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_readonly,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_listattr,
+    .state_machine = &pvfs2_list_attr_sm
+};
+
+/*
+ * Local variables:
+ *  mode: c
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ *
+ * vim: ft=c ts=8 sts=4 sw=4 expandtab
+ */
+

--- /dev/null	2004-06-24 14:04:38.000000000 -0400
+++ pvfs2-server-req.c	2008-07-21 14:18:15.000000000 -0400
@@ -0,0 +1,166 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#include "pvfs2-server.h"
+#include <assert.h>
+
+/* server operation state machines */
+extern struct PINT_server_req_params pvfs2_get_config_params;
+extern struct PINT_server_req_params pvfs2_get_attr_params;
+extern struct PINT_server_req_params pvfs2_list_attr_params;
+extern struct PINT_server_req_params pvfs2_set_attr_params;
+extern struct PINT_server_req_params pvfs2_create_params;
+extern struct PINT_server_req_params pvfs2_crdirent_params;
+extern struct PINT_server_req_params pvfs2_mkdir_params;
+extern struct PINT_server_req_params pvfs2_readdir_params;
+extern struct PINT_server_req_params pvfs2_lookup_params;
+extern struct PINT_server_req_params pvfs2_io_params;
+extern struct PINT_server_req_params pvfs2_small_io_params;
+extern struct PINT_server_req_params pvfs2_remove_params;
+extern struct PINT_server_req_params pvfs2_mgmt_remove_object_params;
+extern struct PINT_server_req_params pvfs2_mgmt_remove_dirent_params;
+extern struct PINT_server_req_params pvfs2_mgmt_get_dirdata_handle_params;
+extern struct PINT_server_req_params pvfs2_rmdirent_params;
+extern struct PINT_server_req_params pvfs2_chdirent_params;
+extern struct PINT_server_req_params pvfs2_flush_params;
+extern struct PINT_server_req_params pvfs2_truncate_params;
+extern struct PINT_server_req_params pvfs2_setparam_params;
+extern struct PINT_server_req_params pvfs2_noop_params;
+extern struct PINT_server_req_params pvfs2_unexpected_params;
+extern struct PINT_server_req_params pvfs2_statfs_params;
+extern struct PINT_server_req_params pvfs2_perf_update_params;
+extern struct PINT_server_req_params pvfs2_job_timer_params;
+extern struct PINT_server_req_params pvfs2_proto_error_params;
+extern struct PINT_server_req_params pvfs2_perf_mon_params;
+extern struct PINT_server_req_params pvfs2_event_mon_params;
+extern struct PINT_server_req_params pvfs2_iterate_handles_params;
+extern struct PINT_server_req_params pvfs2_get_eattr_params;
+extern struct PINT_server_req_params pvfs2_get_eattr_list_params;
+extern struct PINT_server_req_params pvfs2_set_eattr_params;
+extern struct PINT_server_req_params pvfs2_set_eattr_list_params;
+extern struct PINT_server_req_params pvfs2_del_eattr_params;
+extern struct PINT_server_req_params pvfs2_list_eattr_params;
+
+/* table of incoming request types and associated parameters */
+struct PINT_server_req_entry PINT_server_req_table[] =
+{
+    /* 0 */ {PVFS_SERV_INVALID, NULL},
+    /* 1 */ {PVFS_SERV_CREATE, &pvfs2_create_params},
+    /* 2 */ {PVFS_SERV_REMOVE, &pvfs2_remove_params},
+    /* 3 */ {PVFS_SERV_IO, &pvfs2_io_params},
+    /* 4 */ {PVFS_SERV_GETATTR, &pvfs2_get_attr_params},
+    /* 5 */ {PVFS_SERV_SETATTR, &pvfs2_set_attr_params},
+    /* 6 */ {PVFS_SERV_LOOKUP_PATH, &pvfs2_lookup_params},
+    /* 7 */ {PVFS_SERV_CRDIRENT, &pvfs2_crdirent_params},
+    /* 8 */ {PVFS_SERV_RMDIRENT, &pvfs2_rmdirent_params},
+    /* 9 */ {PVFS_SERV_CHDIRENT, &pvfs2_chdirent_params},
+    /* 10 */ {PVFS_SERV_TRUNCATE, &pvfs2_truncate_params},
+    /* 11 */ {PVFS_SERV_MKDIR, &pvfs2_mkdir_params},
+    /* 12 */ {PVFS_SERV_READDIR, &pvfs2_readdir_params},
+    /* 13 */ {PVFS_SERV_GETCONFIG, &pvfs2_get_config_params},
+    /* 14 */ {PVFS_SERV_WRITE_COMPLETION, NULL},
+    /* 15 */ {PVFS_SERV_FLUSH, &pvfs2_flush_params},
+    /* 16 */ {PVFS_SERV_MGMT_SETPARAM, &pvfs2_setparam_params},
+    /* 17 */ {PVFS_SERV_MGMT_NOOP, &pvfs2_noop_params},
+    /* 18 */ {PVFS_SERV_STATFS, &pvfs2_statfs_params},
+    /* 19 */ {PVFS_SERV_PERF_UPDATE, &pvfs2_perf_update_params},
+    /* 20 */ {PVFS_SERV_MGMT_PERF_MON, &pvfs2_perf_mon_params},
+    /* 21 */ {PVFS_SERV_MGMT_ITERATE_HANDLES, &pvfs2_iterate_handles_params},
+    /* 22 */ {PVFS_SERV_MGMT_DSPACE_INFO_LIST, NULL},
+    /* 23 */ {PVFS_SERV_MGMT_EVENT_MON, &pvfs2_event_mon_params},
+    /* 24 */ {PVFS_SERV_MGMT_REMOVE_OBJECT, &pvfs2_mgmt_remove_object_params},
+    /* 25 */ {PVFS_SERV_MGMT_REMOVE_DIRENT, &pvfs2_mgmt_remove_dirent_params},
+    /* 26 */ {PVFS_SERV_MGMT_GET_DIRDATA_HANDLE, &pvfs2_mgmt_get_dirdata_handle_params},
+    /* 27 */ {PVFS_SERV_JOB_TIMER, &pvfs2_job_timer_params},
+    /* 28 */ {PVFS_SERV_PROTO_ERROR, &pvfs2_proto_error_params},
+    /* 29 */ {PVFS_SERV_GETEATTR, &pvfs2_get_eattr_params},
+    /* 30 */ {PVFS_SERV_SETEATTR, &pvfs2_set_eattr_params},
+    /* 31 */ {PVFS_SERV_DELEATTR, &pvfs2_del_eattr_params},
+    /* 32 */ {PVFS_SERV_LISTEATTR, &pvfs2_list_eattr_params},
+    /* 33 */ {PVFS_SERV_SMALL_IO, &pvfs2_small_io_params},
+    /* 34 */ {PVFS_SERV_LISTATTR, &pvfs2_list_attr_params},
+};
+
+#define CHECK_OP(_op_) assert(_op_ == PINT_server_req_table[_op_].op_type)
+
+enum PINT_server_req_access_type PINT_server_req_readonly(
+                                    struct PVFS_server_req *req)
+{
+    return PINT_SERVER_REQ_READONLY;
+}
+
+enum PINT_server_req_access_type PINT_server_req_modify(
+                                    struct PVFS_server_req *req)
+{
+    return PINT_SERVER_REQ_MODIFY;
+}
+
+enum PINT_server_req_permissions
+PINT_server_req_get_perms(struct PVFS_server_req *req)
+{
+    CHECK_OP(req->op);
+    return PINT_server_req_table[req->op].params->perm;
+}
+
+enum PINT_server_req_access_type
+PINT_server_req_get_access_type(struct PVFS_server_req *req)
+{
+    CHECK_OP(req->op);
+
+    if(!PINT_server_req_table[req->op].params->access_type)
+    {
+        return PINT_SERVER_REQ_READONLY;
+    }
+    return PINT_server_req_table[req->op].params->access_type(req);
+}
+
+enum PINT_server_sched_policy
+PINT_server_req_get_sched_policy(struct PVFS_server_req *req)
+{
+    CHECK_OP(req->op);
+    return PINT_server_req_table[req->op].params->sched_policy;
+}
+
+int PINT_server_req_get_object_ref(
+    struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
+{
+    CHECK_OP(req->op);
+
+    if(!PINT_server_req_table[req->op].params->get_object_ref)
+    {
+        *fs_id = 0;
+        *handle = 0;
+        return 0;
+    }
+    else
+    {
+        return PINT_server_req_table[req->op].params->get_object_ref(
+            req, fs_id, handle);
+    }
+}
+
+/*
+ * PINT_map_server_op_to_string()
+ *
+ * provides a string representation of the server operation number
+ *
+ * returns a pointer to a static string (DONT FREE IT) on success,
+ * null on failure
+ */
+const char* PINT_map_server_op_to_string(enum PVFS_server_op op)
+{
+    CHECK_OP(op);
+    return PINT_server_req_table[op].params->string_name;
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */

--- /dev/null	2004-06-24 14:04:38.000000000 -0400
+++ unexpected.sm	2008-07-21 14:18:15.000000000 -0400
@@ -0,0 +1,129 @@
+/* 
+ * (C) 2001 Clemson University and The University of Chicago 
+ *
+ * See COPYING in top-level directory.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "pvfs2-server.h"
+#include "quicklist.h"
+
+%%
+
+machine pvfs2_unexpected_sm
+{
+	state post_unexpected
+	{
+		run unexpected_post;
+		default => map_request;
+	}
+
+	state map_request
+	{
+		run unexpected_map;
+		default => terminate;
+	}
+}
+
+%%
+
+/* unexpected_post()
+ *
+ * Post an unexpected receive
+ */
+static PINT_sm_action unexpected_post(
+        struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    int ret = -PVFS_EINVAL;
+    job_id_t j_id;
+    struct PINT_server_op *s_op =
+            (struct PINT_server_op *)PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+
+    /*
+       TODO: Consider the optimization of enabling immediate
+       completion in this part of the code (see the mailing list
+       thread from Feb. 2003 on pvfs2-internal).
+                                                                                
+       note: unexp_bmi_buff is really a struct that describes an
+       unexpected message (it is an output parameter).
+     */
+    ret = job_bmi_unexp(&s_op->unexp_bmi_buff, smcb, 0,
+                        js_p, &j_id, JOB_NO_IMMED_COMPLETE,
+                        server_job_context);
+    if(ret == SM_ACTION_COMPLETE)
+    {
+        PVFS_perror_gossip("Error: job_bmi_unexp failure", ret);
+        return SM_ACTION_TERMINATE;
+    }
+    return SM_ACTION_DEFERRED;
+}
+
+/* unexpected_map()
+ *
+ * Change the state machine OP to that of the received request
+ * This instance will continue execution in another state machine
+ * Set up another unexpected receive
+ */
+static PINT_sm_action unexpected_map(
+        struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    int ret = 0;
+    PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+
+    /* Remove s_op from posted_sop_list */
+    qlist_del(&s_op->next);
+    /* If op was cancelled, kill the SM */
+    if (s_op->op_cancelled)
+    {
+        /* is there a reason to do any cleanup? */
+        return SM_ACTION_TERMINATE;
+    }
+    /* Else move it to the inprogress_sop_list */
+    qlist_add_tail(&s_op->next, &inprogress_sop_list);
+
+    /* start replacement unexpected recv */
+    ret = server_post_unexpected_recv(js_p);
+    if (ret < 0)
+    {
+        /* TODO: do something here, the return value was
+         * not being checked for failure before.  I just
+         * put something here to make it exit for the
+         * moment.  -Phil
+         */
+        gossip_lerr("Error: post unexpected failure when restarting.\n");
+    }
+
+    /* Bump up the reference count on the bmi address that we are using */
+    BMI_set_info(s_op->unexp_bmi_buff.addr, BMI_INC_ADDR_REF, NULL);
+
+    /* restart as new request state machine */
+    memset(js_p, 0, sizeof(job_status_s));
+    ret = server_state_machine_start(smcb, js_p);
+    if (ret < 0)
+    {
+        PVFS_perror_gossip("Error: server_state_machine_start", ret);
+        /* TODO: tell BMI to drop this address? */
+        /* set return code to let this SM end
+         */
+        ret = SM_ACTION_TERMINATE;
+    }
+
+    return ret;
+}
+
+
+/*
+ * Local variables:
+ *  mode: c
+ *  c-indent-level: 4
+ *  c-basic-offset: 4
+ * End:
+ *
+ * vim: ft=c ts=8 sts=4 sw=4 expandtab
+ */
+

Index: chdirent.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/chdirent.sm,v
diff -p -u -r1.14 -r1.14.12.1
--- chdirent.sm	9 Aug 2006 04:43:51 -0000	1.14
+++ chdirent.sm	21 Jul 2008 18:18:14 -0000	1.14.12.1
@@ -19,41 +19,9 @@ enum
     UPDATE_DIR_ATTR_REQUIRED = 135
 };
 
-static int chdirent_verify_parent_metadata_and_read_directory_entry_handle(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int chdirent_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int chdirent_change_directory_entry(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int chdirent_check_for_req_dir_update(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int chdirent_update_directory_attr(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int chdirent_read_directory_entry(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int chdirent_read_directory_entry_failure(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int chdirent_change_directory_entry_failure(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int chdirent_setup_resp(
-    PINT_server_op *s_op, job_status_s* js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_chdirent_sm(
-    prelude,
-    verify_parent_metadata_and_read_directory_entry_handle,
-    read_directory_entry,
-    read_directory_entry_failure,
-    change_directory_entry,
-    change_directory_entry_failure,
-    check_for_req_dir_update,
-    update_directory_attr,
-    setup_resp,
-    final_response,
-    cleanup)
+machine pvfs2_chdirent_sm
 {
     state prelude
     {
@@ -129,9 +97,10 @@ machine pvfs2_chdirent_sm(
 
 %%
 
-static int chdirent_verify_parent_metadata_and_read_directory_entry_handle(
-    PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action chdirent_verify_parent_metadata_and_read_directory_entry_handle(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -146,7 +115,7 @@ static int chdirent_verify_parent_metada
         "  reading dirdata handle (coll_id = 0x%x, handle = %llu, "
         "key = %s (%d), val_buf = %p (%d))\n",
         s_op->req->u.chdirent.fs_id,
-        llu(s_op->req->u.chdirent.parent_handle),
+        llu(s_op->req->u.chdirent.handle),
         (char *) s_op->key.buffer,
         s_op->key.buffer_sz,
         s_op->val.buffer,
@@ -154,12 +123,12 @@ static int chdirent_verify_parent_metada
 
     ret = job_trove_keyval_read(
         s_op->req->u.chdirent.fs_id,
-        s_op->req->u.chdirent.parent_handle,
+        s_op->req->u.chdirent.handle,
         &s_op->key,
         &s_op->val,
         0,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &i,
@@ -168,9 +137,10 @@ static int chdirent_verify_parent_metada
     return ret;
 }
 
-static int chdirent_read_directory_entry(PINT_server_op *s_op,
-					 job_status_s* js_p)
+static PINT_sm_action chdirent_read_directory_entry(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t j_id;
 
@@ -191,7 +161,7 @@ static int chdirent_read_directory_entry
         &s_op->val,
         0,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &j_id,
@@ -200,8 +170,8 @@ static int chdirent_read_directory_entry
     return ret;
 }
 
-static int chdirent_read_directory_entry_failure(PINT_server_op *s_op,
-						 job_status_s *js_p)
+static PINT_sm_action chdirent_read_directory_entry_failure(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     switch (js_p->error_code)
     {
@@ -213,12 +183,13 @@ static int chdirent_read_directory_entry
                        "unexpected error %d\n", js_p->error_code);
 	    break;
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int chdirent_change_directory_entry(PINT_server_op *s_op,
-                                           job_status_s* js_p)
+static PINT_sm_action chdirent_change_directory_entry(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t j_id;
 
@@ -251,26 +222,28 @@ static int chdirent_change_directory_ent
         &s_op->key, &s_op->val, 
         TROVE_SYNC |
         0,
-        NULL, s_op, 0, js_p, &j_id, server_job_context);
+        NULL, smcb, 0, js_p, &j_id, server_job_context);
 
     s_op->u.chdirent.dir_attr_update_required = 1;
     return ret;
 }
 
-static int chdirent_check_for_req_dir_update(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action chdirent_check_for_req_dir_update(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if ((js_p->error_code == 0) &&
         (s_op->u.chdirent.dir_attr_update_required))
     {
         js_p->error_code = UPDATE_DIR_ATTR_REQUIRED;
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int chdirent_update_directory_attr(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action chdirent_update_directory_attr(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t j_id;
     PVFS_object_attr tmp_attr, *tmp_attr_ptr = &tmp_attr;
@@ -281,7 +254,7 @@ static int chdirent_update_directory_att
     {
         PVFS_perror_gossip("previous keyval write failed",
                            js_p->error_code);
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     memset(&tmp_attr, 0, sizeof(PVFS_object_attr));
@@ -293,17 +266,17 @@ static int chdirent_update_directory_att
     PVFS_object_attr_to_ds_attr(tmp_attr_ptr, ds_attr);
 
     ret = job_trove_dspace_setattr(
-        s_op->req->u.chdirent.fs_id, s_op->req->u.chdirent.parent_handle,
+        s_op->req->u.chdirent.fs_id, s_op->req->u.chdirent.handle,
         ds_attr, 
         TROVE_SYNC |
         0,
-        s_op, 0, js_p, &j_id, server_job_context);
+        smcb, 0, js_p, &j_id, server_job_context);
 
     return ret;
 }
 
-static int chdirent_change_directory_entry_failure(PINT_server_op *s_op,
-						   job_status_s *js_p)
+static PINT_sm_action chdirent_change_directory_entry_failure(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     assert(js_p->error_code != -TROVE_ENOENT);
 	    
@@ -316,12 +289,13 @@ static int chdirent_change_directory_ent
 	    break;
     }
     gossip_err("unexpected error %d\n", js_p->error_code);
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int chdirent_setup_resp(PINT_server_op *s_op,
-                               job_status_s* js_p)
+static PINT_sm_action chdirent_setup_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if (js_p->error_code == 0)
     {
 	/* return original dirent handle in the response */
@@ -336,14 +310,26 @@ static int chdirent_setup_resp(PINT_serv
     {
 	gossip_debug(GOSSIP_SERVER_DEBUG, "  sending error response\n");
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int chdirent_cleanup(PINT_server_op *s_op,
-                            job_status_s* js_p)
+static PINT_sm_action chdirent_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return (server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(chdirent);
+
+struct PINT_server_req_params pvfs2_chdirent_params =
+{
+    .string_name = "chdirent",
+    .perm = PINT_SERVER_CHECK_WRITE,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_chdirent,
+    .state_machine = &pvfs2_chdirent_sm
+};
 
 /*
  * Local variables:

Index: crdirent.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/crdirent.sm,v
diff -p -u -r1.63 -r1.63.12.1
--- crdirent.sm	9 Aug 2006 04:43:51 -0000	1.63
+++ crdirent.sm	21 Jul 2008 18:18:14 -0000	1.63.12.1
@@ -20,38 +20,9 @@ enum
     UPDATE_DIR_ATTR_REQUIRED
 };
 
-static int crdirent_setup_op(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int crdirent_validate(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int crdirent_read_directory_entry_handle(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int crdirent_write_directory_entry(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int crdirent_check_for_req_dir_update(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int crdirent_update_directory_attr(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int crdirent_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int validation_object_type_failure(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_crdirent_sm(
-    prelude,
-    setup_op,
-    validate,
-    validation_object_type_failure,
-    read_directory_entry_handle,
-    write_directory_entry,
-    check_for_req_dir_update,
-    update_directory_attr,
-    cleanup,
-    final_response)
+machine pvfs2_crdirent_sm
 {
     state prelude
     {
@@ -127,16 +98,17 @@ machine pvfs2_crdirent_sm(
  *
  * Synopsis: verifies that entry name and object type is valid
  */
-static int crdirent_validate(PINT_server_op *s_op,
-                             job_status_s *js_p)
+static PINT_sm_action crdirent_validate(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     char *ptr = NULL;
 
     if ((s_op->u.crdirent.name == NULL) ||
         (s_op->u.crdirent.parent_handle == PVFS_HANDLE_NULL))
     {
         js_p->error_code = -PVFS_EINVAL;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     gossip_debug(GOSSIP_SERVER_DEBUG,
@@ -162,7 +134,7 @@ static int crdirent_validate(PINT_server
 
          /* Do not zero the scheduled_id, as this operation was
           * scheduled before we checked the filename */
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* make sure we're dealing with a directory */
@@ -173,11 +145,11 @@ static int crdirent_validate(PINT_server
                      "a non-directory!  Returning error.\n");
 
         js_p->error_code = INVALID_OBJECT;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     js_p->error_code = 0;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -204,9 +176,10 @@ static int crdirent_validate(PINT_server
  * space and if it does not exist, we need to create it.
  *
  */
-static int crdirent_read_directory_entry_handle(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action crdirent_read_directory_entry_handle(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -225,7 +198,7 @@ static int crdirent_read_directory_entry
         &s_op->val,
         0,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &i,
@@ -234,14 +207,14 @@ static int crdirent_read_directory_entry
     return ret;
 }
 
-static int validation_object_type_failure(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action validation_object_type_failure(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     gossip_debug(GOSSIP_SERVER_DEBUG, "crdirent: validation_object_"
                  "type_failure called\n");
 
     js_p->error_code = -PVFS_ENOTDIR;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -261,9 +234,10 @@ static int validation_object_type_failur
  * Synopsis: We are now ready to store the name/handle pair in the k/v
  *           space for directory handles.
  */
-static int crdirent_write_directory_entry(PINT_server_op *s_op,
-                                          job_status_s *js_p)
+static PINT_sm_action crdirent_write_directory_entry(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
     TROVE_ds_flags keyval_flags;
@@ -305,7 +279,7 @@ static int crdirent_write_directory_entr
         s_op->u.crdirent.fs_id, s_op->u.crdirent.dirent_handle,
         &s_op->key, &s_op->val, 
         keyval_flags,
-        NULL, s_op, 0, js_p, &i, server_job_context);
+        NULL, smcb, 0, js_p, &i, server_job_context);
 
     /*
      * creating an entry will cause directory times to be updated.
@@ -314,20 +288,22 @@ static int crdirent_write_directory_entr
     return ret;
 }
 
-static int crdirent_check_for_req_dir_update(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action crdirent_check_for_req_dir_update(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if ((js_p->error_code == 0) &&
         (s_op->u.crdirent.dir_attr_update_required))
     {
         js_p->error_code = UPDATE_DIR_ATTR_REQUIRED;
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
     
-static int crdirent_update_directory_attr(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action crdirent_update_directory_attr(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t j_id;
     PVFS_object_attr tmp_attr, *tmp_attr_ptr = &tmp_attr;
@@ -338,7 +314,7 @@ static int crdirent_update_directory_att
     {
         PVFS_perror_gossip("previous keyval write failed",
                            js_p->error_code);
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     memset(&tmp_attr, 0, sizeof(PVFS_object_attr));
@@ -350,18 +326,18 @@ static int crdirent_update_directory_att
     PVFS_object_attr_to_ds_attr(tmp_attr_ptr, ds_attr);
 
     ret = job_trove_dspace_setattr(
-        s_op->req->u.crdirent.fs_id, s_op->req->u.crdirent.parent_handle,
+        s_op->req->u.crdirent.fs_id, s_op->req->u.crdirent.handle,
         ds_attr, 
         TROVE_SYNC,
-        s_op, 0, js_p, &j_id, server_job_context);
+        smcb, 0, js_p, &j_id, server_job_context);
 
     return ret;
 }
 
-static int crdirent_cleanup(PINT_server_op *s_op,
-                            job_status_s *js_p)
+static PINT_sm_action crdirent_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
 /* crdirent_setup_op()
@@ -370,21 +346,34 @@ static int crdirent_cleanup(PINT_server_
  * storing request structure fields in state machine so that nested
  * machines are not dependent on request type
  */
-static int crdirent_setup_op(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action crdirent_setup_op(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG, "crdirent entry: %s points to %llu\n",
         s_op->req->u.crdirent.name, llu(s_op->req->u.crdirent.new_handle));
 
     s_op->u.crdirent.name = s_op->req->u.crdirent.name;
     s_op->u.crdirent.new_handle = s_op->req->u.crdirent.new_handle;
-    s_op->u.crdirent.parent_handle = s_op->req->u.crdirent.parent_handle;
+    s_op->u.crdirent.parent_handle = s_op->req->u.crdirent.handle;
     s_op->u.crdirent.fs_id = s_op->req->u.crdirent.fs_id;
     s_op->u.crdirent.dir_attr_update_required = 0;
 
     js_p->error_code = 0;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
+
+PINT_GET_OBJECT_REF_DEFINE(crdirent);
+
+struct PINT_server_req_params pvfs2_crdirent_params =
+{
+    .string_name = "crdirent",
+    .perm = PINT_SERVER_CHECK_CRDIRENT,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_crdirent,
+    .state_machine = &pvfs2_crdirent_sm
+};
 
 /*
  * Local variables:

Index: create.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/create.sm,v
diff -p -u -r1.41 -r1.41.16.1
--- create.sm	13 Jul 2006 05:11:42 -0000	1.41
+++ create.sm	21 Jul 2008 18:18:14 -0000	1.41.16.1
@@ -13,21 +13,9 @@
 #include "gossip.h"
 #include "pvfs2-internal.h"
 
-static int create_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int create_create(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int create_setup_resp(
-    PINT_server_op *s_op, job_status_s* js_p);
-
 %%
 
-machine pvfs2_create_sm(
-    prelude,
-    create,
-    setup_resp,
-    final_response,
-    cleanup)
+machine pvfs2_create_sm
 {
     state prelude
     {
@@ -78,8 +66,10 @@ machine pvfs2_create_sm(
  * Synopsis: Create the new dataspace with the values provided in the response.
  *           
  */
-static int create_create(PINT_server_op *s_op, job_status_s* js_p)
+static int create_create(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t i;
 
@@ -89,7 +79,7 @@ static int create_create(PINT_server_op 
         s_op->req->u.create.object_type,
         NULL,
         TROVE_SYNC ,
-        s_op,
+        smcb,
         0,
         js_p,
         &i,
@@ -102,8 +92,10 @@ static int create_create(PINT_server_op 
  *
  * fills in the response structure based on results of previous operation
  */
-static int create_setup_resp(PINT_server_op *s_op, job_status_s* js_p)
+static int create_setup_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if (js_p->error_code == 0)
     {
 	gossip_debug(GOSSIP_SERVER_DEBUG, "Handle created: %llu\n",
@@ -113,27 +105,27 @@ static int create_setup_resp(PINT_server
         {
             case PVFS_TYPE_NONE:
                 PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG, 
-                    "new handle: %llu, type unknown.\n");
+                    "new handle: %llu, type unknown.\n", llu(js_p->handle));
                 break;
             case PVFS_TYPE_METAFILE:
                 PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG, 
-                    "new handle: %llu, type metafile.\n");
+                    "new handle: %llu, type metafile.\n", llu(js_p->handle));
                 break;
             case PVFS_TYPE_DATAFILE:
                 PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG,    
-                    "new handle: %llu, type datafile.\n");
+                    "new handle: %llu, type datafile.\n", llu(js_p->handle));
                 break;
             case PVFS_TYPE_DIRECTORY:
                 PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG, 
-                    "new handle: %llu, type directory.\n");
+                    "new handle: %llu, type directory.\n", llu(js_p->handle));
                 break;
             case PVFS_TYPE_SYMLINK:
                 PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG,    
-                    "new handle: %llu, type symlink.\n");
+                    "new handle: %llu, type symlink.\n", llu(js_p->handle));
                 break;
             case PVFS_TYPE_DIRDATA:
                 PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG,    
-                    "new handle: %llu, type dirdata.\n");
+                    "new handle: %llu, type dirdata.\n", llu(js_p->handle));
                 break;
         }
     }
@@ -141,7 +133,7 @@ static int create_setup_resp(PINT_server
     /* NOTE: we _deliberately_ leave the error_code unchanged so that it
      * can be used by the next state.
      */
-    return(1);
+    return SM_ACTION_COMPLETE;
 }
 
 
@@ -160,11 +152,28 @@ static int create_setup_resp(PINT_server
  * Synopsis: free memory and return
  *           
  */
-static int create_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static int create_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
+static inline int PINT_get_object_ref_create(
+    struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
+{
+    *fs_id = req->u.create.fs_id;
+    *handle = PVFS_HANDLE_NULL;
+    return 0;
+};
+
+struct PINT_server_req_params pvfs2_create_params =
+{
+    .string_name = "create",
+    .get_object_ref = PINT_get_object_ref_create,
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_modify,
+    .state_machine = &pvfs2_create_sm
+};
 
 /*
  * Local variables:

Index: del-eattr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/del-eattr.sm,v
diff -p -u -r1.8 -r1.8.14.1
--- del-eattr.sm	13 Jul 2006 05:11:42 -0000	1.8
+++ del-eattr.sm	21 Jul 2008 18:18:14 -0000	1.8.14.1
@@ -12,24 +12,11 @@
 #include "pvfs2-attr.h"
 #include "pvfs2-internal.h"
 #include "pvfs2-util.h"
-
-static int deleattr_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int deleattr_delobj_eattribs(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int deleattr_verify_eattribs(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
+#include "pint-util.h"
 
 %%
 
-machine pvfs2_del_eattr_sm(
-    prelude,
-    cleanup,
-    verify_eattribs,
-    delobj_eattrib,
-    final_response)
+machine pvfs2_del_eattr_sm
 {
     state prelude
     {
@@ -73,9 +60,10 @@ machine pvfs2_del_eattr_sm(
  * extended attributes on certain object types if we want.  We might
  * want to prevent access to standard metadata keys.
  */
-static int deleattr_verify_eattribs(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action deleattr_verify_eattribs(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *a_p = NULL;
 
     a_p = &s_op->attr;
@@ -86,7 +74,7 @@ static int deleattr_verify_eattribs(
                  "  ext attr delete from handle %llu refers to a %s\n\t"
                  "[owner = %d, group = %d, perms = %o, type = %d]\n",
                  llu(s_op->req->u.deleattr.handle),
-                 get_object_type(a_p->objtype),
+                 PINT_util_get_object_type(a_p->objtype),
                  a_p->owner, a_p->group, a_p->perms, a_p->objtype);
 
     switch (a_p->objtype)
@@ -136,15 +124,17 @@ static int deleattr_verify_eattribs(
         return -PVFS_EINVAL;
     }
 
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
  * This is where the actual extended attrib gets written.
  * Not much to this, its pretty straight-forward.
  */
-static int deleattr_delobj_eattribs(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action deleattr_delobj_eattribs(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = 0;
     job_id_t j_id;
 
@@ -172,7 +162,7 @@ static int deleattr_delobj_eattribs(PINT
         NULL,
         TROVE_SYNC ,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &j_id,
@@ -192,15 +182,30 @@ static int deleattr_delobj_eattribs(PINT
  * Synopsis: free memory and return
  *           
  */
-static int deleattr_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action deleattr_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op __attribute__((unused)) =
+        PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     gossip_debug(
         GOSSIP_DELEATTR_DEBUG,
         "keybuf %p keylen %d\n",
         s_op->req->u.deleattr.key.buffer, s_op->req->u.deleattr.key.buffer_sz);
 
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(deleattr);
+
+struct PINT_server_req_params pvfs2_del_eattr_params =
+{
+    .string_name = "del_eattr",
+    .perm = PINT_SERVER_CHECK_ATTR,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_deleattr,
+    .state_machine = &pvfs2_del_eattr_sm
+};
 
 /*
  * Local variables:

Index: event-mon.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/event-mon.sm,v
diff -p -u -r1.5 -r1.5.28.1
--- event-mon.sm	5 Jun 2006 19:57:28 -0000	1.5
+++ event-mon.sm	21 Jul 2008 18:18:14 -0000	1.5.28.1
@@ -14,12 +14,9 @@
 #include "pvfs2-server.h"
 #include "pint-event.h"
 
-static int event_mon_cleanup(PINT_server_op *s_op, job_status_s* js_p);
-static int event_mon_do_work(PINT_server_op *s_op, job_status_s* js_p);
-
 %%
 
-machine pvfs2_event_mon_sm(prelude, do_work, final_response, cleanup)
+machine pvfs2_event_mon_sm
 {
 	state prelude
 	{
@@ -53,20 +50,24 @@ machine pvfs2_event_mon_sm(prelude, do_w
  * cleans up any resources consumed by this state machine and ends
  * execution of the machine
  */
-static int event_mon_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action event_mon_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if(s_op->resp.u.mgmt_event_mon.event_array)
 	free(s_op->resp.u.mgmt_event_mon.event_array);
 
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
 /* event_mon_do_work()
  *
  * gathers statistics and builds response
  */
-static int event_mon_do_work(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action event_mon_do_work(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     /* allocate memory to hold events */
     s_op->resp.u.mgmt_event_mon.event_array
 	= (struct PVFS_mgmt_event*)malloc(s_op->req->u.mgmt_event_mon.event_count
@@ -74,7 +75,7 @@ static int event_mon_do_work(PINT_server
     if(!s_op->resp.u.mgmt_event_mon.event_array)
     {
 	js_p->error_code = -PVFS_ENOMEM;
-	return(1);
+	return SM_ACTION_COMPLETE;
     }
 
     s_op->resp.u.mgmt_event_mon.event_count = 
@@ -85,10 +86,15 @@ static int event_mon_do_work(PINT_server
 	s_op->req->u.mgmt_event_mon.event_count);
 
     js_p->error_code = 0;
-    return(1);
+    return SM_ACTION_COMPLETE;
 }
 
-
+struct PINT_server_req_params pvfs2_event_mon_params =
+{
+    .string_name = "mgmt_event_mon",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .state_machine = &pvfs2_event_mon_sm
+};
 
 /*
  * Local variables:

Index: final-response.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/final-response.sm,v
diff -p -u -r1.31.8.1 -r1.31.8.1.2.1
--- final-response.sm	27 Sep 2006 20:39:17 -0000	1.31.8.1
+++ final-response.sm	21 Jul 2008 18:18:14 -0000	1.31.8.1.2.1
@@ -29,22 +29,12 @@
  *   stored in s_op->scheduled_id
  */
 
-static int final_response_release(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int final_response_send_resp(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int final_response_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-
 static void PINT_gossip_err_server_resp(
     struct PVFS_server_resp *resp);
 
 %%
 
-nested machine pvfs2_final_response_sm(
-    release,
-    send_resp,
-    cleanup)
+nested machine pvfs2_final_response_sm
 {
     state release
     {
@@ -71,15 +61,16 @@ nested machine pvfs2_final_response_sm(
  *
  * releases the operation from the request scheduler
  */
-static int final_response_release(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action final_response_release(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t tmp_id;
 
     gossip_debug(GOSSIP_SERVER_DEBUG, 
-                 "(%p) %s (FR sm) state: release: (error_code = %d)\n", s_op,
-                 PINT_map_server_op_to_string(s_op->req->op),
+                 "(s_op %p) %s (FR sm) state: release: (error_code = %d)\n",
+                 s_op, PINT_map_server_op_to_string(s_op->req->op),
                  js_p->error_code);
 
     /* this seems a little odd, but since this is the first state of the
@@ -95,11 +86,11 @@ static int final_response_release(
     if (!s_op->scheduled_id)
     {
         js_p->error_code = 0;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     ret = job_req_sched_release(
-        s_op->scheduled_id, s_op, 0, js_p, &tmp_id, server_job_context);
+        s_op->scheduled_id, smcb, 0, js_p, &tmp_id, server_job_context);
 
     PINT_perf_count(PINT_server_pc, PINT_PERF_REQSCHED, 1, PINT_PERF_SUB);
 
@@ -110,18 +101,18 @@ static int final_response_release(
  *
  * encodes and sends a response to the client
  */
-static int final_response_send_resp(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action final_response_send_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t tmp_id;
     struct server_configuration_s *user_opts = get_server_config_struct();
     
     gossip_debug(
         GOSSIP_SERVER_DEBUG, 
-	"(%p) %s (FR sm) state: send_resp (status = %d)\n",
-	s_op,
-	PINT_map_server_op_to_string(s_op->req->op),
+	"(s_op %p) %s (FR sm) state: send_resp (status = %d)\n",
+	s_op, PINT_map_server_op_to_string(s_op->req->op),
 	s_op->resp.status);
 
     if (js_p->error_code != 0)
@@ -137,14 +128,14 @@ static int final_response_send_resp(
         PINT_gossip_err_server_resp(&s_op->resp);
 
         js_p->error_code = ret;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* send the response */
     ret = job_bmi_send_list(
         s_op->addr, s_op->encoded.buffer_list, s_op->encoded.size_list,
         s_op->encoded.list_count, s_op->encoded.total_size, s_op->tag,
-        s_op->encoded.buffer_type, 0, s_op, 0, js_p, &tmp_id,
+        s_op->encoded.buffer_type, 0, smcb, 0, js_p, &tmp_id,
         server_job_context, user_opts->server_job_bmi_timeout);
 
     return ret;
@@ -156,12 +147,14 @@ static int final_response_send_resp(
  * cleans up resources allocated while in this nested machine.  Right now 
  * that just means releasing the encoding of the response
  */
-static int final_response_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action final_response_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     char status_string[64] = {0};
 
     gossip_debug(GOSSIP_SERVER_DEBUG, 
-                 "(%p) %s (FR sm) state: cleanup\n",
+                 "(s_op %p) %s (FR sm) state: cleanup\n",
                  s_op, PINT_map_server_op_to_string(s_op->req->op));
 
     PVFS_strerror_r(s_op->resp.status, status_string, 64);
@@ -169,54 +162,10 @@ static int final_response_cleanup(PINT_s
 
     PINT_encode_release(&s_op->encoded, PINT_ENCODE_RESP);
 
-    /* decrement reference count for this bmi address */
-    BMI_set_info(s_op->addr, BMI_DEC_ADDR_REF, NULL);
-
     js_p->error_code = 0;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static __req_resp_type_desc_t s_req_resp_type_map[] =
-{
-    { PVFS_SERV_INVALID, "PVFS_SERV_INVALID"},
-    { PVFS_SERV_CREATE, "PVFS_SERV_CREATE" },
-    { PVFS_SERV_REMOVE, "PVFS_SERV_REMOVE" },
-    { PVFS_SERV_IO, "PVFS_SERV_IO" },
-    { PVFS_SERV_GETATTR, "PVFS_SERV_GETATTR" },
-    { PVFS_SERV_SETATTR, "PVFS_SERV_SETATTR" },
-    { PVFS_SERV_LOOKUP_PATH, "PVFS_SERV_LOOKUP_PATH" },
-    { PVFS_SERV_CRDIRENT, "PVFS_SERV_CRDIRENT" },
-    { PVFS_SERV_RMDIRENT, "PVFS_SERV_RMDIRENT" },
-    { PVFS_SERV_CHDIRENT, "PVFS_SERV_CHDIRENT" },
-    { PVFS_SERV_TRUNCATE, "PVFS_SERV_TRUNCATE" },
-    { PVFS_SERV_MKDIR, "PVFS_SERV_MKDIR" },
-    { PVFS_SERV_READDIR, "PVFS_SERV_READDIR" },
-    { PVFS_SERV_GETCONFIG, "PVFS_SERV_GETCONFIG" },
-    { PVFS_SERV_WRITE_COMPLETION, "PVFS_SERV_WRITE_COMPLETION" },
-    { PVFS_SERV_FLUSH, "PVFS_SERV_FLUSH" },
-    { PVFS_SERV_MGMT_SETPARAM, "PVFS_SERV_MGMT_SETPARAM" },
-    { PVFS_SERV_MGMT_NOOP, "PVFS_SERV_MGMT_NOOP" },
-    { PVFS_SERV_STATFS, "PVFS_SERV_STATFS" },
-    { PVFS_SERV_PERF_UPDATE, "PVFS_SERV_PERF_UPDATE" },
-    { PVFS_SERV_MGMT_PERF_MON, "PVFS_SERV_MGMT_PERF_MON" },
-    { PVFS_SERV_MGMT_ITERATE_HANDLES, "PVFS_SERV_MGMT_ITERATE_HANDLES" },
-    { PVFS_SERV_MGMT_DSPACE_INFO_LIST,
-      "PVFS_SERV_MGMT_DSPACE_INFO_LIST" },
-    { PVFS_SERV_MGMT_EVENT_MON, "PVFS_SERV_MGMT_EVENT_MON" },
-    { PVFS_SERV_MGMT_REMOVE_OBJECT, "PVFS_SERV_MGMT_REMOVE_OBJECT" },
-    { PVFS_SERV_MGMT_REMOVE_DIRENT, "PVFS_SERV_MGMT_REMOVE_DIRENT" },
-    { PVFS_SERV_MGMT_GET_DIRDATA_HANDLE,
-      "PVFS_SERV_MGMT_GET_DIRDATA_HANDLE" },
-    { PVFS_SERV_JOB_TIMER, "PVFS_SERV_JOB_TIMER" },
-    { PVFS_SERV_PROTO_ERROR, "PVFS_SERV_PROTO_ERROR" },
-    { PVFS_SERV_GETEATTR, "PVFS_SERV_GETEATTR" },
-    { PVFS_SERV_SETEATTR, "PVFS_SERV_SETEATTR" },
-    { PVFS_SERV_DELEATTR, "PVFS_SERV_DELEATTR" },
-    { PVFS_SERV_LISTEATTR, "PVFS_SERV_LISTEATTR" },
-    { PVFS_SERV_SMALL_IO, "PVFS_SERV_SMALL_IO" },
-    { PVFS_SERV_LOCK, "PVFS_SERV_LOCK" }
-};
-
 static void PINT_gossip_err_server_resp(
     struct PVFS_server_resp *resp)
 {
@@ -225,7 +174,7 @@ static void PINT_gossip_err_server_resp(
         if (resp->op >= 0 && resp->op < PVFS_SERV_NUM_OPS)
         {
             gossip_err("Server Response %p is of type: %s\n",
-                       resp, s_req_resp_type_map[resp->op].type_str);
+                       resp, PINT_map_server_op_to_string(resp->op));
         }
         else
         {

Index: flush.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/flush.sm,v
diff -p -u -r1.19 -r1.19.24.1
--- flush.sm	13 Jul 2006 05:11:42 -0000	1.19
+++ flush.sm	21 Jul 2008 18:18:14 -0000	1.19.24.1
@@ -25,29 +25,11 @@ enum
     FLUSH_BSTREAM = 5
 };
 
-static int flush_check_type(
-    PINT_server_op *s_op, job_status_s * js_p);
-static int flush_keyval_flush(
-    PINT_server_op *s_op, job_status_s * js_p);
-static int flush_bstream_flush(
-    PINT_server_op *s_op, job_status_s * js_p);
-static int flush_cleanup(
-    PINT_server_op *s_op, job_status_s *ret);
-static int flush_check_error(
-    PINT_server_op *s_op, job_status_s *js_p);
 void flush_init_state_machine(void);
 
 %%
 
-machine pvfs2_flush_sm(
-    prelude,
-    flush_check_type,
-    kflush,
-    kflush_check_error,
-    bflush, 
-    bflush_check_error,
-    final_response,
-    cleanup)
+machine pvfs2_flush_sm
 {
     state prelude
     {
@@ -103,8 +85,10 @@ machine pvfs2_flush_sm(
 
 %%
 
-static int flush_check_type(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action flush_check_type(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     js_p->error_code = 0;
 
     if (s_op->attr.objtype == PVFS_TYPE_METAFILE)
@@ -115,7 +99,7 @@ static int flush_check_type(PINT_server_
     {
         js_p->error_code = FLUSH_BSTREAM;
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -131,8 +115,10 @@ static int flush_check_type(PINT_server_
  * Synopsys: send a keyval flush request to storage
  *
  */
-static int flush_keyval_flush(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action flush_keyval_flush(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t tmp_id;
 
@@ -143,7 +129,7 @@ static int flush_keyval_flush(PINT_serve
         s_op->req->u.flush.fs_id,
         s_op->req->u.flush.handle,
         s_op->req->u.flush.flags,
-        s_op,
+        smcb,
         0,
         js_p,
         &tmp_id,
@@ -152,8 +138,10 @@ static int flush_keyval_flush(PINT_serve
     return ret;
 }
 
-static int flush_check_error(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action flush_check_error(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     char buf[64] = {0};
     if (js_p->error_code != 0)
     {
@@ -162,7 +150,7 @@ static int flush_check_error(PINT_server
         gossip_err("failed to flush handle %llu: %s\n",
                    llu(s_op->req->u.flush.handle), buf);
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -178,8 +166,10 @@ static int flush_check_error(PINT_server
  * Synopsys: send a bstream flush request to storage
  *
  */
-static int flush_bstream_flush(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action flush_bstream_flush(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t i;
 
@@ -190,7 +180,7 @@ static int flush_bstream_flush(PINT_serv
         s_op->req->u.flush.fs_id,
         s_op->req->u.flush.handle,
         s_op->req->u.flush.flags,
-        s_op,
+        smcb,
         0,
         js_p,
         &i,
@@ -199,10 +189,23 @@ static int flush_bstream_flush(PINT_serv
     return ret;
 }
 	    
-static int flush_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action flush_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(flush);
+
+struct PINT_server_req_params pvfs2_flush_params =
+{
+    .string_name = "flush",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_flush,
+    .state_machine = &pvfs2_flush_sm
+};
 
 /*
  * Local variables:

Index: get-attr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/get-attr.sm,v
diff -p -u -r1.81 -r1.81.4.1
--- get-attr.sm	11 Sep 2006 15:42:41 -0000	1.81
+++ get-attr.sm	21 Jul 2008 18:18:14 -0000	1.81.4.1
@@ -29,19 +29,12 @@
 #include "pint-util.h"
 #include "pvfs2-internal.h"
 
-enum 
-{
-    DIST_NAME_KEY = 0,
-    DIST_PARAMS_KEY = 1,
-    NUM_DFILES_KEY = 2,
-    NUM_SPECIAL_KEYS = 3,
-};
-
 PINT_server_trove_keys_s Trove_Special_Keys[] =
 {
-    {"user.pvfs2.dist_name", 21},
-    {"user.pvfs2.dist_params", 23},
-    {"user.pvfs2.num_dfiles", 22},
+    {"user.pvfs2.dist_name"  , SPECIAL_DIST_NAME_KEYLEN},
+    {"user.pvfs2.dist_params", SPECIAL_DIST_PARAMS_KEYLEN},
+    {"user.pvfs2.num_dfiles" , SPECIAL_NUM_DFILES_KEYLEN},
+    {"user.pvfs2.meta_hint"  , SPECIAL_METAFILE_HINT_KEYLEN},
 };
 
 enum
@@ -53,52 +46,17 @@ enum
     STATE_DONE     = 12
 };
 
-static int getattr_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_verify_attribs(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_read_symlink_target(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_get_dirdata_handle(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_get_dirent_count(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_interpret_dirent_count(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_get_dir_hint(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_interpret_dir_hint(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_read_metafile_datafile_handles_if_required(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_read_metafile_distribution_if_required(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_setup_resp(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int getattr_setup_op(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
+static void free_nested_getattr_data(struct PINT_server_op *s_op);
 
 %%
 
-nested machine pvfs2_get_attr_work_sm(
-    verify_attribs,
-    read_symlink_target,
-    read_metafile_datafile_handles_if_required,
-    read_metafile_distribution_if_required,
-    get_dirdata_handle,
-    get_dirent_count,
-    interpret_dirent_count,
-    get_dir_hint,
-    interpret_dir_hint,
-    setup_resp)
+nested machine pvfs2_get_attr_work_sm
 {
     state verify_attribs
     {
         run getattr_verify_attribs;
         STATE_SYMLINK => read_symlink_target;
-        STATE_METAFILE => read_metafile_datafile_handles_if_required;
+        STATE_METAFILE => read_metafile_hint;
         STATE_DIR => get_dirdata_handle;
         default => setup_resp;
     }
@@ -109,16 +67,42 @@ nested machine pvfs2_get_attr_work_sm(
         default => setup_resp;
     }
 
+    state read_metafile_hint
+    {
+        run getattr_read_metafile_hint;
+        default => interpret_metafile_hint;
+    }
+
+    state interpret_metafile_hint
+    {
+        run getattr_interpret_metafile_hint;
+        STATE_METAFILE => read_metafile_datafile_handles_if_required;
+        default => setup_resp;
+    }
+
     state read_metafile_datafile_handles_if_required
     {
         run getattr_read_metafile_datafile_handles_if_required;
-        success => read_metafile_distribution_if_required;
+        success => datafile_handles_safety_check;
+        default => setup_resp;
+    }
+
+    state datafile_handles_safety_check
+    {
+        run getattr_datafile_handles_safety_check;
+        success => read_metafile_distribution_if_required; 
         default => setup_resp;
     }
 
     state read_metafile_distribution_if_required
     {
         run getattr_read_metafile_distribution_if_required;
+        default => distribution_safety_check;
+    }
+
+    state distribution_safety_check
+    {
+        run getattr_distribution_safety_check;
         default => setup_resp;
     }
 
@@ -162,12 +146,7 @@ nested machine pvfs2_get_attr_work_sm(
     }
 }
 
-machine pvfs2_get_attr_sm(
-    prelude,
-    setup_op,
-    do_work,
-    final_response,
-    cleanup)
+machine pvfs2_get_attr_sm
 {
     state prelude
     {
@@ -208,9 +187,10 @@ machine pvfs2_get_attr_sm(
  * We initialize the attribute mask that will be returned in this
  * function.  This mask can be augmented in some of the other states.
  */
-static int getattr_verify_attribs(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_verify_attribs(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *resp_attr = NULL;
 
     js_p->error_code = 0;
@@ -230,7 +210,7 @@ static int getattr_verify_attribs(
     resp_attr->perms = s_op->attr.perms;
     resp_attr->atime = s_op->attr.atime;
 
-    resp_attr->mtime = PVFS_util_mkversion_time(s_op->attr.mtime);
+    resp_attr->mtime = PINT_util_mkversion_time(s_op->attr.mtime);
     if (resp_attr->mtime == 0)
     {
         /*
@@ -317,19 +297,7 @@ static int getattr_verify_attribs(
 
             resp_attr->mask &= ~PVFS_ATTR_META_DIST;
         }
-
-        if ((resp_attr->mask & PVFS_ATTR_META_DFILES) ||
-            (resp_attr->mask & PVFS_ATTR_META_DIST))
-        {
-            gossip_debug(GOSSIP_GETATTR_DEBUG, " * client wants extra "
-                         "meta info, about to retrieve it now\n");
-            js_p->error_code = STATE_METAFILE;
-        }
-        else
-        {
-            gossip_debug(GOSSIP_GETATTR_DEBUG, " * client doesn't want "
-                         "extra meta info, preparing response now\n");
-        }
+        js_p->error_code = STATE_METAFILE;
     }
     else if (resp_attr->objtype == PVFS_TYPE_DATAFILE)
     {
@@ -415,12 +383,13 @@ static int getattr_verify_attribs(
             llu(s_op->u.getattr.handle));
         js_p->error_code = -PVFS_ENXIO;
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int getattr_read_symlink_target(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_read_symlink_target(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret;
     job_id_t i;
 
@@ -429,9 +398,9 @@ static int getattr_read_symlink_target(
     {
         gossip_debug(GOSSIP_GETATTR_DEBUG, "skipping symlink target read\n");
         js_p->error_code = 0;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
-
+    
     s_op->key.buffer    = Trove_Common_Keys[SYMLINK_TARGET_KEY].key;
     s_op->key.buffer_sz = Trove_Common_Keys[SYMLINK_TARGET_KEY].size;
 
@@ -447,26 +416,119 @@ static int getattr_read_symlink_target(
     if (!s_op->resp.u.getattr.attr.u.sym.target_path)
     {
 	js_p->error_code = -PVFS_ENOMEM;
-	return(1);
+	return SM_ACTION_COMPLETE;
     }
 
+    if(s_op->free_val)
+    {
+        free(s_op->val.buffer);
+    }
     s_op->val.buffer = s_op->resp.u.getattr.attr.u.sym.target_path;
     s_op->val.buffer_sz = s_op->resp.u.getattr.attr.u.sym.target_path_len;
+    /* this will get cleaned up with attr structure */
+    s_op->free_val = 0;
 
     ret = job_trove_keyval_read(
         s_op->u.getattr.fs_id, s_op->u.getattr.handle,
         &(s_op->key), &(s_op->val), 
         0, 
-        NULL, s_op, 0, js_p,
+        NULL, smcb, 0, js_p,
         &i, server_job_context);
 
     return ret;
 }
 
+static PINT_sm_action getattr_interpret_metafile_hint(
+    PINT_smcb *smcb, job_status_s *js_p)
+{
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+    PVFS_object_attr *resp_attr = NULL;
 
-static int getattr_read_metafile_datafile_handles_if_required(
-    PINT_server_op *s_op, job_status_s *js_p)
+    resp_attr = &s_op->resp.u.getattr.attr;
+    assert(resp_attr->objtype == PVFS_TYPE_METAFILE);
+    if (js_p->error_code == 0 || js_p->error_code == -TROVE_ENOENT)
+    {
+        if (js_p->error_code == 0)
+        {
+            memcpy(&s_op->resp.u.getattr.attr.u.meta.hint, s_op->val.buffer, 
+                sizeof(s_op->resp.u.getattr.attr.u.meta.hint));
+        }
+        if ((resp_attr->mask & PVFS_ATTR_META_DFILES) ||
+            (resp_attr->mask & PVFS_ATTR_META_DIST))
+        {
+            gossip_debug(GOSSIP_GETATTR_DEBUG, " * client wants extra "
+                         "meta info, about to retrieve it now\n");
+            js_p->error_code = STATE_METAFILE;
+        }
+        else
+        {
+            gossip_debug(GOSSIP_GETATTR_DEBUG, " * client doesn't want "
+                         "extra meta info, preparing response now\n");
+            js_p->error_code = 0;
+        }
+    }
+    else {
+        /*If we hit an error the DIST & DFILES are no longer valid*/
+        s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DIST;
+        s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DFILES;
+    }
+    return 1;
+}
+
+static PINT_sm_action getattr_read_metafile_hint(
+    struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+    int ret = -PVFS_EINVAL;
+    job_id_t i;
+    char *buf = NULL;
+
+    assert(s_op->attr.objtype == PVFS_TYPE_METAFILE);
+    buf = (char *) calloc(sizeof(PVFS_metafile_hint) + 1, 1);
+    if (buf == NULL) 
+    {
+        js_p->error_code = -PVFS_ENOMEM;
+        /*If we hit an error the DIST & DFILES are no longer valid*/
+        s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DIST;
+        s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DFILES;
+        return 1;
+    }
+
+    js_p->error_code = 0;
+
+    s_op->key.buffer = Trove_Special_Keys[METAFILE_HINT_KEY].key;
+    s_op->key.buffer_sz = Trove_Special_Keys[METAFILE_HINT_KEY].size;
+
+    if(s_op->free_val)
+    {
+        free(s_op->val.buffer);
+    }
+    s_op->val.buffer = buf;
+    s_op->val.buffer_sz = sizeof(s_op->resp.u.getattr.attr.u.meta.hint) + 1;
+    s_op->free_val = 1;
+
+    gossip_debug(GOSSIP_GETATTR_DEBUG,
+		 "  reading metafile hint (coll_id = %d, "
+                 "handle = %llu, key = %s (%d), val_buf = %p (%d))\n",
+		 s_op->u.getattr.fs_id,
+		 llu(s_op->u.getattr.handle), (char *)s_op->key.buffer,
+		 s_op->key.buffer_sz, s_op->val.buffer,
+		 s_op->val.buffer_sz);
+
+    ret = job_trove_keyval_read(
+        s_op->u.getattr.fs_id, s_op->u.getattr.handle,
+        &s_op->key, &s_op->val, 
+        0, 
+        NULL, smcb, 0, js_p,
+        &i, server_job_context);
+
+    return ret;
+}
+
+static PINT_sm_action getattr_read_metafile_datafile_handles_if_required(
+        struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     int dfile_count = 0;
     job_id_t i;
@@ -479,7 +541,7 @@ static int getattr_read_metafile_datafil
     if (!(s_op->u.getattr.attrmask & PVFS_ATTR_META_DFILES))
     {
         gossip_debug(GOSSIP_GETATTR_DEBUG, "skipping data handle read\n");
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     dfile_count = s_op->resp.u.getattr.attr.u.meta.dfile_count;
@@ -517,7 +579,7 @@ static int getattr_read_metafile_datafil
         s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DFILES;
         
 	js_p->error_code = -PVFS_EOVERFLOW;
-	return 1;
+	return SM_ACTION_COMPLETE;
     }
 
     s_op->key.buffer = Trove_Common_Keys[METAFILE_HANDLES_KEY].key;
@@ -533,11 +595,17 @@ static int getattr_read_metafile_datafil
         gossip_err("Cannot allocate dfile array of count %d\n",
                    dfile_count);
 	js_p->error_code = -PVFS_ENOMEM;
-	return 1;
+	return SM_ACTION_COMPLETE;
     }
 
+    if(s_op->free_val)
+    {
+        free(s_op->val.buffer);
+    }
     s_op->val.buffer = s_op->resp.u.getattr.attr.u.meta.dfile_array;
     s_op->val.buffer_sz = (dfile_count * sizeof(PVFS_handle));
+    /* this will get cleaned up with attr structure */
+    s_op->free_val = 0;
 
     gossip_debug(GOSSIP_GETATTR_DEBUG,
 		 "  reading %d datafile handles (coll_id = %d, "
@@ -551,15 +619,16 @@ static int getattr_read_metafile_datafil
         s_op->u.getattr.fs_id, s_op->u.getattr.handle,
         &s_op->key, &s_op->val, 
         0, 
-        NULL, s_op, 0, js_p,
+        NULL, smcb, 0, js_p,
         &i, server_job_context);
 
     return ret;
 }
 
-static int getattr_read_metafile_distribution_if_required(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_read_metafile_distribution_if_required(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -572,7 +641,7 @@ static int getattr_read_metafile_distrib
     {
         gossip_debug(GOSSIP_GETATTR_DEBUG, "skipping data handle "
                      "distribution read\n");
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     s_op->key.buffer = Trove_Common_Keys[METAFILE_DIST_KEY].key;
@@ -589,13 +658,17 @@ static int getattr_read_metafile_distrib
                    "handle %llu,%d\n",llu(s_op->u.getattr.handle),
                    s_op->u.getattr.fs_id);
         js_p->error_code = -PVFS_EINVAL;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     assert(s_op->resp.u.getattr.attr.u.meta.dist_size > 0);
 
     /* add mask value to indicate the distribution is filled */
     s_op->resp.u.getattr.attr.mask |= PVFS_ATTR_META_DIST;
 
+    if(s_op->free_val)
+    {
+        free(s_op->val.buffer);
+    }
     s_op->val.buffer_sz = s_op->resp.u.getattr.attr.u.meta.dist_size; 
     s_op->val.buffer = malloc(s_op->val.buffer_sz);
     if (!s_op->val.buffer)
@@ -603,21 +676,24 @@ static int getattr_read_metafile_distrib
         gossip_err("Cannot allocate dist of size %d\n",
                    s_op->val.buffer_sz);
 	js_p->error_code = -PVFS_ENOMEM;
-	return 1;
+	return SM_ACTION_COMPLETE;
     }
+    s_op->free_val = 1;
 
     ret = job_trove_keyval_read(
         s_op->u.getattr.fs_id, s_op->u.getattr.handle,
         &(s_op->key), &(s_op->val), 
         0, 
         NULL,
-        s_op, 0, js_p, &i, server_job_context);
+        smcb, 0, js_p, &i, server_job_context);
 
     return ret;
 }
 
-static int getattr_setup_resp(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_setup_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *resp_attr = &s_op->resp.u.getattr.attr;
 
     if(js_p->error_code > 0)
@@ -630,11 +706,8 @@ static int getattr_setup_resp(PINT_serve
     }
     if(js_p->error_code < 0)
     {
-        if(s_op->val.buffer)
-        {
-            free(s_op->val.buffer);
-        }
-        return 1;
+        free_nested_getattr_data(s_op);
+        return SM_ACTION_COMPLETE;
     }
 
     gossip_debug(
@@ -664,14 +737,14 @@ static int getattr_setup_resp(PINT_serve
         {
             assert(s_op->val.buffer);
             PINT_dist_decode(&resp_attr->u.meta.dist, s_op->val.buffer);
-            free(s_op->val.buffer);
 
             if(resp_attr->u.meta.dist == 0) {
                 gossip_err("Found dist of 0 for handle %llu,%d\n",
                         llu(s_op->u.getattr.handle), s_op->u.getattr.fs_id);
                 PVFS_perror("Metafile getattr_setup_resp",js_p->error_code);
+                free_nested_getattr_data(s_op);
                 js_p->error_code = -PVFS_EIO;
-                return 1;
+                return SM_ACTION_COMPLETE;
             }
             
             gossip_debug(GOSSIP_GETATTR_DEBUG,
@@ -712,8 +785,9 @@ static int getattr_setup_resp(PINT_serve
                        s_op->u.getattr.fs_id);
             PVFS_perror("Symlink retrieval failure",js_p->error_code);
 
+            free_nested_getattr_data(s_op);
             js_p->error_code = -PVFS_EINVAL;
-            return 1;
+            return SM_ACTION_COMPLETE;
         }
     }
     else if ((resp_attr->objtype == PVFS_TYPE_DIRECTORY) &&
@@ -732,7 +806,7 @@ static int getattr_setup_resp(PINT_serve
 
     gossip_debug(GOSSIP_GETATTR_DEBUG,"@ End %s attributes: sending "
                  "status %d (error = %d)\n",
-                 get_object_type(resp_attr->objtype),
+                 PINT_util_get_object_type(resp_attr->objtype),
 		 s_op->resp.status, js_p->error_code);
 
 #if 0
@@ -741,18 +815,15 @@ static int getattr_setup_resp(PINT_serve
                         s_op->resp.u.getattr.attr.mask);
 #endif
 
-    return 1;
+    free_nested_getattr_data(s_op);
+    return SM_ACTION_COMPLETE;
 }
 
-static int getattr_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static void free_nested_getattr_data(struct PINT_server_op *s_op)
 {
-
+    /* free up anything that was set up specifically by this nested machine */
     if(s_op->val_a)
     {
-        if(s_op->val_a[NUM_DFILES_KEY].buffer)
-        {
-            free(s_op->val_a[NUM_DFILES_KEY].buffer);
-        }
         free(s_op->val_a);
         s_op->val_a = NULL;
     }
@@ -766,39 +837,119 @@ static int getattr_cleanup(PINT_server_o
         free(s_op->u.getattr.err_array);
         s_op->u.getattr.err_array = NULL;
     }
+    if(s_op->free_val)
+    {
+        free(s_op->val.buffer);
+        s_op->val.buffer = NULL;
+    }
+
+    return;
+}
+
+static PINT_sm_action getattr_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
 
     PINT_free_object_attr(&s_op->resp.u.getattr.attr);
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
-static int getattr_setup_op(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_setup_op(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     s_op->u.getattr.handle = s_op->req->u.getattr.handle;
     s_op->u.getattr.fs_id = s_op->req->u.getattr.fs_id;
     s_op->u.getattr.attrmask = s_op->req->u.getattr.attrmask;
 
     js_p->error_code = 0;
-    return(1);
+    return SM_ACTION_COMPLETE;
+}
+
+static PINT_sm_action getattr_datafile_handles_safety_check(
+        struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+
+    if((js_p->error_code == 0) &&
+        (s_op->u.getattr.attrmask & PVFS_ATTR_META_DFILES))
+    {
+        /* successfully read datafile key; make sure we got something valid */
+        if(s_op->val.read_sz != s_op->val.buffer_sz)
+        {
+            gossip_err("Error: %s key found val size: %d when expecting val size: %d\n",
+                Trove_Common_Keys[METAFILE_HANDLES_KEY].key,
+                s_op->val.read_sz,
+                s_op->val.buffer_sz);
+
+            /* clear bitmask to prevent double free between setup_resp and
+             * PINT_free_object_attr()
+             */
+            s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DFILES;
+
+            js_p->error_code = -PVFS_EIO;
+            return SM_ACTION_COMPLETE;
+        }
+    }
+
+    /* otherwise deliberately preserve existing error code */
+    return SM_ACTION_COMPLETE;
+}
+
+static PINT_sm_action getattr_distribution_safety_check(
+        struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+
+    if((js_p->error_code == 0) &&
+        (s_op->u.getattr.attrmask & PVFS_ATTR_META_DIST))
+    {
+        /* successfully read dist key; make sure we got something valid */
+        if(s_op->val.read_sz != s_op->val.buffer_sz)
+        {
+            gossip_err("Error: %s key found val size: %d when expecting val size: %d\n",
+                Trove_Common_Keys[METAFILE_DIST_KEY].key,
+                s_op->val.read_sz,
+                s_op->val.buffer_sz);
+
+            /* clear bitmask to prevent double free between setup_resp and
+             * PINT_free_object_attr()
+             */
+            s_op->resp.u.getattr.attr.mask &= ~PVFS_ATTR_META_DIST;
+
+            js_p->error_code = -PVFS_EIO;
+            return SM_ACTION_COMPLETE;
+        }
+    }
+
+    /* otherwise deliberately preserve existing error code */
+    return SM_ACTION_COMPLETE;
 }
 
-static int getattr_get_dirdata_handle(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_get_dirdata_handle(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret;
     job_id_t tmp_id;
 
     s_op->key.buffer = Trove_Common_Keys[DIR_ENT_KEY].key;
     s_op->key.buffer_sz = Trove_Common_Keys[DIR_ENT_KEY].size;
+    if(s_op->free_val)
+    {
+        free(s_op->val.buffer);
+    }
     s_op->val.buffer = &s_op->u.getattr.dirent_handle;
     s_op->val.buffer_sz = sizeof(PVFS_handle);
+    s_op->free_val = 0;
 
     ret = job_trove_keyval_read(
         s_op->u.getattr.fs_id, s_op->u.getattr.handle,
         &s_op->key, &s_op->val,
         0,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &tmp_id,
@@ -807,9 +958,10 @@ static int getattr_get_dirdata_handle(
     return ret;
 }
         
-static int getattr_get_dirent_count(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_get_dirent_count(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret;
     job_id_t tmp_id;
 
@@ -819,7 +971,7 @@ static int getattr_get_dirent_count(
           * directory hints
           */
          js_p->error_code = STATE_DIR_HINT;
-         return(1);
+         return SM_ACTION_COMPLETE;
     }
     ret = job_trove_keyval_get_handle_info(
         s_op->u.getattr.fs_id,
@@ -827,7 +979,7 @@ static int getattr_get_dirent_count(
         TROVE_KEYVAL_HANDLE_COUNT |
         0,
         &s_op->u.getattr.keyval_handle_info,
-        s_op,
+        smcb,
         0,
         js_p,
         &tmp_id,
@@ -836,9 +988,10 @@ static int getattr_get_dirent_count(
     return ret;
 }
 
-static int getattr_interpret_dirent_count(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_interpret_dirent_count(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     switch(js_p->error_code)
     {
         case -TROVE_ENOENT:
@@ -850,18 +1003,19 @@ static int getattr_interpret_dirent_coun
                 s_op->u.getattr.keyval_handle_info.count;
             break;
         default:
-            return 1;
+            return SM_ACTION_COMPLETE;
     }
 
     gossip_debug(GOSSIP_GETATTR_DEBUG, "getattr: dirent_count: %lld\n",
         lld(s_op->resp.u.getattr.attr.u.dir.dirent_count));
 
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int getattr_get_dir_hint(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_get_dir_hint(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret, i;
     job_id_t tmp_id;
 
@@ -874,7 +1028,7 @@ static int getattr_get_dir_hint(
         /* the caller didn't really want the dir hints; skip
          */
         js_p->error_code = STATE_DONE;
-        return(1);
+        return SM_ACTION_COMPLETE;
     }
 
 
@@ -890,7 +1044,7 @@ static int getattr_get_dir_hint(
     if (!s_op->resp.u.getattr.attr.u.dir.hint.dist_params)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     s_op->resp.u.getattr.attr.u.dir.hint.dist_params_len = 
         PVFS_REQ_LIMIT_DIST_BYTES;
@@ -900,7 +1054,7 @@ static int getattr_get_dir_hint(
     if (!s_op->resp.u.getattr.attr.u.dir.hint.dist_name)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     s_op->resp.u.getattr.attr.u.dir.hint.dist_name_len   = 
         PVFS_REQ_LIMIT_DIST_NAME;
@@ -910,20 +1064,20 @@ static int getattr_get_dir_hint(
     if (s_op->key_a == NULL)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     s_op->val_a = (PVFS_ds_keyval *) calloc(NUM_SPECIAL_KEYS, sizeof(PVFS_ds_keyval));
     if (s_op->val_a == NULL)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     s_op->u.getattr.err_array = (PVFS_error*)calloc(NUM_SPECIAL_KEYS,
         sizeof(PVFS_error));
     if(s_op->u.getattr.err_array == NULL)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
 
     }
     for (i = 0; i < NUM_SPECIAL_KEYS; i++)
@@ -936,7 +1090,7 @@ static int getattr_get_dir_hint(
             if(s_op->val_a[i].buffer == NULL)
             {
                 js_p->error_code = -PVFS_ENOMEM;
-                return 1;
+                return SM_ACTION_COMPLETE;
             }
             s_op->val_a[i].buffer_sz = 16;
         }
@@ -952,26 +1106,26 @@ static int getattr_get_dir_hint(
 
     js_p->error_code = 0;
     ret = job_trove_keyval_read_list(
-        s_op->req->u.getattr.fs_id, 
-        s_op->req->u.getattr.handle,
+        s_op->u.getattr.fs_id, 
+        s_op->u.getattr.handle,
         s_op->key_a, s_op->val_a, s_op->u.getattr.err_array, NUM_SPECIAL_KEYS,
-        0, NULL, s_op, 0, js_p, &tmp_id,
+        0, NULL, smcb, 0, js_p, &tmp_id,
         server_job_context);
 
     return ret;
 }
 
-static int getattr_interpret_dir_hint(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action getattr_interpret_dir_hint(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if(js_p->error_code != 0 && js_p->error_code != -TROVE_ENOENT)
     {
         /* if we failed to get any of the keys, and the error code is due to
          * something other than the keys simply not being present, then
          * propigate the error.
          */
-        return(1);
+        return SM_ACTION_COMPLETE;
     }
 
     gossip_debug(GOSSIP_SERVER_DEBUG, 
@@ -1021,6 +1175,9 @@ static int getattr_interpret_dir_hint(
             {
                 dfile_count = 0;
             }
+        }
+        if(s_op->val_a[NUM_DFILES_KEY].buffer)
+        {
             free(s_op->val_a[NUM_DFILES_KEY].buffer);
             s_op->val_a[NUM_DFILES_KEY].buffer = NULL;
             s_op->val_a[NUM_DFILES_KEY].buffer_sz = 0;
@@ -1033,8 +1190,20 @@ static int getattr_interpret_dir_hint(
 
         js_p->error_code = 0;
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
+
+PINT_GET_OBJECT_REF_DEFINE(getattr);
+
+struct PINT_server_req_params pvfs2_get_attr_params =
+{
+    .string_name = "getattr",
+    .perm = PINT_SERVER_CHECK_ATTR,
+    .access_type = PINT_server_req_readonly,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_getattr,
+    .state_machine = &pvfs2_get_attr_sm
+};
 
 /*
  * Local variables:

Index: get-config.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/get-config.sm,v
diff -p -u -r1.34 -r1.34.28.1
--- get-config.sm	5 Jun 2006 19:57:28 -0000	1.34
+++ get-config.sm	21 Jul 2008 18:18:14 -0000	1.34.28.1
@@ -14,12 +14,9 @@
 #include "server-config.h"
 #include "pvfs2-server.h"
 
-static int getconfig_cleanup(PINT_server_op *s_op, job_status_s* js_p);
-static int getconfig_init(PINT_server_op *s_op, job_status_s* js_p);
-
 %%
 
-machine pvfs2_get_config_sm(prelude, init, final_response, cleanup)
+machine pvfs2_get_config_sm
 {
 	state prelude
 	{
@@ -49,7 +46,6 @@ machine pvfs2_get_config_sm(prelude, ini
 
 %%
 
-
 /*
  * Function: getconfig_init
  *
@@ -67,26 +63,23 @@ machine pvfs2_get_config_sm(prelude, ini
  *           
  */
 
-static int getconfig_init(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action getconfig_init(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     struct server_configuration_s *user_opts = get_server_config_struct();
     assert(user_opts);
 
     /* TODO: handle this properly later */
     assert(user_opts->fs_config_buflen <= PVFS_REQ_LIMIT_CONFIG_FILE_BYTES);
-    assert(user_opts->server_config_buflen <= PVFS_REQ_LIMIT_CONFIG_FILE_BYTES);
 
     s_op->resp.u.getconfig.fs_config_buf_size =
         (uint32_t)user_opts->fs_config_buflen;
     s_op->resp.u.getconfig.fs_config_buf =
         (char*)user_opts->fs_config_buf;
-    s_op->resp.u.getconfig.server_config_buf_size =
-        (uint32_t)user_opts->server_config_buflen;
-    s_op->resp.u.getconfig.server_config_buf =
-        (char*)user_opts->server_config_buf;
 
     js_p->error_code = 0;
-    return(1);
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -105,11 +98,18 @@ static int getconfig_init(PINT_server_op
  *           response structure
  */
 
-static int getconfig_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action getconfig_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
+struct PINT_server_req_params pvfs2_get_config_params =
+{
+    .string_name = "getconfig",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .state_machine = &pvfs2_get_config_sm
+};
 
 /*
  * Local variables:

Index: get-eattr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/get-eattr.sm,v
diff -p -u -r1.13 -r1.13.12.1
--- get-eattr.sm	18 Aug 2006 22:54:32 -0000	1.13
+++ get-eattr.sm	21 Jul 2008 18:18:14 -0000	1.13.12.1
@@ -23,27 +23,11 @@
 #include "pvfs2-types.h"
 #include "pvfs2-util.h"
 #include "pint-util.h"
-
-static int geteattr_setup_resp(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int geteattr_read_eattrib(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int geteattr_check_resp(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int geteattr_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
+#include "pint-eattr.h"
 
 %%
 
-machine pvfs2_get_eattr_sm(
-    prelude,
-    setup_resp,
-    read_eattrib,
-    check_resp,
-    final_response,
-    cleanup)
+machine pvfs2_get_eattr_sm
 {
     state prelude
     {
@@ -90,58 +74,31 @@ machine pvfs2_get_eattr_sm(
  * geteattr_setup_resp()
  * Set up the response - allocate needed resources
  */
-static int geteattr_setup_resp(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action geteattr_setup_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     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;
+            return SM_ACTION_COMPLETE;
         }
     }
 
@@ -149,53 +106,48 @@ static int geteattr_setup_resp(PINT_serv
         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);
+        return SM_ACTION_COMPLETE;
     }
     s_op->resp.u.geteattr.err =
         malloc(s_op->req->u.geteattr.nkey*sizeof(PVFS_error));
     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);
+        return SM_ACTION_COMPLETE;
     }
     s_op->resp.u.geteattr.nkey = s_op->req->u.geteattr.nkey;
     for (i = 0, tsz = 0; i < s_op->req->u.geteattr.nkey; i++)
-        tsz += s_op->req->u.geteattr.valsz[i];
-    s_op->u.eattr.buffer = malloc(tsz);
-    if (!s_op->u.eattr.buffer)
-    {
-        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);
-    }
-    gossip_debug(GOSSIP_GETEATTR_DEBUG,"geteattr buffer size %d bytes\n",
-            tsz);
-    for (i = 0, tsz = 0; i < s_op->req->u.geteattr.nkey; i++)
     {
-        s_op->resp.u.geteattr.val[i].buffer_sz =
-            s_op->req->u.geteattr.valsz[i];
-        s_op->resp.u.geteattr.val[i].buffer =
-            (char *) s_op->u.eattr.buffer + tsz;
-        tsz += s_op->req->u.geteattr.valsz[i];
+        s_op->resp.u.geteattr.val[i].buffer = malloc(
+            s_op->req->u.geteattr.valsz[i]);
+        if (!s_op->resp.u.geteattr.val[i].buffer)
+        {
+            for(--i; i >= 0; --i)
+            {
+                free(s_op->resp.u.geteattr.val[i].buffer);
+            }
+            s_op->resp.u.geteattr.nkey = 0;
+            free (s_op->resp.u.geteattr.val);
+            free (s_op->resp.u.geteattr.err);
+            js_p->error_code = -PVFS_ENOMEM;
+            return SM_ACTION_COMPLETE;
+        }
+        s_op->resp.u.geteattr.val[i].buffer_sz = s_op->req->u.geteattr.valsz[i];
     }
-    free(tmp_buffer);
-    return 1;
+
+    return SM_ACTION_COMPLETE;
 }
 
 /*
  * geteattr_read_eattrib()
  * Here is where the eattrib get read.  Not much to this.
  */
-static int geteattr_read_eattrib(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action geteattr_read_eattrib(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -210,7 +162,7 @@ static int geteattr_read_eattrib(
         s_op->req->u.geteattr.nkey,
         0,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &i,
@@ -223,8 +175,11 @@ static int geteattr_read_eattrib(
  * geteattr_check_resp()
  * Check the response - handle any errors
  */
-static int geteattr_check_resp(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action geteattr_check_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    int ret;
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int k;
     gossip_debug(GOSSIP_GETEATTR_DEBUG,"geteattr returning %d values\n",
             s_op->resp.u.geteattr.nkey);
@@ -236,32 +191,59 @@ static int geteattr_check_resp(PINT_serv
     {
         if (js_p->error_code == 0)
         {
+            ret = PINT_eattr_encode(
+                &s_op->req->u.geteattr.key[k],
+                &s_op->resp.u.geteattr.val[k]);
+            if(ret != 0)
+            {
+                gossip_err("%s: failed encoding extended attribute: %s\n",
+                           __func__, (char *)s_op->req->u.geteattr.key[k].buffer);
+                s_op->resp.u.geteattr.err[k] = ret;
+            }
+
             s_op->resp.u.geteattr.val[k].buffer_sz =
                 s_op->resp.u.geteattr.val[k].read_sz;
             gossip_debug(GOSSIP_GETEATTR_DEBUG, "key %s, read_sz = %d\n",
-                (char *) s_op->req->u.geteattr.key[k].buffer, s_op->resp.u.geteattr.val[k].buffer_sz);
+                (char *) s_op->req->u.geteattr.key[k].buffer, 
+                s_op->resp.u.geteattr.val[k].buffer_sz);
         }
         /* in case of any errors, we initialize it to 0 */
         else {
             s_op->resp.u.geteattr.val[k].buffer_sz = 0;
         }
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /* geteattr_cleanup()
  * free resources alloc'd by state machine
  */
-static int geteattr_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action geteattr_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    int i = 0;
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+    for(; i < s_op->resp.u.geteattr.nkey; ++i)
+    {
+        free(s_op->resp.u.geteattr.val[i].buffer);
+    }
     if (s_op->resp.u.geteattr.val)
         free(s_op->resp.u.geteattr.val);
     if (s_op->resp.u.geteattr.err)
         free(s_op->resp.u.geteattr.err);
-    if (s_op->u.eattr.buffer)
-        free(s_op->u.eattr.buffer);
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(geteattr);
+
+struct PINT_server_req_params pvfs2_get_eattr_params =
+{
+    .string_name = "get_eattr",
+    .perm = PINT_SERVER_CHECK_ATTR,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_geteattr,
+    .state_machine = &pvfs2_get_eattr_sm
+};
 
 /*
  * Local variables:

Index: io.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/io.sm,v
diff -p -u -r1.63 -r1.63.12.1
--- io.sm	15 Aug 2006 20:24:27 -0000	1.63
+++ io.sm	21 Jul 2008 18:18:14 -0000	1.63.12.1
@@ -19,29 +19,9 @@
 #include "pint-request.h"
 #include "pvfs2-internal.h"
 
-static int io_send_ack(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int io_send_completion_ack(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int io_start_flow(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int io_release(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int io_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_io_sm(
-    prelude,
-    send_positive_ack,
-    send_negative_ack, 
-    start_flow,
-    cleanup,
-    release,
-    send_completion_ack)
+machine pvfs2_io_sm
 {
     state prelude
     {
@@ -57,7 +37,7 @@ machine pvfs2_io_sm(
         default => release;
     }
 
-    state send_negative_ack 
+    state send_negative_ack
     {
         run io_send_ack;
         default => release;
@@ -66,7 +46,8 @@ machine pvfs2_io_sm(
     state start_flow
     {
         run io_start_flow;
-        default => send_completion_ack;
+        success => send_completion_ack;
+        default => release;
     }
 
     state send_completion_ack
@@ -108,8 +89,10 @@ machine pvfs2_io_sm(
  *           send either positive or negative acknowledgements.
  *           
  */
-static int io_send_ack(PINT_server_op *s_op, job_status_s *js_p)
+static int io_send_ack(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int err = -PVFS_EIO;
     job_id_t tmp_id;
     struct server_configuration_s *user_opts = get_server_config_struct();
@@ -127,13 +110,13 @@ static int io_send_ack(PINT_server_op *s
     {
         gossip_lerr("Server: IO SM: PINT_encode() failure.\n");
         js_p->error_code = err;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     err = job_bmi_send_list(
         s_op->addr, s_op->encoded.buffer_list, s_op->encoded.size_list,
         s_op->encoded.list_count, s_op->encoded.total_size,
-        s_op->tag, s_op->encoded.buffer_type, 0, s_op, 0, js_p,
+        s_op->tag, s_op->encoded.buffer_type, 0, smcb, 0, js_p,
         &tmp_id, server_job_context, user_opts->server_job_bmi_timeout);
 
     return err;
@@ -157,8 +140,10 @@ static int io_send_ack(PINT_server_op *s
  *           carry out the data transfer
  *           
  */
-static int io_start_flow(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action io_start_flow(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int err = -PVFS_EIO;
     job_id_t tmp_id;
     struct server_configuration_s *user_opts = get_server_config_struct();
@@ -168,7 +153,7 @@ static int io_start_flow(PINT_server_op 
     if (!s_op->u.io.flow_d)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* we still have the file size stored in the response structure 
@@ -244,10 +229,10 @@ static int io_start_flow(PINT_server_op 
     {
         gossip_lerr("Server: IO SM: unknown IO type requested.\n");
         js_p->error_code = -PVFS_EINVAL;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
-    err = job_flow(s_op->u.io.flow_d, s_op, 0, js_p, &tmp_id,
+    err = job_flow(s_op->u.io.flow_d, smcb, 0, js_p, &tmp_id,
                    server_job_context, user_opts->server_job_flow_timeout);
 
     return err;
@@ -268,8 +253,10 @@ static int io_start_flow(PINT_server_op 
  *
  * Synopsis: releases the operation from the scheduler
  */
-static int io_release(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action io_release(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = 0;
     job_id_t i;
 
@@ -278,7 +265,7 @@ static int io_release(PINT_server_op *s_
       was scheduled in the first place)
     */
     ret = job_req_sched_release(
-        s_op->scheduled_id, s_op, 0, js_p, &i, server_job_context);
+        s_op->scheduled_id, smcb, 0, js_p, &i, server_job_context);
     return ret;
 }
 
@@ -297,8 +284,10 @@ static int io_release(PINT_server_op *s_
  * Synopsis: free up any buffers associated with the operation,
  *           including any encoded or decoded protocol structures
  */
-static int io_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action io_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     char status_string[64] = {0};
 
     PVFS_strerror_r(s_op->resp.status, status_string, 64);
@@ -317,14 +306,7 @@ static int io_cleanup(PINT_server_op *s_
         PINT_encode_release(&s_op->encoded, PINT_ENCODE_RESP);
     }
 
-    /* NOTE: this would happen in final_response nested state machine
-     * for most operations, but io.sm is the one state machine which
-     * does not use final_response -- decrement reference count for
-     * this bmi address
-     */
-    BMI_set_info(s_op->addr, BMI_DEC_ADDR_REF, NULL);
-
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
 /*
@@ -345,9 +327,10 @@ static int io_cleanup(PINT_server_op *s_
  *           send either positive or negative acknowledgements.
  *           
  */
-static int io_send_completion_ack(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action io_send_completion_ack(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int err = -PVFS_EIO;
     job_id_t tmp_id;
     struct server_configuration_s *user_opts = get_server_config_struct();
@@ -358,7 +341,7 @@ static int io_send_completion_ack(
     if (s_op->req->u.io.io_type == PVFS_IO_READ)
     {
         js_p->error_code = 0;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* release encoding of the first ack that we sent */
@@ -384,17 +367,39 @@ static int io_send_completion_ack(
     {
         gossip_lerr("Server: IO SM: PINT_encode() failure.\n");
         js_p->error_code = err;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     err = job_bmi_send_list(
         s_op->addr, s_op->encoded.buffer_list, s_op->encoded.size_list,
         s_op->encoded.list_count, s_op->encoded.total_size, s_op->tag,
-        s_op->encoded.buffer_type, 0, s_op, 0, js_p, &tmp_id,
+        s_op->encoded.buffer_type, 0, smcb, 0, js_p, &tmp_id,
         server_job_context, user_opts->server_job_bmi_timeout);
 
     return err;
 }
+
+static enum PINT_server_req_access_type PINT_server_req_access_io(
+    struct PVFS_server_req *req)
+{
+    if(req->u.io.io_type == PVFS_IO_READ)
+    {
+        return PINT_SERVER_REQ_READONLY;
+    }
+    return PINT_SERVER_REQ_MODIFY;
+}
+
+PINT_GET_OBJECT_REF_DEFINE(io);
+
+struct PINT_server_req_params pvfs2_io_params =
+{
+    .string_name = "io",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_access_io,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_io,
+    .state_machine = &pvfs2_io_sm
+};
 
 /*
  * Local variables:

Index: iterate-handles.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/iterate-handles.sm,v
diff -p -u -r1.6 -r1.6.24.1
--- iterate-handles.sm	13 Jul 2006 05:11:42 -0000	1.6
+++ iterate-handles.sm	21 Jul 2008 18:18:14 -0000	1.6.24.1
@@ -13,13 +13,9 @@
 #include "pvfs2-server.h"
 #include "server-config.h"
 
-static int iterate_handles_cleanup(PINT_server_op *s_op, job_status_s* js_p);
-static int iterate_handles_do_work(PINT_server_op *s_op, job_status_s* js_p);
-static int iterate_handles_fill_resp(PINT_server_op *s_op, job_status_s* js_p);
-
 %%
 
-machine pvfs2_iterate_handles_sm(prelude, do_work, fill_resp, final_response, cleanup)
+machine pvfs2_iterate_handles_sm
 {
 	state prelude
 	{
@@ -59,12 +55,14 @@ machine pvfs2_iterate_handles_sm(prelude
  * cleans up any resources consumed by this state machine and ends
  * execution of the machine
  */
-static int iterate_handles_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action iterate_handles_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if(s_op->resp.u.mgmt_iterate_handles.handle_array)
 	free(s_op->resp.u.mgmt_iterate_handles.handle_array);
 
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
 
@@ -72,9 +70,12 @@ static int iterate_handles_cleanup(PINT_
  *
  * actually performs work necessary to retrieve handles
  */
-static int iterate_handles_do_work(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action iterate_handles_do_work(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     job_id_t tmp_id;
+    int ret;
 
     /* allocate memory to hold handles */
     s_op->resp.u.mgmt_iterate_handles.handle_array
@@ -83,43 +84,66 @@ static int iterate_handles_do_work(PINT_
     if(!s_op->resp.u.mgmt_iterate_handles.handle_array)
     {
 	js_p->error_code = -PVFS_ENOMEM;
-	return(1);
+	return SM_ACTION_COMPLETE;
     }
     
     s_op->resp.u.mgmt_iterate_handles.position
 	= s_op->req->u.mgmt_iterate_handles.position;
 
-    return(job_trove_dspace_iterate_handles(
+    ret = job_trove_dspace_iterate_handles(
 	s_op->req->u.mgmt_iterate_handles.fs_id,
 	s_op->resp.u.mgmt_iterate_handles.position,
 	s_op->resp.u.mgmt_iterate_handles.handle_array,
 	s_op->req->u.mgmt_iterate_handles.handle_count,
 	0,
 	NULL,
-	s_op,
+	smcb,
 	0,
 	js_p,
 	&tmp_id,
-	server_job_context));
+	server_job_context);
+    if (ret < 0)
+        return ret;  /* error */
+    if (ret == 1)
+        return SM_ACTION_COMPLETE;  /* immediate */
+    return SM_ACTION_DEFERRED;
 }
 
 /* iterate_handles_fill_resp()
  *
  * gathers results from job status for response
  */
-static int iterate_handles_fill_resp(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action iterate_handles_fill_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if(js_p->error_code != 0)
     {
 	/* propigate error and let final_response handle it */
-	return(1);
+	return SM_ACTION_COMPLETE;
     }
 
     s_op->resp.u.mgmt_iterate_handles.handle_count = js_p->count;
     s_op->resp.u.mgmt_iterate_handles.position = js_p->position;
 
-    return(1);
+    return SM_ACTION_COMPLETE;
+}
+
+static inline int PINT_get_object_ref_iterate_handles(
+    struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
+{
+    *fs_id = req->u.mgmt_iterate_handles.fs_id;
+    *handle = PVFS_HANDLE_NULL;
+    return 0;
 }
+
+struct PINT_server_req_params pvfs2_iterate_handles_params =
+{
+    .string_name = "mgmt_iterate_handles",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .get_object_ref = PINT_get_object_ref_iterate_handles,
+    .state_machine = &pvfs2_iterate_handles_sm
+};
 
 /*
  * Local variables:

Index: job-timer.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/job-timer.sm,v
diff -p -u -r1.3 -r1.3.28.1
--- job-timer.sm	5 Jun 2006 19:57:28 -0000	1.3
+++ job-timer.sm	21 Jul 2008 18:18:14 -0000	1.3.28.1
@@ -15,12 +15,9 @@
 #include "job-time-mgr.h"
 #include "server-config.h"
 
-static int job_timer_do_work(PINT_server_op *s_op, job_status_s* js_p);
-static int job_timer_error(PINT_server_op *s_op, job_status_s* js_p);
-
 %%
 
-machine pvfs2_job_timer_sm(do_work, error)
+machine pvfs2_job_timer_sm
 {
 	state do_work 
 	{
@@ -43,11 +40,12 @@ machine pvfs2_job_timer_sm(do_work, erro
  * cleans up any resources consumed by this state machine and ends
  * execution of the machine
  */
-static int job_timer_error(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action job_timer_error(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     gossip_err("Error: stopping server job timer.\n");
 
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
 /* job_timer_do_work()
@@ -55,7 +53,8 @@ static int job_timer_error(PINT_server_o
  * resets counters, updates metrices, etc- this is intended to be called
  * repeatedly on a regular interval
  */
-static int job_timer_do_work(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action job_timer_do_work(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     int ret = -1;
     job_id_t tmp_id;
@@ -69,17 +68,24 @@ static int job_timer_do_work(PINT_server
     if(ret < 0)
     {
 	js_p->error_code = ret;
-	return(1);
+	return SM_ACTION_COMPLETE;
     }
 	
     /* post another timer */
     return(job_req_sched_post_timer(1000,
-	s_op,
-	0,
-	js_p,
-	&tmp_id,
-	server_job_context));
+	    smcb,
+	    0,
+	    js_p,
+	    &tmp_id,
+	    server_job_context));
 }
+
+struct PINT_server_req_params pvfs2_job_timer_params =
+{
+    .string_name = "job_timer",
+    .perm = PINT_SERVER_CHECK_INVALID,
+    .state_machine = &pvfs2_job_timer_sm
+};
 
 
 

Index: list-eattr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/list-eattr.sm,v
diff -p -u -r1.7 -r1.7.12.1
--- list-eattr.sm	18 Aug 2006 15:17:45 -0000	1.7
+++ list-eattr.sm	21 Jul 2008 18:18:14 -0000	1.7.12.1
@@ -23,27 +23,11 @@
 #include "pvfs2-types.h"
 #include "pvfs2-util.h"
 #include "pint-util.h"
-
-static int listeattr_setup_resp(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int listeattr_list_eattrib(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int listeattr_check_resp(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int listeattr_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
+#include "pint-eattr.h"
 
 %%
 
-machine pvfs2_list_eattr_sm(
-    prelude,
-    setup_resp,
-    list_eattrib,
-    check_resp,
-    final_response,
-    cleanup)
+machine pvfs2_list_eattr_sm
 {
     state prelude
     {
@@ -90,8 +74,10 @@ machine pvfs2_list_eattr_sm(
  * listeattr_setup_resp()
  * Set up the response - allocate needed resources
  */
-static int listeattr_setup_resp(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action listeattr_setup_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int i, tsz;
     gossip_debug(GOSSIP_LISTEATTR_DEBUG, "listeattr requesting %d keys\n",
             s_op->req->u.listeattr.nkey);
@@ -103,7 +89,7 @@ static int listeattr_setup_resp(PINT_ser
     if (!s_op->resp.u.listeattr.key)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return(1);
+        return SM_ACTION_COMPLETE;
     }
 
     s_op->resp.u.listeattr.nkey = s_op->req->u.listeattr.nkey;
@@ -115,7 +101,7 @@ static int listeattr_setup_resp(PINT_ser
         s_op->resp.u.listeattr.nkey = 0;
         free (s_op->resp.u.listeattr.key);
         js_p->error_code = -PVFS_ENOMEM;
-        return(1);
+        return SM_ACTION_COMPLETE;
     }
     gossip_debug(GOSSIP_LISTEATTR_DEBUG,"listeattr buffer size %d bytes\n",
             tsz);
@@ -127,16 +113,17 @@ static int listeattr_setup_resp(PINT_ser
             (char *)s_op->u.eattr.buffer + tsz;
         tsz += s_op->req->u.listeattr.keysz[i];
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
  * listeattr_list_eattrib()
  * Here is where the eattrib get listed.
  */
-static int listeattr_list_eattrib(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action listeattr_list_eattrib(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -150,7 +137,7 @@ static int listeattr_list_eattrib(
         s_op->req->u.listeattr.nkey,
         0,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &i,
@@ -186,21 +173,19 @@ static void print_string(char *buffer, s
  * will translate it so that it appears in the "system.pvfs2." name
  * space on the client side.
  */
-static int listeattr_check_resp(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action listeattr_check_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     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)
     {
         s_op->resp.u.listeattr.token = js_p->count;
         js_p->error_code = 0;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* how many entries did we find that we can process? */
@@ -217,70 +202,52 @@ static int listeattr_check_resp(PINT_ser
     {
         /* there aren't any extended attr's; go ahead and return */
         js_p->error_code = 0;
-        return(1);
-    }
-  
-    tmp_buffer = (char*)malloc(PVFS_REQ_LIMIT_KEY_LEN);
-    if(!tmp_buffer)
-    {
-        js_p->error_code = -PVFS_ENOMEM;
-        return(1);
+        return SM_ACTION_COMPLETE;
     }
 
     /* 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 SM_ACTION_COMPLETE;
         }
 
         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);
+    return SM_ACTION_COMPLETE;
 }
 
 /* listeattr_cleanup()
  * free resources alloc'd by state machine
  */
-static int listeattr_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action listeattr_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if (s_op->resp.u.listeattr.key)
         free(s_op->resp.u.listeattr.key);
     if (s_op->u.eattr.buffer)
         free(s_op->u.eattr.buffer);
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(listeattr);
+
+struct PINT_server_req_params pvfs2_list_eattr_params =
+{
+    .string_name = "listeattr",
+    .perm = PINT_SERVER_CHECK_ATTR,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_listeattr,
+    .state_machine = &pvfs2_list_eattr_sm
+};
 
 /*
  * Local variables:

Index: lock.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/Attic/lock.sm,v
diff -p -u -r1.1.2.4 -r1.1.2.4.2.1
--- lock.sm	14 Jul 2008 19:56:42 -0000	1.1.2.4
+++ lock.sm	21 Jul 2008 18:18:14 -0000	1.1.2.4.2.1
@@ -35,20 +35,16 @@ const char *PVFS_lock_type_mapping[] =
     "PVFS_SERVER_RELEASE_ALL"           
 };
 
-static int lock_change_lock(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int lock_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p);
+static PINT_sm_action lock_change_lock(
+    struct PINT_smcb *smcb, job_status_s* js_p);
+static PINT_sm_action lock_cleanup(
+    struct PINT_smcb *smcb, job_status_s* js_p);
 
 extern PINT_server_trove_keys_s Trove_Common_Keys[];
 
 %%
 
-machine pvfs2_lock_sm(
-    prelude,
-    change_lock,
-    send_response,
-    cleanup)
+machine pvfs2_lock_sm
 {
     state prelude
     {
@@ -78,9 +74,10 @@ machine pvfs2_lock_sm(
 
 %%
 
-static int lock_change_lock(
-    PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lock_change_lock(
+    struct PINT_smcb *smcb, job_status_s* js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     PVFS_object_ref object_ref;
     PINT_request_file_data fdata;
@@ -100,9 +97,9 @@ static int lock_change_lock(
     fdata.extend_flag = 1;
 
     gossip_debug(GOSSIP_LOCK_DEBUG,
-		 "Request %s received with final_offset %lld\n", 
+		 "Request %s received with final_offset %Ld\n", 
 		 PVFS_lock_type_mapping[s_op->req->u.lock.lock_type],
-		 lld(s_op->req->u.lock.final_offset));
+		 s_op->req->u.lock.final_offset);
 
     if ((s_op->req->u.lock.lock_type != PVFS_SERVER_RELEASE_SOME) &&
 	(s_op->req->u.lock.lock_type != PVFS_SERVER_RELEASE_ALL))
@@ -136,7 +133,7 @@ static int lock_change_lock(
 	    gossip_debug(GOSSIP_LOCK_DEBUG, 
 			 "lock_change_lock: starting job\n");
 	    
-	    err = job_lock_wait_block_bytes(s_op,
+	    err = job_lock_wait_block_bytes(smcb,
 					    lock_req_p);
 	    return err;
 #if 0
@@ -156,12 +153,13 @@ static int lock_change_lock(
 #if 0
     print_lock_file_table_all_info();
 #endif
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int lock_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lock_cleanup(
+    struct PINT_smcb *smcb, job_status_s* js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     /* Do the check after the message is sent so the client doesn't
      * have to wait excessively */
     if (((s_op->req->u.lock.lock_type == PVFS_SERVER_RELEASE_SOME) ||
@@ -171,7 +169,7 @@ static int lock_cleanup(
 	check_lock_reqs(s_op->u.lock.lock_node_p);
     }
 
-    return server_state_machine_complete(s_op);
+    return server_state_machine_complete(smcb);
 }
 
 

Index: lookup.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/lookup.sm,v
diff -p -u -r1.48 -r1.48.12.1
--- lookup.sm	23 Aug 2006 19:39:39 -0000	1.48
+++ lookup.sm	21 Jul 2008 18:18:14 -0000	1.48.12.1
@@ -19,6 +19,7 @@
 #include "str-utils.h"
 #include "pint-util.h"
 #include "pvfs2-internal.h"
+#include "check.h"
 
 enum 
 {
@@ -27,41 +28,9 @@ enum 
     LOOKUP_CHECK_DIR_ACLS = 24,
 };
 
-static int lookup_init(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int lookup_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int lookup_read_object_metadata(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int lookup_verify_object_metadata(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int lookup_check_acls_if_needed(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int lookup_check_acls(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int lookup_read_directory_entry(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int lookup_read_directory_entry_handle(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int lookup_setup_resp(
-    PINT_server_op *s_op, job_status_s* js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_lookup_sm(
-    prelude,
-    init,
-    read_object_metadata,
-    read_directory_entry_handle,
-    read_directory_entry,
-    verify_object_metadata,
-    read_directory_acls,
-    check_acls,
-    setup_resp,
-    final_response,
-    cleanup)
+machine pvfs2_lookup_sm
 {
     state prelude
     {
@@ -157,10 +126,13 @@ machine pvfs2_lookup_sm(
  * s_op->resp.u.lookup_path.handle_array.
  *
  */
-static int lookup_init(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lookup_init(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     char *ptr = NULL;
 
+
     /* fill in the lookup portion of the PINT_server_op */
     s_op->u.lookup.segp = NULL;
     s_op->u.lookup.seg_nr = 0;
@@ -169,6 +141,14 @@ static int lookup_init(PINT_server_op *s
     s_op->u.lookup.handle_ct = 0;
     s_op->u.lookup.attr_ct = 0;
 
+    gossip_debug(GOSSIP_SERVER_DEBUG, " STARTING LOOKUP REQUEST "
+                     "(path:%s)(fs_id:%d)(handle:%llu)(attrmask:%u)"
+                     "(# of segments:%u)\n",
+                     s_op->req->u.lookup_path.path,
+                     s_op->req->u.lookup_path.fs_id,
+                     llu(s_op->req->u.lookup_path.handle),
+                     s_op->req->u.lookup_path.attrmask,
+                     s_op->u.lookup.seg_ct);
     if ((s_op->u.lookup.seg_ct < 0) ||
         (s_op->u.lookup.seg_ct > PVFS_REQ_LIMIT_PATH_SEGMENT_COUNT))
     {
@@ -176,7 +156,7 @@ static int lookup_init(PINT_server_op *s
                    "sending error response\n",
 		   s_op->req->u.lookup_path.path);
 	js_p->error_code = -PVFS_ENOTDIR;
-        return 0;
+        return SM_ACTION_DEFERRED;
     }
 
     /* allocate the internal ds_attr_array */
@@ -198,7 +178,7 @@ static int lookup_init(PINT_server_op *s
     if (!ptr)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     s_op->resp.u.lookup_path.handle_array = (PVFS_handle *)ptr;
@@ -207,7 +187,7 @@ static int lookup_init(PINT_server_op *s
     s_op->resp.u.lookup_path.attr_array = (PVFS_object_attr *)ptr;
 
     js_p->error_code = 0;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -223,9 +203,10 @@ static int lookup_init(PINT_server_op *s
  *
  * Posts the keyval read to trove.
  */
-static int lookup_read_object_metadata(
-    PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lookup_read_object_metadata(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t j_id;
     PVFS_handle handle = PVFS_HANDLE_NULL;
@@ -236,7 +217,7 @@ static int lookup_read_object_metadata(
     /* use the base handle if we haven't looked up a segment yet */
     if (s_op->u.lookup.seg_nr == 0)
     {
-        handle = s_op->req->u.lookup_path.starting_handle;
+        handle = s_op->req->u.lookup_path.handle;
         ds_attr = &(s_op->u.lookup.ds_attr_array[0]);
     }
     else
@@ -256,7 +237,7 @@ static int lookup_read_object_metadata(
 
     /* get the dspace attributes/metadata */
     ret = job_trove_dspace_getattr(
-        s_op->req->u.lookup_path.fs_id, handle, s_op, ds_attr,
+        s_op->req->u.lookup_path.fs_id, handle, smcb, ds_attr,
         0, js_p, &j_id, server_job_context);
 
     return ret;
@@ -277,9 +258,10 @@ static int lookup_read_object_metadata(
  * This function does not post an operation, but rather returns 1
  * immediately.
  */
-static int lookup_verify_object_metadata(
-    PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lookup_verify_object_metadata(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     PVFS_object_attr *a_p = NULL;
     PVFS_ds_attributes *ds_attr = NULL;
@@ -320,7 +302,7 @@ static int lookup_verify_object_metadata
                      "halting lookup and sending response\n");
 
 	js_p->error_code = STATE_ENOTDIR;
-	return 1;
+	return SM_ACTION_COMPLETE;
     }
 
     /*
@@ -333,7 +315,7 @@ static int lookup_verify_object_metadata
                      "halting lookup and sending response\n");
 
 	js_p->error_code = STATE_ENOTDIR;
-	return 1;
+	return SM_ACTION_COMPLETE;
     }
 
     /* if we looked up all the segments, we are done */
@@ -343,7 +325,7 @@ static int lookup_verify_object_metadata
                      "sending response\n");
 
 	js_p->error_code = STATE_NOMORESEGS;
-	return 1;
+	return SM_ACTION_COMPLETE;
     }
 
     /* if we reach this point, the object is a directory.  Verify that we
@@ -357,7 +339,7 @@ static int lookup_verify_object_metadata
          * out
          */
         js_p->error_code = LOOKUP_CHECK_DIR_ACLS;
-        return(1);
+        return SM_ACTION_COMPLETE;
     }
 
     /* find the segment that we should look up in the directory */
@@ -377,18 +359,19 @@ static int lookup_verify_object_metadata
 		 s_op->u.lookup.segp);
 
 
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
  * Post a keyval DB read of the posix acls to check and see if 
  * directory traversal is allowed or not
  */
-static int lookup_check_acls_if_needed(
-    PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lookup_check_acls_if_needed(
+    struct PINT_smcb *smcb, job_status_s* js_p)
 {
     int ret = -PVFS_EINVAL;
     job_id_t i;
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
 
     /* If we get here with an invalid fsid and handle, we have to
      * return -PVFS_EACCESS 
@@ -397,7 +380,7 @@ static int lookup_check_acls_if_needed(
         || s_op->target_handle == PVFS_HANDLE_NULL)
     {
         js_p->error_code = -PVFS_EACCES;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     js_p->error_code = 0;
 
@@ -409,7 +392,7 @@ static int lookup_check_acls_if_needed(
     if (!s_op->val.buffer)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     s_op->val.buffer_sz = PVFS_REQ_LIMIT_VAL_LEN;
 
@@ -424,11 +407,12 @@ static int lookup_check_acls_if_needed(
         &s_op->val,
         0,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &i,
         server_job_context);
+
     return ret;
 }
 
@@ -437,9 +421,10 @@ static int lookup_check_acls_if_needed(
  * to proceed or not. i.e. executable privileges on directory
  * for the requesting user or not.
  */
-static int lookup_check_acls(
-    PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lookup_check_acls(
+    struct PINT_smcb *smcb, job_status_s* js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *obj_attr = NULL;
     int want = PVFS2_ACL_EXECUTE;
 
@@ -463,23 +448,30 @@ static int lookup_check_acls(
        find the segment that we should look up in the directory */
     if (js_p->error_code == 0)
     {
-        int ret = PINT_string_next_segment(
+        js_p->error_code = PINT_string_next_segment(
             s_op->req->u.lookup_path.path, &s_op->u.lookup.segp,
             &s_op->u.lookup.segstate);
 
-        assert(ret == 0);
-
-        gossip_debug(GOSSIP_SERVER_DEBUG, "  after ACL check "
-                    "object is a directory; will be "
-                     "looking for handle for segment \"%s\" in a bit\n",
-                     s_op->u.lookup.segp);
+        if(js_p->error_code != 0)
+        {
+            gossip_err("PINT_string_next_segment failed to get the"
+                       "next segment to lookup from the path: %s\n",
+                       s_op->req->u.lookup_path.path);
+        }
+        else
+        {
+            gossip_debug(GOSSIP_SERVER_DEBUG, "  after ACL check "
+                         "object is a directory; will be "
+                         "looking for handle for segment \"%s\" in a bit\n",
+                         s_op->u.lookup.segp);
+        }
     }
 cleanup:
     if (s_op->val.buffer) 
         free(s_op->val.buffer);
     memset(&s_op->key, 0, sizeof(PVFS_ds_keyval));
     memset(&s_op->val, 0, sizeof(PVFS_ds_keyval));
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -498,9 +490,10 @@ cleanup:
  *
  * Posts the keyval read to trove.
  */
-static int lookup_read_directory_entry_handle(
-    PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lookup_read_directory_entry_handle(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     PVFS_handle handle = PVFS_HANDLE_NULL;
     job_id_t j_id;
@@ -508,7 +501,7 @@ static int lookup_read_directory_entry_h
     /* use the base handle if we haven't looked up a segment yet */
     if (s_op->u.lookup.seg_nr == 0)
     {
-        handle = s_op->req->u.lookup_path.starting_handle;
+        handle = s_op->req->u.lookup_path.handle;
     }
     else
     {
@@ -528,7 +521,7 @@ static int lookup_read_directory_entry_h
     ret = job_trove_keyval_read(
         s_op->req->u.lookup_path.fs_id, handle, &s_op->key, &s_op->val,
         0, 
-        NULL, s_op, 0, js_p, &j_id, server_job_context);
+        NULL, smcb, 0, js_p, &j_id, server_job_context);
 
     return ret;
 }
@@ -539,9 +532,10 @@ static int lookup_read_directory_entry_h
  * Synopsis: Given a handle for a dspace holding directory entries,
  * look up the current segment and obtain its handle.
  */
-static int lookup_read_directory_entry(
-    PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lookup_read_directory_entry(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t j_id;
 
@@ -566,15 +560,17 @@ static int lookup_read_directory_entry(
         s_op->req->u.lookup_path.fs_id, s_op->u.lookup.dirent_handle,
         &s_op->key, &s_op->val, 
         0, 
-        NULL, s_op, 0, js_p, &j_id,
+        NULL, smcb, 0, js_p, &j_id,
         server_job_context);
 
     return ret;
 }
 
 
-static int lookup_setup_resp(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lookup_setup_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
 
     /*
       NOTE: we may have handle_count N with attr_count N-1 in the case
@@ -594,6 +590,7 @@ static int lookup_setup_resp(PINT_server
     else if(js_p->error_code < 0)
     {
         /* preserve error code in this case and fall through */
+        gossip_debug(GOSSIP_SERVER_DEBUG, "  lookup error in previous step\n");
     }
     else
     {
@@ -608,17 +605,20 @@ static int lookup_setup_resp(PINT_server
 
     if(js_p->error_code == 0)
     {
-        PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG, "path: %s, handle: %llu\n",
-            s_op->req->u.lookup_path.path,
-            llu(s_op->resp.u.lookup_path.handle_array[s_op->resp.u.lookup_path.handle_count-1]));
+        PINT_ACCESS_DEBUG(
+            s_op, GOSSIP_ACCESS_DEBUG, "path: %s, handle: %llu\n", 
+            s_op->req->u.lookup_path.path, 
+            llu(s_op->resp.u.lookup_path.handle_array[
+                s_op->resp.u.lookup_path.handle_count-1]));
     }
     else
     {
-        PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DEBUG, "path: %s, lookup failed\n",
+        PINT_ACCESS_DEBUG(
+            s_op, GOSSIP_ACCESS_DEBUG, "path: %s, lookup failed\n", 
             s_op->req->u.lookup_path.path);
     }
 
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -636,8 +636,10 @@ static int lookup_setup_resp(PINT_server
  *   s_op->resp.u.lookup_path.handle_array)
  * - the server operation structure itself
  */
-static int lookup_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action lookup_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if (s_op->resp.u.lookup_path.handle_array)
     {
         free(s_op->resp.u.lookup_path.handle_array);
@@ -649,8 +651,19 @@ static int lookup_cleanup(PINT_server_op
         free(s_op->u.lookup.ds_attr_array);
         s_op->u.lookup.ds_attr_array = NULL;
     }
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(lookup_path);
+
+struct PINT_server_req_params pvfs2_lookup_params =
+{
+    .string_name = "lookup_path",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_lookup_path,
+    .state_machine = &pvfs2_lookup_sm
+};
 
 /*
  * Local variables:

Index: mgmt-get-dirdata-handle.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/mgmt-get-dirdata-handle.sm,v
diff -p -u -r1.5 -r1.5.14.1
--- mgmt-get-dirdata-handle.sm	13 Jul 2006 05:11:42 -0000	1.5
+++ mgmt-get-dirdata-handle.sm	21 Jul 2008 18:18:14 -0000	1.5.14.1
@@ -14,23 +14,9 @@
 #include "gossip.h"
 #include "pvfs2-internal.h"
 
-static int mgmt_get_dirdata_handle_from_parent(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mgmt_get_dirdata_handle_setup_resp(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mgmt_get_dirdata_handle_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_mgmt_get_dirdata_handle_sm(
-    prelude,
-    get_dirdata_handle_from_parent,
-    get_dirdata_handle_setup_resp,
-    final_response,
-    cleanup)
+machine pvfs2_mgmt_get_dirdata_handle_sm
 {
     state prelude
     {
@@ -68,8 +54,9 @@ machine pvfs2_mgmt_get_dirdata_handle_sm
 %%
 
 static int mgmt_get_dirdata_handle_from_parent(
-    PINT_server_op *s_op, job_status_s *js_p)
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -93,15 +80,16 @@ static int mgmt_get_dirdata_handle_from_
         s_op->req->u.mgmt_get_dirdata_handle.handle,
         &s_op->key, &s_op->val, 
         0, 
-        NULL, s_op, 0, js_p, &i,
+        NULL, smcb, 0, js_p, &i,
         server_job_context);
 
     return ret;
 }
 
-static int mgmt_get_dirdata_handle_setup_resp(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mgmt_get_dirdata_handle_setup_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if (js_p->error_code == 0)
     {
         s_op->resp.u.mgmt_get_dirdata_handle.handle =
@@ -120,14 +108,25 @@ static int mgmt_get_dirdata_handle_setup
                      "handle from parent %llu\n",
                      llu(s_op->req->u.mgmt_get_dirdata_handle.handle));
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int mgmt_get_dirdata_handle_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mgmt_get_dirdata_handle_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(mgmt_get_dirdata_handle);
+
+struct PINT_server_req_params pvfs2_mgmt_get_dirdata_handle_params =
+{
+    .string_name = "mgmt-get-dirdata-handle",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_mgmt_get_dirdata_handle,
+    .state_machine = &pvfs2_mgmt_get_dirdata_handle_sm
+};
 
 /*
  * Local variables:

Index: mgmt-remove-dirent.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/mgmt-remove-dirent.sm,v
diff -p -u -r1.8 -r1.8.14.1
--- mgmt-remove-dirent.sm	13 Jul 2006 05:11:42 -0000	1.8
+++ mgmt-remove-dirent.sm	21 Jul 2008 18:18:14 -0000	1.8.14.1
@@ -14,23 +14,9 @@
 #include "gossip.h"
 #include "pvfs2-internal.h"
 
-static int mgmt_remove_dirent_get_dirdata_handle_from_parent(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mgmt_remove_dirent(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mgmt_remove_dirent_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_mgmt_remove_dirent_sm(
-    prelude,
-    get_dirdata_handle_from_parent,
-    remove_dirent,
-    final_response,
-    cleanup)
+machine pvfs2_mgmt_remove_dirent_sm
 {
     state prelude
     {
@@ -68,8 +54,9 @@ machine pvfs2_mgmt_remove_dirent_sm(
 %%
 
 static int mgmt_remove_dirent_get_dirdata_handle_from_parent(
-    PINT_server_op *s_op, job_status_s *js_p)
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -94,15 +81,16 @@ static int mgmt_remove_dirent_get_dirdat
         s_op->req->u.mgmt_remove_dirent.handle,
         &s_op->key, &s_op->val, 
         0, 
-        NULL, s_op, 0, js_p, &i,
+        NULL, smcb, 0, js_p, &i,
         server_job_context);
 
     return ret;
 }
 
-static int mgmt_remove_dirent(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mgmt_remove_dirent(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t j_id;
 
@@ -120,9 +108,9 @@ static int mgmt_remove_dirent(
         s_op->u.mgmt_remove_dirent.dirdata_handle,
         &s_op->key,
         NULL,
-        TROVE_SYNC,
+        TROVE_SYNC | TROVE_KEYVAL_HANDLE_COUNT,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &j_id,
@@ -131,11 +119,23 @@ static int mgmt_remove_dirent(
     return ret;
 }
 
-static int mgmt_remove_dirent_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mgmt_remove_dirent_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(mgmt_remove_dirent);
+
+struct PINT_server_req_params pvfs2_mgmt_remove_dirent_params =
+{
+    .string_name = "mgmt-remove-dirent",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_mgmt_remove_dirent,
+    .state_machine = &pvfs2_mgmt_remove_dirent_sm
+};
 
 /*
  * Local variables:

Index: mgmt-remove-object.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/mgmt-remove-object.sm,v
diff -p -u -r1.9 -r1.9.14.1
--- mgmt-remove-object.sm	13 Jul 2006 05:11:42 -0000	1.9
+++ mgmt-remove-object.sm	21 Jul 2008 18:18:14 -0000	1.9.14.1
@@ -14,20 +14,9 @@
 #include "gossip.h"
 #include "pvfs2-internal.h"
 
-static int mgmt_remove_dspace(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mgmt_remove_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_mgmt_remove_object_sm(
-    prelude,
-    remove_dspace,
-    final_response,
-    cleanup)
+machine pvfs2_mgmt_remove_object_sm
 {
     state prelude
     {
@@ -57,9 +46,10 @@ machine pvfs2_mgmt_remove_object_sm(
 
 %%
 
-static int mgmt_remove_dspace(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mgmt_remove_dspace(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t j_id;
     
@@ -72,7 +62,7 @@ static int mgmt_remove_dspace(
         s_op->req->u.mgmt_remove_object.fs_id,
         s_op->req->u.mgmt_remove_object.handle,
         TROVE_SYNC,
-        s_op,
+        smcb,
         0,
         js_p,
         &j_id,
@@ -81,11 +71,23 @@ static int mgmt_remove_dspace(
     return ret;
 }
 
-static int mgmt_remove_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mgmt_remove_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(mgmt_remove_object);
+
+struct PINT_server_req_params pvfs2_mgmt_remove_object_params =
+{
+    .string_name = "mgmt-remove-object",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_mgmt_remove_object,
+    .state_machine = &pvfs2_mgmt_remove_object_sm
+};
 
 /*
  * Local variables:

Index: mkdir.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/mkdir.sm,v
diff -p -u -r1.45 -r1.45.12.1
--- mkdir.sm	1 Aug 2006 00:27:16 -0000	1.45
+++ mkdir.sm	21 Jul 2008 18:18:15 -0000	1.45.12.1
@@ -13,31 +13,11 @@
 #include "pvfs2-attr.h"
 #include "pvfs2-util.h"
 #include "pvfs2-internal.h"
-
-static int mkdir_create(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mkdir_setattrib(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mkdir_create_dirdata_dspace(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mkdir_write_dirdata_handle(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mkdir_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mkdir_error(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int mkdir_prep_sm(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
+#include "pint-util.h"
 
 %%
 
-nested machine pvfs2_mkdir_work_sm(create, 
-                                   set_attrib,
-                                   create_dirdata_dspace, 
-                                   write_dirdata_handle, 
-                                   err_msg)
+nested machine pvfs2_mkdir_work_sm
 {
     state create
     {
@@ -74,12 +54,7 @@ nested machine pvfs2_mkdir_work_sm(creat
     }
 }
 
-machine pvfs2_mkdir_sm(
-    prelude,
-    prep_sm,
-    work,
-    final_response,
-    cleanup)
+machine pvfs2_mkdir_sm
 {
     state prelude
     {
@@ -128,9 +103,10 @@ machine pvfs2_mkdir_sm(
  * NOTE: returned handle will pop out in js_p->handle (the job status
  * struct).
  */
-static int mkdir_create(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mkdir_create(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret;
     job_id_t i;
 
@@ -147,7 +123,7 @@ static int mkdir_create(PINT_server_op *
         s_op->u.mkdir.fs_id, &s_op->u.mkdir.handle_extent_array,
         PVFS_TYPE_DIRECTORY, NULL,
         TROVE_SYNC, 
-        s_op, 0, js_p, &i,
+        smcb, 0, js_p, &i,
         server_job_context);
 
     return ret;
@@ -164,8 +140,10 @@ static int mkdir_create(PINT_server_op *
  * Synopsis: 
  *           
  */
-static int mkdir_setattrib(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mkdir_setattrib(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t j_id;
     PVFS_ds_attributes *ds_attr = NULL;
@@ -181,20 +159,21 @@ static int mkdir_setattrib(PINT_server_o
 
     gossip_debug(GOSSIP_MKDIR_DEBUG, " setting directory version to "
                  "%llu\n\tmtime is %llu\n", llu(ds_attr->mtime),
-                 llu(PVFS_util_mkversion_time(ds_attr->mtime)));
+                 llu(PINT_util_mkversion_time(ds_attr->mtime)));
 
     ret = job_trove_dspace_setattr(
         s_op->u.mkdir.fs_id, s_op->resp.u.mkdir.handle,
         ds_attr, 
         TROVE_SYNC,
-        s_op, 0, js_p, &j_id, server_job_context);
+        smcb, 0, js_p, &j_id, server_job_context);
 
     return ret;
 }
 
-static int mkdir_create_dirdata_dspace(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mkdir_create_dirdata_dspace(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_ENOMEM;
     job_id_t i;
     PVFS_handle_extent_array extent_array;
@@ -217,7 +196,7 @@ static int mkdir_create_dirdata_dspace(
     ret = job_trove_dspace_create(
         s_op->u.mkdir.fs_id, &extent_array, PVFS_TYPE_DIRDATA, NULL,
         TROVE_SYNC,
-        s_op, 0, js_p, &i,
+        smcb, 0, js_p, &i,
         server_job_context);
 
     free(extent_array.extent_array);
@@ -226,15 +205,16 @@ static int mkdir_create_dirdata_dspace(
     return ret;
 }
 
-static int mkdir_write_dirdata_handle(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mkdir_write_dirdata_handle(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
     if (js_p->error_code)
     {
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     js_p->error_code = 0;
 
@@ -262,20 +242,22 @@ static int mkdir_write_dirdata_handle(
         s_op->u.mkdir.fs_id, s_op->resp.u.mkdir.handle,
         &s_op->key, &s_op->val, 
         0,
-        NULL, s_op, 0, js_p, &i, server_job_context);
+        NULL, smcb, 0, js_p, &i, server_job_context);
 
     return ret;
 }
 
-static int mkdir_error(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mkdir_error(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     s_op->resp.u.mkdir.handle = 0;
 
     if (js_p->error_code > -1)
     {
         js_p->error_code = -PVFS_EINVAL;
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -289,14 +271,16 @@ static int mkdir_error(PINT_server_op *s
  * Synopsis: free memory and return
  *           
  */
-static int mkdir_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mkdir_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
-static int mkdir_prep_sm(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action mkdir_prep_sm(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *a_p = NULL;
     PVFS_ds_attributes *ds_attr = NULL;
 
@@ -309,7 +293,7 @@ static int mkdir_prep_sm(
     if (a_p->objtype != PVFS_TYPE_DIRECTORY)
     {
         js_p->error_code = -PVFS_EINVAL;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     gossip_debug(GOSSIP_MKDIR_DEBUG, " attrs to write: [owner = %d, "
@@ -321,8 +305,24 @@ static int mkdir_prep_sm(
     PVFS_object_attr_to_ds_attr(a_p, ds_attr);
 
     js_p->error_code = 0;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
+
+static inline int PINT_get_object_ref_mkdir(
+    struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
+{
+    *fs_id = req->u.mkdir.fs_id;
+    *handle = PVFS_HANDLE_NULL;
+    return 0;
+};
+
+struct PINT_server_req_params pvfs2_mkdir_params =
+{
+    .string_name = "mkdir",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_modify,
+    .state_machine = &pvfs2_mkdir_sm
+};
 
 /*
  * Local variables:

Index: module.mk.in
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/module.mk.in,v
diff -p -u -r1.46.26.1 -r1.46.26.1.2.1
--- module.mk.in	27 Sep 2006 20:39:17 -0000	1.46.26.1
+++ module.mk.in	21 Jul 2008 18:18:15 -0000	1.46.26.1.2.1
@@ -1,4 +1,5 @@
 BUILD_SERVER = @BUILD_SERVER@
+PVFS2_SEGV_BACKTRACE = @PVFS2_SEGV_BACKTRACE@
 
 ifdef BUILD_SERVER
         DIR := src/server
@@ -12,6 +13,7 @@ ifdef BUILD_SERVER
 		$(DIR)/set-attr.c \
 		$(DIR)/mkdir.c \
 		$(DIR)/get-attr.c \
+		$(DIR)/list-attr.c \
 		$(DIR)/readdir.c \
 		$(DIR)/get-config.c \
 		$(DIR)/remove.c \
@@ -38,21 +40,30 @@ ifdef BUILD_SERVER
 		$(DIR)/get-eattr.c \
 		$(DIR)/set-eattr.c \
 		$(DIR)/del-eattr.c \
-		$(DIR)/list-eattr.c
+		$(DIR)/list-eattr.c \
+		$(DIR)/unexpected.c
 
 	# c files that should be added to server library
 	SERVERSRC += \
 		$(SERVER_SMCGEN)
 
+	# server only file
+	SERVERSRC += $(DIR)/check.c
+
 	# track generate .c files to remove during dist clean, etc. 
 		SMCGEN += $(SERVER_SMCGEN)
 
 	# server code that will be linked manually, not included in library
-	MISCSRC += \
-		$(DIR)/pvfs2-server.c
+	SERVERBINSRC += \
+		$(DIR)/pvfs2-server.c $(DIR)/pvfs2-server-req.c
 
 	# to stat the fs, need to know about handle statistics
-	        MODCFLAGS_$(DIR)/statfs.c = \
-                        -I$(srcdir)/src/io/trove/trove-handle-mgmt
+	MODCFLAGS_$(DIR)/statfs.c = \
+		-I$(srcdir)/src/io/trove/trove-handle-mgmt
+
+ifdef PVFS2_SEGV_BACKTRACE
+	MODCFLAGS_$(DIR)/pvfs2-server.c := -D__PVFS2_SEGV_BACKTRACE__
+endif
+
 endif
 

Index: noop.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/noop.sm,v
diff -p -u -r1.4 -r1.4.28.1
--- noop.sm	5 Jun 2006 19:57:28 -0000	1.4
+++ noop.sm	21 Jul 2008 18:18:15 -0000	1.4.28.1
@@ -12,11 +12,9 @@
 
 #include "pvfs2-server.h"
 
-static int noop_cleanup(PINT_server_op *s_op, job_status_s* js_p);
-
 %%
 
-machine pvfs2_noop_sm(prelude, final_response, cleanup)
+machine pvfs2_noop_sm
 {
 	state prelude
 	{
@@ -44,11 +42,19 @@ machine pvfs2_noop_sm(prelude, final_res
  * cleans up any resources consumed by this state machine and ends
  * execution of the machine
  */
-static int noop_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action noop_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
+struct PINT_server_req_params pvfs2_noop_params =
+{
+    .string_name = "noop",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_readonly,
+    .state_machine = &pvfs2_noop_sm
+};
 
 /*
  * Local variables:

Index: perf-mon.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/perf-mon.sm,v
diff -p -u -r1.11 -r1.11.28.1
--- perf-mon.sm	5 Jun 2006 19:57:28 -0000	1.11
+++ perf-mon.sm	21 Jul 2008 18:18:15 -0000	1.11.28.1
@@ -15,9 +15,6 @@
 #include "pvfs2-server.h"
 #include "pint-perf-counter.h"
 
-static int perf_mon_cleanup(PINT_server_op *s_op, job_status_s* js_p);
-static int perf_mon_do_work(PINT_server_op *s_op, job_status_s* js_p);
-
 static uint64_t* static_start_time_array_ms = NULL;
 static uint64_t* static_interval_array_ms = NULL;
 static int64_t** static_value_matrix = NULL;
@@ -30,7 +27,7 @@ static int reallocate_static_arrays_if_n
 
 %%
 
-machine pvfs2_perf_mon_sm(prelude, do_work, final_response, cleanup)
+machine pvfs2_perf_mon_sm
 {
 	state prelude
 	{
@@ -64,20 +61,24 @@ machine pvfs2_perf_mon_sm(prelude, do_wo
  * cleans up any resources consumed by this state machine and ends
  * execution of the machine
  */
-static int perf_mon_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action perf_mon_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if(s_op->resp.u.mgmt_perf_mon.perf_array)
 	free(s_op->resp.u.mgmt_perf_mon.perf_array);
 
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
 /* perf_mon_do_work()
  *
  * gathers statistics and builds response
  */
-static int perf_mon_do_work(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action perf_mon_do_work(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     struct timeval tv;
     int i;
     int valid_count = 0;
@@ -88,7 +89,7 @@ static int perf_mon_do_work(PINT_server_
 #ifdef __PVFS2_DISABLE_PERF_COUNTERS__
     gossip_err("Error: perf_mon request received, but perf counters are disabled.\n");
     js_p->error_code = -PVFS_ENOSYS;
-    return(1);
+    return SM_ACTION_COMPLETE;
 #endif
 
     /* allocate memory to hold statistics */
@@ -98,7 +99,7 @@ static int perf_mon_do_work(PINT_server_
     if(!s_op->resp.u.mgmt_perf_mon.perf_array)
     {
 	js_p->error_code = -PVFS_ENOMEM;
-	return(1);
+	return SM_ACTION_COMPLETE;
     }
 
     /* fill in some of the response */
@@ -119,7 +120,7 @@ static int perf_mon_do_work(PINT_server_
         free(s_op->resp.u.mgmt_perf_mon.perf_array);
         s_op->resp.u.mgmt_perf_mon.perf_array = NULL;
         js_p->error_code = ret;
-        return(1);
+        return SM_ACTION_COMPLETE;
     }
 
     PINT_perf_retrieve(PINT_server_pc,
@@ -211,7 +212,7 @@ static int perf_mon_do_work(PINT_server_
     }
 
     js_p->error_code = 0;
-    return(1);
+    return SM_ACTION_COMPLETE;
 }
 
 /* reallocate_static_arrays()
@@ -310,6 +311,13 @@ static int reallocate_static_arrays_if_n
 
     return(0);
 }
+
+struct PINT_server_req_params pvfs2_perf_mon_params =
+{
+    .string_name = "mgmt_perf_mon",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .state_machine = &pvfs2_perf_mon_sm
+};
 
 /*
  * Local variables:

Index: perf-update.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/perf-update.sm,v
diff -p -u -r1.8 -r1.8.28.1
--- perf-update.sm	5 Jun 2006 19:57:28 -0000	1.8
+++ perf-update.sm	21 Jul 2008 18:18:15 -0000	1.8.28.1
@@ -15,12 +15,9 @@
 #include "pint-perf-counter.h"
 #include "server-config.h"
 
-static int perf_update_do_work(PINT_server_op *s_op, job_status_s* js_p);
-static int perf_update_error(PINT_server_op *s_op, job_status_s* js_p);
-
 %%
 
-machine pvfs2_perf_update_sm(do_work, error)
+machine pvfs2_perf_update_sm
 {
 	state do_work 
 	{
@@ -43,13 +40,14 @@ machine pvfs2_perf_update_sm(do_work, er
  * cleans up any resources consumed by this state machine and ends
  * execution of the machine
  */
-static int perf_update_error(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action perf_update_error(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     gossip_err("Error: stopping server performance monitoring.\n");
 
     PINT_perf_finalize(PINT_server_pc);
 
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
 /* perf_update_do_work()
@@ -57,7 +55,8 @@ static int perf_update_error(PINT_server
  * resets counters, updates metrices, etc- this is intended to be called
  * repeatedly on a regular interval
  */
-static int perf_update_do_work(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action perf_update_do_work(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     job_id_t tmp_id;
     uint64_t current_mask = 0;
@@ -94,12 +93,18 @@ static int perf_update_do_work(PINT_serv
 	
     /* post another timer */
     return(job_req_sched_post_timer(user_opts->perf_update_interval,
-	s_op,
+	smcb,
 	0,
 	js_p,
 	&tmp_id,
 	server_job_context));
 }
+
+struct PINT_server_req_params pvfs2_perf_update_params =
+{
+    .string_name = "perf_update",
+    .state_machine = &pvfs2_perf_update_sm
+};
 
 
 

Index: prelude.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/prelude.sm,v
diff -p -u -r1.62.2.1 -r1.62.2.1.2.1
--- prelude.sm	14 Jul 2008 19:56:42 -0000	1.62.2.1
+++ prelude.sm	21 Jul 2008 18:18:15 -0000	1.62.2.1.2.1
@@ -4,7 +4,6 @@
  * See COPYING in top-level directory.
  */
 
-
 #include <string.h>
 #include <assert.h>
 
@@ -16,6 +15,7 @@
 #include "pint-util.h"
 #include "pvfs2-internal.h"
 #include "pint-perf-counter.h"
+#include "check.h"
 
 /* prelude state machine:
  * This is a nested state machine that performs initial setup 
@@ -23,31 +23,13 @@
  * - post the request to the request scheduler
  * - check permissions
  */
-static int prelude_req_sched(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int prelude_perm_check(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int prelude_getattr_if_needed(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int prelude_check_acls_if_needed(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int prelude_check_acls(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 enum {
     PRELUDE_RUN_ACL_CHECKS = 1,
 };
 
 %%
 
-nested machine pvfs2_prelude_sm(
-    req_sched,
-    getattr_if_needed,
-    perm_check,
-    check_acls_if_needed,
-    check_acls)
+nested machine pvfs2_prelude_work_sm
 {
     state req_sched
     {
@@ -82,15 +64,45 @@ nested machine pvfs2_prelude_sm(
     }
 }
 
+nested machine pvfs2_prelude_sm
+{
+    state setup
+    {
+        run prelude_setup;
+        default => prelude_work;
+    }
+
+    state prelude_work
+    {
+        jump pvfs2_prelude_work_sm;
+        default => return;
+    }
+}
+
 %%
 
+static PINT_sm_action prelude_setup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    int ret;
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+
+    ret = PINT_server_req_get_object_ref(
+        s_op->req, &s_op->target_fs_id, &s_op->target_handle);
+    s_op->access_type = PINT_server_req_get_access_type(s_op->req);
+    s_op->sched_policy = PINT_server_req_get_sched_policy(s_op->req);
+
+    return SM_ACTION_COMPLETE;
+}
+
 /* prelude_req_sched()
  *
  * posts a request scheduler job
  */
-static int prelude_req_sched(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action prelude_req_sched(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
 
     gossip_debug(GOSSIP_SERVER_DEBUG,
@@ -99,23 +111,9 @@ static int prelude_req_sched(
 
     PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DETAIL_DEBUG, "request\n");
 
-    /* this is the first state for every normal pvfs2 server state
-     * machine, so we get to do some housekeeping here.  In
-     * particular, bump up the reference count on the bmi address that
-     * we are using
-     */
-    BMI_set_info(s_op->addr, BMI_INC_ADDR_REF, NULL);
-
-    /* this is a bit of a hack; if we are changing server mode we must
-     * preserve the old mode value before calling req scheduler
-     */
-    if ((s_op->op == PVFS_SERV_MGMT_SETPARAM) &&
-        (s_op->req->u.mgmt_setparam.param == PVFS_SERV_PARAM_MODE))
-    {
-        s_op->resp.u.mgmt_setparam.old_value = PINT_req_sched_get_mode();
-    }
-    
-    ret = job_req_sched_post(s_op->req, 0, s_op, 0, js_p,
+    ret = job_req_sched_post(s_op->op, s_op->target_fs_id, s_op->target_handle,
+                             s_op->access_type, s_op->sched_policy,
+                             smcb, 0, js_p,
                              &(s_op->scheduled_id), server_job_context);
 
     PINT_perf_count(PINT_server_pc, PINT_PERF_REQSCHED, 1, PINT_PERF_ADD);
@@ -127,10 +125,11 @@ static int prelude_req_sched(
  * reads basic attributes of target object, if there is a particular
  * target object for the operation
  */
-static int prelude_getattr_if_needed(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action prelude_getattr_if_needed(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    int ret = -PVFS_EINVAL, readonly_flag = 0;
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+    int ret = -PVFS_EINVAL;
     job_id_t tmp_id;
 
     PINT_ACCESS_DEBUG(s_op, GOSSIP_ACCESS_DETAIL_DEBUG, "start\n");
@@ -139,23 +138,6 @@ static int prelude_getattr_if_needed(
                  "(%p) %s (prelude sm) state: getattr_if_needed\n", s_op,
                  PINT_map_server_op_to_string(s_op->req->op));
 
-    /* first, run a request scheduler utility function that tells us
-     * what handle this request will operate on
-     */
-    ret = PINT_req_sched_target_handle(
-        s_op->req, 0, &s_op->target_handle, 
-        &s_op->target_fs_id, &readonly_flag);
-
-    if (ret < 0)
-    {
-        gossip_debug(GOSSIP_SERVER_DEBUG, "PINT_req_sched_target_handle "
-                     "returned %d ret, skipping getattr on handle %llu\n",
-                     ret, llu(s_op->target_handle));
-
-        js_p->error_code = ret;
-        return 1;
-    }
-
     /* if the handle is 0, that indicates that the request does not
      * operate on a specific handle, so there is nothing we can do
      * here
@@ -163,7 +145,7 @@ static int prelude_getattr_if_needed(
     if (s_op->target_handle == PVFS_HANDLE_NULL)
     {
         js_p->error_code = 0;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* all other operations fall to this point and read basic
@@ -175,135 +157,12 @@ static int prelude_getattr_if_needed(
                  "for handle %llu\n", llu(s_op->target_handle));
 
     ret = job_trove_dspace_getattr(
-        s_op->target_fs_id, s_op->target_handle,
-        s_op, &(s_op->ds_attr),
+        s_op->target_fs_id, s_op->target_handle, smcb, &(s_op->ds_attr),
         0, js_p, &tmp_id, server_job_context);
 
     return ret;
 }
 
-static void get_fs_intent(struct PVFS_server_req *req, PVFS_fs_id *fsid, int *read_only)
-{
-    if (req == NULL)
-    {
-        *fsid = PVFS_FS_ID_NULL;
-        *read_only = -1;
-        return;
-    }
-    switch (req->op)
-    {
-        case PVFS_SERV_CREATE:
-            *fsid = req->u.create.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_REMOVE:
-            *fsid = req->u.remove.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_IO:
-            *fsid = req->u.io.fs_id;
-            *read_only = (req->u.io.io_type == PVFS_IO_READ) ? 1 : 0;
-            break;
-        case PVFS_SERV_GETATTR:
-            *fsid = req->u.getattr.fs_id;
-            *read_only = 1;
-            break;
-        case PVFS_SERV_SETATTR:
-            *fsid = req->u.setattr.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_LOOKUP_PATH:
-            *fsid = req->u.lookup_path.fs_id;
-            *read_only = 1;
-            break;
-        case PVFS_SERV_CRDIRENT:
-            *fsid = req->u.crdirent.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_RMDIRENT:
-            *fsid = req->u.rmdirent.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_CHDIRENT:
-            *fsid = req->u.chdirent.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_TRUNCATE:
-            *fsid = req->u.truncate.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_MKDIR:
-            *fsid = req->u.mkdir.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_READDIR:
-            *fsid = req->u.readdir.fs_id;
-            *read_only = 1;
-            break;
-        case PVFS_SERV_FLUSH:
-            *fsid = req->u.flush.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_MGMT_SETPARAM:
-            *fsid = req->u.mgmt_setparam.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_STATFS:
-            *fsid = req->u.statfs.fs_id;
-            *read_only = 1;
-            break;
-        case PVFS_SERV_MGMT_ITERATE_HANDLES:
-            *fsid = req->u.mgmt_iterate_handles.fs_id;
-            *read_only = 1;
-            break;
-        case PVFS_SERV_MGMT_DSPACE_INFO_LIST:
-            *fsid = req->u.mgmt_dspace_info_list.fs_id;
-            *read_only = 1;
-            break;
-        case PVFS_SERV_MGMT_REMOVE_OBJECT:
-            *fsid = req->u.mgmt_remove_object.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_MGMT_REMOVE_DIRENT:
-            *fsid = req->u.mgmt_remove_dirent.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_MGMT_GET_DIRDATA_HANDLE:
-            *fsid = req->u.mgmt_get_dirdata_handle.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_GETEATTR:
-            *fsid = req->u.geteattr.fs_id;
-            *read_only = 1;
-            break;
-        case PVFS_SERV_SETEATTR:
-            *fsid = req->u.seteattr.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_DELEATTR:
-            *fsid = req->u.deleattr.fs_id;
-            *read_only = 0;
-            break;
-        case PVFS_SERV_LISTEATTR:
-            *fsid = req->u.listeattr.fs_id;
-            *read_only = 1;
-            break;
-        case PVFS_SERV_PROTO_ERROR:
-        case PVFS_SERV_JOB_TIMER:
-        case PVFS_SERV_MGMT_EVENT_MON:
-        case PVFS_SERV_MGMT_PERF_MON:
-        case PVFS_SERV_PERF_UPDATE:
-        case PVFS_SERV_MGMT_NOOP:
-        case PVFS_SERV_WRITE_COMPLETION:
-        case PVFS_SERV_GETCONFIG:
-        default:
-            *fsid = PVFS_FS_ID_NULL;
-            *read_only = -1;
-            break;
-    }
-    return;
-}
-
 static void get_anon_ids(struct filesystem_configuration_s *fsconfig,
     PVFS_uid *uid, PVFS_gid *gid)
 {
@@ -335,10 +194,25 @@ static int iterate_root_squash_wildcards
 {
     int i;
 
+    /* check exceptions first */
+    for (i = 0; i < fsconfig->root_squash_exceptions_count; i++)
+    {
+        gossip_debug(GOSSIP_SERVER_DEBUG, "BMI_query_addr_range %lld, %s, netmask: %i\n",
+            lld(client_addr), fsconfig->root_squash_exceptions_hosts[i],
+            fsconfig->root_squash_exceptions_netmasks[i]);
+        if (BMI_query_addr_range(client_addr, fsconfig->root_squash_exceptions_hosts[i], 
+                fsconfig->root_squash_exceptions_netmasks[i]) == 1)
+        {
+            /* in the exception list, do not squash */
+            return 0;
+        }
+    }
+
     for (i = 0; i < fsconfig->root_squash_count; i++)
     {
-        gossip_debug(GOSSIP_SERVER_DEBUG, "BMI_query_addr_range %lld, %s\n",
-            lld(client_addr), fsconfig->root_squash_hosts[i]);
+        gossip_debug(GOSSIP_SERVER_DEBUG, "BMI_query_addr_range %lld, %s, netmask: %i\n",
+            lld(client_addr), fsconfig->root_squash_hosts[i],
+            fsconfig->root_squash_netmasks[i]);
         if (BMI_query_addr_range(client_addr, fsconfig->root_squash_hosts[i], 
                 fsconfig->root_squash_netmasks[i]) == 1)
         {
@@ -415,15 +289,20 @@ static int iterate_ro_wildcards(struct f
     return 0;
 }
 
-static int permit_operation(PVFS_fs_id fsid, int read_only, PVFS_BMI_addr_t client_addr)
+/*
+ * Return zero if this operation should be allowed.
+ */
+static int permit_operation(PVFS_fs_id fsid,
+                            enum PINT_server_req_access_type access_type,
+                            PVFS_BMI_addr_t client_addr)
 { 
     int exp_flags = 0; 
     struct server_configuration_s *serv_config = NULL;
     struct filesystem_configuration_s * fsconfig = NULL;
 
-    if (read_only == 1)
+    if (access_type == PINT_SERVER_REQ_READONLY)
     {
-        return 0;
+        return 0;  /* anything that doesn't modify state is okay */
     }
     serv_config = PINT_get_server_config();
     fsconfig = PINT_config_find_fs_id(serv_config, fsid);
@@ -457,15 +336,17 @@ static int permit_operation(PVFS_fs_id f
  * permission checking, it will be replaced by a couple of states that
  * actually perform this task later
  */
-static int prelude_perm_check(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action prelude_perm_check(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *obj_attr = NULL;
     PVFS_ds_attributes *ds_attr = NULL;
     PVFS_uid translated_uid = s_op->req->credentials.uid;
     PVFS_gid translated_gid = s_op->req->credentials.gid;
-    PVFS_fs_id  fsid;
-    int  rdonly = -1;
+    PVFS_fs_id  fsid = PVFS_FS_ID_NULL;
+    int squashed_flag = 0;
+    int skip_acl_flag = 0;
 
     /* moved gossip server debug output to end of state, so we can report
      * resulting status value.
@@ -482,36 +363,17 @@ static int prelude_perm_check(
     /* Set the target object attribute pointer.. used later by the acl check */
     s_op->target_object_attr = obj_attr;
 
-    /* Commenting out the below block for now.  I think this code is
-     * deprecated?  Even if not all of the attributes have been filled in
-     * yet, we should still be able to read them after the object has been
-     * created.  If this change seems stable then we need to also come back
-     * and remove the PINT_SERVER_ATTRIBS_NOT_REQUIRED flag. -Phil 4-13-2006
-     */
-#if 0
-    /* the next thing we need to do is interpret the error code from
-     * reading the attributes.  Normally it is an error if that step
-     * failed, but we have to look for the special case in which we
-     * set attributes on a file that did not have attributes
-     * previously.
-     */
-    if (PINT_server_req_table[s_op->req->op].attrib_flags ==
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED)
-    {
-        js_p->error_code = 0;
-    }
-#endif
-    get_fs_intent(s_op->req, &fsid, &rdonly);
-    if (fsid != PVFS_FS_ID_NULL)
+    if (s_op->target_fs_id != PVFS_FS_ID_NULL)
     {
         /*
          * if we are exporting a volume readonly, disallow any operation that modifies
          * the state of the file-system.
          */
-        if (permit_operation(fsid, rdonly, s_op->addr) < 0)
+        if (permit_operation(
+                s_op->target_fs_id, s_op->access_type, s_op->addr) < 0)
         {
             js_p->error_code = -PVFS_EROFS;
-            return 1;
+            return SM_ACTION_COMPLETE;
         }
         else 
         {
@@ -519,6 +381,7 @@ static int prelude_perm_check(
             if (translate_ids(fsid, s_op->req->credentials.uid, s_op->req->credentials.gid,
                 &translated_uid, &translated_gid, s_op->addr) == 1)
             {
+                squashed_flag = 1;
                 s_op->req->credentials.uid = translated_uid;
                 s_op->req->credentials.gid = translated_gid;
                 /* in the case of a setattr, translate the ids as well right here */
@@ -540,7 +403,7 @@ static int prelude_perm_check(
     if (js_p->error_code)
     {
         js_p->error_code = -PVFS_ERROR_CODE(-js_p->error_code);
-        return(1);
+        return SM_ACTION_COMPLETE;
     }
 
     gossip_debug(
@@ -554,7 +417,7 @@ static int prelude_perm_check(
         ((s_op->attr.mask & PVFS_ATTR_COMMON_GID) ? "yes" : "no"),
         s_op->attr.group, translated_gid);
     
-    switch(PINT_server_req_table[s_op->req->op].perm)
+    switch(PINT_server_req_get_perms(s_op->req))
     {
         case PINT_SERVER_CHECK_WRITE:
             js_p->error_code = PINT_check_mode(
@@ -621,7 +484,27 @@ static int prelude_perm_check(
             }
             break;
         case PINT_SERVER_CHECK_NONE:
-            js_p->error_code = 0;
+            if(squashed_flag &&
+               PINT_server_req_get_access_type(s_op->req) == PINT_SERVER_REQ_MODIFY &&
+               ((s_op->req->op == PVFS_SERV_IO) ||
+                (s_op->req->op == PVFS_SERV_SMALL_IO) ||
+                (s_op->req->op == PVFS_SERV_TRUNCATE)))
+            {
+                /* special case:
+                 * If we have been squashed, deny write permission to the
+                 * file system.  At the datafile level we don't have enough
+                 * attribute information to figure out if the nobody/guest
+                 * user has permission to write or not, so we disallow all
+                 * writes to be safe.  Not perfect semantics, but better
+                 * than being too permissive.
+                 */
+                skip_acl_flag = 1;
+                js_p->error_code = -PVFS_EACCES;
+            }
+            else
+            {
+                js_p->error_code = 0;
+            }
             break;
         case PINT_SERVER_CHECK_INVALID:
             js_p->error_code = -PVFS_EINVAL;
@@ -639,15 +522,16 @@ static int prelude_perm_check(
         PINT_map_server_op_to_string(s_op->req->op),
 	js_p->error_code);
     /* If regular checks fail, we need to run acl checks */
-    if (js_p->error_code == -PVFS_EACCES)
+    if (js_p->error_code == -PVFS_EACCES && !skip_acl_flag)
         js_p->error_code = PRELUDE_RUN_ACL_CHECKS;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 
-static int prelude_check_acls_if_needed(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action prelude_check_acls_if_needed(
+    struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -662,7 +546,7 @@ static int prelude_check_acls_if_needed(
         || s_op->target_handle == PVFS_HANDLE_NULL)
     {
         js_p->error_code = -PVFS_EACCES;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     js_p->error_code = 0;
 
@@ -674,7 +558,7 @@ static int prelude_check_acls_if_needed(
     if (!s_op->val.buffer)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     s_op->val.buffer_sz = PVFS_REQ_LIMIT_VAL_LEN;
 
@@ -689,7 +573,7 @@ static int prelude_check_acls_if_needed(
         &s_op->val,
         0,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &i,
@@ -697,9 +581,10 @@ static int prelude_check_acls_if_needed(
     return ret;
 }
 
-static int prelude_check_acls(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action prelude_check_acls(
+    struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *obj_attr = NULL;
     int want = 0;
 
@@ -722,7 +607,7 @@ static int prelude_check_acls(
         js_p->error_code = -PVFS_EINVAL;
         goto cleanup;
     }
-    switch (PINT_server_req_table[s_op->req->op].perm)
+    switch (PINT_server_req_get_perms(s_op->req))
     {
         case PINT_SERVER_CHECK_WRITE:
         default:
@@ -758,7 +643,7 @@ cleanup:
         free(s_op->val.buffer);
     memset(&s_op->key, 0, sizeof(PVFS_ds_keyval));
     memset(&s_op->val, 0, sizeof(PVFS_ds_keyval));
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*

Index: proto-error.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/proto-error.sm,v
diff -p -u -r1.4 -r1.4.28.1
--- proto-error.sm	5 Jun 2006 19:57:28 -0000	1.4
+++ proto-error.sm	21 Jul 2008 18:18:15 -0000	1.4.28.1
@@ -13,12 +13,9 @@
 #include "pvfs2-server.h"
 #include "server-config.h"
 
-static int proto_error_cleanup(PINT_server_op *s_op, job_status_s* js_p);
-static int proto_error_init(PINT_server_op *s_op, job_status_s* js_p);
-
 %%
 
-machine pvfs2_proto_error_sm(init, cleanup)
+machine pvfs2_proto_error_sm
 {
 	state init
 	{
@@ -39,8 +36,10 @@ machine pvfs2_proto_error_sm(init, clean
  *
  * encode and send a response indicating a protocol error
  */
-static int proto_error_init(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action proto_error_init(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret;
     job_id_t tmp_id;
     struct server_configuration_s *user_opts = get_server_config_struct();
@@ -63,7 +62,7 @@ static int proto_error_init(PINT_server_
 	 * some clues as to what went wrong
 	 */
 	js_p->error_code = ret;
-	return 1;
+	return SM_ACTION_COMPLETE;
     }
 
     /* send the response */
@@ -75,7 +74,7 @@ static int proto_error_init(PINT_server_
 			    s_op->tag,
 			    s_op->encoded.buffer_type,
 			    0,
-			    s_op,
+			    smcb,
 			    0,
 			    js_p,
 			    &tmp_id,
@@ -90,10 +89,17 @@ static int proto_error_init(PINT_server_
  * cleans up any resources consumed by this state machine and ends
  * execution of the machine
  */
-static int proto_error_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action proto_error_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+struct PINT_server_req_params pvfs2_proto_error_params =
+{
+    .string_name = "proto_error",
+    .state_machine = &pvfs2_proto_error_sm
+};
 
 
 /*

Index: pvfs2-server.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/pvfs2-server.c,v
diff -p -u -r1.226.2.1 -r1.226.2.1.2.1
--- pvfs2-server.c	27 Sep 2006 20:39:17 -0000	1.226.2.1
+++ pvfs2-server.c	21 Jul 2008 18:18:15 -0000	1.226.2.1.2.1
@@ -30,9 +30,8 @@
 #include "pvfs2-debug.h"
 #include "pvfs2-storage.h"
 #include "PINT-reqproto-encode.h"
-#include "src/server/request-scheduler/request-scheduler.h"
 #include "pvfs2-server.h"
-#include "state-machine-fns.h"
+#include "state-machine.h"
 #include "mkspace.h"
 #include "server-config.h"
 #include "quicklist.h"
@@ -44,6 +43,8 @@
 #include "pint-cached-config.h"
 #include "pvfs2-internal.h"
 #include "lock-storage.h"
+#include "src/server/request-scheduler/request-scheduler.h"
+#include "pint-util.h"
 
 #ifndef PVFS2_VERSION
 #define PVFS2_VERSION "Unknown"
@@ -94,9 +95,11 @@ static int signal_recvd_flag = 0;
 static pid_t server_controlling_pid = 0;
 
 /* A list of all serv_op's posted for unexpected message alone */
-static QLIST_HEAD(posted_sop_list);
+QLIST_HEAD(posted_sop_list);
 /* A list of all serv_op's posted for expected messages alone */
-static QLIST_HEAD(inprogress_sop_list);
+QLIST_HEAD(inprogress_sop_list);
+/* A list of all serv_op's that are started automatically without requests */
+static QLIST_HEAD(noreq_sop_list);
 
 /* this is used externally by some server state machines */
 job_context_id server_job_context = -1;
@@ -107,9 +110,11 @@ typedef struct
     int server_create_storage_space;
     int server_background;
     char *pidfile;
+    char *server_alias;
 } options_t;
 
-static options_t s_server_options = { 0, 0, 1, NULL };
+static options_t s_server_options = { 0, 0, 1, NULL, NULL};
+static char *fs_conf = NULL;
 
 /* each of the elements in this array consists of a string and its length.
  * we're able to use sizeof here because sizeof an inlined string ("") gives
@@ -117,21 +122,11 @@ static options_t s_server_options = { 0,
  */
 PINT_server_trove_keys_s Trove_Common_Keys[] =
 {
-    {ROOT_HANDLE_KEYSTR, sizeof(ROOT_HANDLE_KEYSTR)},
-    {DIRECTORY_ENTRY_KEYSTR, sizeof(DIRECTORY_ENTRY_KEYSTR)},
-    {DATAFILE_HANDLES_KEYSTR, sizeof(DATAFILE_HANDLES_KEYSTR)},
-    {METAFILE_DIST_KEYSTR, sizeof(METAFILE_DIST_KEYSTR)},
-    {SYMLINK_TARGET_KEYSTR, sizeof(SYMLINK_TARGET_KEYSTR)}
-};
-
-/* extended attribute name spaces supported in PVFS2 */
-const char *PINT_eattr_namespaces[] =
-{
-    "system.",
-    "user.",
-    "trusted.",
-    "security.",
-    NULL
+    {ROOT_HANDLE_KEYSTR, ROOT_HANDLE_KEYLEN},
+    {DIRECTORY_ENTRY_KEYSTR, DIRECTORY_ENTRY_KEYLEN},
+    {DATAFILE_HANDLES_KEYSTR, DATAFILE_HANDLES_KEYLEN},
+    {METAFILE_DIST_KEYSTR, METAFILE_DIST_KEYLEN},
+    {SYMLINK_TARGET_KEYSTR, SYMLINK_TARGET_KEYLEN}
 };
 
 /* These three are used continuously in our wait loop.  They could be
@@ -155,266 +150,16 @@ static int server_shutdown(
     PINT_server_status_flag status,
     int ret, int sig);
 static void server_sig_handler(int sig);
-static int server_post_unexpected_recv(job_status_s * js_p);
 static int server_parse_cmd_line_args(int argc, char **argv);
-static int server_state_machine_start(
-    PINT_server_op *s_op, job_status_s *js_p);
 #ifdef __PVFS2_SEGV_BACKTRACE__
 static void bt_sighandler(int sig, siginfo_t *info, void *secret);
 #endif
 static int create_pidfile(char *pidfile);
 static void write_pidfile(int fd);
 static void remove_pidfile(void);
-static int parse_port_from_host_id(char* host_id);
+static int generate_shm_key_hint(void);
 
-/* table of incoming request types and associated parameters */
-struct PINT_server_req_params PINT_server_req_table[] =
-{
-    /* 0 */
-    {PVFS_SERV_INVALID,
-        "invalid",
-        PINT_SERVER_CHECK_INVALID,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        NULL},
-
-    /* 1 */
-    {PVFS_SERV_CREATE,
-        "create",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_create_sm},
-
-    /* 2 */
-    {PVFS_SERV_REMOVE,
-        "remove",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_remove_sm},
-
-    /* 3 */
-    {PVFS_SERV_IO,
-        "io",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_io_sm},
-
-    /* 4 */
-    {PVFS_SERV_GETATTR,
-        "getattr",
-        PINT_SERVER_CHECK_ATTR,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_get_attr_sm},
-
-    /* 5 */
-    {PVFS_SERV_SETATTR,
-        "setattr",
-        PINT_SERVER_CHECK_ATTR,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_set_attr_sm},
-
-    /* 6 */
-    {PVFS_SERV_LOOKUP_PATH,
-        "lookup_path",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_lookup_sm},
-
-    /* 7 */
-    {PVFS_SERV_CRDIRENT,
-        "crdirent",
-        PINT_SERVER_CHECK_CRDIRENT,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_crdirent_sm},
-
-    /* 8 */
-    {PVFS_SERV_RMDIRENT,
-        "rmdirent",
-        PINT_SERVER_CHECK_WRITE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_rmdirent_sm},
-
-    /* 9 */
-    {PVFS_SERV_CHDIRENT,
-        "chdirent",
-        PINT_SERVER_CHECK_WRITE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_chdirent_sm},
-
-    /* 10 */
-    {PVFS_SERV_TRUNCATE,
-        "truncate",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_truncate_sm},
-
-    /* 11 */
-    {PVFS_SERV_MKDIR,
-        "mkdir",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_mkdir_sm},
-
-    /* 12 */
-    {PVFS_SERV_READDIR,
-        "readdir",
-        PINT_SERVER_CHECK_READ,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_readdir_sm},
-
-    /* 13 */
-    {PVFS_SERV_GETCONFIG,
-        "getconfig",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_get_config_sm},
-
-    /* 14 */
-    {PVFS_SERV_WRITE_COMPLETION,
-        "write_completion",
-        PINT_SERVER_CHECK_INVALID,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        NULL},
-
-    /* 15 */
-    {PVFS_SERV_FLUSH,
-        "flush",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_flush_sm},
-
-    /* 16 */
-    {PVFS_SERV_MGMT_SETPARAM,
-        "mgmt_setparam",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_setparam_sm},
-
-    /* 17 */
-    {PVFS_SERV_MGMT_NOOP,
-        "mgmt_noop",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_noop_sm},
-
-    /* 18 */
-    {PVFS_SERV_STATFS,
-        "statfs",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_statfs_sm},
-
-    /* 19 */
-    {PVFS_SERV_PERF_UPDATE,
-        "perf_update",
-        PINT_SERVER_CHECK_INVALID,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_perf_update_sm},
-
-    /* 20 */
-    {PVFS_SERV_MGMT_PERF_MON,
-        "mgmt_perf_mon",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_perf_mon_sm},
-
-    /* 21 */
-    {PVFS_SERV_MGMT_ITERATE_HANDLES,
-        "mgmt_iterate_handles",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_iterate_handles_sm},
-
-    /* 22 */
-    {PVFS_SERV_MGMT_DSPACE_INFO_LIST,
-        "mgmt_dspace_info_list",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        NULL},
-
-    /* 23 */
-    {PVFS_SERV_MGMT_EVENT_MON,
-        "mgmt_event_mon",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_event_mon_sm},
-
-    /* 24 */
-    {PVFS_SERV_MGMT_REMOVE_OBJECT,
-        "mgmt-remove-object",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_mgmt_remove_object_sm},
-
-    /* 25 */
-    {PVFS_SERV_MGMT_REMOVE_DIRENT,
-        "mgmt-remove-dirent",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_mgmt_remove_dirent_sm},
-
-    /* 26 */
-    {PVFS_SERV_MGMT_GET_DIRDATA_HANDLE,
-        "mgmt-get-dirdata-handle",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_mgmt_get_dirdata_handle_sm},
-
-    /* 27 */
-    {PVFS_SERV_JOB_TIMER,
-        "job_timer",
-        PINT_SERVER_CHECK_INVALID,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_job_timer_sm},
-
-    /* 28 */
-    {PVFS_SERV_PROTO_ERROR,
-        "proto_error",
-        PINT_SERVER_CHECK_INVALID,
-        PINT_SERVER_ATTRIBS_REQUIRED,
-        &pvfs2_proto_error_sm},
-
-    /* 29 */
-    {PVFS_SERV_GETEATTR,
-        "geteattr",
-        PINT_SERVER_CHECK_ATTR,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_get_eattr_sm},
-
-    /* 30 */
-    {PVFS_SERV_SETEATTR,
-        "seteattr",
-        PINT_SERVER_CHECK_ATTR,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_set_eattr_sm},
-
-    /* 31 */
-    {PVFS_SERV_DELEATTR,
-        "deleattr",
-        PINT_SERVER_CHECK_ATTR,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_del_eattr_sm},
-
-    /* 32 */
-    {PVFS_SERV_LISTEATTR,
-        "listeattr",
-        PINT_SERVER_CHECK_ATTR,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-        &pvfs2_list_eattr_sm},
-
-    /* 33 */
-    {PVFS_SERV_SMALL_IO,
-        "small_io",
-        PINT_SERVER_CHECK_NONE,
-        PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-     &pvfs2_small_io_sm},
-
-    /* 34 */
-    {PVFS_SERV_LOCK,
-     "lock",
-     PINT_SERVER_CHECK_NONE,
-     PINT_SERVER_ATTRIBS_NOT_REQUIRED,
-     &pvfs2_lock_sm}
-};
+static TROVE_method_id trove_coll_to_method_callback(TROVE_coll_id);
 
 struct server_configuration_s *PINT_get_server_config(void)
 {
@@ -424,8 +169,7 @@ struct server_configuration_s *PINT_get_
 int main(int argc, char **argv)
 {
     int ret = -1, siglevel = 0;
-    char *fs_conf = NULL, *server_conf = NULL;
-    PINT_server_op *tmp_op = NULL;
+    struct PINT_smcb *tmp_op = NULL;
     uint64_t debug_mask = 0;
 
 #ifdef WITH_MTRACE
@@ -456,20 +200,24 @@ int main(int argc, char **argv)
         goto server_shutdown;
     }
 
-    gossip_debug(GOSSIP_SERVER_DEBUG,
-                 "PVFS2 Server version %s starting.\n", PVFS2_VERSION);
+    gossip_debug_fp(stderr, 'S', GOSSIP_LOGSTAMP_DATETIME,
+                    "PVFS2 Server on node %s version %s starting...\n",
+                    s_server_options.server_alias, PVFS2_VERSION);
 
-    fs_conf = ((argc >= optind) ? argv[optind] : NULL);
-    server_conf = ((argc >= (optind + 1)) ? argv[optind + 1] : NULL);
+    /* code to handle older two config file format */
 
-    ret = PINT_parse_config(&server_config, fs_conf, server_conf);
-    if (ret < 0)
+    ret = PINT_parse_config(&server_config, fs_conf, s_server_options.server_alias);
+    if (ret)
     {
-        gossip_err("Error: Please check your config files.\n");  
+        gossip_err("Error: Please check your config files.\n");
         gossip_err("Error: Server aborting.\n");
+        free(s_server_options.server_alias);
+        ret = -PVFS_EINVAL;
         goto server_shutdown;
     }
 
+    free(s_server_options.server_alias);
+
     server_status_flag |= SERVER_CONFIG_INIT;
 
     if (!PINT_config_is_valid_configuration(&server_config))
@@ -584,6 +332,9 @@ int main(int argc, char **argv)
         goto server_shutdown;
     }
 
+    gossip_debug_fp(stderr, 'S', GOSSIP_LOGSTAMP_DATETIME,
+                    "PVFS2 Server ready.\n");
+
     /* Initialization complete; process server requests indefinitely. */
     for ( ;; )  
     {
@@ -626,76 +377,24 @@ int main(int argc, char **argv)
         */
         for (i = 0; i < comp_ct; i++)
         {
-            int unexpected_msg = 0;
-            PINT_server_op *s_op = server_completed_job_p_array[i];
-
-            /* Completed jobs might be ongoing, or might be new
-             * (unexpected) ones.  We handle the first step of either
-             * type here.
-             */
-            if (s_op->op == BMI_UNEXPECTED_OP)
-            {
-                unexpected_msg = 1;
-                memset(&server_job_status_array[i], 0,
-                       sizeof(job_status_s));
-                ret = server_state_machine_start(
-                    s_op, &server_job_status_array[i]);
-                if (ret < 0)
-                {
-                    PVFS_perror_gossip("Error: server_state_machine_start", ret);
-                    /* TODO: tell BMI to drop this address? */
-                    /* set return code to zero to allow server to continue
-                     * processing 
-                     */
-                    ret = 0;
-                }
-            }
-            else
-            {
-                /* NOTE: PINT_state_machine_next() is a function that
-                 * is shared with the client-side state machine
-                 * processing, so it is defined in the src/common
-                 * directory.
-                 */
-                ret = PINT_state_machine_next(
-                    s_op, &server_job_status_array[i]);
-            }
+            /* int unexpected_msg = 0; */
+            struct PINT_smcb *smcb = server_completed_job_p_array[i];
 
-            /* Either of the above might have completed immediately
-             * (ret == 1).  While the job continues to complete
-             * immediately, we continue to service it.
-             */
-            while (ret == 1)
-            {
-                ret = PINT_state_machine_next(
-                    s_op, &server_job_status_array[i]);
-            }
+               /* NOTE: PINT_state_machine_next() is a function that
+                * is shared with the client-side state machine
+                * processing, so it is defined in the src/common
+                * directory.
+                */
+            ret = PINT_state_machine_continue(
+                    smcb, &server_job_status_array[i]);
 
-            if (ret < 0)
+            if (SM_ACTION_ISERR(ret)) /* ret < 0 */
             {
                 PVFS_perror_gossip("Error: state machine processing error", ret);
                 ret = 0;
             }
 
-            if (unexpected_msg)
-            {
-                /* If this was a new (unexpected) job, we need to post
-                 * a replacement unexpected job so that we can
-                 * continue to receive incoming requests.
-                 */
-                ret = server_post_unexpected_recv(
-                    &server_job_status_array[i]);
-                if (ret < 0)
-                {
-                    /* TODO: do something here, the return value was
-                     * not being checked for failure before.  I just
-                     * put something here to make it exit for the
-                     * moment.  -Phil
-                     */
-                    gossip_lerr("Error: post unexpected failure not handled.\n");
-                    goto server_shutdown;
-                }
-            }
+            /* else ret == SM_ACTION_DEFERED */
         }
     }
 
@@ -752,15 +451,19 @@ static int server_initialize(
     uint64_t debug_mask = 0;
     
     assert(server_config.logfile != NULL);
-    dummy = fopen(server_config.logfile, "a");
-    if (dummy == NULL)
+
+    if(!strcmp(server_config.logtype, "file"))
     {
-        int tmp_errno = errno;
-        gossip_err("error opening log file %s\n",
-                server_config.logfile);
-        return -tmp_errno;
+        dummy = fopen(server_config.logfile, "a");
+        if (dummy == NULL)
+        {
+            int tmp_errno = errno;
+            gossip_err("error opening log file %s\n",
+                    server_config.logfile);
+            return -tmp_errno;
+        }
+        fclose(dummy);
     }
-    fclose(dummy);
 
     /* redirect gossip to specified target if backgrounded */
     if (s_server_options.server_background)
@@ -769,13 +472,24 @@ static int server_initialize(
         freopen("/dev/null", "w", stdout);
         freopen("/dev/null", "w", stderr);
 
-        ret = gossip_enable_file(server_config.logfile, "a");
+        if(!strcmp(server_config.logtype, "syslog"))
+        {
+            ret = gossip_enable_syslog(LOG_INFO);
+        }
+        else if(!strcmp(server_config.logtype, "file"))
+        {
+            ret = gossip_enable_file(server_config.logfile, "a");
+        }
+        else
+        {
+            ret = gossip_enable_stderr();
+        }
+
         if (ret < 0)
         {
-            int tmp_errno = errno;
-            gossip_lerr("error opening log file %s\n",
+            gossip_err("error opening log file %s\n",
                         server_config.logfile);
-            return -tmp_errno;
+            return ret;
         }
         /* log starting message again so it appears in log file, not just
          * console
@@ -860,7 +574,7 @@ static int server_setup_process_environm
 
     if (chdir("/"))
     {
-        gossip_lerr("cannot change working directory to \"/\" "
+        gossip_err("cannot change working directory to \"/\" "
                     "(errno = %x). aborting.\n", errno);
         return(-PVFS_EINVAL);
     }
@@ -872,7 +586,7 @@ static int server_setup_process_environm
         new_pid = fork();
         if (new_pid < 0)
         {
-            gossip_lerr("error in fork() system call (errno = %x). "
+            gossip_err("error in fork() system call (errno = %x). "
                         "aborting.\n", errno);
             return(-PVFS_EINVAL);
         }
@@ -885,7 +599,7 @@ static int server_setup_process_environm
         new_pid = setsid();
         if (new_pid < 0)
         {
-            gossip_lerr("error in setsid() system call.  aborting.\n");
+            gossip_err("error in setsid() system call.  aborting.\n");
             return(-PVFS_EINVAL);
         }
     }
@@ -919,7 +633,6 @@ static int server_initialize_subsystems(
     PINT_server_status_flag *server_status_flag)
 {
     int ret = -PVFS_EINVAL;
-    char *method_name = NULL;
     char *cur_merged_handle_range = NULL;
     PINT_llist *cur = NULL;
     struct filesystem_configuration_s *cur_fs;
@@ -927,8 +640,8 @@ static int server_initialize_subsystems(
     char buf[16] = {0};
     PVFS_fs_id orig_fsid;
     PVFS_ds_flags init_flags = 0;
-    int port_num = 0;
     int bmi_flags = BMI_INIT_SERVER;
+    int shm_key_hint;
 
     /* Initialize distributions */
     ret = PINT_dist_initialize(0);
@@ -980,24 +693,16 @@ static int server_initialize_subsystems(
                                    &server_config.db_cache_size_bytes);
     /* this should never fail */
     assert(ret == 0);
-    ret = trove_collection_setinfo(0, 0, TROVE_ALT_AIO_MODE,
-        &server_config.trove_alt_aio_mode);
-    /* this should never fail */
-    assert(ret == 0);
     ret = trove_collection_setinfo(0, 0, TROVE_MAX_CONCURRENT_IO,
-        &server_config.trove_max_concurrent_io);
+                                   &server_config.trove_max_concurrent_io);
     /* this should never fail */
     assert(ret == 0);
 
-    /* parse port number and allow trove to use it to help differentiate
-     * shmem regions if needed
-     */
-    port_num = parse_port_from_host_id(server_config.host_id);
-    if(port_num > 0)
-    {
-        ret = trove_collection_setinfo(0, 0, TROVE_SHM_KEY_HINT, &port_num);
-        assert(ret == 0);
-    }
+    /* help trove chose a differentiating shm key if needed for Berkeley DB */
+    shm_key_hint = generate_shm_key_hint();
+    gossip_debug(GOSSIP_SERVER_DEBUG, "Server using shm key hint: %d\n", shm_key_hint);
+    ret = trove_collection_setinfo(0, 0, TROVE_SHM_KEY_HINT, &shm_key_hint);
+    assert(ret == 0);
 
     if(server_config.db_cache_type && (!strcmp(server_config.db_cache_type,
                                                "mmap")))
@@ -1012,8 +717,11 @@ static int server_initialize_subsystems(
     BMI_set_info(0, BMI_TCP_BUFFER_RECEIVE_SIZE, 
                  (void *)&server_config.tcp_buffer_size_receive);
 
-    ret = trove_initialize(server_config.storage_path,
-                           init_flags, &method_name, 0);
+    ret = trove_initialize(
+        server_config.trove_method, 
+        trove_coll_to_method_callback,
+        server_config.storage_path,
+        init_flags);
     if (ret < 0)
     {
         PVFS_perror_gossip("Error: trove_initialize", ret);
@@ -1060,7 +768,7 @@ static int server_initialize_subsystems(
             break;
         }
 
-        ret = PINT_handle_load_mapping(&server_config, cur_fs);
+        ret = PINT_cached_config_handle_load_mapping(cur_fs);
         if(ret)
         {
             PVFS_perror("Error: PINT_handle_load_mapping", ret);
@@ -1069,11 +777,12 @@ static int server_initialize_subsystems(
 
         orig_fsid = cur_fs->coll_id;
         ret = trove_collection_lookup(
+            cur_fs->trove_method,
             cur_fs->file_system_name, &(cur_fs->coll_id), NULL, NULL);
 
         if (ret < 0)
         {
-            gossip_lerr("Error initializing filesystem %s\n",
+            gossip_err("Error initializing filesystem %s\n",
                         cur_fs->file_system_name);
             return ret;
         }
@@ -1107,7 +816,7 @@ static int server_initialize_subsystems(
          */
         if (!cur_merged_handle_range)
         {
-            gossip_lerr("Error: Invalid handle range for host %s "
+            gossip_err("Error: Invalid handle range for host %s "
                         "(alias %s) specified in file system %s\n",
                         server_config.host_id,
                         PINT_config_get_host_alias_ptr(
@@ -1120,7 +829,7 @@ static int server_initialize_subsystems(
             ret = trove_open_context(cur_fs->coll_id, &trove_context);
             if (ret < 0)
             {
-                gossip_lerr("Error initializing trove context\n");
+                gossip_err("Error initializing trove context\n");
                 return ret;
             }
 
@@ -1135,7 +844,7 @@ static int server_initialize_subsystems(
                 (void *)&cur_fs->handle_recycle_timeout_sec);
             if (ret < 0)
             {
-                gossip_lerr("Error setting handle timeout\n");
+                gossip_err("Error setting handle timeout\n");
             }
 
             if (cur_fs->attr_cache_keywords &&
@@ -1148,7 +857,7 @@ static int server_initialize_subsystems(
                     (void *)cur_fs->attr_cache_keywords);
                 if (ret < 0)
                 {
-                    gossip_lerr("Error setting attr cache keywords\n");
+                    gossip_err("Error setting attr cache keywords\n");
                 }
                 ret = trove_collection_setinfo(
                     cur_fs->coll_id, trove_context, 
@@ -1156,7 +865,7 @@ static int server_initialize_subsystems(
                     (void *)&cur_fs->attr_cache_size);
                 if (ret < 0)
                 {
-                    gossip_lerr("Error setting attr cache size\n");
+                    gossip_err("Error setting attr cache size\n");
                 }
                 ret = trove_collection_setinfo(
                     cur_fs->coll_id, trove_context, 
@@ -1164,7 +873,7 @@ static int server_initialize_subsystems(
                     (void *)&cur_fs->attr_cache_max_num_elems);
                 if (ret < 0)
                 {
-                    gossip_lerr("Error setting attr cache max num elems\n");
+                    gossip_err("Error setting attr cache max num elems\n");
                 }
                 ret = trove_collection_setinfo(
                     cur_fs->coll_id, trove_context, 
@@ -1172,7 +881,7 @@ static int server_initialize_subsystems(
                     (void *)0);
                 if (ret < 0)
                 {
-                    gossip_lerr("Error initializing the attr cache\n");
+                    gossip_err("Error initializing the attr cache\n");
                 }
             }
 
@@ -1188,7 +897,7 @@ static int server_initialize_subsystems(
                 (void *)cur_merged_handle_range);
             if (ret < 0)
             {
-                gossip_lerr("Error adding handle range %s to "
+                gossip_err("Error adding handle range %s to "
                             "filesystem %s\n",
                             cur_merged_handle_range,
                             cur_fs->file_system_name);
@@ -1201,7 +910,7 @@ static int server_initialize_subsystems(
                 (void *)&cur_fs->coalescing_high_watermark);
             if(ret < 0)
             {
-                gossip_lerr("Error setting coalescing high watermark\n");
+                gossip_err("Error setting coalescing high watermark\n");
                 return ret;
             }
 
@@ -1211,7 +920,7 @@ static int server_initialize_subsystems(
                 (void *)&cur_fs->coalescing_low_watermark);
             if(ret < 0)
             {
-                gossip_lerr("Error setting coalescing low watermark\n");
+                gossip_err("Error setting coalescing low watermark\n");
                 return ret;
             }
             
@@ -1221,7 +930,7 @@ static int server_initialize_subsystems(
                 (void *)&cur_fs->trove_sync_meta);
             if(ret < 0)
             {
-                gossip_lerr("Error setting coalescing low watermark\n");
+                gossip_err("Error setting coalescing low watermark\n");
                 return ret;
             } 
             
@@ -1231,7 +940,7 @@ static int server_initialize_subsystems(
                 (void *)&cur_fs->immediate_completion);
             if(ret < 0)
             {
-                gossip_lerr("Error setting trove immediate completion\n");
+                gossip_err("Error setting trove immediate completion\n");
                 return ret;
             } 
 
@@ -1526,7 +1235,7 @@ static int server_shutdown(
     {
         gossip_debug(GOSSIP_SERVER_DEBUG, "[+] halting storage "
                      "interface         [   ...   ]\n");
-        trove_finalize();
+        trove_finalize(server_config.trove_method);
         gossip_debug(GOSSIP_SERVER_DEBUG, "[-]         storage "
                      "interface         [ stopped ]\n");
     }
@@ -1540,6 +1249,15 @@ static int server_shutdown(
                      "interface         [ stopped ]\n");
     }
 
+    if (status & SERVER_DIST_INIT)
+    {
+        gossip_debug(GOSSIP_SERVER_DEBUG, "[+] halting dist "
+                     "interface            [   ...   ]\n");
+        PINT_dist_finalize();
+        gossip_debug(GOSSIP_SERVER_DEBUG, "[-]         dist "
+                     "interface            [ stopped ]\n");
+    }
+
     if (status & SERVER_PERF_COUNTER_INIT)
     {
         gossip_debug(GOSSIP_SERVER_DEBUG, "[+] halting performance "
@@ -1618,7 +1336,7 @@ static void server_sig_handler(int sig)
 static void usage(int argc, char **argv)
 {
     gossip_err("Usage: %s: [OPTIONS] <global_config_file> "
-               "<server_config_file>\n\n", argv[0]);
+               "\n\n", argv[0]);
     gossip_err("  -d, --foreground\t"
                "will keep server in the foreground\n");
     gossip_err("  -f, --mkfs\t\twill cause server to "
@@ -1629,11 +1347,13 @@ static void usage(int argc, char **argv)
     gossip_err("  -v, --version\t\toutput version information "
                "and exit\n");
     gossip_err("  -p, --pidfile <file>\twrite process id to file\n");
+    gossip_err("  -a, --alias <alias>\tuse the specified alias for this node\n");
 }
 
 static int server_parse_cmd_line_args(int argc, char **argv)
 {
     int ret = 0, option_index = 0;
+    int total_arguments = 0;
     const char *cur_option = NULL;
     static struct option long_opts[] =
     {
@@ -1643,12 +1363,14 @@ static int server_parse_cmd_line_args(in
         {"rmfs",0,0,0},
         {"version",0,0,0},
         {"pidfile",1,0,0},
+        {"alias",0,0,0},
         {0,0,0,0}
     };
 
-    while ((ret = getopt_long(argc, argv,"dfhrvp:",
+    while ((ret = getopt_long(argc, argv,"dfhrvp:a:",
                               long_opts, &option_index)) != -1)
     {
+        total_arguments++;
         switch (ret)
         {
             case 0:
@@ -1679,6 +1401,10 @@ static int server_parse_cmd_line_args(in
                 {
                     goto do_pidfile;
                 }
+                else if (strcmp("alias", cur_option) == 0)
+                {
+                    goto do_alias;
+                }
                 break;
             case 'v':
           do_version:
@@ -1698,6 +1424,7 @@ static int server_parse_cmd_line_args(in
                 break;
             case 'p':
           do_pidfile:
+                total_arguments++;
                 s_server_options.pidfile = optarg;
                 if(optarg[0] != '/')
                 {
@@ -1705,20 +1432,50 @@ static int server_parse_cmd_line_args(in
                     goto parse_cmd_line_args_failure;
                 }
                 break;
+            case 'a':
+           do_alias:
+                total_arguments++;
+                s_server_options.server_alias = strdup(optarg);
+                break;
             case '?':
             case 'h':
           do_help:
             default:
           parse_cmd_line_args_failure:
                 usage(argc, argv);
+                if(s_server_options.server_alias)
+                {
+                    free(s_server_options.server_alias);
+                }
                 return 1;
         }
     }
 
-    if (argc == 1)
+    if(argc < optind)
+    {
+        gossip_err("Missing config file in command line arguments\n");
+        goto parse_cmd_line_args_failure;
+    }
+
+    fs_conf = argv[optind++];
+
+    if(argc - total_arguments > 2)
     {
+        /* Assume user is passing in a server.conf.  Bit of a hack here to
+         * support server.conf files in the old format by appending the
+         * server.conf options onto the fs.conf.
+         */
+        gossip_err("The two config file format is no longer supported.  "
+                   "Generate a single fs.conf that uses the new format with the "
+                   "pvfs2-config-convert script.\n\n");
         goto parse_cmd_line_args_failure;
     }
+
+    if (s_server_options.server_alias == NULL)
+    {
+        /* Try to guess the alias from the hostname */
+        s_server_options.server_alias = PINT_util_guess_alias();
+    }
     return 0;
 }
 
@@ -1728,19 +1485,30 @@ static int server_parse_cmd_line_args(in
  *
  * Returns 0 on success, -PVFS_error on failure.
  */
-static int server_post_unexpected_recv(job_status_s *js_p)
+int server_post_unexpected_recv(job_status_s *js_p)
 {
     int ret = -PVFS_EINVAL;
-    job_id_t j_id;
-    PINT_server_op *s_op = NULL;
+    /* job_id_t j_id; */
+    struct PINT_smcb *smcb = NULL;
+    struct PINT_server_op *s_op;
+
+    gossip_debug(GOSSIP_SERVER_DEBUG,
+            "server_post_unexpected_recv\n");
 
     if (js_p)
     {
-        s_op = (PINT_server_op *) malloc(sizeof(PINT_server_op));
-        if (s_op == NULL)
+        ret = PINT_smcb_alloc(&smcb, BMI_UNEXPECTED_OP,
+                sizeof(struct PINT_server_op),
+                server_op_state_get_machine,
+                server_state_machine_terminate,
+                server_job_context);
+        if (ret < 0)
         {
-            return -PVFS_ENOMEM;
+            gossip_lerr("Error: failed to allocate SMCB "
+                        "of op type %x\n", BMI_UNEXPECTED_OP);
+            return ret;
         }
+        s_op = (struct PINT_server_op *)PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
         memset(s_op, 0, sizeof(PINT_server_op));
         s_op->op = BMI_UNEXPECTED_OP;
         s_op->target_handle = PVFS_HANDLE_NULL;
@@ -1748,22 +1516,12 @@ static int server_post_unexpected_recv(j
         /* Add an unexpected s_ops to the list */
         qlist_add_tail(&s_op->next, &posted_sop_list);
 
-        /*
-          TODO: Consider the optimization of enabling immediate
-          completion in this part of the code (see the mailing list
-          thread from Feb. 2003 on pvfs2-internal).
-
-          note: unexp_bmi_buff is really a struct that describes an
-          unexpected message (it is an output parameter).
-        */
-        ret = job_bmi_unexp(&s_op->unexp_bmi_buff, s_op, 0,
-                            js_p, &j_id, JOB_NO_IMMED_COMPLETE,
-                            server_job_context);
-        if (ret < 0)
+        ret = PINT_state_machine_start(smcb, js_p);
+        if(ret == SM_ACTION_TERMINATE)
         {
-            PVFS_perror_gossip("Error: job_bmi_unexp failure", ret);
-            free(s_op);
-            s_op = NULL;
+            /* error posting unexpected */
+            PINT_smcb_free(smcb);
+            return js_p->error_code;
         }
     }
     return ret;
@@ -1789,10 +1547,13 @@ static int server_purge_unexpected_recv_
         PINT_server_op *s_op = qlist_entry(tmp, PINT_server_op, next);
 
         /* Remove s_op from the posted_sop_list */
-        qlist_del(&s_op->next);
+        /* don't see a reason to remove this */
+        /* will be removed in state machine */
+        /* if and when message completes after cancellation */
+        /* qlist_del(&s_op->next); */
 
-        /* free the operation structure itself */
-        free(s_op);
+        /* mark the message for cancellation */
+        s_op->op_cancelled = 1;
     }
     return 0;
 }
@@ -1804,13 +1565,17 @@ static int server_purge_unexpected_recv_
  *
  * returns 0 on success, -PVFS_errno on failure
  */
-static int server_state_machine_start(
-    PINT_server_op *s_op,
+int server_state_machine_start(
+    PINT_smcb *smcb,
     job_status_s *js_p)
 {
+    PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     PVFS_id_gen_t tmp_id;
 
+    gossip_debug(GOSSIP_SERVER_DEBUG,
+            "server_state_machine_start %p\n",smcb);
+
     ret = PINT_decode(s_op->unexp_bmi_buff.buffer,
                       PINT_DECODE_REQ,
                       &s_op->decoded,
@@ -1821,17 +1586,18 @@ static int server_state_machine_start(
      * If *someone* decides to do in-place decoding, then we will have to move
      * this back to state_machine_complete().
      */
-    s_op->req  = (struct PVFS_server_req *)s_op->decoded.buffer;
     if (ret == -PVFS_EPROTONOSUPPORT)
     {
         /* we have a protocol mismatch of some sort; try to trigger a
          * response that gives a helpful error on client side even
          * though we can't interpret what the client was asking for
          */
-        s_op->op = PVFS_SERV_PROTO_ERROR;
+        ret = PINT_smcb_set_op(smcb, PVFS_SERV_PROTO_ERROR);
     }
     else if (ret == 0)
     {
+        s_op->req  = (struct PVFS_server_req *)s_op->decoded.buffer;
+        ret = PINT_smcb_set_op(smcb, s_op->req->op);
         s_op->op = s_op->req->op;
     }
     else
@@ -1845,14 +1611,18 @@ static int server_state_machine_start(
 
     /* set timestamp on the beginning of this state machine */
     id_gen_fast_register(&tmp_id, s_op);
-    PINT_event_timestamp(PVFS_EVENT_API_SM, (int32_t)s_op->req->op,
-                         0, tmp_id, PVFS_EVENT_FLAG_START);
+
+    if(s_op->req)
+    {
+        PINT_event_timestamp(PVFS_EVENT_API_SM, (int32_t)s_op->req->op,
+                             0, tmp_id, PVFS_EVENT_FLAG_START);
+        s_op->resp.op = s_op->req->op;
+    }
 
     s_op->addr = s_op->unexp_bmi_buff.addr;
     s_op->tag  = s_op->unexp_bmi_buff.tag;
-    s_op->current_state = PINT_state_machine_locate(s_op);
 
-    if (!s_op->current_state)
+    if (!ret)
     {
         gossip_err("Error: server does not implement request type: %d\n",
                    (int)s_op->req->op);
@@ -1860,8 +1630,7 @@ static int server_state_machine_start(
         return -PVFS_ENOSYS;
     }
 
-    s_op->resp.op = s_op->op;
-    return PINT_state_machine_invoke(s_op,js_p);
+    return PINT_state_machine_invoke(smcb, js_p);
 }
 
 /* server_state_machine_alloc_noreq()
@@ -1873,34 +1642,36 @@ static int server_state_machine_start(
  */
 int server_state_machine_alloc_noreq(
     enum PVFS_server_op op,
-    PINT_server_op **new_op)
+    struct PINT_smcb **new_op)
 {
     int ret = -PVFS_EINVAL;
 
+    gossip_debug(GOSSIP_SERVER_DEBUG,
+            "server_state_machine_alloc_noreq %d\n",op);
+
     if (new_op)
     {
-        *new_op = (PINT_server_op*)malloc(sizeof(PINT_server_op));
-        if (!(*new_op))
+        PINT_server_op *tmp_op;
+        ret = PINT_smcb_alloc(new_op, op, 
+                sizeof(struct PINT_server_op),
+                server_op_state_get_machine,
+                server_state_machine_terminate,
+                server_job_context);
+        if (ret < 0)
         {
-            return -PVFS_ENOMEM;
+            gossip_lerr("Error: failed to allocate SMCB "
+                        "of op type %x\n", op);
+            return ret;
         }
-        memset(*new_op, 0, sizeof(PINT_server_op));
-        (*new_op)->op = op;
-        (*new_op)->target_handle = PVFS_HANDLE_NULL;
-        (*new_op)->target_fs_id = PVFS_FS_ID_NULL;
-
-        /* NOTE: We do not add these state machines to the in-progress or posted sop lists */
+        tmp_op = PINT_sm_frame(*new_op, PINT_FRAME_CURRENT);
+        tmp_op->op = op;
+        tmp_op->target_handle = PVFS_HANDLE_NULL;
+        tmp_op->target_fs_id = PVFS_FS_ID_NULL;
 
-        /* find the state machine for this op type */
-        (*new_op)->current_state = PINT_state_machine_locate(*new_op);
+        /* NOTE: We do not add these state machines to the 
+         * in-progress or posted sop lists 
+         */
 
-        if (!((*new_op)->current_state))
-        {
-            gossip_lerr("Error: failed to start state machine "
-                        "of op type %x\n", op);
-            free(*new_op);
-            return -PVFS_ENOSYS;
-        }
         ret = 0;
     }
     return ret;
@@ -1917,34 +1688,29 @@ int server_state_machine_alloc_noreq(
  *
  * returns 0 on success, -PVFS_error on failure
  */
-int server_state_machine_start_noreq(PINT_server_op *new_op)
+int server_state_machine_start_noreq(struct PINT_smcb *smcb)
 {
+    struct PINT_server_op *new_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_status_s tmp_status;
 
+    gossip_debug(GOSSIP_SERVER_DEBUG,
+            "server_state_machine_start_noreq %p\n",smcb);
+
     tmp_status.error_code = 0;
 
     if (new_op)
     {
+        /* add to list of state machines started without a request */
+        qlist_add_tail(&new_op->next, &noreq_sop_list);
+
         /* execute first state */
-        ret = PINT_state_machine_invoke(new_op, &tmp_status);
+        ret = PINT_state_machine_start(smcb, &tmp_status);
         if (ret < 0)
         {
             gossip_lerr("Error: failed to start state machine.\n");
             return ret;
         }
-
-        /* continue as long as states are immediately completing */
-        while(ret == 1)
-        {
-            ret = PINT_state_machine_next(new_op, &tmp_status);
-        }
-
-        if (ret < 0)
-        {
-            gossip_lerr("Error: unhandled state machine processing "
-                        "error (most likely an unhandled job error).\n");
-        }
     }
     return ret;
 }
@@ -1958,10 +1724,14 @@ int server_state_machine_start_noreq(PIN
  *
  * returns 0
  */
-int server_state_machine_complete(PINT_server_op *s_op)
+int server_state_machine_complete(PINT_smcb *smcb)
 {
+    PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_id_gen_t tmp_id;
-    
+
+    gossip_debug(GOSSIP_SERVER_DEBUG,
+            "server_state_machine_complete %p\n",smcb);
+
     /* set a timestamp on the completion of the state machine */
     id_gen_fast_register(&tmp_id, s_op);
     PINT_event_timestamp(PVFS_EVENT_API_SM, (int32_t)s_op->req->op,
@@ -1973,17 +1743,26 @@ int server_state_machine_complete(PINT_s
         PINT_decode_release(&(s_op->decoded),PINT_DECODE_REQ);
     }
 
+    BMI_set_info(s_op->unexp_bmi_buff.addr, BMI_DEC_ADDR_REF, NULL);
     BMI_unexpected_free(s_op->unexp_bmi_buff.addr, 
                         s_op->unexp_bmi_buff.buffer);
     s_op->unexp_bmi_buff.buffer = NULL;
 
+
    /* Remove s_op from the inprogress_sop_list */
     qlist_del(&s_op->next);
 
-    /* free the operation structure itself */
-    free(s_op);
+    return SM_ACTION_TERMINATE;
+}
 
-    return 0;
+int server_state_machine_terminate(
+        struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    /* free the operation structure itself */
+    gossip_debug(GOSSIP_SERVER_DEBUG,
+            "server_state_machine_terminate %p\n",smcb);
+    PINT_smcb_free(smcb);
+    return SM_ACTION_TERMINATE;
 }
 
 struct server_configuration_s *get_server_config_struct(void)
@@ -1991,35 +1770,126 @@ struct server_configuration_s *get_serve
     return &server_config;
 }
 
-/* parse_port_from_host_id()
- *
- * attempts to parse the port number from a BMI address.  Returns port number
- * on success, -1 on failure
+/* server_op_get_machine()
+ * 
+ * looks up the state machine for the op * given and returns it, or
+ * NULL of the op is out of range.
+ * pointer to this function set in the control block of server state
+ * machines.
  */
-static int parse_port_from_host_id(char* host_id)
+struct PINT_state_machine_s *server_op_state_get_machine(int op)
+{
+    gossip_debug(GOSSIP_SERVER_DEBUG,
+            "server_op_state_get_machine %d\n",op);
+
+    switch (op)
+    {
+    case BMI_UNEXPECTED_OP :
+        {
+            return &pvfs2_unexpected_sm;
+            break;
+        }
+    default :
+        {
+            if (op >= 0 && op < PVFS_SERV_NUM_OPS)
+                return PINT_server_req_table[op].params->state_machine;
+            else
+                return NULL;
+            break;
+        }
+    }
+}
+
+static TROVE_method_id trove_coll_to_method_callback(TROVE_coll_id coll_id)
+{
+    struct filesystem_configuration_s * fs_config;
+
+    fs_config = PINT_config_find_fs_id(&server_config, coll_id);
+    if(!fs_config)
+    {
+        return server_config.trove_method;
+    }
+    return fs_config->trove_method;
+}
+
+#ifndef GOSSIP_DISABLE_DEBUG
+void PINT_server_access_debug(PINT_server_op * s_op,
+                              int64_t debug_mask,
+                              const char * format,
+                              ...)
 {
-    int ret = -1;
-    int port_num;
-    char* port_index;
-    char* colon_index;
+    static char pint_access_buffer[GOSSIP_BUF_SIZE];
+    struct passwd* pw;
+    struct group* gr;
+    va_list ap;
 
-    /* see if we have a <proto>://<hostname>:<port> format */
-    port_index = rindex(host_id, ':');
-    colon_index = index(host_id, ':');
-    /* if so, parse the port number */
-    if(port_index && (port_index != colon_index))
+    if ((gossip_debug_on) &&
+        (gossip_debug_mask & debug_mask) &&
+        (gossip_facility))
     {
-        port_index++;
-        ret = sscanf(port_index, "%d", &port_num);
+        va_start(ap, format);
+
+        pw = getpwuid(s_op->req->credentials.uid);
+        gr = getgrgid(s_op->req->credentials.gid);
+        snprintf(pint_access_buffer, GOSSIP_BUF_SIZE,
+            "%s.%s@%s H=%llu S=%p: %s: %s",
+            ((pw) ? pw->pw_name : "UNKNOWN"),
+            ((gr) ? gr->gr_name : "UNKNOWN"),
+            BMI_addr_rev_lookup_unexpected(s_op->addr),
+            llu(s_op->target_handle),
+            s_op,
+            PINT_map_server_op_to_string(s_op->req->op),
+            format);
+
+        __gossip_debug_va(debug_mask, 'A', pint_access_buffer, ap);
+
+        va_end(ap);
     }
+}
+#endif
+
+/* generate_shm_key_hint()
+ *
+ * Makes a best effort to produce a unique shm key (for Trove's Berkeley
+ * DB use) for each server.  By default it will base this on the server's
+ * position in the fs.conf, but it will fall back to using a random number
+ *
+ * returns integer key
+ */
+static int generate_shm_key_hint(void)
+{
+    int server_index = 1;
+    struct host_alias_s *cur_alias = NULL;
+
+    PINT_llist *cur = server_config.host_aliases;
 
-    /* report error if we don't find a valid port number in the string */
-    if(ret != 1)
+    /* iterate through list of aliases in configuration file */
+    while(cur)
     {
-        return(-1);
+        cur_alias = PINT_llist_head(cur);
+        if(!cur_alias)
+        {
+            break;
+        }
+        if(strcmp(cur_alias->bmi_address, server_config.host_id) == 0)
+        {
+            /* match */
+            /* space the shm keys out by 10 to allow for Berkeley DB using 
+             * using more than one key on each server
+             */
+            return(server_index*10);        
+        }
+
+        server_index++;
+        cur = PINT_llist_next(cur);
     }
     
-    return(port_num);
+    /* If we reach this point, we didn't find this server in the alias list.
+     * This is not a normal situation, but fall back to using a random
+     * number for the key just to be safe.
+     */
+    srand((unsigned int)time(NULL));
+    return(rand());
 }
 
 /*

Index: pvfs2-server.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/pvfs2-server.h,v
diff -p -u -r1.138.8.2 -r1.138.8.2.2.1
--- pvfs2-server.h	5 Apr 2007 16:28:30 -0000	1.138.8.2
+++ pvfs2-server.h	21 Jul 2008 18:18:15 -0000	1.138.8.2.2.1
@@ -25,23 +25,15 @@
 #include "pvfs2-internal.h"
 #include "job.h"
 #include "bmi.h"
-#include "src/server/request-scheduler/request-scheduler.h"
 #include "trove.h"
 #include "gossip.h"
 #include "PINT-reqproto-encode.h"
 #include "msgpairarray.h"
 #include "pvfs2-req-proto.h"
+#include "state-machine.h"
 
-/* skip everything except #includes if __SM_CHECK_DEP is already
- * defined; this allows us to get the dependencies right for
- * msgpairarray.sm which relies on conflicting headers for dependency
- * information
- */
-#ifndef __SM_CHECK_DEP
 extern job_context_id server_job_context;
 
-/* size of stack for nested state machines */
-#define PINT_STATE_STACK_SIZE                  8
 #define PVFS2_SERVER_DEFAULT_TIMEOUT_MS      100
 #define BMI_UNEXPECTED_OP                    999
 
@@ -78,70 +70,77 @@ enum PINT_server_req_permissions
                                       needs write and execute */
 };
 
-/* indicates if the attributes for the target object must exist for
- * the operation to proceed (see prelude.sm)
- */
-enum PINT_server_req_attrib_flags
+#define PINT_GET_OBJECT_REF_DEFINE(req_name)                             \
+static inline int PINT_get_object_ref_##req_name(                        \
+    struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle) \
+{                                                                        \
+    *fs_id = req->u.req_name.fs_id;                                      \
+    *handle = req->u.req_name.handle;                                    \
+    return 0;                                                            \
+}
+
+enum PINT_server_req_access_type PINT_server_req_readonly(
+                                    struct PVFS_server_req *req);
+enum PINT_server_req_access_type PINT_server_req_modify(
+                                    struct PVFS_server_req *req);
+
+struct PINT_server_req_params
 {
-    PINT_SERVER_ATTRIBS_INVALID = 0,
-    PINT_SERVER_ATTRIBS_REQUIRED = 1,
-    /* operations that operate on datafiles or on incomplete metafiles
-     * do not expect to necessarily find attributes present before
-     * starting the operation
+    const char* string_name;
+
+    /* For each request that specifies an object ref (fsid,handle) we
+     * get the common attributes on that object and check the permissions.
+     * For the request to proceed the permissions required by this flag
+     * must be met.
+     */
+    enum PINT_server_req_permissions perm;
+
+    /* Specifies the type of access on the object (readonly, modify).  This
+     * is used by the request scheduler to determine 
+     * which requests to queue (block), and which to schedule (proceed).
+     * This is a callback implemented by the request.  For example, sometimes
+     * the io request writes, sometimes it reads.
+     * Default functions PINT_server_req_readonly and PINT_server_req_modify
+     * are used for requests that always require the same access type.
      */
-    PINT_SERVER_ATTRIBS_NOT_REQUIRED = 2
+    enum PINT_server_req_access_type (*access_type)(
+                                        struct PVFS_server_req *req);
+
+    /* Specifies the scheduling policy for the request.  In some cases,
+     * we can bypass the request scheduler and proceed directly with the
+     * request.
+     */
+    enum PINT_server_sched_policy sched_policy;
+
+    /* A callback implemented by the request to return the object reference
+     * from the server request structure.
+     */
+    int (*get_object_ref)(
+        struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle);
+
+    /* The state machine that performs the request */
+    struct PINT_state_machine_s *state_machine;
 };
 
-struct PINT_server_req_params
+struct PINT_server_req_entry
 {
     enum PVFS_server_op op_type;
-    const char* string_name;
-    enum PINT_server_req_permissions perm;
-    enum PINT_server_req_attrib_flags attrib_flags;
-    struct PINT_state_machine_s* sm;
+    struct PINT_server_req_params *params;
 };
 
-extern struct PINT_server_req_params PINT_server_req_table[];
+extern struct PINT_server_req_entry PINT_server_req_table[];
 
-/*
- * PINT_map_server_op_to_string()
- *
- * provides a string representation of the server operation number
- *
- * returns a pointer to a static string (DONT FREE IT) on success,
- * null on failure
- */
-static inline const char* PINT_map_server_op_to_string(enum PVFS_server_op op)
-{
-    const char *s = NULL;
+int PINT_server_req_get_object_ref(
+    struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle);
 
-    if (op >= 0 && op < PVFS_SERV_NUM_OPS)
-        s = PINT_server_req_table[op].string_name;
-    return s;
-}
+enum PINT_server_req_permissions
+PINT_server_req_get_perms(struct PVFS_server_req *req);
+enum PINT_server_req_access_type
+PINT_server_req_get_access_type(struct PVFS_server_req *req);
+enum PINT_server_sched_policy
+PINT_server_req_get_sched_policy(struct PVFS_server_req *req);
 
-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);
-}
+const char* PINT_map_server_op_to_string(enum PVFS_server_op op);
 
 /* used to keep a random, but handy, list of keys around */
 typedef struct PINT_server_trove_keys
@@ -150,13 +149,25 @@ typedef struct PINT_server_trove_keys
     int size;
 } PINT_server_trove_keys_s;
 
-enum
+extern PINT_server_trove_keys_s Trove_Common_Keys[];
+/* Reserved keys */
+enum 
 {
     ROOT_HANDLE_KEY      = 0,
     DIR_ENT_KEY          = 1,
     METAFILE_HANDLES_KEY = 2,
     METAFILE_DIST_KEY    = 3,
-    SYMLINK_TARGET_KEY   = 4
+    SYMLINK_TARGET_KEY   = 4,
+};
+
+/* optional; user-settable keys */
+enum 
+{
+    DIST_NAME_KEY        = 0,
+    DIST_PARAMS_KEY      = 1,
+    NUM_DFILES_KEY       = 2,
+    NUM_SPECIAL_KEYS     = 3, /* not an index */
+    METAFILE_HINT_KEY    = 3,
 };
 
 typedef enum
@@ -250,12 +261,11 @@ struct PINT_server_remove_op
                                    * the event that we are removing a
                                    * directory */
     PVFS_size dirent_count;
-    PVFS_ds_keyval * key_array;
+    PVFS_ds_keyval key;
     PVFS_ds_position pos;
     int key_count;
     int index;
     int remove_keyvals_state;
-    PVFS_ds_keyval_handle_info keyval_handle_info;
 };
 
 struct PINT_server_mgmt_remove_dirent_op
@@ -322,6 +332,14 @@ struct PINT_server_getattr_op
     PVFS_handle dirent_handle;
 };
 
+struct PINT_server_listattr_op
+{
+    PVFS_object_attr *attr_a;
+    PVFS_ds_attributes *ds_attr_a;
+    PVFS_error *errors;
+    int parallel_sms;
+};
+
 /* this is used in both set_eattr, get_eattr and list_eattr */
 struct PINT_server_eattr_op
 {
@@ -335,13 +353,8 @@ struct PINT_server_eattr_op
 typedef struct PINT_server_op
 {
     struct qlist_head   next; /* used to queue structures used for unexp style messages */
+    int op_cancelled; /* indicates unexp message was cancelled */
     enum PVFS_server_op op;  /* type of operation that we are servicing */
-    /* the following fields are used in state machine processing to keep
-     * track of the current state
-     */
-    int stackptr;
-    union PINT_state_array_values *current_state; 
-    union PINT_state_array_values *state_stack[PINT_STATE_STACK_SIZE]; 
 
     /* holds id from request scheduler so we can release it later */
     job_id_t scheduled_id; 
@@ -376,23 +389,21 @@ typedef struct PINT_server_op
     struct PINT_encoded_msg encoded;
     struct PINT_decoded_msg decoded;
 
-    /* generic msgpair used with msgpair substate */
-    PINT_sm_msgpair_state msgpair;
-
-    /* state information for msgpairarray nested state machine */
-    int msgarray_count;
-    PINT_sm_msgpair_state *msgarray;
-    PINT_sm_msgpair_params msgarray_params;
+    PINT_sm_msgarray_op msgarray_op;
 
     PVFS_handle target_handle;
     PVFS_fs_id target_fs_id;
     PVFS_object_attr *target_object_attr;
 
+    enum PINT_server_req_access_type access_type;
+    enum PINT_server_sched_policy sched_policy;
+
     union
     {
 	/* request-specific scratch spaces for use during processing */
         struct PINT_server_eattr_op eattr;
         struct PINT_server_getattr_op getattr;
+        struct PINT_server_listattr_op listattr;
 	struct PINT_server_getconfig_op getconfig;
 	struct PINT_server_lookup_op lookup;
 	struct PINT_server_crdirent_op crdirent;
@@ -422,103 +433,55 @@ typedef struct PINT_server_op
 #define PINT_ACCESS_DEBUG(__s_op, __mask, format, f...) do {} while (0)
 #else
 #define PINT_ACCESS_DEBUG(__s_op, __mask, format, f...)                     \
-do {                                                                        \
-    PVFS_handle __handle;                                                   \
-    PVFS_fs_id __fsid;                                                      \
-    int __flag;                                                             \
-    static char __pint_access_buffer[GOSSIP_BUF_SIZE];                      \
-    struct passwd* __pw;                                                    \
-    struct group* __gr;                                                     \
-                                                                            \
-    if ((gossip_debug_on) &&                                                \
-        (gossip_debug_mask & __mask) &&                                     \
-        (gossip_facility))                                                  \
-    {                                                                       \
-        PINT_req_sched_target_handle(__s_op->req, 0, &__handle,             \
-            &__fsid, &__flag);                                              \
-        __pw = getpwuid(__s_op->req->credentials.uid);                      \
-        __gr = getgrgid(__s_op->req->credentials.gid);                      \
-        snprintf(__pint_access_buffer, GOSSIP_BUF_SIZE,                     \
-            "%s.%s@%s H=%llu S=%p: %s: %s",                                  \
-            ((__pw) ? __pw->pw_name : "UNKNOWN"),                           \
-            ((__gr) ? __gr->gr_name : "UNKNOWN"),                           \
-            BMI_addr_rev_lookup_unexpected(__s_op->addr),                   \
-            llu(__handle),                                                   \
-            __s_op,                                                         \
-            PINT_map_server_op_to_string(__s_op->req->op),                  \
-            format);                                                        \
-        __gossip_debug(__mask, 'A', __pint_access_buffer, ##f);             \
-    }                                                                       \
-} while(0);
+    PINT_server_access_debug(__s_op, __mask, format, ##f)
 #endif
 
-/* server operation state machines */
-extern struct PINT_state_machine_s pvfs2_get_config_sm;
-extern struct PINT_state_machine_s pvfs2_get_attr_sm;
-extern struct PINT_state_machine_s pvfs2_set_attr_sm;
-extern struct PINT_state_machine_s pvfs2_create_sm;
-extern struct PINT_state_machine_s pvfs2_crdirent_sm;
-extern struct PINT_state_machine_s pvfs2_mkdir_sm;
-extern struct PINT_state_machine_s pvfs2_readdir_sm;
-extern struct PINT_state_machine_s pvfs2_lookup_sm;
-extern struct PINT_state_machine_s pvfs2_lock_sm;
-extern struct PINT_state_machine_s pvfs2_io_sm;
-extern struct PINT_state_machine_s pvfs2_small_io_sm;
-extern struct PINT_state_machine_s pvfs2_remove_sm;
-extern struct PINT_state_machine_s pvfs2_mgmt_remove_object_sm;
-extern struct PINT_state_machine_s pvfs2_mgmt_remove_dirent_sm;
-extern struct PINT_state_machine_s pvfs2_mgmt_get_dirdata_handle_sm;
-extern struct PINT_state_machine_s pvfs2_rmdirent_sm;
-extern struct PINT_state_machine_s pvfs2_chdirent_sm;
-extern struct PINT_state_machine_s pvfs2_flush_sm;
-extern struct PINT_state_machine_s pvfs2_truncate_sm;
-extern struct PINT_state_machine_s pvfs2_setparam_sm;
-extern struct PINT_state_machine_s pvfs2_noop_sm;
-extern struct PINT_state_machine_s pvfs2_statfs_sm;
-extern struct PINT_state_machine_s pvfs2_perf_update_sm;
-extern struct PINT_state_machine_s pvfs2_job_timer_sm;
-extern struct PINT_state_machine_s pvfs2_proto_error_sm;
-extern struct PINT_state_machine_s pvfs2_perf_mon_sm;
-extern struct PINT_state_machine_s pvfs2_event_mon_sm;
-extern struct PINT_state_machine_s pvfs2_iterate_handles_sm;
-extern struct PINT_state_machine_s pvfs2_get_eattr_sm;
-extern struct PINT_state_machine_s pvfs2_get_eattr_list_sm;
-extern struct PINT_state_machine_s pvfs2_set_eattr_sm;
-extern struct PINT_state_machine_s pvfs2_set_eattr_list_sm;
-extern struct PINT_state_machine_s pvfs2_del_eattr_sm;
-extern struct PINT_state_machine_s pvfs2_list_eattr_sm;
-extern struct PINT_state_machine_s pvfs2_list_eattr_list_sm;
+void PINT_server_access_debug(PINT_server_op * s_op,
+                              int64_t debug_mask,
+                              const char * format,
+                              ...) __attribute__((format(printf, 3, 4)));
 
 /* nested state machines */
 extern struct PINT_state_machine_s pvfs2_get_attr_work_sm;
 extern struct PINT_state_machine_s pvfs2_prelude_sm;
+extern struct PINT_state_machine_s pvfs2_prelude_work_sm;
 extern struct PINT_state_machine_s pvfs2_final_response_sm;
 extern struct PINT_state_machine_s pvfs2_check_entry_not_exist_sm;
 extern struct PINT_state_machine_s pvfs2_remove_work_sm;
 extern struct PINT_state_machine_s pvfs2_mkdir_work_sm;
+extern struct PINT_state_machine_s pvfs2_unexpected_sm;
 
 /* Exported Prototypes */
 struct server_configuration_s *get_server_config_struct(void);
 
 /* exported state machine resource reclamation function */
-int server_state_machine_complete(PINT_server_op *s_op);
+int server_post_unexpected_recv(job_status_s *js_p);
+int server_state_machine_start( PINT_smcb *smcb, job_status_s *js_p);
+int server_state_machine_complete(PINT_smcb *smcb);
+int server_state_machine_terminate(PINT_smcb *smcb, job_status_s *js_p);
+
+/* lists of server ops */
+extern struct qlist_head posted_sop_list;
+extern struct qlist_head inprogress_sop_list;
 
 /* starts state machines not associated with an incoming request */
 int server_state_machine_alloc_noreq(
-    enum PVFS_server_op op, PINT_server_op** new_op);
+    enum PVFS_server_op op, struct PINT_smcb ** new_op);
 int server_state_machine_start_noreq(
-    PINT_server_op *new_op);
+    struct PINT_smcb *new_op);
 
 /* INCLUDE STATE-MACHINE.H DOWN HERE */
+#if 0
 #define PINT_OP_STATE       PINT_server_op
 #define PINT_OP_STATE_GET_MACHINE(_op) \
     ((_op >= 0 && _op < PVFS_SERV_NUM_OPS) ? \
-    PINT_server_req_table[_op].sm : NULL)
+    PINT_server_req_table[_op].params->sm : NULL)
+#endif
 
-#include "state-machine.h"
 #include "pvfs2-internal.h"
 
-#endif /* __SM_CHECK_DEP */ 
+struct PINT_state_machine_s *server_op_state_get_machine(int);
+
 #endif /* __PVFS_SERVER_H */
 
 /*

Index: readdir.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/readdir.sm,v
diff -p -u -r1.45 -r1.45.14.1
--- readdir.sm	13 Jul 2006 05:11:42 -0000	1.45
+++ readdir.sm	21 Jul 2008 18:18:15 -0000	1.45.14.1
@@ -22,29 +22,9 @@ enum
     STATE_ENOTDIR = 7
 };
 
-static int readdir_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int readdir_read_dirdata_handle(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int readdir_iterate_on_entries(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int readdir_verify_directory_metadata(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int readdir_setup_resp(
-    PINT_server_op *s_op, job_status_s* js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_readdir_sm(
-    prelude,
-    iterate_on_entries,
-    read_dirdata_handle,
-    verify_directory_metadata,
-    setup_resp,
-    final_response,
-    cleanup)
+machine pvfs2_readdir_sm
 {
     state prelude
     {
@@ -94,9 +74,10 @@ machine pvfs2_readdir_sm(
 
 %%
 
-static int readdir_verify_directory_metadata(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action readdir_verify_directory_metadata(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *attr = &s_op->attr;
 
     js_p->error_code = 0;
@@ -115,12 +96,13 @@ static int readdir_verify_directory_meta
     }
 
     s_op->u.readdir.directory_version = (uint64_t)attr->mtime;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int readdir_read_dirdata_handle(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action readdir_read_dirdata_handle(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -141,15 +123,16 @@ static int readdir_read_dirdata_handle(
         s_op->req->u.readdir.fs_id, s_op->req->u.readdir.handle,
         &s_op->key, &s_op->val, 
         0, 
-        NULL, s_op, 0, js_p, &i,
+        NULL, smcb, 0, js_p, &i,
         server_job_context);
 
     return ret;
 }
 
-static int readdir_iterate_on_entries(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action readdir_iterate_on_entries(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     int j = 0, memory_size = 0, kv_array_size = 0;
     char *memory_buffer = NULL;
@@ -162,13 +145,13 @@ static int readdir_iterate_on_entries(
     if (s_op->req->u.readdir.dirent_count == 0)
     {
 	js_p->error_code = 0;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     if (s_op->req->u.readdir.dirent_count > PVFS_REQ_LIMIT_DIRENT_COUNT)
     {
         js_p->error_code = -PVFS_EINVAL;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /*
@@ -187,7 +170,7 @@ static int readdir_iterate_on_entries(
     if (!memory_buffer)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* set up all the pointers into the one big buffer */
@@ -211,37 +194,38 @@ static int readdir_iterate_on_entries(
 
     gossip_debug(
         GOSSIP_READDIR_DEBUG, " - iterating keyvals: [%llu,%d], "
-        "\n\ttoken=0x%x, count=%d\n",
+        "\n\ttoken=%llu, count=%d\n",
         llu(s_op->u.readdir.dirent_handle), s_op->req->u.readdir.fs_id,
-        s_op->req->u.readdir.token, s_op->req->u.readdir.dirent_count);
+        llu(s_op->req->u.readdir.token),
+        s_op->req->u.readdir.dirent_count);
 
     ret = job_trove_keyval_iterate(
         s_op->req->u.readdir.fs_id, s_op->u.readdir.dirent_handle,
         s_op->req->u.readdir.token, s_op->key_a, s_op->val_a,
         s_op->req->u.readdir.dirent_count, 
         0, 
-        NULL, s_op, 0, js_p, 
+        NULL, smcb, 0, js_p, 
         &j_id, server_job_context);
 
     return ret;
 }
 
-static int readdir_setup_resp(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action readdir_setup_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if (js_p->error_code == STATE_ENOTDIR)
     {
 	gossip_debug(GOSSIP_READDIR_DEBUG,
 		     "  handle didn't refer to a directory\n");
 
 	js_p->error_code = -PVFS_EINVAL;
-	return 1;
+	return SM_ACTION_COMPLETE;
     }
     else if(js_p->error_code != 0)
     {
         PVFS_perror_gossip("readdir_setup_resp failed: ", js_p->error_code);
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     s_op->resp.u.readdir.directory_version =
@@ -256,12 +240,13 @@ static int readdir_setup_resp(
      */
     s_op->resp.u.readdir.token = js_p->position;
     js_p->error_code = 0;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int readdir_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action readdir_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if (s_op->key_a)
     {
         free(s_op->key_a);
@@ -269,8 +254,18 @@ static int readdir_cleanup(
         s_op->val_a = NULL;
         s_op->resp.u.readdir.dirent_array = NULL;
     }
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(readdir);
+
+struct PINT_server_req_params pvfs2_readdir_params =
+{
+    .string_name = "readdir",
+    .perm = PINT_SERVER_CHECK_READ,
+    .get_object_ref = PINT_get_object_ref_readdir,
+    .state_machine = &pvfs2_readdir_sm
+};
 
 /*
  * Local variables:

Index: remove.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/remove.sm,v
diff -p -u -r1.50 -r1.50.14.1
--- remove.sm	14 Jul 2006 20:46:00 -0000	1.50
+++ remove.sm	21 Jul 2008 18:18:15 -0000	1.50.14.1
@@ -59,36 +59,9 @@ enum
     STATE_TYPE_DATAFILE = 2,
 };
 
-static int remove_check_object_type(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int remove_verify_object_metadata(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int remove_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int remove_remove_dspace(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int remove_read_dirdata_handle(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int remove_get_dirent_count(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int remove_check_dirdata_entries(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int remove_remove_dirdata_dspace(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int remove_setup_work(
-    PINT_server_op *s_op, job_status_s *js_p);
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-nested machine pvfs2_remove_work_sm(
-    check_object_type,
-    verify_object_metadata,
-    remove_dspace,
-    read_dirdata_handle,
-    getattr_of_dirdata_handle,
-    check_dirdata_entries,
-    remove_dirdata_dspace)
+nested machine pvfs2_remove_work_sm
 {
 
     state check_object_type
@@ -142,12 +115,7 @@ nested machine pvfs2_remove_work_sm(
 
 }
 
-machine pvfs2_remove_sm(
-    prelude,
-    setup_work,
-    work,
-    final_response,
-    cleanup)
+machine pvfs2_remove_sm
 {
     state prelude
     {
@@ -191,20 +159,21 @@ machine pvfs2_remove_sm(
  * retrive object attributes earlier
  *
  */
-static int remove_check_object_type(PINT_server_op *s_op,
-                                    job_status_s *js_p)
+static PINT_sm_action remove_check_object_type(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if(s_op->attr.objtype == PVFS_TYPE_DATAFILE)
     {
 	/* it must be a datafile, transition to try reading datafile 
 	 * attribs with dspace_getattr()
 	 */
 	js_p->error_code = STATE_TYPE_DATAFILE;
-	return(1);
+	return SM_ACTION_COMPLETE;
     }
 
     js_p->error_code = 0;
-    return(1);
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -219,9 +188,10 @@ static int remove_check_object_type(PINT
  * Note: errors from the previous state are redirected elsewhere, so
  * we know that we have metadata if we make it here.
  */
-static int remove_verify_object_metadata(PINT_server_op *s_op,
-					 job_status_s *js_p)
+static PINT_sm_action remove_verify_object_metadata(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *a_p;
 
     a_p = &s_op->attr;
@@ -245,12 +215,13 @@ static int remove_verify_object_metadata
             "dirdata object before removing directory itself.\n");
     }
 
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int remove_read_dirdata_handle(PINT_server_op *s_op,
-                                      job_status_s *js_p)
+static PINT_sm_action remove_read_dirdata_handle(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret;
     job_id_t j_id;
 
@@ -272,30 +243,35 @@ static int remove_read_dirdata_handle(PI
         s_op->u.remove.fs_id, s_op->u.remove.handle,
         &s_op->key, &s_op->val, 
         0, 
-        NULL, s_op, 0, js_p,
+        NULL, smcb, 0, js_p,
         &j_id, server_job_context);
 
     return ret;
 }
 
-static int remove_get_dirent_count(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action remove_get_dirent_count(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret;
     job_id_t tmp_id;
 
     if (js_p->error_code)
     {
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     js_p->error_code = 0;
 
-    ret = job_trove_keyval_get_handle_info(
+
+    ret = job_trove_keyval_iterate_keys(
         s_op->u.remove.fs_id,
         s_op->u.remove.dirdata_handle,
-        TROVE_KEYVAL_HANDLE_COUNT,
-        &s_op->u.remove.keyval_handle_info,
-        s_op,
+        PVFS_ITERATE_START,
+        &s_op->u.remove.key,
+        1,
+        0,
+        NULL,
+        smcb,
         0,
         js_p,
         &tmp_id,
@@ -304,20 +280,21 @@ static int remove_get_dirent_count(
     return ret;
 }
 
-static int remove_check_dirdata_entries(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action remove_check_dirdata_entries(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op __attribute__((unused)) =
+        PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if (js_p->error_code == 0)
     {
-        if (s_op->u.remove.keyval_handle_info.count > 0)
+        if(js_p->count > 0)
         {
             gossip_debug(GOSSIP_SERVER_DEBUG, 
                          " detected non-empty "
-                         "directory (fsid: %u, handle: %llu, size %llu) "
+                         "directory (fsid: %u, handle: %llu) "
                          "-- returning error\n",
                          s_op->u.remove.fs_id,
-                         llu(s_op->u.remove.handle),
-                         llu(s_op->u.remove.dirent_count));
+                         llu(s_op->u.remove.handle));
             js_p->error_code = -PVFS_ENOTEMPTY;
         }
     }
@@ -325,12 +302,10 @@ static int remove_check_dirdata_entries(
     {
         /* no entries because count is 0 */
         js_p->error_code = 0;
-        s_op->u.remove.keyval_handle_info.count = 0;
     }
 
     /* setup position for next state (remove[_dirdata]_keyvals) */
-    s_op->u.remove.pos = PVFS_ITERATE_START;
-     return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -339,9 +314,10 @@ static int remove_check_dirdata_entries(
  * Remove the dirdata dspace using the handle that we ready in the
  * read_dirdata_handle state.
  */
-static int remove_remove_dirdata_dspace(PINT_server_op *s_op,
-					job_status_s *js_p)
+static PINT_sm_action remove_remove_dirdata_dspace(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret;
     job_id_t j_id;
     gossip_debug(GOSSIP_SERVER_DEBUG,
@@ -351,8 +327,8 @@ static int remove_remove_dirdata_dspace(
     ret = job_trove_dspace_remove(
         s_op->u.remove.fs_id,
         s_op->u.remove.dirdata_handle,
-        TROVE_SYNC,
-        s_op,
+        0,  /* don't sync here, we do a dspace remove on the dir handle next */
+        smcb,
         0,
         js_p,
         &j_id,
@@ -367,9 +343,10 @@ static int remove_remove_dirdata_dspace(
  * Remove the dspace using the handle from the incoming request
  * (which was verified in previous states).
  */
-static int remove_remove_dspace(PINT_server_op *s_op,
-				job_status_s *js_p)
+static PINT_sm_action remove_remove_dspace(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t j_id;
     gossip_debug(GOSSIP_SERVER_DEBUG, "(%p) remove: removing dspace "
@@ -379,7 +356,7 @@ static int remove_remove_dspace(PINT_ser
     ret = job_trove_dspace_remove(
         s_op->u.remove.fs_id, s_op->u.remove.handle,
         TROVE_SYNC, 
-        s_op, 0, js_p,
+        smcb, 0, js_p,
         &j_id, server_job_context);
 
     return ret;
@@ -391,20 +368,33 @@ static int remove_remove_dspace(PINT_ser
  * Free all memory associated with this request and return 0, indicating
  * we're done processing.
  */
-static int remove_cleanup(PINT_server_op *s_op,
-			  job_status_s *js_p)
+static PINT_sm_action remove_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
-static int remove_setup_work(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action remove_setup_work(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     s_op->u.remove.handle = s_op->req->u.remove.handle;
     s_op->u.remove.fs_id = s_op->req->u.remove.fs_id;
     js_p->error_code = 0;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
+
+PINT_GET_OBJECT_REF_DEFINE(remove);
+
+struct PINT_server_req_params pvfs2_remove_params =
+{
+    .string_name = "remove",
+    .get_object_ref = PINT_get_object_ref_remove,
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .state_machine = &pvfs2_remove_sm
+};
 
 
 /*

Index: rmdirent.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/rmdirent.sm,v
diff -p -u -r1.50 -r1.50.12.1
--- rmdirent.sm	9 Aug 2006 04:43:51 -0000	1.50
+++ rmdirent.sm	21 Jul 2008 18:18:15 -0000	1.50.12.1
@@ -19,37 +19,9 @@ enum
     UPDATE_DIR_ATTR_REQUIRED = 133
 };
 
-static int rmdirent_verify_parent_metadata_and_read_directory_entry_handle(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int rmdirent_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int rmdirent_remove_directory_entry(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int rmdirent_check_for_req_dir_update(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int rmdirent_update_directory_attr(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int rmdirent_remove_directory_entry_failure(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int rmdirent_setup_resp(
-    PINT_server_op *s_op, job_status_s* js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_rmdirent_sm(
-    prelude,
-    verify_parent_metadata_and_read_directory_entry_handle,
-    read_directory_entry,
-    read_directory_entry_failure,
-    remove_directory_entry,
-    remove_directory_entry_failure,
-    check_for_req_dir_update,
-    update_directory_attr,
-    setup_resp,
-    final_response,
-    cleanup)
+machine pvfs2_rmdirent_sm
 {
     state prelude
     {
@@ -113,8 +85,9 @@ machine pvfs2_rmdirent_sm(
 %%
 
 static int rmdirent_verify_parent_metadata_and_read_directory_entry_handle(
-    PINT_server_op *s_op, job_status_s* js_p)
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
@@ -135,7 +108,7 @@ static int rmdirent_verify_parent_metada
         "  reading dirdata handle (coll_id = 0x%x, handle = %llu, "
         "key = %s (%d), val_buf = %p (%d))\n",
         s_op->req->u.rmdirent.fs_id,
-        llu(s_op->req->u.rmdirent.parent_handle),
+        llu(s_op->req->u.rmdirent.handle),
         (char *)s_op->key.buffer,
         s_op->key.buffer_sz,
         s_op->val.buffer,
@@ -143,12 +116,12 @@ static int rmdirent_verify_parent_metada
 
     ret = job_trove_keyval_read(
         s_op->req->u.rmdirent.fs_id,
-        s_op->req->u.rmdirent.parent_handle,
+        s_op->req->u.rmdirent.handle,
         &s_op->key,
         &s_op->val,
         0,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &i,
@@ -164,9 +137,10 @@ static int rmdirent_verify_parent_metada
  * from the dirdata object.
  *           
  */
-static int rmdirent_remove_directory_entry(PINT_server_op *s_op,
-                                           job_status_s* js_p)
+static int rmdirent_remove_directory_entry(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t j_id;
     TROVE_ds_flags flags;
@@ -195,7 +169,7 @@ static int rmdirent_remove_directory_ent
         &s_op->key, 
         &s_op->val,
         flags,
-        NULL, s_op, 0, js_p, &j_id, server_job_context);
+        NULL, smcb, 0, js_p, &j_id, server_job_context);
 
     /* 
      * Removing an entry causes an update of directory timestamps
@@ -204,20 +178,22 @@ static int rmdirent_remove_directory_ent
     return ret;
 }
 
-static int rmdirent_check_for_req_dir_update(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action rmdirent_check_for_req_dir_update(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if ((js_p->error_code == 0) &&
         (s_op->u.rmdirent.dir_attr_update_required))
     {
         js_p->error_code = UPDATE_DIR_ATTR_REQUIRED;
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int rmdirent_update_directory_attr(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action rmdirent_update_directory_attr(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t j_id;
     PVFS_object_attr tmp_attr, *tmp_attr_ptr = &tmp_attr;
@@ -228,7 +204,7 @@ static int rmdirent_update_directory_att
     {
         PVFS_perror_gossip("previous keyval remove failed",
                            js_p->error_code);
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     memset(&tmp_attr, 0, sizeof(PVFS_object_attr));
@@ -240,10 +216,10 @@ static int rmdirent_update_directory_att
     PVFS_object_attr_to_ds_attr(tmp_attr_ptr, ds_attr);
 
     ret = job_trove_dspace_setattr(
-        s_op->req->u.rmdirent.fs_id, s_op->req->u.rmdirent.parent_handle,
+        s_op->req->u.rmdirent.fs_id, s_op->req->u.rmdirent.handle,
         ds_attr, 
         TROVE_SYNC,
-        s_op, 0, js_p, &j_id, server_job_context);
+        smcb, 0, js_p, &j_id, server_job_context);
 
     return ret;
 }
@@ -263,8 +239,8 @@ static int rmdirent_update_directory_att
  * This state always returns 1, and it allows another function to
  * handle actually returning the error value.
  */
-static int rmdirent_remove_directory_entry_failure(PINT_server_op *s_op,
-						   job_status_s *js_p)
+static PINT_sm_action rmdirent_remove_directory_entry_failure(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     switch (js_p->error_code)
     {
@@ -276,12 +252,13 @@ static int rmdirent_remove_directory_ent
 	    break;
     }
 
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int rmdirent_setup_resp(PINT_server_op *s_op,
-                               job_status_s* js_p)
+static PINT_sm_action rmdirent_setup_resp(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     /* Set the handle if it was removed */
     if(js_p->error_code == 0)
     {
@@ -304,14 +281,26 @@ static int rmdirent_setup_resp(PINT_serv
      * we found it, so that later states can use it to set the resp.status
      * field.
      */
-    return(1);
+    return SM_ACTION_COMPLETE;
 }
 
-static int rmdirent_cleanup(PINT_server_op *s_op,
-                            job_status_s* js_p)
+static PINT_sm_action rmdirent_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(rmdirent);
+
+struct PINT_server_req_params pvfs2_rmdirent_params =
+{
+    .string_name = "rmdirent",
+    .perm = PINT_SERVER_CHECK_WRITE,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_rmdirent,
+    .state_machine = &pvfs2_rmdirent_sm
+};
 
 /*
  * Local variables:

Index: set-attr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/set-attr.sm,v
diff -p -u -r1.66 -r1.66.12.1
--- set-attr.sm	8 Aug 2006 02:16:06 -0000	1.66
+++ set-attr.sm	21 Jul 2008 18:18:15 -0000	1.66.12.1
@@ -12,6 +12,7 @@
 #include "pvfs2-attr.h"
 #include "pvfs2-util.h"
 #include "pvfs2-internal.h"
+#include "pint-util.h"
 
 enum
 {
@@ -19,32 +20,9 @@ enum
     STATE_SYMLINK = 8
 };
 
-static int setattr_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int setattr_setobj_attribs(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int setattr_write_metafile_datafile_handles_if_required(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int setattr_write_metafile_distribution_if_required(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int setattr_write_symlink_target_if_required(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int setattr_verify_attribs(
-    PINT_server_op *s_op, job_status_s *js_p);
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
 %%
 
-machine pvfs2_set_attr_sm(
-    prelude,
-    cleanup,
-    verify_attribs,
-    write_metafile_datafile_handles_if_required,
-    write_metafile_distribution_if_required,
-    write_symlink_target_if_required,
-    setobj_attrib,
-    final_response)
+machine pvfs2_set_attr_sm
 {
     state prelude
     {
@@ -104,9 +82,10 @@ machine pvfs2_set_attr_sm(
 
 %%
 
-static int setattr_verify_attribs(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action setattr_verify_attribs(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     PVFS_object_attr *a_p = NULL, *req_a_p = NULL;
 
     a_p = &s_op->attr;
@@ -138,7 +117,7 @@ static int setattr_verify_attribs(
 
         /* set an error to bail out of set-attr processing */
         js_p->error_code = -PVFS_EACCES;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     else if (req_a_p->objtype == PVFS_TYPE_NONE)
     {
@@ -250,11 +229,13 @@ static int setattr_verify_attribs(
 
         js_p->error_code = -PVFS_EACCES;
     }
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int setattr_setobj_attribs(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action setattr_setobj_attribs(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     job_id_t j_id;
     PVFS_object_attr *a_p = NULL;
@@ -282,7 +263,7 @@ static int setattr_setobj_attribs(PINT_s
      if (a_p->mask & PVFS_ATTR_COMMON_MTIME_SET)
      {
          PVFS_time orig_mtime = a_p->mtime;
-         a_p->mtime = PVFS_util_mktime_version(orig_mtime);
+         a_p->mtime = PINT_util_mktime_version(orig_mtime);
          gossip_debug(GOSSIP_SETATTR_DEBUG, "setting version "
                  "to %llu\n\tmtime is %llu\n",
                  llu(a_p->mtime), llu(orig_mtime));
@@ -297,7 +278,7 @@ static int setattr_setobj_attribs(PINT_s
         {
             gossip_debug(GOSSIP_SETATTR_DEBUG, "Cannot change perms of symlink: Permission denied\n");
             js_p->error_code = -PVFS_EPERM;
-            return(1);
+            return SM_ACTION_COMPLETE;
         }
     }
 
@@ -316,7 +297,7 @@ static int setattr_setobj_attribs(PINT_s
         "ctime = %llu | dfile_count = %d | dist_size = %d]\n",
         dspace_a_p->owner, dspace_a_p->group, dspace_a_p->perms,
         dspace_a_p->objtype, llu(dspace_a_p->atime),
-        llu(PVFS_util_mkversion_time(dspace_a_p->mtime)), llu(dspace_a_p->ctime),
+        llu(PINT_util_mkversion_time(dspace_a_p->mtime)), llu(dspace_a_p->ctime),
         (int)dspace_a_p->u.meta.dfile_count,
         (int)dspace_a_p->u.meta.dist_size);
 
@@ -328,17 +309,21 @@ static int setattr_setobj_attribs(PINT_s
         s_op->req->u.setattr.fs_id, s_op->req->u.setattr.handle,
         ds_attr, 
         TROVE_SYNC,
-        s_op, 0, js_p, &j_id, server_job_context);
+        smcb, 0, js_p, &j_id, server_job_context);
 
     return ret;
 }
 
-static int setattr_write_metafile_datafile_handles_if_required(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action setattr_write_metafile_datafile_handles_if_required(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = 0, dfile_count = 0;
     job_id_t j_id;
 
+    /* reset from jump to here with STATE_METAFILE */
+    js_p->error_code = 0;
+
     gossip_debug(GOSSIP_SETATTR_DEBUG,
                  " request has dfile_count of %d | dspace has %d\n",
                  s_op->req->u.setattr.attr.u.meta.dfile_count,
@@ -351,7 +336,7 @@ static int setattr_write_metafile_datafi
         gossip_err("The requested dfile count of %d is invalid; "
                    "aborting operation.\n", dfile_count);
         js_p->error_code = -PVFS_EOVERFLOW;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* set up key and value structure for keyval write */
@@ -378,14 +363,15 @@ static int setattr_write_metafile_datafi
         s_op->req->u.setattr.fs_id, s_op->req->u.setattr.handle,
         &(s_op->key), &(s_op->val),
         0,
-        NULL, s_op, 0, js_p, &j_id, server_job_context);
+        NULL, smcb, 0, js_p, &j_id, server_job_context);
 
     return ret;
 }
 
-static int setattr_write_metafile_distribution_if_required(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action setattr_write_metafile_distribution_if_required(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = 0;
     job_id_t j_id;
 
@@ -395,7 +381,7 @@ static int setattr_write_metafile_distri
         gossip_debug(GOSSIP_SETATTR_DEBUG,
                      "skipping distribution write\n");
         js_p->error_code = 0;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* set up key and value structure for keyval write */
@@ -412,7 +398,7 @@ static int setattr_write_metafile_distri
     if(!s_op->val.buffer)
     {
         js_p->error_code = -PVFS_ENOMEM;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     s_op->free_val = 1;
     
@@ -428,14 +414,15 @@ static int setattr_write_metafile_distri
         s_op->req->u.setattr.fs_id, s_op->req->u.setattr.handle,
         &(s_op->key), &(s_op->val),
         TROVE_SYNC,
-        NULL, s_op, 0, js_p, &j_id, server_job_context);
+        NULL, smcb, 0, js_p, &j_id, server_job_context);
 
     return ret;
 }
 
-static int setattr_write_symlink_target_if_required(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action setattr_write_symlink_target_if_required(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = 0;
     job_id_t j_id;
 
@@ -445,7 +432,7 @@ static int setattr_write_symlink_target_
         gossip_debug(GOSSIP_SETATTR_DEBUG,
                      "skipping symlink target write\n");
         js_p->error_code = 0;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     assert(s_op->req->u.setattr.attr.u.sym.target_path_len > 0);
@@ -472,7 +459,7 @@ static int setattr_write_symlink_target_
         s_op->req->u.setattr.fs_id, s_op->req->u.setattr.handle,
         &(s_op->key), &(s_op->val),
         TROVE_SYNC,
-        NULL, s_op, 0, js_p, &j_id, server_job_context);
+        NULL, smcb, 0, js_p, &j_id, server_job_context);
 
     return ret;
 }
@@ -488,14 +475,28 @@ static int setattr_write_symlink_target_
  * Synopsis: free memory and return
  *           
  */
-static int setattr_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action setattr_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if(s_op->free_val)
     {
         free(s_op->val.buffer);
     }
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(setattr);
+
+struct PINT_server_req_params pvfs2_set_attr_params =
+{
+    .string_name = "setattr",
+    .perm = PINT_SERVER_CHECK_ATTR,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_setattr,
+    .state_machine = &pvfs2_set_attr_sm
+};
 
 /*
  * Local variables:

Index: set-eattr.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/set-eattr.sm,v
diff -p -u -r1.11 -r1.11.14.1
--- set-eattr.sm	13 Jul 2006 05:11:43 -0000	1.11
+++ set-eattr.sm	21 Jul 2008 18:18:15 -0000	1.11.14.1
@@ -12,24 +12,12 @@
 #include "pvfs2-attr.h"
 #include "pvfs2-internal.h"
 #include "pvfs2-util.h"
-
-extern PINT_server_trove_keys_s Trove_Common_Keys[];
-
-static int seteattr_verify_eattribs(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int seteattr_setobj_eattribs(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int seteattr_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
+#include "pint-util.h"
+#include "pint-eattr.h"
 
 %%
 
-machine pvfs2_set_eattr_sm(
-    prelude,
-    verify_eattrib,
-    setobj_eattrib,
-    cleanup,
-    final_response)
+machine pvfs2_set_eattr_sm
 {
     state prelude
     {
@@ -71,13 +59,11 @@ machine pvfs2_set_eattr_sm(
  * It also prints debugging information.
  */
 static int seteattr_verify_eattribs(
-    PINT_server_op *s_op, job_status_s *js_p)
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    PVFS_object_attr *a_p = NULL;
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int i;
-    char reserved_prefix[] = "system.pvfs2.";
-    int reserved_prefix_len = strlen("system.pvfs2.");
-
+    PVFS_object_attr *a_p = NULL;
     a_p = &s_op->attr;
 
     js_p->error_code = 0;
@@ -86,32 +72,22 @@ static int seteattr_verify_eattribs(
                  "  ext attr list write to handle %llu refers to a %s\n\t"
                  "[owner = %d, group = %d, perms = %o, type = %d]\n",
                  llu(s_op->req->u.seteattr.handle),
-                 get_object_type(a_p->objtype),
+                 PINT_util_get_object_type(a_p->objtype),
                  a_p->owner, a_p->group, a_p->perms, a_p->objtype);
 
     /* 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))
+        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)
         {
-            /* 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)
-        {
-            /* what error code make sense here? */
-            js_p->error_code = -PVFS_EINVAL;
-            return 1;
+            return SM_ACTION_COMPLETE;
         }
     }
 
-    js_p->error_code = 0;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /*
@@ -130,8 +106,9 @@ static int seteattr_verify_eattribs(
  *  (TROVE_NOOVERWRITE, TROVE_ONLYOVERWRITE)
  */
 static int seteattr_setobj_eattribs(
-        PINT_server_op *s_op, job_status_s *js_p)
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = 0;
     PVFS_ds_flags trove_flags = 0;
     job_id_t j_id;
@@ -161,7 +138,7 @@ static int seteattr_setobj_eattribs(
         s_op->req->u.seteattr.nkey,
         trove_flags,
         NULL,
-        s_op,
+        smcb,
         0,
         js_p,
         &j_id,
@@ -181,12 +158,25 @@ static int seteattr_setobj_eattribs(
  * Synopsis: free memory and return
  *           
  */
-static int seteattr_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static int seteattr_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     /* do I need to free memory from decoding key and val?*/
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
+PINT_GET_OBJECT_REF_DEFINE(seteattr);
+
+struct PINT_server_req_params pvfs2_set_eattr_params =
+{
+    .string_name = "set_eattr",
+    .perm = PINT_SERVER_CHECK_ATTR,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_seteattr,
+    .state_machine = &pvfs2_set_eattr_sm
+};
+
 /*
  * Local variables:
  *  mode: c
@@ -196,4 +186,3 @@ static int seteattr_cleanup(PINT_server_
  *
  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  */
-

Index: setparam.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/setparam.sm,v
diff -p -u -r1.29 -r1.29.14.1
--- setparam.sm	13 Jul 2006 05:11:43 -0000	1.29
+++ setparam.sm	21 Jul 2008 18:18:15 -0000	1.29.14.1
@@ -15,21 +15,15 @@
 #include "pvfs2-server.h"
 #include "pint-event.h"
 #include "pvfs2-internal.h"
-
-static int setparam_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int setparam_work(
-    PINT_server_op *s_op, job_status_s* js_p);
+#include "gossip.h"
+#include "request-scheduler/request-scheduler.h"
 
 static int check_fs_id(PVFS_fs_id fs_id);
+static int drop_caches(void);
 
 %%
 
-machine pvfs2_setparam_sm(
-    prelude,
-    work,
-    final_response,
-    cleanup)
+machine pvfs2_setparam_sm
 {
     state prelude
     {
@@ -63,8 +57,10 @@ machine pvfs2_setparam_sm(
  *
  * actually does the "work" involved in setting a runtime server parameter
  */
-static int setparam_work(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action setparam_work(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1, tmp_on = 0, old_event_on = 0;
     job_id_t tmp_id;
     uint64_t tmp_mask = 0;
@@ -82,17 +78,17 @@ static int setparam_work(PINT_server_op 
             gossip_set_debug_mask(
                 1, s_op->req->u.mgmt_setparam.value);
             js_p->error_code = 0;
-            return(1);
+            return SM_ACTION_COMPLETE;
         case PVFS_SERV_PARAM_INVALID:
             gossip_lerr("Error: mgmt_setparam for unknown parameter %d.\n",
                 (int)s_op->req->u.mgmt_setparam.param);
             js_p->error_code = -PVFS_ENOSYS;
-            return(1);
+            return SM_ACTION_COMPLETE;
         case PVFS_SERV_PARAM_FSID_CHECK:
             s_op->resp.u.mgmt_setparam.old_value = 0;
             js_p->error_code = check_fs_id(
                 (PVFS_fs_id)s_op->req->u.mgmt_setparam.value);
-            return(1);
+            return SM_ACTION_COMPLETE;
         case PVFS_SERV_PARAM_ROOT_CHECK:
             tmp_handle = (PVFS_handle)s_op->req->u.mgmt_setparam.value;
             s_op->resp.u.mgmt_setparam.old_value = 0;
@@ -102,7 +98,7 @@ static int setparam_work(PINT_server_op 
             ret = job_trove_dspace_verify(
                 s_op->req->u.mgmt_setparam.fs_id, tmp_handle,
                 0, 
-                s_op, 0, js_p, &tmp_id, server_job_context);
+                smcb, 0, js_p, &tmp_id, server_job_context);
             return(ret);
         case PVFS_SERV_PARAM_EVENT_ON:
             ret = 0;
@@ -113,7 +109,7 @@ static int setparam_work(PINT_server_op 
                 old_api_mask, old_op_mask);
             s_op->resp.u.mgmt_setparam.old_value = old_event_on;
             js_p->error_code = ret;
-            return(1);
+            return SM_ACTION_COMPLETE;
         case PVFS_SERV_PARAM_EVENT_MASKS:
             PINT_event_get_masks(
                 &old_event_on, &old_api_mask, &old_op_mask);
@@ -123,7 +119,7 @@ static int setparam_work(PINT_server_op 
             s_op->resp.u.mgmt_setparam.old_value = old_api_mask +
                 ((int64_t)old_op_mask << 32);
             js_p->error_code = 0;
-            return(1);
+            return SM_ACTION_COMPLETE;
         case PVFS_SERV_PARAM_SYNC_META:
             user_opts = get_server_config_struct();
             fs_conf = PINT_config_find_fs_id(user_opts, 
@@ -136,7 +132,7 @@ static int setparam_work(PINT_server_op 
                     fs_conf->trove_sync_meta = 0;
             }
             js_p->error_code = 0;
-            return(1);
+            return SM_ACTION_COMPLETE;
         case PVFS_SERV_PARAM_SYNC_DATA:
             user_opts = get_server_config_struct();
             fs_conf = PINT_config_find_fs_id(user_opts, 
@@ -159,18 +155,26 @@ static int setparam_work(PINT_server_op 
                 }
             }
             js_p->error_code = 0;
-            return(1);
+            return SM_ACTION_COMPLETE;
         case PVFS_SERV_PARAM_MODE:
-            /* no work to do here; request scheduler has already handled */
+
+            s_op->resp.u.mgmt_setparam.old_value = PINT_req_sched_get_mode();
+            ret = job_req_sched_change_mode(s_op->req->u.mgmt_setparam.value,
+                                            NULL, 0, js_p, &s_op->scheduled_id,
+                                            server_job_context);
+
             js_p->error_code = 0;
-            return(1);
+            return ret;
+        case PVFS_SERV_PARAM_DROP_CACHES:
+            js_p->error_code = drop_caches();
+            return SM_ACTION_COMPLETE;
     }
 
     gossip_lerr("Error: mgmt_setparam for unknown parameter %d.\n",
                 (int)s_op->req->u.mgmt_setparam.param);
 
     js_p->error_code = -PVFS_ENOSYS;
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 /* setparam_cleanup()
@@ -178,11 +182,12 @@ static int setparam_work(PINT_server_op 
  * cleans up any resources consumed by this state machine and ends
  * execution of the machine
  */
-static int setparam_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action setparam_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
     gossip_debug(GOSSIP_SERVER_DEBUG, " - setparam returning %d\n",
                  js_p->error_code);
-    return(server_state_machine_complete(s_op));
+    return(server_state_machine_complete(smcb));
 }
 
 /* check_fs_id()
@@ -198,6 +203,7 @@ static int check_fs_id(PVFS_fs_id fs_id)
     TROVE_keyval_s name;
     TROVE_coll_id tmp_coll;
     TROVE_op_id tmp_id;
+    struct server_configuration_s * server_config;
 
     name.buffer = malloc(PVFS_NAME_MAX);
     if (!name.buffer)
@@ -207,9 +213,12 @@ static int check_fs_id(PVFS_fs_id fs_id)
     }
     name.buffer_sz = PVFS_NAME_MAX;
 
+    server_config = get_server_config_struct();
+
     while(count == 1)
     {
         ret = trove_collection_iterate(
+            server_config->trove_method,
             &pos, &name, &tmp_coll, &count, 0, 0, NULL, &tmp_id);
 
         if (ret == 0)
@@ -240,6 +249,62 @@ free_name_buffer:
 check_failed:
 
     return ret;
+}
+
+static inline int PINT_get_object_ref_setparam(
+    struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
+{
+    *fs_id = req->u.mgmt_setparam.fs_id;
+    *handle = PVFS_HANDLE_NULL;
+    return 0;
+};
+
+struct PINT_server_req_params pvfs2_setparam_params =
+{
+    .string_name = "mgmt_setparam",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_modify,
+    .get_object_ref = PINT_get_object_ref_setparam,
+    .state_machine = &pvfs2_setparam_sm
+};
+
+/* drop_caches()
+ *
+ * Linux specific, but should fail cleanly on other platforms. 
+ *
+ * This function asks the operating system to sync and drop any in memory
+ * caches that it may have.  Applies globally to all file systems on the
+ * server, not just the PVFS storage space.
+ */
+static int drop_caches(void)
+{
+    int fd;
+    int ret;
+
+    /* try to commit buffer cache first */
+    sync();
+
+    /* open Linux specific control file if present */
+    fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
+    if(fd < 0)
+    {
+        gossip_debug(GOSSIP_SERVER_DEBUG, 
+            "Warning: drop_caches not supported.\n");
+        return(-PVFS_EOPNOTSUPP);
+    }
+
+    /* free page cache, dentries, and inodes */
+    ret = write(fd, "3", 2);
+    if(ret < 0)
+    {
+        gossip_debug(GOSSIP_SERVER_DEBUG, 
+            "Warning: found drop_caches file but failed to write to it.\n");
+        close(fd);
+        return(-PVFS_EOPNOTSUPP);
+    }
+   
+    close(fd);
+    return(0);
 }
 
 /*

Index: small-io.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/small-io.sm,v
diff -p -u -r1.16 -r1.16.24.1
--- small-io.sm	13 Jul 2006 05:11:43 -0000	1.16
+++ small-io.sm	21 Jul 2008 18:18:15 -0000	1.16.24.1
@@ -18,18 +18,9 @@
 #include "pint-distribution.h"
 #include "pint-request.h"
 
-static int small_io_start_job(PINT_server_op *s_op, job_status_s *js_p);
-static int small_io_check_size(PINT_server_op *s_op, job_status_s *js_p);
-static int small_io_cleanup(PINT_server_op *s_op, job_status_s *js_p);
-
 %%
 
-machine pvfs2_small_io_sm(
-    prelude,
-    start_job,
-    check_size,
-    send_response,
-    cleanup)
+machine pvfs2_small_io_sm
 {
     state prelude
     {
@@ -65,8 +56,10 @@ machine pvfs2_small_io_sm(
 
 %%
 
-static int small_io_start_job(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action small_io_start_job(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret;
     job_id_t tmp_id;
     PINT_Request_state * file_req_state;
@@ -86,9 +79,9 @@ static int small_io_start_job(PINT_serve
     if(s_op->req->u.small_io.io_type == PVFS_IO_READ &&
        s_op->ds_attr.b_size == 0)
     {
-        /* nothing to read.  return 0 */
+        /* nothing to read.  return SM_ACTION_DEFERRED */
         js_p->error_code = 0;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     file_req_state = PINT_new_request_state(
@@ -125,7 +118,7 @@ static int small_io_start_job(PINT_serve
     {
         gossip_err("small_io: Failed to process file request\n");
         js_p->error_code = ret;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
  
     /* figure out if the fs config has trove data sync turned on or off
@@ -135,7 +128,7 @@ static int small_io_start_job(PINT_serve
     {
         gossip_err("small_io: server config is NULL!\n");
         js_p->error_code = -PVFS_EINVAL;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
     
     fs_config = PINT_config_find_fs_id(
@@ -146,7 +139,7 @@ static int small_io_start_job(PINT_serve
                    "config from fs_id of: %d\n",
                    s_op->req->u.small_io.fs_id);
         js_p->error_code = -PVFS_EINVAL;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     if(s_op->req->u.small_io.io_type == PVFS_IO_WRITE)
@@ -163,7 +156,7 @@ static int small_io_start_job(PINT_serve
            &s_op->resp.u.small_io.result_size,
            (fs_config->trove_sync_data ? TROVE_SYNC : 0),
            NULL,
-           s_op,
+           smcb,
            0,
            js_p,
            &tmp_id,
@@ -181,7 +174,7 @@ static int small_io_start_job(PINT_serve
         if(!s_op->resp.u.small_io.buffer)
         {
             js_p->error_code = -PVFS_ENOMEM;
-            return 1;
+            return SM_ACTION_COMPLETE;
         }
         
         s_op->u.small_io.result_bytes = result.bytes;
@@ -197,7 +190,7 @@ static int small_io_start_job(PINT_serve
             &s_op->resp.u.small_io.result_size,
             (fs_config->trove_sync_data ? TROVE_SYNC : 0),
             NULL,
-            s_op,
+            smcb,
             0,
             js_p,
             &tmp_id,
@@ -206,7 +199,7 @@ static int small_io_start_job(PINT_serve
         {
             gossip_err("small-io: Failed to post trove bstream read\n");
             js_p->error_code = ret;
-            return 1;
+            return SM_ACTION_COMPLETE;
         }
     }
 
@@ -215,8 +208,10 @@ static int small_io_start_job(PINT_serve
     return ret;
 }
 
-static int small_io_check_size(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action small_io_check_size(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if(s_op->req->u.small_io.io_type == PVFS_IO_READ)
     {
         if(s_op->resp.u.small_io.result_size !=
@@ -229,11 +224,13 @@ static int small_io_check_size(PINT_serv
         }
     }
 
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int small_io_cleanup(PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action small_io_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     if(s_op->req->u.small_io.io_type == PVFS_IO_READ &&
        s_op->resp.u.small_io.buffer)
     {
@@ -241,8 +238,30 @@ static int small_io_cleanup(PINT_server_
                     s_op->req->u.small_io.total_bytes, BMI_SEND);
     }
 
-    return server_state_machine_complete(s_op);
+    return server_state_machine_complete(smcb);
 }
+
+static inline enum PINT_server_req_access_type PINT_server_req_access_small_io(
+    struct PVFS_server_req *req)
+{
+    if(req->u.io.io_type == PVFS_IO_READ)
+    {
+        return PINT_SERVER_REQ_READONLY;
+    }
+    return PINT_SERVER_REQ_MODIFY;
+}
+
+PINT_GET_OBJECT_REF_DEFINE(small_io);
+
+struct PINT_server_req_params pvfs2_small_io_params =
+{
+    .string_name = "small_io",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_access_small_io,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_small_io,
+    .state_machine = &pvfs2_small_io_sm
+};
 
 /*
  * Local variables:

Index: statfs.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/statfs.sm,v
diff -p -u -r1.13 -r1.13.28.1
--- statfs.sm	5 Jun 2006 19:57:29 -0000	1.13
+++ statfs.sm	21 Jul 2008 18:18:15 -0000	1.13.28.1
@@ -19,18 +19,9 @@
 #include <sys/sysinfo.h>
 #endif
 
-static int statfs_cleanup(
-    PINT_server_op *s_op, job_status_s* js_p);
-static int statfs_do_statfs(
-    PINT_server_op *s_op, job_status_s* js_p);
-
 %%
 
-machine pvfs2_statfs_sm(
-    prelude,
-    do_statfs,
-    final_response,
-    cleanup)
+machine pvfs2_statfs_sm
 {
     state prelude
     {
@@ -63,8 +54,10 @@ machine pvfs2_statfs_sm(
  *
  * issue the trove call to retrieve fs statistics
  */
-static int statfs_do_statfs(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action statfs_do_statfs(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -1;
     TROVE_context_id tmp_context;
     struct server_configuration_s *user_opts = get_server_config_struct();
@@ -77,7 +70,7 @@ static int statfs_do_statfs(PINT_server_
     if (ret < 0)
     {
         js_p->error_code = ret;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     /* find out how many total handles this server controls */
@@ -87,7 +80,7 @@ static int statfs_do_statfs(PINT_server_
     if(ret < 0)
     {   
         js_p->error_code = ret;
-        return(1);
+        return SM_ACTION_COMPLETE;
     }
 
     /* we need a context to be able to make the getinfo call */
@@ -95,7 +88,7 @@ static int statfs_do_statfs(PINT_server_
     if (ret < 0)
     {
         js_p->error_code = ret;
-        return 1;
+        return SM_ACTION_COMPLETE;
     }
 
     ret = trove_collection_getinfo(
@@ -138,7 +131,7 @@ static int statfs_do_statfs(PINT_server_
 #endif
 
     js_p->error_code = ((ret != 1) ? ret : 0);
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
 
@@ -147,10 +140,26 @@ static int statfs_do_statfs(PINT_server_
  * cleans up any resources consumed by this state machine and ends
  * execution of the machine
  */
-static int statfs_cleanup(PINT_server_op *s_op, job_status_s* js_p)
+static PINT_sm_action statfs_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
+{
+    return(server_state_machine_complete(smcb));
+}
+
+static inline int PINT_get_object_ref_statfs(
+    struct PVFS_server_req *req, PVFS_fs_id *fs_id, PVFS_handle *handle)
 {
-    return(server_state_machine_complete(s_op));
+    *fs_id = req->u.statfs.fs_id;
+    *handle = PVFS_HANDLE_NULL;
+    return 0;
 }
+
+struct PINT_server_req_params pvfs2_statfs_params =
+{
+    .string_name = "statfs",
+    .get_object_ref = PINT_get_object_ref_statfs,
+    .state_machine = &pvfs2_statfs_sm
+};
 
 
 /*

Index: truncate.sm
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/server/truncate.sm,v
diff -p -u -r1.5 -r1.5.28.1
--- truncate.sm	5 Jun 2006 19:57:29 -0000	1.5
+++ truncate.sm	21 Jul 2008 18:18:15 -0000	1.5.28.1
@@ -14,21 +14,9 @@
 #include "server-config.h"
 #include "pvfs2-server.h"
 
-static int truncate_resize(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int truncate_check_error(
-    PINT_server_op *s_op, job_status_s *js_p);
-static int truncate_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p);
-
 %%
 
-machine pvfs2_truncate_sm(
-    prelude, 
-    resize,
-    check_error,
-    final_response, 
-    cleanup)
+machine pvfs2_truncate_sm
 {
     state prelude
     {
@@ -64,31 +52,44 @@ machine pvfs2_truncate_sm(
 
 %%
 
-static int truncate_resize(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action truncate_resize(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
+    struct PINT_server_op *s_op = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
     int ret = -PVFS_EINVAL;
     job_id_t i;
 
     ret = job_trove_bstream_resize(
         s_op->req->u.truncate.fs_id, s_op->req->u.truncate.handle,
         s_op->req->u.truncate.size, s_op->req->u.truncate.flags,
-        NULL, s_op, 0, js_p, &i, server_job_context);
+        NULL, smcb, 0, js_p, &i, server_job_context);
 
     return ret;
 }
 
-static int truncate_check_error(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action truncate_check_error(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return 1;
+    return SM_ACTION_COMPLETE;
 }
 
-static int truncate_cleanup(
-    PINT_server_op *s_op, job_status_s *js_p)
+static PINT_sm_action truncate_cleanup(
+        struct PINT_smcb *smcb, job_status_s *js_p)
 {
-    return (server_state_machine_complete(s_op));
+    return (server_state_machine_complete(smcb));
 }
+
+PINT_GET_OBJECT_REF_DEFINE(truncate);
+
+struct PINT_server_req_params pvfs2_truncate_params =
+{
+    .string_name = "truncate",
+    .perm = PINT_SERVER_CHECK_NONE,
+    .access_type = PINT_server_req_modify,
+    .sched_policy = PINT_SERVER_REQ_SCHEDULE,
+    .get_object_ref = PINT_get_object_ref_truncate,
+    .state_machine = &pvfs2_truncate_sm
+};
 
 /*
  * Local variables:



More information about the Pvfs2-cvs mailing list