diff mbox

[1/2] hw/9pfs: Add 9P2000.L detach operation

Message ID 20111124122105.16532.32764.stgit@deepak-ThinkPad-T60p
State New
Headers show

Commit Message

Deepak C Shetty Nov. 24, 2011, 12:21 p.m. UTC
detach - close session

size[4] Tdetach tag[2]
size[4] Rdetach tag[2]

The detach msg is used to close an already existing session.
This enable us to notify qemu that an unmount have happened in
the client. Such notification enable us to do specific task
like remove migration blocker in qemu.

Signed-off-by: Deepak C Shetty <deepakcs@linux.vnet.ibm.com>
---

 hw/9pfs/virtio-9p.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 hw/9pfs/virtio-9p.h |    2 ++
 trace-events        |    2 ++
 3 files changed, 47 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 177c0ee..ee83d81 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -20,6 +20,7 @@ 
 #include "virtio-9p-xattr.h"
 #include "virtio-9p-coth.h"
 #include "trace.h"
+#include "qemu-error.h"
 
 int open_fd_hw;
 int total_open_fd;
@@ -613,6 +614,32 @@  static int v9fs_mark_fids_unreclaim(V9fsPDU *pdu, V9fsPath *path)
     return 0;
 }
 
+static void virtfs_reset(V9fsPDU *pdu)
+{
+    V9fsState *s = pdu->s;
+    V9fsFidState *fidp = NULL;
+
+    /* Free all fids */
+    while (s->fid_list) {
+        fidp = s->fid_list;
+        s->fid_list = fidp->next;
+
+        if (fidp->ref) {
+            fidp->clunked = 1;
+        } else {
+            free_fid(pdu, fidp);
+        }
+    }
+
+    if (fidp) {
+        /* One or more unclunked fids found... */
+        error_report("9pfs:%s: One or more uncluncked fids "
+                     "found during reset", __func__);
+    }
+
+    return;
+}
+
 #define P9_QID_TYPE_DIR         0x80
 #define P9_QID_TYPE_SYMLINK     0x02
 
@@ -1096,6 +1123,20 @@  out_nofid:
     v9fs_string_free(&aname);
 }
 
+static void v9fs_detach(void *opaque)
+{
+    V9fsPDU *pdu = opaque;
+
+    trace_v9fs_detach(pdu->tag, pdu->id);
+
+    virtfs_reset(pdu);
+
+    trace_v9fs_detach_return(pdu->tag, pdu->id);
+    complete_pdu(pdu->s, pdu, 7);
+
+    return;
+}
+
 static void v9fs_stat(void *opaque)
 {
     int32_t fid;
@@ -3064,6 +3105,7 @@  static CoroutineEntry *pdu_co_handlers[] = {
     [P9_TWRITE] = v9fs_write,
     [P9_TWSTAT] = v9fs_wstat,
     [P9_TREMOVE] = v9fs_remove,
+    [P9_TDETACH] = v9fs_detach,
 };
 
 static void v9fs_op_not_supp(void *opaque)
@@ -3099,6 +3141,7 @@  static inline bool is_read_only_op(V9fsPDU *pdu)
     case P9_TREAD:
     case P9_TAUTH:
     case P9_TFLUSH:
+    case P9_TDETACH:
         return 1;
     default:
         return 0;
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 1d8665e..d305375 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -56,6 +56,8 @@  enum {
     P9_RRENAMEAT,
     P9_TUNLINKAT = 76,
     P9_RUNLINKAT,
+    P9_TDETACH = 78,
+    P9_RDETACH,
     P9_TVERSION = 100,
     P9_RVERSION,
     P9_TAUTH = 102,
diff --git a/trace-events b/trace-events
index 0f0a6b0..9d9d3f3 100644
--- a/trace-events
+++ b/trace-events
@@ -559,6 +559,8 @@  v9fs_version(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id
 v9fs_version_return(uint16_t tag, uint8_t id, int32_t msize, char* version) "tag %d id %d msize %d version %s"
 v9fs_attach(uint16_t tag, uint8_t id, int32_t fid, int32_t afid, char* uname, char* aname) "tag %u id %u fid %d afid %d uname %s aname %s"
 v9fs_attach_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path) "tag %d id %d type %d version %d path %"PRId64""
+v9fs_detach(uint16_t tag, uint8_t id) "tag %u id %u"
+v9fs_detach_return(uint16_t tag, uint8_t id) "tag %u id %u"
 v9fs_stat(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
 v9fs_stat_return(uint16_t tag, uint8_t id, int32_t mode, int32_t atime, int32_t mtime, int64_t length) "tag %d id %d stat={mode %d atime %d mtime %d length %"PRId64"}"
 v9fs_getattr(uint16_t tag, uint8_t id, int32_t fid, uint64_t request_mask) "tag %d id %d fid %d request_mask %"PRIu64""