From patchwork Thu May 27 09:27:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sripathi Kodi X-Patchwork-Id: 102585 Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o4R9RxG4021582 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 27 May 2010 09:28:35 GMT Received: from localhost ([127.0.0.1] helo=sfs-ml-4.v29.ch3.sourceforge.com) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1OHZNY-0007dB-1k; Thu, 27 May 2010 09:27:52 +0000 Received: from sfi-mx-3.v28.ch3.sourceforge.com ([172.29.28.123] helo=mx.sourceforge.net) by sfs-ml-4.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1OHZNX-0007d6-80 for v9fs-developer@lists.sourceforge.net; Thu, 27 May 2010 09:27:51 +0000 Received-SPF: softfail (sfi-mx-3.v28.ch3.sourceforge.com: transitioning domain of in.ibm.com does not designate 122.248.162.9 as permitted sender) client-ip=122.248.162.9; envelope-from=sripathik@in.ibm.com; helo=e28smtp09.in.ibm.com; Received: from e28smtp09.in.ibm.com ([122.248.162.9]) by sfi-mx-3.v28.ch3.sourceforge.com with esmtps (TLSv1:AES256-SHA:256) (Exim 4.69) id 1OHZNV-0004qG-B6 for v9fs-developer@lists.sourceforge.net; Thu, 27 May 2010 09:27:51 +0000 Received: from d28relay01.in.ibm.com (d28relay01.in.ibm.com [9.184.220.58]) by e28smtp09.in.ibm.com (8.14.3/8.13.1) with ESMTP id o4R8T3GW003266 for ; Thu, 27 May 2010 13:59:03 +0530 Received: from d28av03.in.ibm.com (d28av03.in.ibm.com [9.184.220.65]) by d28relay01.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o4R9RZlv2810024 for ; Thu, 27 May 2010 14:57:38 +0530 Received: from d28av03.in.ibm.com (loopback [127.0.0.1]) by d28av03.in.ibm.com (8.14.3/8.13.1/NCO v10.0 AVout) with ESMTP id o4R9RZOu010791 for ; Thu, 27 May 2010 19:27:35 +1000 Received: from sripathi.in.ibm.com ([9.124.46.73]) by d28av03.in.ibm.com (8.14.3/8.13.1/NCO v10.0 AVin) with ESMTP id o4R9RZPH010788; Thu, 27 May 2010 19:27:35 +1000 Received: from localhost.localdomain (localhost [IPv6:::1]) by sripathi.in.ibm.com (Postfix) with ESMTP id AEC568F242; Thu, 27 May 2010 14:57:34 +0530 (IST) From: Sripathi Kodi To: v9fs-developer@lists.sourceforge.net Date: Thu, 27 May 2010 14:57:34 +0530 Message-ID: <20100527092734.7079.94343.stgit@localhost.localdomain> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Spam-Score: -0.4 (/) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.7 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -1.1 AWL AWL: From: address is in the auto white-list X-Headers-End: 1OHZNV-0004qG-B6 Subject: [V9fs-developer] [PATCH] virtio-9p: readdir implementation for 9p2000.L X-BeenThere: v9fs-developer@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: v9fs-developer-bounces@lists.sourceforge.net X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 27 May 2010 09:28:36 +0000 (UTC) diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c index 2fb2673..a82b771 100644 --- a/hw/virtio-9p-debug.c +++ b/hw/virtio-9p-debug.c @@ -328,6 +328,19 @@ void pprint_pdu(V9fsPDU *pdu) } switch (pdu->id) { + case P9_TREADDIR: + fprintf(llogfile, "TREADDIR: ("); + pprint_int32(pdu, 0, &offset, "fid"); + pprint_int64(pdu, 0, &offset, ", initial offset"); + pprint_int32(pdu, 0, &offset, ", max count"); + break; + case P9_RREADDIR: + fprintf(llogfile, "RREADDIR: ("); + pprint_int32(pdu, 1, &offset, "count"); +#ifdef DEBUG_DATA + pprint_data(pdu, 1, &offset, ", data"); +#endif + break; case P9_TVERSION: fprintf(llogfile, "TVERSION: ("); pprint_int32(pdu, 0, &offset, "msize"); diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c index e5d0112..39a535a 100644 --- a/hw/virtio-9p.c +++ b/hw/virtio-9p.c @@ -1606,6 +1606,115 @@ typedef struct V9fsWriteState { int cnt; } V9fsWriteState; +typedef struct V9fsReadDirState { + V9fsPDU *pdu; + V9fsFidState *fidp; + off_t saved_dir_pos; + struct dirent *dent; + int32_t count; + int32_t max_count; + size_t offset; + int64_t initial_offset; + V9fsString name; +} V9fsReadDirState; + +static void v9fs_readdir_post_seekdir(V9fsState *s, V9fsReadDirState *vs) +{ + vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count); + vs->offset += vs->count; + complete_pdu(s, vs->pdu, vs->offset); + qemu_free(vs); + return; +} + +/* Size of each dirent on the wire: size of inode (8) + size of offset (8) + * size of type (1) + size of name.size (2) + strlen(name.data) + */ +#define V9_READDIR_DATA_SZ (19+strlen(vs->name.data)) + +static void v9fs_readdir_post_readdir(V9fsState *s, V9fsReadDirState *vs) +{ + int len; + + if (vs->dent) { + v9fs_string_init(&vs->name); + v9fs_string_sprintf(&vs->name, "%s", vs->dent->d_name); + + if ((vs->count + V9_READDIR_DATA_SZ) > vs->max_count) { + /* Ran out of buffer. Set dir back to old position and return */ + v9fs_do_seekdir(s, vs->fidp->dir, vs->saved_dir_pos); + v9fs_readdir_post_seekdir(s, vs); + return; + } + + len = pdu_marshal(vs->pdu, vs->offset+4+vs->count, "qqbs", + vs->dent->d_ino, vs->dent->d_off, + vs->dent->d_type, &vs->name); + vs->count += len; + v9fs_string_free(&vs->name); + vs->saved_dir_pos = vs->dent->d_off; + vs->dent = v9fs_do_readdir(s, vs->fidp->dir); + v9fs_readdir_post_readdir(s, vs); + return; + } + + vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count); + vs->offset += vs->count; + complete_pdu(s, vs->pdu, vs->offset); + qemu_free(vs); + return; +} + +static void v9fs_readdir_post_telldir(V9fsState *s, V9fsReadDirState *vs) +{ + vs->dent = v9fs_do_readdir(s, vs->fidp->dir); + v9fs_readdir_post_readdir(s, vs); + return; +} + +static void v9fs_readdir_post_setdir(V9fsState *s, V9fsReadDirState *vs) +{ + vs->saved_dir_pos = v9fs_do_telldir(s, vs->fidp->dir); + v9fs_readdir_post_telldir(s, vs); + return; +} + +static void v9fs_readdir(V9fsState *s, V9fsPDU *pdu) +{ + int32_t fid; + V9fsReadDirState *vs; + ssize_t err = 0; + size_t offset = 7; + + vs = qemu_malloc(sizeof(*vs)); + vs->pdu = pdu; + vs->offset = 7; + vs->count = 0; + + pdu_unmarshal(vs->pdu, offset, "dqd", &fid, &vs->initial_offset, + &vs->max_count); + + vs->fidp = lookup_fid(s, fid); + if (vs->fidp == NULL || !(vs->fidp->dir)) { + err = -EINVAL; + goto out; + } + + if (vs->initial_offset == 0) { + v9fs_do_rewinddir(s, vs->fidp->dir); + } else { + v9fs_do_seekdir(s, vs->fidp->dir, vs->initial_offset); + } + + v9fs_readdir_post_setdir(s, vs); + return; + +out: + complete_pdu(s, pdu, err); + qemu_free(vs); + return; +} + static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs, ssize_t err) { @@ -2225,6 +2334,7 @@ out: typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu); static pdu_handler_t *pdu_handlers[] = { + [P9_TREADDIR] = v9fs_readdir, [P9_TVERSION] = v9fs_version, [P9_TATTACH] = v9fs_attach, [P9_TSTAT] = v9fs_stat, diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h index b95dbe4..85fbe87 100644 --- a/hw/virtio-9p.h +++ b/hw/virtio-9p.h @@ -13,6 +13,8 @@ #define VIRTIO_9P_MOUNT_TAG 0 enum { + P9_TREADDIR = 40, + P9_RREADDIR, P9_TVERSION = 100, P9_RVERSION, P9_TAUTH = 102,