WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] tools: remove fs-front/fs-back

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] tools: remove fs-front/fs-back
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 17 Jan 2011 07:59:45 -0800
Delivery-date: Mon, 17 Jan 2011 08:15:33 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxx>
# Date 1294769624 0
# Node ID 3c78729b6f06ecd7f48ed3a83d7af63c494c6d65
# Parent  ae3567ccf5240f31f77fed80ba6e174085f49bff
tools: remove fs-front/fs-back

Its access controls are really not OK.  In particular, it's not good for
libxl, which stores per-VM config blobs in a directory that is exported
to all VMs.

This will break stub-qemu save/restore, which is the only user of
fs-front that I'm aware of, but:
 - It's currently broken anyway (fs-back isn't run by default and crashes
   if it is run manually); and
 - Stefano has a plan to plumb qemu save records through a dedicated
   console channel instead.

Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
Committed-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
---
 extras/mini-os/fs-front.c        | 1297 ---------------------------------------
 extras/mini-os/include/fs.h      |   56 -
 tools/fs-back/Makefile           |   35 -
 tools/fs-back/fs-backend.c       |  500 ---------------
 tools/fs-back/fs-backend.h       |  102 ---
 tools/fs-back/fs-debug.h         |   12 
 tools/fs-back/fs-ops.c           |  794 -----------------------
 tools/fs-back/fs-xenbus.c        |  273 --------
 tools/fs-back/sys-queue.h        |  338 ----------
 extras/mini-os/include/fbfront.h |    1 
 extras/mini-os/kernel.c          |    7 
 extras/mini-os/lib/sys.c         |  221 ------
 extras/mini-os/main.c            |    2 
 tools/Makefile                   |    2 
 14 files changed, 14 insertions(+), 3626 deletions(-)

diff -r ae3567ccf524 -r 3c78729b6f06 extras/mini-os/fs-front.c
--- a/extras/mini-os/fs-front.c Tue Jan 11 16:48:09 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1297 +0,0 @@
-/******************************************************************************
- * fs-front.c
- * 
- * Frontend driver for FS split device driver.
- *
- * Copyright (c) 2007, Grzegorz Milos, <gm281@xxxxxxxxx>.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
- * DEALINGS IN THE SOFTWARE.
- */
-
-#undef NDEBUG
-#include <stdint.h>
-#include <mini-os/os.h>
-#include <mini-os/list.h>
-#include <mini-os/xmalloc.h>
-#include <mini-os/xenbus.h>
-#include <mini-os/gnttab.h>
-#include <mini-os/events.h>
-#include <xen/io/fsif.h>
-#include <mini-os/fs.h>
-#include <mini-os/sched.h>
-
-#define preempt_disable()
-#define preempt_enable()
-#define cmpxchg(p,o,n) synch_cmpxchg(p,o,n)
-
-
-#ifdef FS_DEBUG
-#define DEBUG(_f, _a...) \
-    printk("MINI_OS(file=fs-front.c, line=%d) " _f "\n", __LINE__, ## _a)
-#else
-#define DEBUG(_f, _a...)    ((void)0)
-#endif
-
-
-struct fs_request;
-struct fs_import *fs_import;
-void *alloc_buffer_page(struct fs_request *req, domid_t domid, grant_ref_t 
*gref);
-void free_buffer_page(struct fs_request *req);
-
-/******************************************************************************/
-/*                      RING REQUEST/RESPONSES HANDLING                       
*/
-/******************************************************************************/
-
-struct fs_request
-{
-    void *private1;                        /* Specific to request type */
-    void *private2;
-    struct thread *thread;                 /* Thread blocked on this request */
-    struct fsif_response shadow_rsp;       /* Response copy writen by the 
-                                              interrupt handler */  
-};
-
-struct fs_rw_gnts
-{
-    /* TODO 16 bit? */
-    int count;
-    grant_ref_t grefs[FSIF_NR_READ_GNTS];  
-    void *pages[FSIF_NR_READ_GNTS];  
-};
-
-/* Ring operations:
- * FSIF ring is used differently to Linux-like split devices. This stems from 
- * the fact that no I/O request queue is present. The use of some of the macros
- * defined in ring.h is not allowed, in particular:
- * RING_PUSH_REQUESTS_AND_CHECK_NOTIFY cannot be used.
- *
- * The protocol used for FSIF ring is described below:
- *
- * In order to reserve a request the frontend:
- * a) saves current frontend_ring->req_prod_pvt into a local variable
- * b) checks that there are free request using the local req_prod_pvt
- * c) tries to reserve the request using cmpxchg on frontend_ring->req_prod_pvt
- *    if cmpxchg fails, it means that someone reserved the request, start from
- *    a)
- * 
- * In order to commit a request to the shared ring:
- * a) cmpxchg shared_ring->req_prod from local req_prod_pvt to req_prod_pvt+1 
- *    Loop if unsuccessful.
- * NOTE: Request should be commited to the shared ring as quickly as possible,
- *       because otherwise other threads might busy loop trying to commit next
- *       requests. It also follows that preemption should be disabled, if
- *       possible, for the duration of the request construction.
- */
-
-/* Number of free requests (for use on front side only). */
-#define FS_RING_FREE_REQUESTS(_r, _req_prod_pvt)                         \
-    (RING_SIZE(_r) - (_req_prod_pvt - (_r)->rsp_cons))
-
-
-
-static RING_IDX reserve_fsif_request(struct fs_import *import)
-{
-    RING_IDX idx; 
-
-    down(&import->reqs_sem);
-    preempt_disable();
-again:    
-    /* We will attempt to reserve slot idx */
-    idx = import->ring.req_prod_pvt;
-    ASSERT (FS_RING_FREE_REQUESTS(&import->ring, idx));
-    /* Attempt to reserve */
-    if(cmpxchg(&import->ring.req_prod_pvt, idx, idx+1) != idx)
-        goto again;
-
-    return idx; 
-}
-
-static void commit_fsif_request(struct fs_import *import, RING_IDX idx)
-{
-    while(cmpxchg(&import->ring.sring->req_prod, idx, idx+1) != idx)
-    {
-        printk("Failed to commit a request: req_prod=%d, idx=%d\n",
-                import->ring.sring->req_prod, idx);
-    }
-    preempt_enable();
-
-    /* NOTE: we cannot do anything clever about rsp_event, to hold off
-     * notifications, because we don't know if we are a single request (in 
which
-     * case we have to notify always), or a part of a larger request group
-     * (when, in some cases, notification isn't required) */
-    notify_remote_via_evtchn(import->local_port);
-}
-
-
-
-static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
-{
-    unsigned int old_id, new_id;
-
-again:    
-    old_id = freelist[0];
-    /* Note: temporal inconsistency, since freelist[0] can be changed by 
someone
-     * else, but we are a sole owner of freelist[id + 1], it's OK. */
-    freelist[id + 1] = old_id;
-    new_id = id;
-    if(cmpxchg(&freelist[0], old_id, new_id) != old_id)
-    {
-        printk("Cmpxchg on freelist add failed.\n");
-        goto again;
-    }
-}
-
-/* always call reserve_fsif_request(import) before this, to protect from
- * depletion. */
-static inline unsigned short get_id_from_freelist(unsigned short* freelist)
-{
-    unsigned int old_id, new_id;
-
-again:    
-    old_id = freelist[0];
-    new_id = freelist[old_id + 1];
-    if(cmpxchg(&freelist[0], old_id, new_id) != old_id)
-    {
-        printk("Cmpxchg on freelist remove failed.\n");
-        goto again;
-    }
-    
-    return old_id;
-}
-
-/******************************************************************************/
-/*                  END OF RING REQUEST/RESPONSES HANDLING                    
*/
-/******************************************************************************/
-
-
-
-/******************************************************************************/
-/*                         INDIVIDUAL FILE OPERATIONS                         
*/
-/******************************************************************************/
-int fs_open(struct fs_import *import, char *file)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int fd;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref id=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", file);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_OPEN;
-    req->id = priv_req_id;
-    req->u.fopen.gref = gref;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    fd = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following FD returned: %d\n", fd);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return fd;
-} 
-
-int fs_close(struct fs_import *import, int fd)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_close call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_CLOSE;
-    req->id = priv_req_id;
-    req->u.fclose.fd = fd;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("Close returned: %d\n", ret);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-}
-
-ssize_t fs_read(struct fs_import *import, int fd, void *buf, 
-                ssize_t len, ssize_t offset)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    struct fs_rw_gnts gnts;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    ssize_t ret;
-    int i;
-
-    if (!import)
-        return -1;
-
-    BUG_ON(len > PAGE_SIZE * FSIF_NR_READ_GNTS);
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_read call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_READ;
-    req->id = priv_req_id;
-    req->u.fread.fd = fd;
-    req->u.fread.len = len;
-    req->u.fread.offset = offset;
-
-
-    ASSERT(len > 0);
-    gnts.count = ((len - 1) / PAGE_SIZE) + 1; 
-    for(i=0; i<gnts.count; i++)
-    {
-        gnts.pages[i] = (void *)alloc_page(); 
-        gnts.grefs[i] = gnttab_grant_access(import->dom_id, 
-                                            virt_to_mfn(gnts.pages[i]), 
-                                            0); 
-        memset(gnts.pages[i], 0, PAGE_SIZE);
-        req->u.fread.grefs[i] = gnts.grefs[i];
-    }
-    fsr->thread = current;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (ssize_t)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret value returned %d\n", ret);
-    if(ret > 0)
-    {
-        ssize_t to_copy = ret, current_copy;
-        for(i=0; i<gnts.count; i++)
-        {
-            gnttab_end_access(gnts.grefs[i]);
-            current_copy = to_copy > PAGE_SIZE ? PAGE_SIZE : to_copy;
-            if(current_copy > 0)
-                memcpy(buf, gnts.pages[i], current_copy); 
-            to_copy -= current_copy; 
-            buf = (char*) buf + current_copy;
-            free_page(gnts.pages[i]);
-        }
-    }
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-ssize_t fs_write(struct fs_import *import, int fd, void *buf, 
-                 ssize_t len, ssize_t offset)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    struct fs_rw_gnts gnts;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    ssize_t ret, to_copy;
-    int i;
-
-    if (!import)
-        return -1;
-
-    BUG_ON(len > PAGE_SIZE * FSIF_NR_WRITE_GNTS);
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_read call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_WRITE;
-    req->id = priv_req_id;
-    req->u.fwrite.fd = fd;
-    req->u.fwrite.len = len;
-    req->u.fwrite.offset = offset;
-
-    ASSERT(len > 0);
-    gnts.count = ((len - 1) / PAGE_SIZE) + 1; 
-    to_copy = len;
-    for(i=0; i<gnts.count; i++)
-    {
-        int current_copy = (to_copy > PAGE_SIZE ? PAGE_SIZE : to_copy);
-        gnts.pages[i] = (void *)alloc_page(); 
-        gnts.grefs[i] = gnttab_grant_access(import->dom_id, 
-                                            virt_to_mfn(gnts.pages[i]), 
-                                            0); 
-        memcpy(gnts.pages[i], buf, current_copy);
-        if(current_copy < PAGE_SIZE)
-            memset((char *)gnts.pages[i] + current_copy, 
-                    0, 
-                    PAGE_SIZE - current_copy); 
-        req->u.fwrite.grefs[i] = gnts.grefs[i];
-        to_copy -= current_copy; 
-        buf = (char*) buf + current_copy;
-    }
-    fsr->thread = current;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (ssize_t)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret value returned %d\n", ret);
-    for(i=0; i<gnts.count; i++)
-    {
-        gnttab_end_access(gnts.grefs[i]);
-        free_page(gnts.pages[i]);
-    }
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int fs_stat(struct fs_import *import, 
-            int fd, 
-            struct fsif_stat_response *stat)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_stat call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_STAT;
-    req->id = priv_req_id;
-    req->u.fstat.fd   = fd;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("Following ret from fstat: %d\n", ret);
-    memcpy(stat, 
-           &fsr->shadow_rsp.u.fstat, 
-           sizeof(struct fsif_stat_response));
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int fs_truncate(struct fs_import *import, 
-                int fd, 
-                int64_t length)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_truncate call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_TRUNCATE;
-    req->id = priv_req_id;
-    req->u.ftruncate.fd = fd;
-    req->u.ftruncate.length = length;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("Following ret from ftruncate: %d\n", ret);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int fs_remove(struct fs_import *import, char *file)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", file);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_REMOVE;
-    req->id = priv_req_id;
-    req->u.fremove.gref = gref;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret: %d\n", ret);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-}
-
-
-int fs_rename(struct fs_import *import, 
-              char *old_file_name, 
-              char *new_file_name)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-    char old_header[] = "old: ";
-    char new_header[] = "new: ";
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s%s%c%s%s", 
-            old_header, old_file_name, '\0', new_header, new_file_name);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_RENAME;
-    req->id = priv_req_id;
-    req->u.frename.gref = gref;
-    req->u.frename.old_name_offset = strlen(old_header);
-    req->u.frename.new_name_offset = strlen(old_header) +
-                                     strlen(old_file_name) +
-                                     strlen(new_header) +
-                                     1 /* Accouning for the additional 
-                                          end of string character */;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret: %d\n", ret);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-}
-
-int fs_create(struct fs_import *import, char *name, 
-              int8_t directory, int32_t mode)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_create call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", name);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_CREATE;
-    req->id = priv_req_id;
-    req->u.fcreate.gref = gref;
-    req->u.fcreate.directory = directory;
-    req->u.fcreate.mode = mode;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following ret: %d\n", ret);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-char** fs_list(struct fs_import *import, char *name, 
-               int32_t offset, int32_t *nr_files, int *has_more)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    char **files, *current_file;
-    int i;
-
-    if (!import)
-        return NULL;
-
-    DEBUG("Different masks: NR_FILES=(%llx, %d), ERROR=(%llx, %d), 
HAS_MORE(%llx, %d)\n",
-            NR_FILES_MASK, NR_FILES_SHIFT, ERROR_MASK, ERROR_SHIFT, 
HAS_MORE_FLAG, HAS_MORE_SHIFT);
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_list call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", name);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_DIR_LIST;
-    req->id = priv_req_id;
-    req->u.flist.gref = gref;
-    req->u.flist.offset = offset;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    *nr_files = (fsr->shadow_rsp.u.ret_val & NR_FILES_MASK) >> NR_FILES_SHIFT;
-    files = NULL;
-    if(*nr_files <= 0) goto exit;
-    files = malloc(sizeof(char*) * (*nr_files));
-    current_file = buffer; 
-    for(i=0; i<*nr_files; i++)
-    {
-        files[i] = strdup(current_file); 
-        current_file += strlen(current_file) + 1;
-    }
-    if(has_more != NULL)
-        *has_more = fsr->shadow_rsp.u.ret_val & HAS_MORE_FLAG;
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-exit:
-    return files;
-} 
-
-int fs_chmod(struct fs_import *import, int fd, int32_t mode)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_chmod call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_CHMOD;
-    req->id = priv_req_id;
-    req->u.fchmod.fd = fd;
-    req->u.fchmod.mode = mode;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following returned: %d\n", ret);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int64_t fs_space(struct fs_import *import, char *location)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    grant_ref_t gref;
-    void *buffer;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int64_t ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_space is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    buffer = alloc_buffer_page(fsr, import->dom_id, &gref);
-    DEBUG("gref=%d\n", gref);
-    fsr->thread = current;
-    sprintf(buffer, "%s", location);
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FS_SPACE;
-    req->id = priv_req_id;
-    req->u.fspace.gref = gref;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int64_t)fsr->shadow_rsp.u.ret_val;
-    DEBUG("The following returned: %lld\n", ret);
-    free_buffer_page(fsr);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-} 
-
-int fs_sync(struct fs_import *import, int fd)
-{
-    struct fs_request *fsr;
-    unsigned short priv_req_id;
-    RING_IDX back_req_id; 
-    struct fsif_request *req;
-    int ret;
-
-    if (!import)
-        return -1;
-
-    /* Prepare request for the backend */
-    back_req_id = reserve_fsif_request(import);
-    DEBUG("Backend request id=%d\n", back_req_id);
-
-    /* Prepare our private request structure */
-    priv_req_id = get_id_from_freelist(import->freelist);
-    DEBUG("Request id for fs_sync call is: %d\n", priv_req_id);
-    fsr = &import->requests[priv_req_id];
-    fsr->thread = current;
-
-    req = RING_GET_REQUEST(&import->ring, back_req_id);
-    req->type = REQ_FILE_SYNC;
-    req->id = priv_req_id;
-    req->u.fsync.fd = fd;
-
-    /* Set blocked flag before commiting the request, thus avoiding missed
-     * response race */
-    block(current);
-    commit_fsif_request(import, back_req_id);
-    schedule();
-    
-    /* Read the response */
-    ret = (int)fsr->shadow_rsp.u.ret_val;
-    DEBUG("Close returned: %d\n", ret);
-    add_id_to_freelist(priv_req_id, import->freelist);
-
-    return ret;
-}
-
-
-/******************************************************************************/
-/*                       END OF INDIVIDUAL FILE OPERATIONS                    
*/
-/******************************************************************************/
-
-void *alloc_buffer_page(struct fs_request *req, domid_t domid, grant_ref_t 
*gref)
-{
-    void *page;
-
-    page = (void *)alloc_page(); 
-    *gref = gnttab_grant_access(domid, virt_to_mfn(page), 0); 
-    req->private1 = page;
-    req->private2 = (void *)(uintptr_t)(*gref);
-
-    return page;
-}
-
-void free_buffer_page(struct fs_request *req)
-{
-    gnttab_end_access((grant_ref_t)(uintptr_t)req->private2);
-    free_page(req->private1);
-}
-
-static void fsfront_handler(evtchn_port_t port, struct pt_regs *regs, void 
*data)
-{
-    struct fs_import *import = (struct fs_import*)data;
-    static int in_irq = 0;
-    RING_IDX cons, rp;
-    int more;
-
-    /* Check for non-reentrance */
-    BUG_ON(in_irq);
-    in_irq = 1;
-
-    DEBUG("Event from import [%d:%d].\n", import->dom_id, import->export_id);
-moretodo:   
-    rp = import->ring.sring->rsp_prod;
-    rmb(); /* Ensure we see queued responses up to 'rp'. */
-    cons = import->ring.rsp_cons;
-    while (cons != rp)
-    {
-        struct fsif_response *rsp;
-        struct fs_request *req;
-
-        rsp = RING_GET_RESPONSE(&import->ring, cons); 
-        DEBUG("Response at idx=%d to request id=%d, ret_val=%lx\n", 
-            cons, rsp->id, rsp->u.ret_val);
-        req = &import->requests[rsp->id];
-        memcpy(&req->shadow_rsp, rsp, sizeof(struct fsif_response));
-        DEBUG("Waking up: %s\n", req->thread->name);
-        wake(req->thread);
-
-        cons++;
-        up(&import->reqs_sem);
-    }
-
-    import->ring.rsp_cons = rp;
-    RING_FINAL_CHECK_FOR_RESPONSES(&import->ring, more);
-    if(more) goto moretodo;
-    
-    in_irq = 0;
-}
-
-static void alloc_request_table(struct fs_import *import)
-{
-    struct fs_request *requests;
-    int i;
-
-    BUG_ON(import->nr_entries <= 0);
-    printk("Allocating request array for import %d, nr_entries = %d.\n",
-            import->import_id, import->nr_entries);
-    requests = xmalloc_array(struct fs_request, import->nr_entries);
-    import->freelist = xmalloc_array(unsigned short, import->nr_entries + 1);
-    memset(import->freelist, 0, sizeof(unsigned short) * (import->nr_entries + 
1));
-    for(i=0; i<import->nr_entries; i++)
-        add_id_to_freelist(i, import->freelist);
-    import->requests = requests;
-}
-
-
-/******************************************************************************/
-/*                                FS TESTS                                    
*/
-/******************************************************************************/
-
-
-void test_fs_import(void *data)
-{
-    struct fs_import *import = (struct fs_import *)data; 
-    int ret, fd, i, repeat_count;
-    int32_t nr_files;
-    char buffer[1024];
-    ssize_t offset;
-    char **files;
-    long ret64;
-    struct fsif_stat_response stat;
-    
-    repeat_count = 10; 
-    /* Sleep for 1s and then try to open a file */
-    msleep(1000);
-again:
-    ret = fs_create(import, "mini-os-created-directory", 1, 0777);
-    printk("Directory create: %d\n", ret);
-
-    sprintf(buffer, "mini-os-created-directory/mini-os-created-file-%d", 
-            repeat_count);
-    ret = fs_create(import, buffer, 0, 0666);
-    printk("File create: %d\n", ret);
-
-    fd = fs_open(import, buffer);
-    printk("File descriptor: %d\n", fd);
-    if(fd < 0) return;
-
-    offset = 0;
-    for(i=0; i<10; i++)
-    {
-        sprintf(buffer, "Current time is: %lld\n", NOW());
-        ret = fs_write(import, fd, buffer, strlen(buffer), offset);
-        printk("Writen current time (%d)\n", ret);
-        if(ret < 0)
-            return;
-        offset += ret;
-    }
-    ret = fs_stat(import, fd, &stat);
-    printk("Ret after stat: %d\n", ret);
-    printk(" st_mode=%o\n", stat.stat_mode);
-    printk(" st_uid =%d\n", stat.stat_uid);
-    printk(" st_gid =%d\n", stat.stat_gid);
-    printk(" st_size=%ld\n", stat.stat_size);
-    printk(" st_atime=%ld\n", stat.stat_atime);
-    printk(" st_mtime=%ld\n", stat.stat_mtime);
-    printk(" st_ctime=%ld\n", stat.stat_ctime);
- 
-    ret = fs_close(import, fd);
-    printk("Closed fd: %d, ret=%d\n", fd, ret);
-   
-    printk("Listing files in /\n");
-    files = fs_list(import, "/", 0, &nr_files, NULL); 
-    for(i=0; i<nr_files; i++)
-        printk(" files[%d] = %s\n", i, files[i]);
-
-    ret64 = fs_space(import, "/");
-    printk("Free space: %lld (=%lld Mb)\n", ret64, (ret64 >> 20));
-    repeat_count--;
-    if(repeat_count > 0)
-        goto again;
-    
-}
-
-#if 0
-//    char *content = (char *)alloc_page();
-    int fd, ret;
-//    int read;
-    char write_string[] = "\"test data written from minios\"";
-    struct fsif_stat_response stat;
-    char **files;
-    int32_t nr_files, i;
-    int64_t ret64;
-
-
-    fd = fs_open(import, "test-export-file");
-//    read = fs_read(import, fd, content, PAGE_SIZE, 0);
-//    printk("Read: %d bytes\n", read); 
-//    content[read] = '\0';
-//    printk("Value: %s\n", content);
-    ret = fs_write(import, fd, write_string, strlen(write_string), 0);
-    printk("Ret after write: %d\n", ret);
-    ret = fs_stat(import, fd, &stat);
-    printk("Ret after stat: %d\n", ret);
-    printk(" st_mode=%o\n", stat.stat_mode);
-    printk(" st_uid =%d\n", stat.stat_uid);
-    printk(" st_gid =%d\n", stat.stat_gid);
-    printk(" st_size=%ld\n", stat.stat_size);
-    printk(" st_atime=%ld\n", stat.stat_atime);
-    printk(" st_mtime=%ld\n", stat.stat_mtime);
-    printk(" st_ctime=%ld\n", stat.stat_ctime);
-    ret = fs_truncate(import, fd, 30);
-    printk("Ret after truncate: %d\n", ret);
-    ret = fs_remove(import, "test-to-remove/test-file");
-    printk("Ret after remove: %d\n", ret);
-    ret = fs_remove(import, "test-to-remove");
-    printk("Ret after remove: %d\n", ret);
-    ret = fs_chmod(import, fd, 0700);
-    printk("Ret after chmod: %d\n", ret);
-    ret = fs_sync(import, fd);
-    printk("Ret after sync: %d\n", ret);
-    ret = fs_close(import, fd);
-    //ret = fs_rename(import, "test-export-file", "renamed-test-export-file");
-    //printk("Ret after rename: %d\n", ret);
-    ret = fs_create(import, "created-dir", 1, 0777);
-    printk("Ret after dir create: %d\n", ret);
-    ret = fs_create(import, "created-dir/created-file", 0, 0777);
-    printk("Ret after file create: %d\n", ret);
-    files = fs_list(import, "/", 15, &nr_files, NULL); 
-    for(i=0; i<nr_files; i++)
-        printk(" files[%d] = %s\n", i, files[i]);
-    ret64 = fs_space(import, "created-dir");
-    printk("Ret after space: %lld\n", ret64);
-
-#endif
-
-
-/******************************************************************************/
-/*                            END OF FS TESTS                                 
*/
-/******************************************************************************/
-
-static int init_fs_import(struct fs_import *import)
-{    
-    char *err;
-    xenbus_transaction_t xbt;
-    char nodename[1024], r_nodename[1024], token[128], *message = NULL;
-    struct fsif_sring *sring;
-    int i, retry = 0;
-    domid_t self_id;
-    xenbus_event_queue events = NULL;
-
-    printk("Initialising FS fortend to backend dom %d\n", import->dom_id);
-    /* Allocate page for the shared ring */
-    sring = (struct fsif_sring*) alloc_pages(FSIF_RING_SIZE_ORDER);
-    memset(sring, 0, PAGE_SIZE * FSIF_RING_SIZE_PAGES);
-
-    /* Init the shared ring */
-    SHARED_RING_INIT(sring);
-    ASSERT(FSIF_NR_READ_GNTS == FSIF_NR_WRITE_GNTS);
-
-    /* Init private frontend ring */
-    FRONT_RING_INIT(&import->ring, sring, PAGE_SIZE * FSIF_RING_SIZE_PAGES);
-    import->nr_entries = import->ring.nr_ents;
-
-    /* Allocate table of requests */
-    alloc_request_table(import);
-    init_SEMAPHORE(&import->reqs_sem, import->nr_entries);
-
-    /* Grant access to the shared ring */
-    for(i=0; i<FSIF_RING_SIZE_PAGES; i++) 
-        import->gnt_refs[i] = 
-            gnttab_grant_access(import->dom_id, 
-                                virt_to_mfn((char *)sring + i * PAGE_SIZE), 
-                                0);
-   
-    /* Allocate event channel */ 
-    BUG_ON(evtchn_alloc_unbound(import->dom_id, 
-                                fsfront_handler, 
-                                //ANY_CPU, 
-                                import, 
-                                &import->local_port));
-    unmask_evtchn(import->local_port);
-
-    
-    self_id = xenbus_get_self_id(); 
-    /* Write the frontend info to a node in our Xenbus */
-    sprintf(nodename, "/local/domain/%d/device/vfs/%d", 
-                        self_id, import->import_id);
-
-again:    
-    err = xenbus_transaction_start(&xbt);
-    if (err) {
-        printk("starting transaction\n");
-        free(err);
-    }
-    
-    err = xenbus_printf(xbt, 
-                        nodename, 
-                        "ring-size",
-                        "%u",
-                        FSIF_RING_SIZE_PAGES);
-    if (err) {
-        message = "writing ring-size";
-        goto abort_transaction;
-    }
-    
-    for(i=0; i<FSIF_RING_SIZE_PAGES; i++)
-    {
-        sprintf(r_nodename, "ring-ref-%d", i);
-        err = xenbus_printf(xbt, 
-                            nodename, 
-                            r_nodename,
-                            "%u",
-                            import->gnt_refs[i]);
-        if (err) {
-            message = "writing ring-refs";
-            goto abort_transaction;
-        }
-    }
-
-    err = xenbus_printf(xbt, 
-                        nodename,
-                        "event-channel", 
-                        "%u", 
-                        import->local_port);
-    if (err) {
-        message = "writing event-channel";
-        goto abort_transaction;
-    }
-
-    err = xenbus_printf(xbt, nodename, "state", STATE_READY, 0xdeadbeef);
-    if (err) free(err);
-
-    err = xenbus_transaction_end(xbt, 0, &retry);
-    if (err) free(err);
-    if (retry) {
-            goto again;
-        printk("completing transaction\n");
-    }
-
-    /* Now, when our node is prepared we write request in the exporting domain
-     * */
-    printk("Our own id is %d\n", self_id);
-    sprintf(r_nodename, 
-            "/local/domain/%d/backend/vfs/exports/requests/%d/%d/frontend", 
-            import->dom_id, self_id, import->export_id);
-    BUG_ON(xenbus_write(XBT_NIL, r_nodename, nodename));
-
-    goto done;
-
-abort_transaction:
-    free(err);
-    err = xenbus_transaction_end(xbt, 1, &retry);
-    if (err) free(err);
-
-done:
-
-#define WAIT_PERIOD 10   /* Wait period in ms */    
-#define MAX_WAIT    10   /* Max number of WAIT_PERIODs */
-    import->backend = NULL;
-    sprintf(r_nodename, "%s/backend", nodename);
-   
-    for(retry = MAX_WAIT; retry > 0; retry--)
-    { 
-        xenbus_read(XBT_NIL, r_nodename, &import->backend);
-        if(import->backend)
-        {
-            printk("Backend found at %s\n", import->backend);
-            break;
-        }
-       msleep(WAIT_PERIOD);
-    }        
-    
-    if(!import->backend)
-    {
-        printk("No backend available.\n");
-        /* TODO - cleanup datastructures/xenbus */
-        return 0;
-    }
-    sprintf(r_nodename, "%s/state", import->backend);
-    sprintf(token, "fs-front-%d", import->import_id);
-    /* The token will not be unique if multiple imports are inited */
-    xenbus_watch_path_token(XBT_NIL, r_nodename, r_nodename, &events);
-    err = xenbus_wait_for_value(r_nodename, STATE_READY, &events);
-    if (err) free(err);
-    xenbus_unwatch_path_token(XBT_NIL, r_nodename, r_nodename);
-    printk("Backend ready.\n");
-   
-    //create_thread("fs-tester", test_fs_import, import); 
-
-    return 1;
-}
-
-static void add_export(struct minios_list_head *exports, unsigned int domid)
-{
-    char node[1024], **exports_list = NULL, *ret_msg;
-    int j = 0;
-    static int import_id = 0;
-
-    sprintf(node, "/local/domain/%d/backend/vfs/exports", domid);
-    ret_msg = xenbus_ls(XBT_NIL, node, &exports_list);
-    if (ret_msg && strcmp(ret_msg, "ENOENT"))
-        printk("couldn't read %s: %s\n", node, ret_msg);
-    while(exports_list && exports_list[j])
-    {
-        struct fs_import *import; 
-        int export_id = -1;
-        
-        sscanf(exports_list[j], "%d", &export_id);
-        if(export_id >= 0)
-        {
-            import = xmalloc(struct fs_import);
-            import->dom_id = domid;
-            import->export_id = export_id;
-            import->import_id = import_id++;
-            MINIOS_INIT_LIST_HEAD(&import->list);
-            minios_list_add(&import->list, exports);
-        }
-        free(exports_list[j]);
-        j++;
-    }
-    if(exports_list)
-        free(exports_list);
-    if(ret_msg)
-        free(ret_msg);
-}
-
-#if 0
-static struct minios_list_head* probe_exports(void)
-{
-    struct minios_list_head *exports;
-    char **node_list = NULL, *msg = NULL;
-    int i = 0;
-
-    exports = xmalloc(struct minios_list_head);
-    MINIOS_INIT_LIST_HEAD(exports);
-    
-    msg = xenbus_ls(XBT_NIL, "/local/domain", &node_list);
-    if(msg)
-    {
-        printk("Could not list VFS exports (%s).\n", msg);
-        goto exit;
-    }
-
-    while(node_list[i])
-    {
-        add_export(exports, atoi(node_list[i]));
-        free(node_list[i]);
-        i++;
-    } 
-
-exit:    
-    if(msg)
-        free(msg);
-    if(node_list)
-        free(node_list);
-    return exports;
-}
-#endif
-
-MINIOS_LIST_HEAD(exports);
-
-void init_fs_frontend(void)
-{
-    struct minios_list_head *entry;
-    struct fs_import *import = NULL;
-    printk("Initing FS frontend(s).\n");
-
-    add_export(&exports, 0);
-    minios_list_for_each(entry, &exports)
-    {
-        import = minios_list_entry(entry, struct fs_import, list);
-        printk("FS export [dom=%d, id=%d] found\n", 
-                import->dom_id, import->export_id);
-        if (init_fs_import(import) != 0) {
-            fs_import = import;
-            break;
-        }
-    }
-
-    if (!fs_import)
-       printk("No FS import\n");
-}
-
-/* TODO: shutdown */
diff -r ae3567ccf524 -r 3c78729b6f06 extras/mini-os/include/fbfront.h
--- a/extras/mini-os/include/fbfront.h  Tue Jan 11 16:48:09 2011 +0000
+++ b/extras/mini-os/include/fbfront.h  Tue Jan 11 18:13:44 2011 +0000
@@ -1,5 +1,6 @@
 #include <xen/io/kbdif.h>
 #include <xen/io/fbif.h>
+#include <mini-os/semaphore.h>
 #include <mini-os/wait.h>
 
 /* from <linux/input.h> */
diff -r ae3567ccf524 -r 3c78729b6f06 extras/mini-os/include/fs.h
--- a/extras/mini-os/include/fs.h       Tue Jan 11 16:48:09 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#ifndef __FS_H__
-#define __FS_H__
-
-#include <xen/io/fsif.h>
-#include <mini-os/semaphore.h>
-#include <mini-os/types.h>
-
-#define FSIF_RING_SIZE_ORDER   1
-#define FSIF_RING_SIZE_PAGES   (1<<FSIF_RING_SIZE_ORDER)
-
-struct fs_import 
-{
-    domid_t dom_id;                 /* dom id of the exporting domain       */ 
-    uint16_t export_id;             /* export id (exporting dom specific)   */
-    uint16_t import_id;             /* import id (specific to this domain)  */ 
-    struct minios_list_head list;   /* list of all imports                  */
-    unsigned int nr_entries;        /* Number of entries in rings & request
-                                       array                                */
-    struct fsif_front_ring ring;    /* frontend ring (contains shared ring) */
-    uint32_t gnt_refs[FSIF_RING_SIZE_PAGES];  /* grant references to the 
shared ring  */
-    evtchn_port_t local_port;       /* local event channel port             */
-    char *backend;                  /* XenBus location of the backend       */
-    struct fs_request *requests;    /* Table of requests                    */
-    unsigned short *freelist;       /* List of free request ids             */
-    struct semaphore reqs_sem;      /* Accounts requests resource           */
-};
-
-extern struct fs_import *fs_import;
-
-void init_fs_frontend(void);
-
-int fs_open(struct fs_import *import, char *file);
-int fs_close(struct fs_import *import, int fd);
-ssize_t fs_read(struct fs_import *import, int fd, void *buf, 
-                ssize_t len, ssize_t offset);
-ssize_t fs_write(struct fs_import *import, int fd, void *buf, 
-                 ssize_t len, ssize_t offset);
-int fs_stat(struct fs_import *import, 
-            int fd, 
-            struct fsif_stat_response *stat);
-int fs_truncate(struct fs_import *import, 
-                int fd, 
-                int64_t length);
-int fs_remove(struct fs_import *import, char *file);
-int fs_rename(struct fs_import *import, 
-              char *old_file_name, 
-              char *new_file_name);
-int fs_create(struct fs_import *import, char *name, 
-              int8_t directory, int32_t mode);
-char** fs_list(struct fs_import *import, char *name, 
-               int32_t offset, int32_t *nr_files, int *has_more);
-int fs_chmod(struct fs_import *import, int fd, int32_t mode);
-int64_t fs_space(struct fs_import *import, char *location);
-int fs_sync(struct fs_import *import, int fd);
-
-#endif
diff -r ae3567ccf524 -r 3c78729b6f06 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Tue Jan 11 16:48:09 2011 +0000
+++ b/extras/mini-os/kernel.c   Tue Jan 11 18:13:44 2011 +0000
@@ -41,7 +41,6 @@
 #include <mini-os/blkfront.h>
 #include <mini-os/fbfront.h>
 #include <mini-os/pcifront.h>
-#include <mini-os/fs.h>
 #include <mini-os/xmalloc.h>
 #include <fcntl.h>
 #include <xen/features.h>
@@ -456,11 +455,6 @@ static void pcifront_thread(void *p)
     pcifront_scan(pci_dev, print_pcidev);
 }
 
-static void fs_thread(void *p)
-{
-    init_fs_frontend();
-}
-
 /* This should be overridden by the application we are linked against. */
 __attribute__((weak)) int app_main(start_info_t *si)
 {
@@ -472,7 +466,6 @@ __attribute__((weak)) int app_main(start
     create_thread("fbfront", fbfront_thread, si);
     create_thread("kbdfront", kbdfront_thread, si);
     create_thread("pcifront", pcifront_thread, si);
-    create_thread("fs-frontend", fs_thread, si);
     return 0;
 }
 
diff -r ae3567ccf524 -r 3c78729b6f06 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c  Tue Jan 11 16:48:09 2011 +0000
+++ b/extras/mini-os/lib/sys.c  Tue Jan 11 18:13:44 2011 +0000
@@ -47,7 +47,6 @@
 #ifdef HAVE_LWIP
 #include <lwip/sockets.h>
 #endif
-#include <fs.h>
 
 #define debug(fmt, ...) \
 
@@ -158,13 +157,8 @@ char *getcwd(char *buf, size_t size)
 
 int mkdir(const char *pathname, mode_t mode)
 {
-    int ret;
-    ret = fs_create(fs_import, (char *) pathname, 1, mode);
-    if (ret < 0) {
-        errno = EIO;
-        return -1;
-    }
-    return 0;
+    errno = EIO;
+    return -1;
 }
 
 int posix_openpt(int flags)
@@ -183,7 +177,7 @@ int posix_openpt(int flags)
 
 int open(const char *pathname, int flags, ...)
 {
-    int fs_fd, fd;
+    int fd;
     /* Ugly, but fine.  */
     if (!strncmp(pathname,LOG_PATH,strlen(LOG_PATH))) {
        fd = alloc_fd(FTYPE_CONSOLE);
@@ -197,34 +191,8 @@ int open(const char *pathname, int flags
     }
     if (!strncmp(pathname, "/dev/ptmx", strlen("/dev/ptmx")))
         return posix_openpt(flags);
-    printk("open(%s, %x)", pathname, flags);
-    switch (flags & ~O_ACCMODE) {
-        case 0:
-            fs_fd = fs_open(fs_import, (void *) pathname);
-            break;
-        case O_CREAT|O_TRUNC:
-        {
-            va_list ap;
-            mode_t mode;
-            va_start(ap, flags);
-            mode = va_arg(ap, mode_t);
-            va_end(ap);
-            fs_fd = fs_create(fs_import, (void *) pathname, 0, mode);
-            break;
-        }
-        default:
-            printk(" unsupported flags\n");
-            do_exit();
-    }
-    if (fs_fd < 0) {
-       errno = EIO;
-       return -1;
-    }
-    fd = alloc_fd(FTYPE_FILE);
-    printk("-> %d\n", fd);
-    files[fd].file.fd = fs_fd;
-    files[fd].file.offset = 0;
-    return fd;
+    errno = EIO;
+    return -1;
 }
 
 int isatty(int fd)
@@ -248,20 +216,6 @@ int read(int fd, void *buf, size_t nbyte
             remove_waiter(w);
             return ret;
         }
-       case FTYPE_FILE: {
-           ssize_t ret;
-           if (nbytes > PAGE_SIZE * FSIF_NR_READ_GNTS)
-               nbytes = PAGE_SIZE * FSIF_NR_READ_GNTS;
-           ret = fs_read(fs_import, files[fd].file.fd, buf, nbytes, 
files[fd].file.offset);
-           if (ret > 0) {
-               files[fd].file.offset += ret;
-               return ret;
-           } else if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
 #ifdef HAVE_LWIP
        case FTYPE_SOCKET:
            return lwip_read(files[fd].socket.fd, buf, nbytes);
@@ -309,20 +263,6 @@ int write(int fd, const void *buf, size_
        case FTYPE_CONSOLE:
            console_print(files[fd].cons.dev, (char *)buf, nbytes);
            return nbytes;
-       case FTYPE_FILE: {
-           ssize_t ret;
-           if (nbytes > PAGE_SIZE * FSIF_NR_WRITE_GNTS)
-               nbytes = PAGE_SIZE * FSIF_NR_WRITE_GNTS;
-           ret = fs_write(fs_import, files[fd].file.fd, (void *) buf, nbytes, 
files[fd].file.offset);
-           if (ret > 0) {
-               files[fd].file.offset += ret;
-               return ret;
-           } else if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
 #ifdef HAVE_LWIP
        case FTYPE_SOCKET:
            return lwip_write(files[fd].socket.fd, (void*) buf, nbytes);
@@ -340,48 +280,11 @@ int write(int fd, const void *buf, size_
 
 off_t lseek(int fd, off_t offset, int whence)
 {
-    if (files[fd].type != FTYPE_FILE) {
-       errno = ESPIPE;
-       return (off_t) -1;
-    }
-    switch (whence) {
-       case SEEK_SET:
-           files[fd].file.offset = offset;
-           break;
-       case SEEK_CUR:
-           files[fd].file.offset += offset;
-           break;
-       case SEEK_END: {
-           struct stat st;
-           int ret;
-           ret = fstat(fd, &st);
-           if (ret)
-               return -1;
-           files[fd].file.offset = st.st_size + offset;
-           break;
-       }
-       default:
-           errno = EINVAL;
-           return -1;
-    }
-    return files[fd].file.offset;
+    errno = ESPIPE;
+    return (off_t) -1;
 }
 
 int fsync(int fd) {
-    switch (files[fd].type) {
-       case FTYPE_FILE: {
-           int ret;
-           ret = fs_sync(fs_import, files[fd].file.fd);
-           if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
-       default:
-           break;
-    }
-    printk("fsync(%d): Bad descriptor\n", fd);
     errno = EBADF;
     return -1;
 }
@@ -393,15 +296,6 @@ int close(int fd)
         default:
            files[fd].type = FTYPE_NONE;
            return 0;
-       case FTYPE_FILE: {
-           int ret = fs_close(fs_import, files[fd].file.fd);
-           files[fd].type = FTYPE_NONE;
-           if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
        case FTYPE_XENBUS:
             xs_daemon_close((void*)(intptr_t) fd);
             return 0;
@@ -460,43 +354,10 @@ static void init_stat(struct stat *buf)
     buf->st_blocks = 0;
 }
 
-static void stat_from_fs(struct stat *buf, struct fsif_stat_response *stat)
-{
-    buf->st_mode = stat->stat_mode;
-    buf->st_uid = stat->stat_uid;
-    buf->st_gid = stat->stat_gid;
-    buf->st_size = stat->stat_size;
-    buf->st_atime = stat->stat_atime;
-    buf->st_mtime = stat->stat_mtime;
-    buf->st_ctime = stat->stat_ctime;
-}
-
 int stat(const char *path, struct stat *buf)
 {
-    struct fsif_stat_response stat;
-    int ret;
-    int fs_fd;
-    printk("stat(%s)\n", path);
-    fs_fd = fs_open(fs_import, (char*) path);
-    if (fs_fd < 0) {
-       errno = EIO;
-       ret = -1;
-       goto out;
-    }
-    ret = fs_stat(fs_import, fs_fd, &stat);
-    if (ret < 0) {
-       errno = EIO;
-       ret = -1;
-       goto outfd;
-    }
-    init_stat(buf);
-    stat_from_fs(buf, &stat);
-    ret = 0;
-
-outfd:
-    fs_close(fs_import, fs_fd);
-out:
-    return ret;
+    errno = EIO;
+    return -1;
 }
 
 int fstat(int fd, struct stat *buf)
@@ -514,18 +375,6 @@ int fstat(int fd, struct stat *buf)
            buf->st_ctime = time(NULL);
            return 0;
        }
-       case FTYPE_FILE: {
-           struct fsif_stat_response stat;
-           int ret;
-           ret = fs_stat(fs_import, files[fd].file.fd, &stat);
-           if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           /* The protocol is a bit evasive about this value */
-           stat_from_fs(buf, &stat);
-           return 0;
-       }
        default:
            break;
     }
@@ -537,35 +386,14 @@ int fstat(int fd, struct stat *buf)
 
 int ftruncate(int fd, off_t length)
 {
-    switch (files[fd].type) {
-       case FTYPE_FILE: {
-            int ret;
-            ret = fs_truncate(fs_import, files[fd].file.fd, length);
-           if (ret < 0) {
-               errno = EIO;
-               return -1;
-           }
-           return 0;
-       }
-       default:
-           break;
-    }
-
-    printk("ftruncate(%d): Bad descriptor\n", fd);
     errno = EBADF;
     return -1;
 }
 
 int remove(const char *pathname)
 {
-    int ret;
-    printk("remove(%s)", pathname);
-    ret = fs_remove(fs_import, (char*) pathname);
-    if (ret < 0) {
-        errno = EIO;
-        return -1;
-    }
-    return 0;
+    errno = EIO;
+    return -1;
 }
 
 int unlink(const char *pathname)
@@ -618,26 +446,9 @@ DIR *opendir(const char *name)
 
 struct dirent *readdir(DIR *dir)
 {
-    if (dir->curentry >= 0) {
-        free(dir->entries[dir->curentry]);
-        dir->entries[dir->curentry] = NULL;
-    }
-    dir->curentry++;
-    if (dir->curentry >= dir->nbentries) {
-        dir->offset += dir->nbentries;
-        free(dir->entries);
-        dir->curentry = -1;
-        dir->nbentries = 0;
-        if (!dir->has_more)
-            return NULL;
-        dir->entries = fs_list(fs_import, dir->name, dir->offset, 
&dir->nbentries, &dir->has_more);
-        if (!dir->entries || !dir->nbentries)
-            return NULL;
-        dir->curentry = 0;
-    }
-    dir->dirent.d_name = dir->entries[dir->curentry];
-    return &dir->dirent;
+    return NULL;
 } 
+
 int closedir(DIR *dir)
 {
     int i;
@@ -654,7 +465,6 @@ static const char file_types[] = {
 static const char file_types[] = {
     [FTYPE_NONE]       = 'N',
     [FTYPE_CONSOLE]    = 'C',
-    [FTYPE_FILE]       = 'F',
     [FTYPE_XENBUS]     = 'S',
     [FTYPE_XC]         = 'X',
     [FTYPE_EVTCHN]     = 'E',
@@ -753,11 +563,6 @@ static int select_poll(int nfds, fd_set 
            if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, 
exceptfds))
                printk("bogus fd %d in select\n", i);
            /* Fallthrough.  */
-       case FTYPE_FILE:
-           FD_CLR(i, readfds);
-           FD_CLR(i, writefds);
-           FD_CLR(i, exceptfds);
-           break;
        case FTYPE_CONSOLE:
            if (FD_ISSET(i, readfds)) {
                 if (xencons_ring_avail(files[i].cons.dev))
diff -r ae3567ccf524 -r 3c78729b6f06 extras/mini-os/main.c
--- a/extras/mini-os/main.c     Tue Jan 11 16:48:09 2011 +0000
+++ b/extras/mini-os/main.c     Tue Jan 11 18:13:44 2011 +0000
@@ -13,7 +13,6 @@
 #include <time.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <fs.h>
 #include <xenbus.h>
 #include <events.h>
 
@@ -66,7 +65,6 @@ static void call_main(void *p)
 #if defined(HAVE_LWIP) && !defined(CONFIG_QEMU)
     start_networking();
 #endif
-    init_fs_frontend();
 #endif
     create_thread("pcifront", pcifront_watches, NULL);
 
diff -r ae3567ccf524 -r 3c78729b6f06 tools/Makefile
--- a/tools/Makefile    Tue Jan 11 16:48:09 2011 +0000
+++ b/tools/Makefile    Tue Jan 11 18:13:44 2011 +0000
@@ -28,8 +28,6 @@ SUBDIRS-$(CONFIG_NetBSD) += xenbackendd
 SUBDIRS-$(CONFIG_NetBSD) += xenbackendd
 SUBDIRS-y += libfsimage
 SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
-SUBDIRS-$(CONFIG_Linux) += fs-back
-SUBDIRS-$(CONFIG_NetBSD) += fs-back
 
 # do not recurse in to a dir we are about to delete
 ifneq "$(MAKECMDGOALS)" "distclean"
diff -r ae3567ccf524 -r 3c78729b6f06 tools/fs-back/Makefile
--- a/tools/fs-back/Makefile    Tue Jan 11 16:48:09 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-XEN_ROOT = ../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-INCLUDES += -I.. -I../lib
-
-IBIN         = fs-backend 
-
-CFLAGS   += -Werror
-CFLAGS   += -Wno-unused
-CFLAGS   += -fno-strict-aliasing
-CFLAGS   += $(CFLAGS_libxenctrl)
-CFLAGS   += $(CFLAGS_libxenstore)
-CFLAGS   += $(INCLUDES) -I.
-CFLAGS   += -D_GNU_SOURCE
-
-LIBS      := -L. -L.. -L../lib
-LIBS      += $(LDLIBS_libxenctrl)
-LIBS      += $(LDLIBS_libxenstore)
-LIBS      += -lrt -lpthread
-
-OBJS     := fs-xenbus.o fs-ops.o
-
-all: $(IBIN)
-
-fs-backend: $(OBJS) fs-backend.c
-       $(CC) $(CFLAGS) -o fs-backend $(OBJS) $(LIBS) fs-backend.c
-
-install: all
-       $(INSTALL_PROG) $(IBIN) $(DESTDIR)$(SBINDIR)
-
-clean:
-       rm -rf *.o *~ $(DEPS) xen $(IBIN) $(LIB)
-
-.PHONY: clean install
-
--include $(DEPS)
diff -r ae3567ccf524 -r 3c78729b6f06 tools/fs-back/fs-backend.c
--- a/tools/fs-back/fs-backend.c        Tue Jan 11 16:48:09 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,500 +0,0 @@
-#undef NDEBUG
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <malloc.h>
-#include <xenctrl.h>
-#include <aio.h>
-#include <sys/mman.h>
-#include <sys/select.h>
-#include <sys/socket.h>
-#include <xen/io/ring.h>
-#include <xc_private.h>
-#include <err.h>
-#include "sys-queue.h"
-#include "fs-backend.h"
-#include "fs-debug.h"
-
-struct xs_handle *xsh = NULL;
-static struct fs_export *fs_exports = NULL;
-static int export_id = 0;
-static int mount_id = 0;
-static int pipefds[2];
-static LIST_HEAD(mount_requests_head, fs_mount) mount_requests_head;
-
-static void free_mount_request(struct fs_mount *mount);
-
-static void dispatch_response(struct fs_request *request)
-{
-    int i;
-    struct fs_op *op;
-
-    for(i=0;;i++)
-    {
-        op = fsops[i];
-        /* We should dispatch a response before reaching the end of the array 
*/
-        assert(op != NULL);
-        if(op->type == request->req_shadow.type)
-        {
-            FS_DEBUG("Found op for type=%d\n", op->type);
-            /* There needs to be a response handler */
-            assert(op->response_handler != NULL);
-            op->response_handler(request->mount, request);
-            break;
-        }
-    }
-
-    request->active = 0;
-    add_id_to_freelist(request->id, request->mount->freelist);
-}
-
-static void handle_aio_event(struct fs_request *request)
-{
-    int ret, notify;
-
-    FS_DEBUG("handle_aio_event: mount %s request %d\n", 
request->mount->frontend, request->id);
-    if (request->active < 0) {
-        request->mount->nr_entries++;
-        if (!request->mount->nr_entries)
-            free_mount_request(request->mount);
-        return;
-    }
-
-    ret = aio_error(&request->aiocb);
-    if(ret != EINPROGRESS && ret != ECANCELED)
-        dispatch_response(request);
-
-    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&request->mount->ring, notify);
-    FS_DEBUG("Pushed responces and notify=%d\n", notify);
-    if(notify)
-        xc_evtchn_notify(request->mount->evth, request->mount->local_evtchn);
-}
-
-static void allocate_request_array(struct fs_mount *mount)
-{
-    int i, nr_entries = mount->nr_entries;
-    struct fs_request *requests;
-    unsigned short *freelist;
-    
-    requests = malloc(sizeof(struct fs_request) *nr_entries);
-    freelist = malloc(sizeof(unsigned short) * (nr_entries + 1)); 
-    memset(requests, 0, sizeof(struct fs_request) * nr_entries);
-    memset(freelist, 0, sizeof(unsigned short) * (nr_entries + 1));
-    for(i=0; i< nr_entries; i++)
-    {
-        requests[i].active = 0; 
-        requests[i].mount = mount; 
-        add_id_to_freelist(i, freelist);
-    }
-    mount->requests = requests;
-    mount->freelist = freelist;
-}
-
-
-static void handle_mount(struct fs_mount *mount)
-{
-    int more, notify;
-    int nr_consumed=0;
-    RING_IDX cons, rp;
-    struct fsif_request *req;
-
-moretodo:
-    rp = mount->ring.sring->req_prod;
-    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
-
-    while ((cons = mount->ring.req_cons) != rp)
-    {
-        int i;
-        struct fs_op *op;
-
-        FS_DEBUG("Got a request at %d (of %d)\n", 
-                cons, RING_SIZE(&mount->ring));
-        req = RING_GET_REQUEST(&mount->ring, cons);
-        FS_DEBUG("Request type=%d\n", req->type); 
-        for(i=0;;i++)
-        {
-            op = fsops[i];
-            if(op == NULL)
-            {
-                /* We've reached the end of the array, no appropirate
-                 * handler found. Warn, ignore and continue. */
-                FS_DEBUG("WARN: Unknown request type: %d\n", req->type);
-                mount->ring.req_cons++; 
-                break;
-            }
-            if(op->type == req->type)
-            {
-                /* There needs to be a dispatch handler */
-                assert(op->dispatch_handler != NULL);
-                op->dispatch_handler(mount, req);
-                break;
-            }
-        }
-
-        nr_consumed++;
-    }
-    FS_DEBUG("Backend consumed: %d requests\n", nr_consumed);
-    RING_FINAL_CHECK_FOR_REQUESTS(&mount->ring, more);
-    if(more) goto moretodo;
-
-    RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify);
-    FS_DEBUG("Pushed responces and notify=%d\n", notify);
-    if(notify)
-        xc_evtchn_notify(mount->evth, mount->local_evtchn);
-}
-
-void terminate_mount_request(struct fs_mount *mount)
-{
-    int count = 0, i;
-
-    FS_DEBUG("terminate_mount_request %s\n", mount->frontend);
-    xenbus_write_backend_state(mount, STATE_CLOSING);
-
-    for(i=0; i<mount->nr_entries; i++)
-        if(mount->requests[i].active) {
-            mount->requests[i].active = -1;
-            aio_cancel(mount->requests[i].aiocb.aio_fildes, 
&mount->requests[i].aiocb);
-            count--;
-        }
-    mount->nr_entries = count;
-
-    /* wait for the frontend to shut down but don't wait more than 3
-     * seconds */
-    i = 0;
-    while (!xenbus_frontend_state_changed(mount, STATE_CLOSING) && i < 3) {
-        sleep(1);
-        i++;
-    }
-    xenbus_write_backend_state(mount, STATE_CLOSED);
-
-    xc_gnttab_munmap(mount->gnth, mount->ring.sring, mount->shared_ring_size);
-    xc_gnttab_close(mount->gnth);
-    xc_evtchn_unbind(mount->evth, mount->local_evtchn);
-    xc_evtchn_close(mount->evth);
-
-    if (!count)
-        free_mount_request(mount);
-}
-
-static void free_mount_request(struct fs_mount *mount) {
-    FS_DEBUG("free_mount_request %s\n", mount->frontend);
-    xenbus_free_backend_node(mount);
-    free(mount->frontend);
-    free(mount->requests);
-    free(mount->freelist);
-    LIST_REMOVE (mount, entries);
-    free(mount);
-}
-
-static void handle_connection(int frontend_dom_id, int export_id, char 
*frontend)
-{
-    struct fs_mount *mount;
-    struct fs_export *export;
-    struct fsif_sring *sring = NULL;
-    uint32_t dom_ids[MAX_RING_SIZE];
-    int i;
-
-    FS_DEBUG("Handling connection from dom=%d, for export=%d\n", 
-            frontend_dom_id, export_id);
-    /* Try to find the export on the list */
-    export = fs_exports;
-    while(export)
-    {
-        if(export->export_id == export_id)
-            break;
-        export = export->next;
-    }
-    if(!export)
-    {
-        FS_DEBUG("Could not find the export (the id is unknown).\n");
-        return;
-    }
-
-    mount = (struct fs_mount*)malloc(sizeof(struct fs_mount));
-    memset(mount, 0, sizeof(struct fs_mount));
-    mount->xch = xc_interface_open(0,0,XC_OPENFLAG_DUMMY);
-    if (!mount->xch) goto error;
-
-    mount->dom_id = frontend_dom_id;
-    mount->export = export;
-    mount->mount_id = mount_id++;
-    if (xenbus_read_mount_request(mount, frontend) < 0)
-        goto error;
-    FS_DEBUG("Frontend found at: %s (gref=%d, evtchn=%d)\n", 
-            mount->frontend, mount->grefs[0], mount->remote_evtchn);
-    if (!xenbus_write_backend_node(mount)) {
-        FS_DEBUG("ERROR: failed to write backend node on xenbus\n");
-        goto error;
-    }
-    mount->evth = NULL;
-    mount->evth = xc_evtchn_open(NULL, 0);
-    if (mount->evth == NULL) {
-        FS_DEBUG("ERROR: Couldn't open evtchn!\n");
-        goto error;
-    }
-    mount->local_evtchn = -1;
-    mount->local_evtchn = xc_evtchn_bind_interdomain(mount->evth, 
-                                                     mount->dom_id, 
-                                                     mount->remote_evtchn);
-    if (mount->local_evtchn < 0) {
-        FS_DEBUG("ERROR: Couldn't bind evtchn!\n");
-        goto error;
-    }
-    mount->gnth = NULL;
-    mount->gnth = xc_gnttab_open(NULL, 0);
-    if (mount->gnth == NULL) {
-        FS_DEBUG("ERROR: Couldn't open gnttab!\n");
-        goto error;
-    }
-    for(i=0; i<mount->shared_ring_size; i++)
-        dom_ids[i] = mount->dom_id;
-    sring = xc_gnttab_map_grant_refs(mount->gnth,
-                                     mount->shared_ring_size,
-                                     dom_ids,
-                                     mount->grefs,
-                                     PROT_READ | PROT_WRITE);
-
-    if (!sring) {
-        FS_DEBUG("ERROR: Couldn't amp grant refs!\n");
-        goto error;
-    }
-
-    BACK_RING_INIT(&mount->ring, sring, mount->shared_ring_size * 
XC_PAGE_SIZE);
-    mount->nr_entries = mount->ring.nr_ents; 
-    for (i = 0; i < MAX_FDS; i++)
-        mount->fds[i] = -1;
-
-    LIST_INSERT_HEAD(&mount_requests_head, mount, entries);
-    if (!xenbus_watch_frontend_state(mount)) {
-        FS_DEBUG("ERROR: failed to watch frontend state on xenbus\n");
-        goto error;
-    }
-    if (!xenbus_write_backend_state(mount, STATE_READY)) {
-        FS_DEBUG("ERROR: failed to write backend state to xenbus\n");
-        goto error;
-    }
-
-    allocate_request_array(mount);
-
-    return;
-
-error:
-    xenbus_write_backend_state(mount, STATE_CLOSED);
-    if (sring)
-        xc_gnttab_munmap(mount->gnth, mount->ring.sring, 
mount->shared_ring_size);
-    if (mount->gnth != NULL)
-        xc_gnttab_close(mount->gnth);
-    if (mount->local_evtchn > 0)
-        xc_evtchn_unbind(mount->evth, mount->local_evtchn);
-    if (mount->evth != NULL)
-        xc_evtchn_close(mount->evth);
-    if (mount->xch)
-        xc_interface_close(mount->xch);
-}
-
-static void await_connections(void)
-{
-    int fd, max_fd, ret, dom_id, export_id; 
-    fd_set fds;
-    char **watch_paths;
-    unsigned int len;
-    char d;
-    struct fs_mount *pointer;
-
-    LIST_INIT (&mount_requests_head);
-
-    assert(xsh != NULL);
-    if ((fd = xenbus_get_watch_fd()) == -1)
-           err(1, "xenbus_get_watch_fd: could not setup watch");
-    /* Infinite watch loop */
-    do {
-       FD_ZERO(&fds);
-       FD_SET(fd, &fds);
-       FD_SET(pipefds[0], &fds);
-        max_fd = fd > pipefds[0] ? fd : pipefds[0];
-        LIST_FOREACH(pointer, &mount_requests_head, entries) {
-            int tfd = xc_evtchn_fd(pointer->evth);
-            FD_SET(tfd, &fds);
-            if (tfd > max_fd) max_fd = tfd;
-        }
-        ret = select(max_fd+1, &fds, NULL, NULL, NULL);
-        if (ret < 0) {
-            if (errno == EINTR) continue;
-            /* try to recover */
-            else if (errno == EBADF) {
-                struct timeval timeout;
-                memset(&timeout, 0x00, sizeof(timeout));
-                FD_ZERO(&fds);
-                FD_SET(fd, &fds);
-                FD_SET(pipefds[0], &fds);
-                max_fd = fd > pipefds[0] ? fd : pipefds[0];
-                ret = select(max_fd + 1, &fds, NULL, NULL, &timeout);
-                if (ret < 0)
-                    err(1, "select: unrecoverable error occurred: %d\n", 
errno);
-
-                /* trying to find the bogus fd among the open event channels */
-                LIST_FOREACH(pointer, &mount_requests_head, entries) {
-                    int tfd = xc_evtchn_fd(pointer->evth);
-                    memset(&timeout, 0x00, sizeof(timeout));
-                    FD_ZERO(&fds);
-                    FD_SET(tfd, &fds);
-                    ret = select(tfd + 1, &fds, NULL, NULL, &timeout);
-                    if (ret < 0) {
-                        FS_DEBUG("fd %d is bogus, closing the related 
connection %p\n", tfd, pointer->evth);
-                        /*pointer->evth = fd;*/
-                        terminate_mount_request(pointer);
-                        continue;
-                    }
-                }
-                continue;
-            } else
-                err(1, "select: unrecoverable error occurred: %d\n", errno);
-        }
-        if (FD_ISSET(fd, &fds)) {
-            watch_paths = xs_read_watch(xsh, &len);
-            if (!strcmp(watch_paths[XS_WATCH_TOKEN], "conn-watch")) {
-                dom_id = -1;
-                export_id = -1;
-                d = 0;
-                FS_DEBUG("Path changed %s\n", watch_paths[0]);
-                sscanf(watch_paths[XS_WATCH_PATH], 
WATCH_NODE"/%d/%d/fronten%c", 
-                        &dom_id, &export_id, &d);
-                if((dom_id >= 0) && (export_id >= 0) && d == 'd') {
-                    char *frontend = xs_read(xsh, XBT_NULL, 
watch_paths[XS_WATCH_PATH], NULL);
-                    if (frontend) {
-                        char *p, *wp = strdup(watch_paths[XS_WATCH_PATH]);
-                        handle_connection(dom_id, export_id, frontend);
-                        xs_rm(xsh, XBT_NULL, wp);
-                        p = strrchr(wp, '/');
-                        if (p) {
-                            *p = '\0';
-                            p = strrchr(wp, '/');
-                            if (p) {
-                                *p = '\0';
-                                xs_rm(xsh, XBT_NULL, wp);
-                            }
-                        }
-                        free(wp);
-                    }
-                }
-            } else if (!strcmp(watch_paths[XS_WATCH_TOKEN], "frontend-state")) 
{
-                LIST_FOREACH(pointer, &mount_requests_head, entries) {
-                    if (!strncmp(pointer->frontend, 
watch_paths[XS_WATCH_PATH], strlen(pointer->frontend))) {
-                        char *state = xenbus_read_frontend_state(pointer);
-                        if (!state || strcmp(state, STATE_READY)) {
-                            xenbus_unwatch_frontend_state(pointer);
-                            terminate_mount_request(pointer);
-                        }
-                        free(state);
-                        break;
-                    }
-                }
-            } else {
-                FS_DEBUG("xenstore watch event unrecognized\n");
-            }
-            FS_DEBUG("Awaiting next connection.\n");
-            /* TODO - we need to figure out what to free */
-            free(watch_paths);
-        }
-        if (FD_ISSET(pipefds[0], &fds)) {
-            struct fs_request *request;
-            if (read_exact(pipefds[0], &request, sizeof(struct fs_request *)) 
< 0)
-                err(1, "read request failed\n");
-            handle_aio_event(request); 
-        }
-        LIST_FOREACH(pointer, &mount_requests_head, entries) {
-            if (FD_ISSET(xc_evtchn_fd(pointer->evth), &fds)) {
-                evtchn_port_t port;
-                port = xc_evtchn_pending(pointer->evth);
-                if (port != -1) {
-                    handle_mount(pointer);
-                    xc_evtchn_unmask(pointer->evth, port);
-                }
-            }
-        }
-    } while (1);
-}
-
-static struct fs_export* create_export(char *name, char *export_path)
-{
-    struct fs_export *curr_export, **last_export;
-
-    /* Create export structure */
-    curr_export = (struct fs_export *)malloc(sizeof(struct fs_export));
-    curr_export->name = name;
-    curr_export->export_path = export_path;
-    curr_export->export_id = export_id++;
-    /* Thread it onto the list */
-    curr_export->next = NULL;
-    last_export = &fs_exports;
-    while(*last_export)
-        last_export = &((*last_export)->next);
-    *last_export = curr_export;
-
-    return curr_export;
-}
-
-static void aio_signal_handler(int signo, siginfo_t *info, void *context)
-{
-    struct fs_request *request = (struct fs_request*) info->si_value.sival_ptr;
-    int saved_errno = errno;
-    if (write_exact(pipefds[1], &request, sizeof(struct fs_request *)) < 0)
-        err(1, "write request filed\n");
-    errno = saved_errno;
-}
-
-int main(void)
-{
-    struct fs_export *export;
-    struct sigaction act;
-    sigset_t enable;
-
-    sigemptyset(&enable);
-    sigaddset(&enable, SIGUSR2);
-    pthread_sigmask(SIG_UNBLOCK, &enable, NULL);
-
-    sigfillset(&act.sa_mask);
-    act.sa_flags = SA_SIGINFO; /* do not restart syscalls to interrupt 
select(); use sa_sigaction */
-    act.sa_sigaction = aio_signal_handler;
-    sigaction(SIGUSR2, &act, NULL);
-
-    /* Open the connection to XenStore first */
-    xsh = xs_domain_open();
-    assert(xsh != NULL);
-    xs_rm(xsh, XBT_NULL, ROOT_NODE);
-    /* Create watch node */
-    xenbus_create_request_node();
-    
-    /* Create & register the default export */
-    export = create_export("default", "/var/lib/xen");
-    xenbus_register_export(export);
-
-    if (socketpair(PF_UNIX,SOCK_STREAM, 0, pipefds) == -1)
-        err(1, "failed to create pipe\n");
-
-    await_connections();
-    /* Close the connection to XenStore when we are finished with everything */
-    xs_daemon_close(xsh);
-#if 0
-    xc_interface *xc_handle;
-    char *shared_page;
-    int prot = PROT_READ | PROT_WRITE;
-  
-    xc_handle = xc_gnttab_open();
-    printf("Main fn.\n");
-
-    shared_page = xc_gnttab_map_grant_ref(xc_handle,
-                                           7,
-                                           2047,
-                                           prot);
-    
-    shared_page[20] = '\0';
-    printf("Current content of the page = %s\n", shared_page);
-    sprintf(shared_page, "%s", "Haha dirty page now! Very bad page.");
-    xc_gnttab_munmap(xc_handle, shared_page, 1);
-    xc_gnttab_close(xc_handle);
-    unrelated next line, saved for later convinience    
-    xc_evtchn_notify(mount->evth, mount->local_evtchn);
-#endif
-}
diff -r ae3567ccf524 -r 3c78729b6f06 tools/fs-back/fs-backend.h
--- a/tools/fs-back/fs-backend.h        Tue Jan 11 16:48:09 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-#ifndef __LIB_FS_BACKEND__
-#define __LIB_FS_BACKEND__
-
-#include <aio.h>
-#include <xs.h>
-#include <xen/grant_table.h>
-#include <xen/event_channel.h>
-#include <xen/io/ring.h>
-#include <xen/io/fsif.h>
-#include "sys-queue.h"
-
-#define ROOT_NODE           "backend/vfs"
-#define EXPORTS_SUBNODE     "exports"
-#define EXPORTS_NODE        ROOT_NODE"/"EXPORTS_SUBNODE
-#define WATCH_NODE          EXPORTS_NODE"/requests"
-#define MAX_FDS             16
-#define MAX_RING_SIZE       16
-
-struct fs_export
-{
-    int export_id;
-    char *export_path;
-    char *name;
-    struct fs_export *next; 
-};
-
-struct fs_request
-{
-    struct fs_mount *mount;
-    int id;
-    int active;
-    void *page;                         /* Pointer to mapped grant */
-    int count;
-    struct fsif_request req_shadow;
-    struct aiocb aiocb; 
-};
-
-
-struct fs_mount
-{
-    struct fs_export *export;
-    int dom_id;
-    char *frontend;
-    int mount_id;                     /* = backend id */
-    grant_ref_t grefs[MAX_RING_SIZE];
-    evtchn_port_t remote_evtchn;
-    xc_interface *xch; /* just for error logging, so a dummy */
-    xc_evtchn *evth;               /* Handle to the event channel */
-    evtchn_port_t local_evtchn;
-    xc_gnttab *gnth;
-    int shared_ring_size;             /* in pages */
-    struct fsif_back_ring ring;
-    int nr_entries;
-    struct fs_request *requests;
-    unsigned short *freelist;
-    int fds[MAX_FDS];
-    LIST_ENTRY(fs_mount) entries;
-};
-
-void terminate_mount_request(struct fs_mount *mount);
-
-/* Handle to XenStore driver */
-extern struct xs_handle *xsh;
-
-bool xenbus_create_request_node(void);
-int xenbus_register_export(struct fs_export *export);
-int xenbus_get_watch_fd(void);
-int xenbus_read_mount_request(struct fs_mount *mount, char *frontend);
-bool xenbus_write_backend_node(struct fs_mount *mount);
-bool xenbus_write_backend_state(struct fs_mount *mount, const char *state);
-void xenbus_free_backend_node(struct fs_mount *mount);
-int xenbus_frontend_state_changed(struct fs_mount *mount, const char 
*oldstate);
-bool xenbus_watch_frontend_state(struct fs_mount *mount);
-bool xenbus_unwatch_frontend_state(struct fs_mount *mount);
-char* xenbus_read_frontend_state(struct fs_mount *mount);
-
-/* File operations, implemented in fs-ops.c */
-struct fs_op
-{
-    int type;       /* Type of request (from fsif.h) this handlers 
-                       are responsible for */
-    void (*dispatch_handler)(struct fs_mount *mount, struct fsif_request *req);
-    void (*response_handler)(struct fs_mount *mount, struct fs_request *req);
-};
-
-/* This NULL terminated array of all file requests handlers */
-extern struct fs_op *fsops[];
-
-static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
-{
-    freelist[id + 1] = freelist[0];
-    freelist[0]  = id;
-}
-
-static inline unsigned short get_id_from_freelist(unsigned short* freelist)
-{
-    unsigned int id = freelist[0];
-    freelist[0] = freelist[id + 1];
-    return id;
-}
-
-#endif /* __LIB_FS_BACKEND__ */
diff -r ae3567ccf524 -r 3c78729b6f06 tools/fs-back/fs-debug.h
--- a/tools/fs-back/fs-debug.h  Tue Jan 11 16:48:09 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-#ifndef __FS_DEBUG__
-#define __FS_DEBUG__
-
-// #define DEBUG 1
-
-#ifdef DEBUG
-#define FS_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while 
(0)
-#else
-#define FS_DEBUG(fmt, ...) do { } while (0)
-#endif
-
-#endif /*__FS_DEBUG__*/
diff -r ae3567ccf524 -r 3c78729b6f06 tools/fs-back/fs-ops.c
--- a/tools/fs-back/fs-ops.c    Tue Jan 11 16:48:09 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,794 +0,0 @@
-#undef NDEBUG
-#include <stdio.h>
-#include <aio.h>
-#include <string.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <inttypes.h>
-#include <xenctrl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/mount.h>
-#include <unistd.h>
-#include <ctype.h>
-#include "fs-backend.h"
-#include "fs-debug.h"
-
-/* For debugging only */
-#include <sys/time.h>
-#include <time.h>
-
-
-#define BUFFER_SIZE 1024
-
-static int check_export_path(const char *export_path, const char *path)
-{
-    int i;
-    if (!export_path || !path)
-        return -1;
-    if (strlen(path) < strlen(export_path))
-        return -1;
-    if (strstr(path, "..") != NULL)
-        return -1;
-    for (i = 0; i < strlen(path); i++) {
-        if (!isascii(path[i]))
-            return -1;
-    }
-    if (strncmp(export_path, path, strlen(export_path)))
-        return -1;
-    else
-        return 0;
-}
-
-static unsigned short get_request(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    unsigned short id = get_id_from_freelist(mount->freelist); 
-
-    FS_DEBUG("Private Request id: %d\n", id);
-    memcpy(&mount->requests[id].req_shadow, req, sizeof(struct fsif_request));
-    mount->requests[id].active = 1;
-
-    return id;
-}
-
-static int get_fd(struct fs_mount *mount)
-{
-    int i;
-
-    for (i = 0; i < MAX_FDS; i++)
-        if (mount->fds[i] == -1)
-            return i;
-    return -1;
-}
-
-
-static void dispatch_file_open(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    char *file_name;
-    int fd;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching file open operation (gref=%d).\n", 
req->u.fopen.gref);
-    /* Read the request, and open file */
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.fopen.gref,
-                                        PROT_READ);
-   
-    req_id = req->id;
-    FS_DEBUG("File open issued for %s\n", file_name); 
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        fd = -1;
-        goto out;
-    }
-    fd = get_fd(mount);
-    if (fd >= 0) {
-        int real_fd = open(file_name, O_RDWR);
-        if (real_fd < 0)
-            fd = -1;
-        else
-        {
-            mount->fds[fd] = real_fd;
-            FS_DEBUG("Got FD: %d for real %d\n", fd, real_fd);
-        }
-    }
-out:
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)fd;
-}
-
-static void dispatch_file_close(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    int ret;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching file close operation (fd=%d).\n", req->u.fclose.fd);
-   
-    req_id = req->id;
-    if (req->u.fclose.fd < MAX_FDS) {
-        int fd = mount->fds[req->u.fclose.fd];
-        ret = close(fd);
-        mount->fds[req->u.fclose.fd] = -1;
-    } else
-        ret = -1;
-    FS_DEBUG("Got ret: %d\n", ret);
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-#define MAX_GNTS 16
-static void dispatch_file_read(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    void *buf;
-    int fd, count;
-    uint16_t req_id;
-    unsigned short priv_id;
-    struct fs_request *priv_req;
-
-    /* Read the request */
-    assert(req->u.fread.len > 0); 
-    count = (req->u.fread.len - 1) / XC_PAGE_SIZE + 1;
-    assert(count <= FSIF_NR_READ_GNTS);
-    buf = xc_gnttab_map_domain_grant_refs(mount->gnth,
-                                          count,
-                                          mount->dom_id,
-                                          req->u.fread.grefs,
-                                          PROT_WRITE);
-   
-    req_id = req->id;
-    FS_DEBUG("File read issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 
-            req->u.fread.fd, req->u.fread.len, req->u.fread.offset); 
-
-    if (req->u.fread.fd < MAX_FDS)
-        fd = mount->fds[req->u.fread.fd];
-    else
-        fd = -1;
-
-    priv_id = get_request(mount, req);
-    FS_DEBUG("Private id is: %d\n", priv_id);
-    priv_req = &mount->requests[priv_id];
-    priv_req->page = buf;
-    priv_req->count = count;
-    priv_req->id = priv_id;
-
-    /* Dispatch AIO read request */
-    bzero(&priv_req->aiocb, sizeof(struct aiocb));
-    priv_req->aiocb.aio_fildes = fd;
-    priv_req->aiocb.aio_nbytes = req->u.fread.len;
-    priv_req->aiocb.aio_offset = req->u.fread.offset;
-    priv_req->aiocb.aio_buf = buf;
-    priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
-    priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
-    priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
-    if (aio_read(&priv_req->aiocb) < 0) {
-        FS_DEBUG("ERROR: aio_read failed errno=%d\n", errno);
-        xc_gnttab_munmap(mount->gnth, priv_req->page, priv_req->count);
-        terminate_mount_request(mount);
-    }
-
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-}
-
-static void end_file_read(struct fs_mount *mount, struct fs_request *priv_req)
-{
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    /* Release the grant */
-    if (xc_gnttab_munmap(mount->gnth,
-                         priv_req->page, priv_req->count) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    req_id = priv_req->req_shadow.id; 
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)aio_return(&priv_req->aiocb);
-}
-
-static void dispatch_file_write(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    void *buf;
-    int fd, count;
-    uint16_t req_id;
-    unsigned short priv_id;
-    struct fs_request *priv_req;
-
-    /* Read the request */
-    assert(req->u.fwrite.len > 0); 
-    count = (req->u.fwrite.len - 1) / XC_PAGE_SIZE + 1;
-    assert(count <= FSIF_NR_WRITE_GNTS);
-    buf = xc_gnttab_map_domain_grant_refs(mount->gnth,
-                                          count,
-                                          mount->dom_id,
-                                          req->u.fwrite.grefs,
-                                          PROT_READ);
-   
-    req_id = req->id;
-    FS_DEBUG("File write issued for FD=%d (len=%"PRIu64", 
offest=%"PRIu64")\n", 
-            req->u.fwrite.fd, req->u.fwrite.len, req->u.fwrite.offset); 
-   
-    if (req->u.fwrite.fd < MAX_FDS)
-        fd = mount->fds[req->u.fwrite.fd];
-    else
-        fd = -1;
-
-    priv_id = get_request(mount, req);
-    FS_DEBUG("Private id is: %d\n", priv_id);
-    priv_req = &mount->requests[priv_id];
-    priv_req->page = buf;
-    priv_req->count = count;
-    priv_req->id = priv_id;
-
-    /* Dispatch AIO write request */
-    bzero(&priv_req->aiocb, sizeof(struct aiocb));
-    priv_req->aiocb.aio_fildes = fd;
-    priv_req->aiocb.aio_nbytes = req->u.fwrite.len;
-    priv_req->aiocb.aio_offset = req->u.fwrite.offset;
-    priv_req->aiocb.aio_buf = buf;
-    priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
-    priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
-    priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
-    if (aio_write(&priv_req->aiocb) < 0) {
-        FS_DEBUG("ERROR: aio_write failed errno=%d\n", errno);
-        xc_gnttab_munmap(mount->gnth,
-                         priv_req->page, priv_req->count);
-        terminate_mount_request(mount);
-    }
-
-     
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-}
-
-static void end_file_write(struct fs_mount *mount, struct fs_request *priv_req)
-{
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    /* Release the grant */
-    if (xc_gnttab_munmap(mount->gnth,
-                         priv_req->page, priv_req->count) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    req_id = priv_req->req_shadow.id; 
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)aio_return(&priv_req->aiocb);
-}
-
-static void dispatch_stat(struct fs_mount *mount, struct fsif_request *req)
-{
-    struct stat stat;
-    int fd, ret;
-    uint16_t req_id;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-
-    req_id = req->id;
-    if (req->u.fstat.fd < MAX_FDS)
-        fd = mount->fds[req->u.fstat.fd];
-    else
-        fd = -1;
-
-    FS_DEBUG("File stat issued for FD=%d\n", req->u.fstat.fd); 
-   
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-   
-    /* Stat, and create the response */ 
-    ret = fstat(fd, &stat);
-    FS_DEBUG("Mode=%o, uid=%d, a_time=%ld\n",
-            stat.st_mode, stat.st_uid, (long)stat.st_atime);
-    
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.fstat.stat_ret = (uint32_t)ret;
-    rsp->u.fstat.stat_mode  = stat.st_mode;
-    rsp->u.fstat.stat_uid   = stat.st_uid;
-    rsp->u.fstat.stat_gid   = stat.st_gid;
-#ifdef BLKGETSIZE
-    if (S_ISBLK(stat.st_mode)) {
-       unsigned long sectors;
-       if (ioctl(fd, BLKGETSIZE, &sectors)) {
-           perror("getting device size\n");
-           rsp->u.fstat.stat_size = 0;
-       } else
-           rsp->u.fstat.stat_size = sectors << 9;
-    } else
-#endif
-       rsp->u.fstat.stat_size  = stat.st_size;
-    rsp->u.fstat.stat_atime = stat.st_atime;
-    rsp->u.fstat.stat_mtime = stat.st_mtime;
-    rsp->u.fstat.stat_ctime = stat.st_ctime;
-}
-
-
-static void dispatch_truncate(struct fs_mount *mount, struct fsif_request *req)
-{
-    int fd, ret;
-    uint16_t req_id;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    int64_t length;
-
-    req_id = req->id;
-    length = req->u.ftruncate.length;
-    FS_DEBUG("File truncate issued for FD=%d, length=%"PRId64"\n", 
req->u.ftruncate.fd, length); 
-   
-    if (req->u.ftruncate.fd < MAX_FDS)
-        fd = mount->fds[req->u.ftruncate.fd];
-    else
-        fd = -1;
-
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-   
-    /* Stat, and create the response */ 
-    ret = ftruncate(fd, length);
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-static void dispatch_remove(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *file_name;
-    int ret;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching remove operation (gref=%d).\n", req->u.fremove.gref);
-    /* Read the request, and open file */
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.fremove.gref,
-                                        PROT_READ);
-   
-    req_id = req->id;
-    FS_DEBUG("File remove issued for %s\n", file_name); 
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        ret = -1;
-    } else {
-        ret = remove(file_name);
-    }
-    FS_DEBUG("Got ret: %d\n", ret);
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-
-static void dispatch_rename(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *buf, *old_file_name, *new_file_name;
-    int ret;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching rename operation (gref=%d).\n", req->u.fremove.gref);
-    /* Read the request, and open file */
-    buf = xc_gnttab_map_grant_ref(mount->gnth,
-                                  mount->dom_id,
-                                  req->u.frename.gref,
-                                  PROT_READ);
-   
-    req_id = req->id;
-    old_file_name = buf + req->u.frename.old_name_offset;
-    new_file_name = buf + req->u.frename.new_name_offset;
-    FS_DEBUG("File rename issued for %s -> %s (buf=%s)\n", 
-            old_file_name, new_file_name, buf); 
-    if (check_export_path(mount->export->export_path, old_file_name) < 0 ||
-        check_export_path(mount->export->export_path, new_file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        ret = -1;
-    } else {
-        ret = rename(old_file_name, new_file_name);
-    }
-    FS_DEBUG("Got ret: %d\n", ret);
-    if (xc_gnttab_munmap(mount->gnth, buf, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-
-static void dispatch_create(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *file_name;
-    int ret;
-    int8_t directory;
-    int32_t mode;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    FS_DEBUG("Dispatching file create operation (gref=%d).\n", 
req->u.fcreate.gref);
-    /* Read the request, and create file/directory */
-    mode = req->u.fcreate.mode;
-    directory = req->u.fcreate.directory;
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.fcreate.gref,
-                                        PROT_READ);
-   
-    req_id = req->id;
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        ret = -1;
-        goto out;
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-    if(directory)
-    {
-        FS_DEBUG("Issuing create for directory: %s\n", file_name);
-        ret = mkdir(file_name, mode);
-    }
-    else
-    {
-        FS_DEBUG("Issuing create for file: %s\n", file_name);
-        ret = get_fd(mount);
-        if (ret >= 0) {
-            int real_fd = creat(file_name, mode);
-            if (real_fd < 0)
-                ret = -1;
-            else
-            {
-                mount->fds[ret] = real_fd;
-                FS_DEBUG("Got FD: %d for real %d\n", ret, real_fd);
-            }
-        }
-    }
-out:
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    FS_DEBUG("Got ret %d (errno=%d)\n", ret, errno);
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-static void dispatch_list(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *file_name, *buf;
-    uint32_t offset = 0, nr_files = 0, error_code = 0;
-    uint64_t ret_val;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-    DIR *dir;
-    struct dirent *dirent = NULL;
-
-    FS_DEBUG("Dispatching list operation (gref=%d).\n", req->u.flist.gref);
-    /* Read the request, and list directory */
-    offset = req->u.flist.offset;
-    buf = file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.flist.gref,
-                                        PROT_READ | PROT_WRITE);
-   
-    req_id = req->id;
-    FS_DEBUG("Dir list issued for %s\n", file_name); 
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        error_code = 1;
-        goto error_out;
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-    ret_val = 0;
-    nr_files = 0;
-    dir = opendir(file_name);
-    if(dir == NULL)
-    {
-        error_code = errno;
-        goto error_out;
-    }
-    /* Skip offset dirs */
-    dirent = readdir(dir);
-    while(offset-- > 0 && dirent != NULL)
-        dirent = readdir(dir);
-    /* If there was any error with reading the directory, errno will be set */
-    error_code = errno;
-    /* Copy file names of the remaining non-NULL dirents into buf */
-    if (NAME_MAX >= XC_PAGE_SIZE >> 1)
-        goto error_out;
-    while(dirent != NULL && 
-            (XC_PAGE_SIZE - ((unsigned long)buf & XC_PAGE_MASK) > NAME_MAX))
-    {
-        int curr_length = strlen(dirent->d_name) + 1;
-        
-        memcpy(buf, dirent->d_name, curr_length);
-        buf += curr_length;
-        dirent = readdir(dir);
-        error_code = errno;
-        nr_files++;
-    }
-error_out:    
-    ret_val = ((nr_files << NR_FILES_SHIFT) & NR_FILES_MASK) | 
-              ((error_code << ERROR_SHIFT) & ERROR_MASK) | 
-              (dirent != NULL ? HAS_MORE_FLAG : 0);
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = ret_val;
-}
-
-static void dispatch_chmod(struct fs_mount *mount, struct fsif_request *req)
-{
-    int fd, ret;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-    int32_t mode;
-
-    FS_DEBUG("Dispatching file chmod operation (fd=%d, mode=%o).\n", 
-            req->u.fchmod.fd, req->u.fchmod.mode);
-    req_id = req->id;
-    if (req->u.fchmod.fd < MAX_FDS)
-        fd = mount->fds[req->u.fchmod.fd];
-    else
-        fd = -1;
-
-    mode = req->u.fchmod.mode;
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-    ret = fchmod(fd, mode); 
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-static void dispatch_fs_space(struct fs_mount *mount, struct fsif_request *req)
-{
-    char *file_name;
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-    struct statvfs stat;
-    int64_t ret;
-
-    FS_DEBUG("Dispatching fs space operation (gref=%d).\n", 
req->u.fspace.gref);
-    /* Read the request, and open file */
-    file_name = xc_gnttab_map_grant_ref(mount->gnth,
-                                        mount->dom_id,
-                                        req->u.fspace.gref,
-                                        PROT_READ);
-   
-    req_id = req->id;
-    FS_DEBUG("Fs space issued for %s\n", file_name); 
-    if (check_export_path(mount->export->export_path, file_name) < 0) {
-        FS_DEBUG("Filename check failed\n");
-        ret = -1;
-    } else {
-        ret = statvfs(file_name, &stat);
-    }
-    if(ret >= 0)
-        ret = stat.f_bsize * stat.f_bfree;
-
-    if (xc_gnttab_munmap(mount->gnth, file_name, 1) != 0) {
-        FS_DEBUG("ERROR: xc_gnttab_munmap failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)ret;
-}
-
-static void dispatch_file_sync(struct fs_mount *mount, struct fsif_request 
*req)
-{
-    int fd;
-    uint16_t req_id;
-    unsigned short priv_id;
-    struct fs_request *priv_req;
-
-    req_id = req->id;
-    if (req->u.fsync.fd < MAX_FDS)
-        fd = mount->fds[req->u.fsync.fd];
-    else
-        fd = -1;
-
-    FS_DEBUG("File sync issued for FD=%d\n", req->u.fsync.fd); 
-   
-    priv_id = get_request(mount, req);
-    FS_DEBUG("Private id is: %d\n", priv_id);
-    priv_req = &mount->requests[priv_id];
-    priv_req->id = priv_id;
-
-    /* Dispatch AIO read request */
-    bzero(&priv_req->aiocb, sizeof(struct aiocb));
-    priv_req->aiocb.aio_fildes = fd;
-    priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
-    priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2;
-    priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req;
-    if (aio_fsync(O_SYNC, &priv_req->aiocb) < 0) {
-        FS_DEBUG("ERROR: aio_fsync failed errno=%d\n", errno);
-        terminate_mount_request(mount);
-    }
-
-    /* We can advance the request consumer index, from here on, the request
-     * should not be used (it may be overrinden by a response) */
-    mount->ring.req_cons++;
-}
-
-static void end_file_sync(struct fs_mount *mount, struct fs_request *priv_req)
-{
-    RING_IDX rsp_idx;
-    fsif_response_t *rsp;
-    uint16_t req_id;
-
-    /* Get a response from the ring */
-    rsp_idx = mount->ring.rsp_prod_pvt++;
-    req_id = priv_req->req_shadow.id; 
-    FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id);
-    rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx);
-    rsp->id = req_id; 
-    rsp->u.ret_val = (uint64_t)aio_return(&priv_req->aiocb);
-}
-
-struct fs_op fopen_op     = {.type             = REQ_FILE_OPEN,
-                             .dispatch_handler = dispatch_file_open,
-                             .response_handler = NULL};
-struct fs_op fclose_op    = {.type             = REQ_FILE_CLOSE,
-                             .dispatch_handler = dispatch_file_close,
-                             .response_handler = NULL};
-struct fs_op fread_op     = {.type             = REQ_FILE_READ,
-                             .dispatch_handler = dispatch_file_read,
-                             .response_handler = end_file_read};
-struct fs_op fwrite_op    = {.type             = REQ_FILE_WRITE,
-                             .dispatch_handler = dispatch_file_write,
-                             .response_handler = end_file_write};
-struct fs_op fstat_op     = {.type             = REQ_STAT,
-                             .dispatch_handler = dispatch_stat,
-                             .response_handler = NULL};
-struct fs_op ftruncate_op = {.type             = REQ_FILE_TRUNCATE,
-                             .dispatch_handler = dispatch_truncate,
-                             .response_handler = NULL};
-struct fs_op fremove_op   = {.type             = REQ_REMOVE,
-                             .dispatch_handler = dispatch_remove,
-                             .response_handler = NULL};
-struct fs_op frename_op   = {.type             = REQ_RENAME,
-                             .dispatch_handler = dispatch_rename,
-                             .response_handler = NULL};
-struct fs_op fcreate_op   = {.type             = REQ_CREATE,
-                             .dispatch_handler = dispatch_create,
-                             .response_handler = NULL};
-struct fs_op flist_op     = {.type             = REQ_DIR_LIST,
-                             .dispatch_handler = dispatch_list,
-                             .response_handler = NULL};
-struct fs_op fchmod_op    = {.type             = REQ_CHMOD,
-                             .dispatch_handler = dispatch_chmod,
-                             .response_handler = NULL};
-struct fs_op fspace_op    = {.type             = REQ_FS_SPACE,
-                             .dispatch_handler = dispatch_fs_space,
-                             .response_handler = NULL};
-struct fs_op fsync_op     = {.type             = REQ_FILE_SYNC,
-                             .dispatch_handler = dispatch_file_sync,
-                             .response_handler = end_file_sync};
-
-
-struct fs_op *fsops[] = {&fopen_op, 
-                         &fclose_op, 
-                         &fread_op, 
-                         &fwrite_op, 
-                         &fstat_op, 
-                         &ftruncate_op, 
-                         &fremove_op, 
-                         &frename_op, 
-                         &fcreate_op, 
-                         &flist_op, 
-                         &fchmod_op, 
-                         &fspace_op, 
-                         &fsync_op, 
-                         NULL};
diff -r ae3567ccf524 -r 3c78729b6f06 tools/fs-back/fs-xenbus.c
--- a/tools/fs-back/fs-xenbus.c Tue Jan 11 16:48:09 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-#undef NDEBUG
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/select.h>
-#include <xenctrl.h>
-#include <xs.h>
-#include <xen/io/fsif.h>
-#include "fs-backend.h"
-#include "fs-debug.h"
-
-
-static bool xenbus_printf(struct xs_handle *xsh,
-                          xs_transaction_t xbt,
-                          char* node,
-                          char* path,
-                          char* fmt,
-                          ...)
-{
-    char fullpath[1024];
-    char val[1024];
-    va_list args;
-    
-    va_start(args, fmt);
-    snprintf(fullpath, sizeof(fullpath), "%s/%s", node, path);
-    vsnprintf(val, sizeof(val), fmt, args);
-    va_end(args);
-    FS_DEBUG("xenbus_printf (%s) <= %s.\n", fullpath, val);    
-
-    return xs_write(xsh, xbt, fullpath, val, strlen(val));
-}
-
-bool xenbus_create_request_node(void)
-{
-    bool ret;
-    struct xs_permissions perms;
-    
-    assert(xsh != NULL);
-    xs_rm(xsh, XBT_NULL, WATCH_NODE);
-    ret = xs_mkdir(xsh, XBT_NULL, WATCH_NODE); 
-    if (!ret)
-        return false;
-
-    perms.id = 0;
-    perms.perms = XS_PERM_WRITE;
-    ret = xs_set_permissions(xsh, XBT_NULL, WATCH_NODE, &perms, 1);
-
-    return ret;
-}
-
-int xenbus_register_export(struct fs_export *export)
-{
-    xs_transaction_t xst = 0;
-    char node[1024];
-    struct xs_permissions perms;
-
-    assert(xsh != NULL);
-    if(xsh == NULL)
-    {
-        FS_DEBUG("Could not open connection to xenbus deamon.\n");
-        goto error_exit;
-    }
-    FS_DEBUG("Connection to the xenbus deamon opened successfully.\n");
-
-    /* Start transaction */
-    xst = xs_transaction_start(xsh);
-    if(xst == 0)
-    {
-        FS_DEBUG("Could not start a transaction.\n");
-        goto error_exit;
-    }
-    FS_DEBUG("XS transaction is %d\n", xst); 
- 
-    /* Create node string */
-    snprintf(node, sizeof(node), "%s/%d", EXPORTS_NODE, export->export_id); 
-    /* Remove old export (if exists) */ 
-    xs_rm(xsh, xst, node);
-
-    if(!xenbus_printf(xsh, xst, node, "name", "%s", export->name))
-    {
-        FS_DEBUG("Could not write the export node.\n");
-        goto error_exit;
-    }
-
-    /* People need to be able to read our export */
-    perms.id = 0;
-    perms.perms = XS_PERM_READ;
-    if(!xs_set_permissions(xsh, xst, EXPORTS_NODE, &perms, 1))
-    {
-        FS_DEBUG("Could not set permissions on the export node.\n");
-        goto error_exit;
-    }
-
-    xs_transaction_end(xsh, xst, 0);
-    return 0; 
-
-error_exit:    
-    if(xst != 0)
-        xs_transaction_end(xsh, xst, 1);
-    return -1;
-}
-
-int xenbus_get_watch_fd(void)
-{
-    int res;
-#if DEBUG
-    int errno_orig;
-#endif
-    assert(xsh != NULL);
-    res = xs_watch(xsh, WATCH_NODE, "conn-watch");
-    if (!res) {
-#if DEBUG
-       errno_orig = errno;
-        FS_DEBUG("ERROR: xs_watch %s failed ret=%d errno=%d\n",
-                 WATCH_NODE, res, errno);
-       errno = errno_orig;
-#endif
-        return -1;
-    }
-    return xs_fileno(xsh); 
-}
-
-int xenbus_read_mount_request(struct fs_mount *mount, char *frontend)
-{
-    char node[1024];
-    char *s;
-    int i;
-
-    assert(xsh != NULL);
-#if 0
-    snprintf(node, sizeof(node), WATCH_NODE"/%d/%d/frontend", 
-                           mount->dom_id, mount->export->export_id);
-    frontend = xs_read(xsh, XBT_NULL, node, NULL);
-#endif
-    mount->frontend = frontend;
-    snprintf(node, sizeof(node), "%s/state", frontend);
-    s = xs_read(xsh, XBT_NULL, node, NULL);
-    if (strcmp(s, STATE_READY) != 0) {
-        FS_DEBUG("ERROR: frontend not read\n");
-        goto error;
-    }
-    free(s);
-    snprintf(node, sizeof(node), "%s/ring-size", frontend);
-    s = xs_read(xsh, XBT_NULL, node, NULL);
-    mount->shared_ring_size = atoi(s);
-    if (mount->shared_ring_size > MAX_RING_SIZE) {
-        FS_DEBUG("ERROR: shared_ring_size (%d) > MAX_RING_SIZE\n", 
mount->shared_ring_size);
-        goto error;
-    }
-    free(s);
-    for(i=0; i<mount->shared_ring_size; i++)
-    {
-        snprintf(node, sizeof(node), "%s/ring-ref-%d", frontend, i);
-        s = xs_read(xsh, XBT_NULL, node, NULL);
-        mount->grefs[i] = atoi(s);
-        free(s);
-    }
-    snprintf(node, sizeof(node), "%s/event-channel", frontend);
-    s = xs_read(xsh, XBT_NULL, node, NULL);
-    mount->remote_evtchn = atoi(s);
-    free(s);
-    return 0;
-
-error:
-    free(s);
-    return -1;
-}
-
-/* Small utility function to figure out our domain id */
-static int get_self_id(void)
-{
-    char *dom_id;
-    int ret; 
-                
-    assert(xsh != NULL);
-    dom_id = xs_read(xsh, XBT_NULL, "domid", NULL);
-    sscanf(dom_id, "%d", &ret); 
-    free(dom_id);
-                        
-    return ret;                                  
-} 
-
-
-bool xenbus_write_backend_node(struct fs_mount *mount)
-{
-    char node[1024], backend_node[1024];
-    int self_id;
-
-    assert(xsh != NULL);
-    self_id = get_self_id();
-    FS_DEBUG("Our own dom_id=%d\n", self_id);
-    snprintf(node, sizeof(node), "%s/backend", mount->frontend);
-    snprintf(backend_node, sizeof(backend_node), 
"/local/domain/%d/"ROOT_NODE"/%d",
-                                self_id, mount->mount_id);
-    xs_write(xsh, XBT_NULL, node, backend_node, strlen(backend_node));
-
-    snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id);
-    return xs_write(xsh, XBT_NULL, node, STATE_INITIALISED, 
strlen(STATE_INITIALISED));
-}
-
-bool xenbus_write_backend_state(struct fs_mount *mount, const char *state)
-{
-    char node[1024];
-    int self_id;
-
-    assert(xsh != NULL);
-    self_id = get_self_id();
-    snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id);
-    return xs_write(xsh, XBT_NULL, node, state, strlen(state));
-}
-
-void xenbus_free_backend_node(struct fs_mount *mount)
-{
-    char node[1024];
-    int self_id;
-
-    assert(xsh != NULL);
-    self_id = get_self_id();
-    snprintf(node, sizeof(node), ROOT_NODE"/%d", mount->mount_id);
-    xs_rm(xsh, XBT_NULL, node);
-}
-
-bool xenbus_watch_frontend_state(struct fs_mount *mount)
-{
-    char statepath[1024];
-
-    assert(xsh != NULL);
-    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
-    return xs_watch(xsh, statepath, "frontend-state");
-}
-
-bool xenbus_unwatch_frontend_state(struct fs_mount *mount)
-{
-    char statepath[1024];
-
-    assert(xsh != NULL);
-    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
-    return xs_unwatch(xsh, statepath, "frontend-state");
-}
-
-int xenbus_frontend_state_changed(struct fs_mount *mount, const char *oldstate)
-{
-    unsigned int len;
-    char statepath[1024];
-    char *state = NULL;
-
-    assert(xsh != NULL);
-    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
-    state = xs_read(xsh, XBT_NULL, statepath, &len);
-    if (state && len > 0) {
-        if (strcmp(state, oldstate)) {
-            free(state);
-            return 1;
-        } else {
-            free(state);
-            return 0;
-        }
-    } else
-        return 1;
-}
-
-char* xenbus_read_frontend_state(struct fs_mount *mount)
-{
-    unsigned int len;
-    char statepath[1024];
-
-    assert(xsh != NULL);
-    snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend);
-    return xs_read(xsh, XBT_NULL, statepath, &len);
-}
-
diff -r ae3567ccf524 -r 3c78729b6f06 tools/fs-back/sys-queue.h
--- a/tools/fs-back/sys-queue.h Tue Jan 11 16:48:09 2011 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,338 +0,0 @@
-/*      $NetBSD: queue.h,v 1.45.14.1 2007/07/18 20:13:24 liamjfoy Exp $ */
-
-/*
- * Qemu version: Copy from netbsd, removed debug code, removed some of
- * the implementations.  Left in lists, tail queues and circular queues.
- */
-
-/*
- * Copyright (c) 1991, 1993
- *      The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *      @(#)queue.h     8.5 (Berkeley) 8/20/94
- */
-
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
-
-/*
- * This file defines three types of data structures:
- * lists, tail queues, and circular queues.
- *
- * A list is headed by a single forward pointer (or an array of forward
- * pointers for a hash table header). The elements are doubly linked
- * so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before
- * or after an existing element or at the head of the list. A list
- * may only be traversed in the forward direction.
- *
- * A tail queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or
- * after an existing element, at the head of the list, or at the end of
- * the list. A tail queue may be traversed in either direction.
- *
- * A circle queue is headed by a pair of pointers, one to the head of the
- * list and the other to the tail of the list. The elements are doubly
- * linked so that an arbitrary element can be removed without a need to
- * traverse the list. New elements can be added to the list before or after
- * an existing element, at the head of the list, or at the end of the list.
- * A circle queue may be traversed in either direction, but has a more
- * complex end of list detection.
- *
- * For details on the use of these macros, see the queue(3) manual page.
- */
-
-/*
- * List definitions.
- */
-#define LIST_HEAD(name, type)                                           \
-struct name {                                                           \
-        struct type *lh_first;  /* first element */                     \
-}
-
-#define LIST_HEAD_INITIALIZER(head)                                     \
-        { NULL }
-
-#define LIST_ENTRY(type)                                                \
-struct {                                                                \
-        struct type *le_next;   /* next element */                      \
-        struct type **le_prev;  /* address of previous next element */  \
-}
-
-/*
- * List functions.
- */
-#define LIST_INIT(head) do {                                            \
-        (head)->lh_first = NULL;                                        \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
-        if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
-                (listelm)->field.le_next->field.le_prev =               \
-                    &(elm)->field.le_next;                              \
-        (listelm)->field.le_next = (elm);                               \
-        (elm)->field.le_prev = &(listelm)->field.le_next;               \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
-        (elm)->field.le_prev = (listelm)->field.le_prev;                \
-        (elm)->field.le_next = (listelm);                               \
-        *(listelm)->field.le_prev = (elm);                              \
-        (listelm)->field.le_prev = &(elm)->field.le_next;               \
-} while (/*CONSTCOND*/0)
-
-#define LIST_INSERT_HEAD(head, elm, field) do {                         \
-        if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
-                (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
-        (head)->lh_first = (elm);                                       \
-        (elm)->field.le_prev = &(head)->lh_first;                       \
-} while (/*CONSTCOND*/0)
-
-#define LIST_REMOVE(elm, field) do {                                    \
-        if ((elm)->field.le_next != NULL)                               \
-                (elm)->field.le_next->field.le_prev =                   \
-                    (elm)->field.le_prev;                               \
-        *(elm)->field.le_prev = (elm)->field.le_next;                   \
-} while (/*CONSTCOND*/0)
-
-#define LIST_FOREACH(var, head, field)                                  \
-        for ((var) = ((head)->lh_first);                                \
-                (var);                                                  \
-                (var) = ((var)->field.le_next))
-
-/*
- * List access methods.
- */
-#define LIST_EMPTY(head)                ((head)->lh_first == NULL)
-#define LIST_FIRST(head)                ((head)->lh_first)
-#define LIST_NEXT(elm, field)           ((elm)->field.le_next)
-
-
-/*
- * Tail queue definitions.
- */
-#define _TAILQ_HEAD(name, type, qual)                                   \
-struct name {                                                           \
-        qual type *tqh_first;           /* first element */             \
-        qual type *qual *tqh_last;      /* addr of last next element */ \
-}
-#define TAILQ_HEAD(name, type)  _TAILQ_HEAD(name, struct type,)
-
-#define TAILQ_HEAD_INITIALIZER(head)                                    \
-        { NULL, &(head).tqh_first }
-
-#define _TAILQ_ENTRY(type, qual)                                        \
-struct {                                                                \
-        qual type *tqe_next;            /* next element */              \
-        qual type *qual *tqe_prev;      /* address of previous next element */\
-}
-#define TAILQ_ENTRY(type)       _TAILQ_ENTRY(struct type,)
-
-/*
- * Tail queue functions.
- */
-#define TAILQ_INIT(head) do {                                           \
-        (head)->tqh_first = NULL;                                       \
-        (head)->tqh_last = &(head)->tqh_first;                          \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_HEAD(head, elm, field) do {                        \
-        if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
-                (head)->tqh_first->field.tqe_prev =                     \
-                    &(elm)->field.tqe_next;                             \
-        else                                                            \
-                (head)->tqh_last = &(elm)->field.tqe_next;              \
-        (head)->tqh_first = (elm);                                      \
-        (elm)->field.tqe_prev = &(head)->tqh_first;                     \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_TAIL(head, elm, field) do {                        \
-        (elm)->field.tqe_next = NULL;                                   \
-        (elm)->field.tqe_prev = (head)->tqh_last;                       \
-        *(head)->tqh_last = (elm);                                      \
-        (head)->tqh_last = &(elm)->field.tqe_next;                      \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
-        if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
-                (elm)->field.tqe_next->field.tqe_prev =                 \
-                    &(elm)->field.tqe_next;                             \
-        else                                                            \
-                (head)->tqh_last = &(elm)->field.tqe_next;              \
-        (listelm)->field.tqe_next = (elm);                              \
-        (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
-        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
-        (elm)->field.tqe_next = (listelm);                              \
-        *(listelm)->field.tqe_prev = (elm);                             \
-        (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_REMOVE(head, elm, field) do {                             \
-        if (((elm)->field.tqe_next) != NULL)                            \
-                (elm)->field.tqe_next->field.tqe_prev =                 \
-                    (elm)->field.tqe_prev;                              \
-        else                                                            \
-                (head)->tqh_last = (elm)->field.tqe_prev;               \
-        *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
-} while (/*CONSTCOND*/0)
-
-#define TAILQ_FOREACH(var, head, field)                                 \
-        for ((var) = ((head)->tqh_first);                               \
-                (var);                                                  \
-                (var) = ((var)->field.tqe_next))
-
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
-        for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));   
 \
-                (var);                                                  \
-                (var) = (*(((struct headname 
*)((var)->field.tqe_prev))->tqh_last)))
-
-/*
- * Tail queue access methods.
- */
-#define TAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
-#define TAILQ_FIRST(head)               ((head)->tqh_first)
-#define TAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
-
-#define TAILQ_LAST(head, headname) \
-        (*(((struct headname *)((head)->tqh_last))->tqh_last))
-#define TAILQ_PREV(elm, headname, field) \
-        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-
-
-/*
- * Circular queue definitions.
- */
-#define CIRCLEQ_HEAD(name, type)                                        \
-struct name {                                                           \
-        struct type *cqh_first;         /* first element */             \
-        struct type *cqh_last;          /* last element */              \
-}
-
-#define CIRCLEQ_HEAD_INITIALIZER(head)                                  \
-        { (void *)&head, (void *)&head }
-
-#define CIRCLEQ_ENTRY(type)                                             \
-struct {                                                                \
-        struct type *cqe_next;          /* next element */              \
-        struct type *cqe_prev;          /* previous element */          \
-}
-
-/*
- * Circular queue functions.
- */
-#define CIRCLEQ_INIT(head) do {                                         \
-        (head)->cqh_first = (void *)(head);                             \
-        (head)->cqh_last = (void *)(head);                              \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {            \
-        (elm)->field.cqe_next = (listelm)->field.cqe_next;              \
-        (elm)->field.cqe_prev = (listelm);                              \
-        if ((listelm)->field.cqe_next == (void *)(head))                \
-                (head)->cqh_last = (elm);                               \
-        else                                                            \
-                (listelm)->field.cqe_next->field.cqe_prev = (elm);      \
-        (listelm)->field.cqe_next = (elm);                              \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {           \
-        (elm)->field.cqe_next = (listelm);                              \
-        (elm)->field.cqe_prev = (listelm)->field.cqe_prev;              \
-        if ((listelm)->field.cqe_prev == (void *)(head))                \
-                (head)->cqh_first = (elm);                              \
-        else                                                            \
-                (listelm)->field.cqe_prev->field.cqe_next = (elm);      \
-        (listelm)->field.cqe_prev = (elm);                              \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {                      \
-        (elm)->field.cqe_next = (head)->cqh_first;                      \
-        (elm)->field.cqe_prev = (void *)(head);                         \
-        if ((head)->cqh_last == (void *)(head))                         \
-                (head)->cqh_last = (elm);                               \
-        else                                                            \
-                (head)->cqh_first->field.cqe_prev = (elm);              \
-        (head)->cqh_first = (elm);                                      \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {                      \
-        (elm)->field.cqe_next = (void *)(head);                         \
-        (elm)->field.cqe_prev = (head)->cqh_last;                       \
-        if ((head)->cqh_first == (void *)(head))                        \
-                (head)->cqh_first = (elm);                              \
-        else                                                            \
-                (head)->cqh_last->field.cqe_next = (elm);               \
-        (head)->cqh_last = (elm);                                       \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_REMOVE(head, elm, field) do {                           \
-        if ((elm)->field.cqe_next == (void *)(head))                    \
-                (head)->cqh_last = (elm)->field.cqe_prev;               \
-        else                                                            \
-                (elm)->field.cqe_next->field.cqe_prev =                 \
-                    (elm)->field.cqe_prev;                              \
-        if ((elm)->field.cqe_prev == (void *)(head))                    \
-                (head)->cqh_first = (elm)->field.cqe_next;              \
-        else                                                            \
-                (elm)->field.cqe_prev->field.cqe_next =                 \
-                    (elm)->field.cqe_next;                              \
-} while (/*CONSTCOND*/0)
-
-#define CIRCLEQ_FOREACH(var, head, field)                               \
-        for ((var) = ((head)->cqh_first);                               \
-                (var) != (const void *)(head);                          \
-                (var) = ((var)->field.cqe_next))
-
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field)                       \
-        for ((var) = ((head)->cqh_last);                                \
-                (var) != (const void *)(head);                          \
-                (var) = ((var)->field.cqe_prev))
-
-/*
- * Circular queue access methods.
- */
-#define CIRCLEQ_EMPTY(head)             ((head)->cqh_first == (void *)(head))
-#define CIRCLEQ_FIRST(head)             ((head)->cqh_first)
-#define CIRCLEQ_LAST(head)              ((head)->cqh_last)
-#define CIRCLEQ_NEXT(elm, field)        ((elm)->field.cqe_next)
-#define CIRCLEQ_PREV(elm, field)        ((elm)->field.cqe_prev)
-
-#define CIRCLEQ_LOOP_NEXT(head, elm, field)                             \
-        (((elm)->field.cqe_next == (void *)(head))                      \
-            ? ((head)->cqh_first)                                       \
-            : (elm->field.cqe_next))
-#define CIRCLEQ_LOOP_PREV(head, elm, field)                             \
-        (((elm)->field.cqe_prev == (void *)(head))                      \
-            ? ((head)->cqh_last)                                        \
-            : (elm->field.cqe_prev))
-
-#endif  /* !_SYS_QUEUE_H_ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] tools: remove fs-front/fs-back, Xen patchbot-unstable <=