From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:35657) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTdRt-0000rh-3i for qemu-devel@nongnu.org; Mon, 06 Jun 2011 13:18:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QTdRr-0005Me-CQ for qemu-devel@nongnu.org; Mon, 06 Jun 2011 13:18:44 -0400 Received: from e28smtp04.in.ibm.com ([122.248.162.4]:43539) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QTdRq-0005MD-Bu for qemu-devel@nongnu.org; Mon, 06 Jun 2011 13:18:43 -0400 Received: from d28relay03.in.ibm.com (d28relay03.in.ibm.com [9.184.220.60]) by e28smtp04.in.ibm.com (8.14.4/8.13.1) with ESMTP id p56HIcSm016156 for ; Mon, 6 Jun 2011 22:48:38 +0530 Received: from d28av01.in.ibm.com (d28av01.in.ibm.com [9.184.220.63]) by d28relay03.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p56HIcWO4468830 for ; Mon, 6 Jun 2011 22:48:38 +0530 Received: from d28av01.in.ibm.com (loopback [127.0.0.1]) by d28av01.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p56HIbZZ004143 for ; Mon, 6 Jun 2011 22:48:38 +0530 From: "Aneesh Kumar K.V" Date: Mon, 6 Jun 2011 22:48:36 +0530 Message-Id: <1307380716-2318-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH] hw/9pfs: add 9P2000.L renameat operation List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com, "Aneesh Kumar K.V" rename - change name of file or directory size[4] Trenameat tag[2] olddirfid[4] oldname[s] newdirfid[4] newname[s] size[4] Rrenameat tag[2] older Trename have the below request format size[4] Trename tag[2] fid[4] newdirfid[4] name[s] The rename message is used to change the name of a file, possibly moving it to a new directory. The rename opreation is actually a directory opertation and should ideally have olddirfid, if not we cannot represent the fid on server with anything other than name. We will have to derive the old directory name from fid in the Trename request. Signed-off-by: Aneesh Kumar K.V --- hw/9pfs/virtio-9p.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ hw/9pfs/virtio-9p.h | 2 + 2 files changed, 84 insertions(+), 0 deletions(-) diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 9d1813e..092c9bc 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -2449,6 +2449,87 @@ out_nofid: v9fs_string_free(&name); } +static int v9fs_complete_renameat(V9fsState *s, int32_t olddirfid, + V9fsString *old_name, int32_t newdirfid, + V9fsString *new_name) +{ + int err = 0; + V9fsString old_full_name, new_full_name; + V9fsFidState *newdirfidp = NULL, *olddirfidp = NULL; + + olddirfidp = get_fid(s, olddirfid); + if (olddirfidp == NULL) { + err = -ENOENT; + goto out; + } + v9fs_string_init(&old_full_name); + v9fs_string_init(&new_full_name); + + v9fs_string_sprintf(&old_full_name, "%s/%s", + olddirfidp->path.data, old_name->data); + if (newdirfid != -1) { + newdirfidp = get_fid(s, newdirfid); + if (newdirfidp == NULL) { + err = -ENOENT; + goto out; + } + v9fs_string_sprintf(&new_full_name, "%s/%s", + newdirfidp->path.data, new_name->data); + } else { + v9fs_string_sprintf(&new_full_name, "%s/%s", + olddirfidp->path.data, new_name->data); + } + + if (strcmp(old_full_name.data, new_full_name.data) != 0) { + V9fsFidState *tfidp; + err = v9fs_co_rename(s, &old_full_name, &new_full_name); + if (err < 0) { + goto out; + } + /* + * Fixup fid's pointing to the old name to + * start pointing to the new name + */ + for (tfidp = s->fid_list; tfidp; tfidp = tfidp->next) { + if (v9fs_path_is_ancestor(&old_full_name, &tfidp->path)) { + /* replace the name */ + v9fs_fix_path(&tfidp->path, &new_full_name, old_full_name.size); + } + } + } +out: + if (olddirfidp) { + put_fid(s, olddirfidp); + } + if (newdirfidp) { + put_fid(s, newdirfidp); + } + v9fs_string_free(&old_full_name); + v9fs_string_free(&new_full_name); + return err; +} + +static void v9fs_renameat(void *opaque) +{ + ssize_t err = 0; + size_t offset = 7; + V9fsPDU *pdu = opaque; + V9fsState *s = pdu->s; + int32_t olddirfid, newdirfid; + V9fsString old_name, new_name; + + pdu_unmarshal(pdu, offset, "dsds", &olddirfid, + &old_name, &newdirfid, &new_name); + + err = v9fs_complete_renameat(s, olddirfid, &old_name, newdirfid, &new_name); + if (!err) { + err = offset; + } + complete_pdu(s, pdu, err); + v9fs_string_free(&old_name); + v9fs_string_free(&new_name); +} + static void v9fs_wstat(void *opaque) { int32_t fid; @@ -2964,6 +3045,7 @@ static CoroutineEntry *pdu_co_handlers[] = { [P9_TRENAME] = v9fs_rename, [P9_TLOCK] = v9fs_lock, [P9_TGETLOCK] = v9fs_getlock, + [P9_TRENAMEAT] = v9fs_renameat, [P9_TREADLINK] = v9fs_readlink, [P9_TMKDIR] = v9fs_mkdir, [P9_TVERSION] = v9fs_version, diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 36aa4a5..7291a9c 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -50,6 +50,8 @@ enum { P9_RLINK, P9_TMKDIR = 72, P9_RMKDIR, + P9_TRENAMEAT = 74, + P9_RRENAMEAT, P9_TVERSION = 100, P9_RVERSION, P9_TAUTH = 102, -- 1.7.4.1