diff mbox

[-V2,2/2] hw/9pfs: add 9P2000.L unlinkat operation

Message ID 1315564407-11265-2-git-send-email-aneesh.kumar@linux.vnet.ibm.com
State New
Headers show

Commit Message

Aneesh Kumar K.V Sept. 9, 2011, 10:33 a.m. UTC
unlinkat - Remove a directory entry

size[4] Tunlinkat tag[2] dirfid[4] name[s] flag[4]
size[4] Runlinkat tag[2]

older Tremove have the below request format

size[4] Tremove tag[2] fid[4]

The remove message is used to remove a directory entry either file or directory
The remove opreation is actually a directory opertation and should ideally have
dirfid, if not we cannot represent the fid on server with anything other than
name. We will have to derive the directory name from fid in the Tremove request.

NOTE: The operation doesn't clunk the unlink fid.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 hw/9pfs/virtio-9p.c |   40 ++++++++++++++++++++++++++++++++++++++++
 hw/9pfs/virtio-9p.h |    2 ++
 2 files changed, 42 insertions(+), 0 deletions(-)
diff mbox

Patch

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 0293fe4..d28edb7 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -2338,6 +2338,45 @@  out_nofid:
     complete_pdu(pdu->s, pdu, err);
 }
 
+static void v9fs_unlinkat(void *opaque)
+{
+    int err = 0;
+    V9fsString name;
+    int32_t dfid, flags;
+    size_t offset = 7;
+    V9fsFidState *dfidp;
+    V9fsPDU *pdu = opaque;
+    V9fsString full_name;
+
+    pdu_unmarshal(pdu, offset, "dsd", &dfid, &name, &flags);
+
+    dfidp = get_fid(pdu->s, dfid);
+    if (dfidp == NULL) {
+        err = -EINVAL;
+        goto out_nofid;
+    }
+    v9fs_string_init(&full_name);
+    v9fs_string_sprintf(&full_name, "%s/%s", dfidp->path.data, name.data);
+    /*
+     * IF the file is unlinked, we cannot reopen
+     * the file later. So don't reclaim fd
+     */
+    err = v9fs_mark_fids_unreclaim(pdu->s, &full_name);
+    if (err < 0) {
+        goto out_err;
+    }
+    err = v9fs_co_remove(pdu->s, &full_name);
+    if (!err) {
+        err = offset;
+    }
+out_err:
+    put_fid(pdu->s, dfidp);
+    v9fs_string_free(&full_name);
+out_nofid:
+    complete_pdu(pdu->s, pdu, err);
+    v9fs_string_free(&name);
+}
+
 static int v9fs_complete_rename(V9fsState *s, V9fsFidState *fidp,
                                 int32_t newdirfid, V9fsString *name)
 {
@@ -3040,6 +3079,7 @@  static CoroutineEntry *pdu_co_handlers[] = {
     [P9_TGETLOCK] = v9fs_getlock,
     [P9_TRENAMEAT] = v9fs_renameat,
     [P9_TREADLINK] = v9fs_readlink,
+    [P9_TUNLINKAT] = v9fs_unlinkat,
     [P9_TMKDIR] = v9fs_mkdir,
     [P9_TVERSION] = v9fs_version,
     [P9_TLOPEN] = v9fs_open,
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 4950782..17d44b4 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -52,6 +52,8 @@  enum {
     P9_RMKDIR,
     P9_TRENAMEAT = 74,
     P9_RRENAMEAT,
+    P9_TUNLINKAT = 76,
+    P9_RUNLINKAT,
     P9_TVERSION = 100,
     P9_RVERSION,
     P9_TAUTH = 102,