summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@zresearch.com>2009-05-11 18:23:24 +0530
committerAnand V. Avati <avati@amp.gluster.com>2009-05-18 19:12:52 +0530
commite420eb2206aa773eb32f1a7146cba4d6da5d9d03 (patch)
tree8191e4758f2f435c57a906e71baf92ba3c729bad
parente1ae573f73d69fe1a244ed1493793961dd4cf811 (diff)
libglusterfsclient: Refine readdir entry parsing logic
Here I am only refining the entry parsing code in order to clarify the exit conditions from the loop. There were a few workloads where this loop went infinite. Signed-off-by: Anand V. Avati <avati@amp.gluster.com>
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient.c44
1 files changed, 19 insertions, 25 deletions
diff --git a/libglusterfsclient/src/libglusterfsclient.c b/libglusterfsclient/src/libglusterfsclient.c
index 29ef163df..095edaa7c 100755
--- a/libglusterfsclient/src/libglusterfsclient.c
+++ b/libglusterfsclient/src/libglusterfsclient.c
@@ -3294,19 +3294,29 @@ libgf_client_readdir (libglusterfs_client_ctx_t *ctx,
op_ret = stub->args.readdir_cbk.op_ret;
errno = stub->args.readdir_cbk.op_errno;
+ /* Someday we'll support caching the multiple entries returned
+ * from the server, till then, the logic below only extracts
+ * one entry depending on the previous offset given above.
+ */
if (op_ret > 0) {
list_for_each_entry (entry,
&stub->args.readdir_cbk.entries.list,
list) {
entry_size = offsetof (struct dirent, d_name)
+ strlen (entry->d_name) + 1;
-
- if ((size < entry_size) || (count == num_entries)) {
- if (*offset == entry->d_off)
- count--;
- else
- break;
- }
+
+ /* If the offset requested matches the offset of the current
+ * entry, it means that we need to search
+ * further for entry with the required offset.
+ */
+ if (*offset == entry->d_off)
+ continue;
+
+ /* If we cannot fit more data into the given buffer, or
+ * if we've extracted the requested number of entries, well,
+ * break. */
+ if ((size < entry_size) || (count == num_entries))
+ break;
size -= entry_size;
@@ -3326,24 +3336,8 @@ libgf_client_readdir (libglusterfs_client_ctx_t *ctx,
dirp->d_name[dirp->d_reclen] = '\0';
dirp = (struct dirent *) (((char *) dirp) + entry_size);
- /* FIXME: Someday, we'll enable processing
- * more than one dirent. The reason we should
- * break here is that the offset must not be
- * updated beyond one entry.
- *
- * FIXME2: This offset value check is somewhat
- * better than not having any support for
- * multiple entry extraction. Suppose we're
- * reading a large directory.
- */
- if (*offset == entry->d_off)
- continue;
- else {
- *offset = dirp->d_off = entry->d_off;
- break;
- }
-
- break;
+ *offset = entry->d_off;
+ count++;
}
}