aboutsummaryrefslogtreecommitdiff
path: root/hw/9pfs
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2011-09-09 15:07:01 +0530
committerAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2011-09-09 15:07:01 +0530
commit7834cf77be7e3e301177c6ab98a3d7f1bf73f28f (patch)
treebbabf06a369a344b381aa0edf43970b9be37ee26 /hw/9pfs
parent89bf65938aa9f70e1c903160af509b693bd58c7b (diff)
hw/9pfs: add 9P2000.L unlinkat operation
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>
Diffstat (limited to 'hw/9pfs')
-rw-r--r--hw/9pfs/virtio-9p.c40
-rw-r--r--hw/9pfs/virtio-9p.h2
2 files changed, 42 insertions, 0 deletions
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 0293fe42b1..d28edb799a 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 49507825b6..17d44b41ca 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,