All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] xfsprogs/io: add readdir command
@ 2013-07-24 12:44 Brian Foster
  2013-08-08 14:05 ` Mark Tinguely
  0 siblings, 1 reply; 5+ messages in thread
From: Brian Foster @ 2013-07-24 12:44 UTC (permalink / raw)
  To: xfs

readdir reads the directory entries from an open directory from
the provided offset (or 0 if not specified). On completion,
readdir prints summary information regarding the number of
operations and bytes transferred. Options are available to specify
the starting offset, length and verbose mode to dump directory
entry information.

Signed-off-by: Brian Foster <bfoster@redhat.com>
---

v2:
- Convert from getdents to readdir.
- Use configure mechanism for libc readdir() availability (zab).
- Add extra dirent fields to verbose output (zab).

 configure.ac          |   1 +
 include/builddefs.in  |   1 +
 io/Makefile           |   5 ++
 io/init.c             |   1 +
 io/io.h               |   6 ++
 io/readdir.c          | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++
 m4/package_libcdev.m4 |  15 ++++
 7 files changed, 219 insertions(+)
 create mode 100644 io/readdir.c

diff --git a/configure.ac b/configure.ac
index e5fd94e..da099d8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -112,6 +112,7 @@ AC_HAVE_FIEMAP
 AC_HAVE_PREADV
 AC_HAVE_SYNC_FILE_RANGE
 AC_HAVE_BLKID_TOPO($enable_blkid)
+AC_HAVE_READDIR
 
 AC_CHECK_SIZEOF([long])
 AC_CHECK_SIZEOF([char *])
diff --git a/include/builddefs.in b/include/builddefs.in
index 744e8d3..944bcf6 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -103,6 +103,7 @@ HAVE_FALLOCATE = @have_fallocate@
 HAVE_FIEMAP = @have_fiemap@
 HAVE_PREADV = @have_preadv@
 HAVE_SYNC_FILE_RANGE = @have_sync_file_range@
+HAVE_READDIR = @have_readdir@
 
 GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall 
 #	   -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl
diff --git a/io/Makefile b/io/Makefile
index 50edf91..d73f9b9 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -80,6 +80,11 @@ ifeq ($(HAVE_PREADV),yes)
 LCFLAGS += -DHAVE_PREADV -DHAVE_PWRITEV
 endif
 
+ifeq ($(HAVE_READDIR),yes)
+CFILES += readdir.c
+LCFLAGS += -DHAVE_READDIR
+endif
+
 default: depend $(LTCOMMAND)
 
 include $(BUILDRULES)
diff --git a/io/init.c b/io/init.c
index ca3055a..ee99761 100644
--- a/io/init.c
+++ b/io/init.c
@@ -74,6 +74,7 @@ init_commands(void)
 	fiemap_init();
 	pwrite_init();
 	quit_init();
+	readdir_init();
 	resblks_init();
 	sendfile_init();
 	shutdown_init();
diff --git a/io/io.h b/io/io.h
index 91f0e3e..e1f5328 100644
--- a/io/io.h
+++ b/io/io.h
@@ -149,3 +149,9 @@ extern void		sync_range_init(void);
 #else
 #define sync_range_init()	do { } while (0)
 #endif
+
+#ifdef HAVE_READDIR
+extern void		readdir_init(void);
+#else
+#define readdir_init()		do { } while (0)
+#endif
diff --git a/io/readdir.c b/io/readdir.c
new file mode 100644
index 0000000..eb47ac0
--- /dev/null
+++ b/io/readdir.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2013 Red Hat, Inc.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <xfs/xfs.h>
+#include <xfs/command.h>
+#include <xfs/input.h>
+#include "init.h"
+#include "io.h"
+
+#include <sys/types.h>
+#include <dirent.h>
+
+static struct cmdinfo readdir_cmd;
+
+const char *d_type_str(unsigned int type)
+{
+	const char *str;
+
+	switch (type) {
+	case DT_UNKNOWN:
+		str = "DT_UNKNOWN";
+		break;
+	case DT_FIFO:
+		str = "DT_FIFO";
+		break;
+	case DT_CHR:
+		str = "DT_CHR";
+		break;
+	case DT_DIR:
+		str = "DT_DIR";
+		break;
+	case DT_BLK:
+		str = "DT_BLK";
+		break;
+	case DT_REG:
+		str = "DT_REG";
+		break;
+	case DT_LNK:
+		str = "DT_LNK";
+		break;
+	case DT_SOCK:
+		str = "DT_SOCK";
+		break;
+	case DT_WHT:
+		str = "DT_WHT";
+		break;
+	default:
+		str = "ERROR!";
+		break;
+	}
+
+	return str;
+}
+
+static void
+dump_dirent(
+	long long offset,
+	struct dirent *dirent)
+{
+	printf("%08llx: d_ino: 0x%08lx", offset, dirent->d_ino);
+#ifdef _DIRENT_HAVE_D_OFF
+	printf(" d_off: 0x%08lx", dirent->d_off);
+#endif
+#ifdef _DIRENT_HAVE_D_RECLEN
+	printf(" d_reclen: 0x%x", dirent->d_reclen);
+#endif
+#ifdef _DIRENT_HAVE_D_TYPE
+	printf(" d_type: %s", d_type_str(dirent->d_type));
+#endif
+	printf(" d_name: %s\n", dirent->d_name);
+}
+
+static int
+read_directory(
+	DIR *dir,
+	long long offset,
+	unsigned long long length,
+	int dump,
+	unsigned long long *total)
+{
+	struct dirent *dirent;
+	int count = 0;
+
+	seekdir(dir, offset);
+
+	*total = 0;
+	while (*total < length) {
+		dirent = readdir(dir);
+		if (!dirent)
+			break;
+
+		*total += dirent->d_reclen;
+		count++;
+
+		if (dump) {
+			dump_dirent(offset, dirent);
+			offset = dirent->d_off;
+		}
+	}
+
+	return count;
+}
+
+static int
+readdir_f(
+	int argc,
+	char **argv)
+{
+	int cnt;
+	unsigned long long total;
+	int c;
+	size_t fsblocksize, fssectsize;
+	struct timeval t1, t2;
+	char s1[64], s2[64], ts[64];
+	long long offset = -1;
+	unsigned long long length = -1;		/* max length limit */
+	int verbose = 0;
+	DIR *dir;
+
+	init_cvtnum(&fsblocksize, &fssectsize);
+
+	while ((c = getopt(argc, argv, "l:o:v")) != EOF) {
+		switch (c) {
+		case 'l':
+			length = cvtnum(fsblocksize, fssectsize, optarg);
+			break;
+		case 'o':
+			offset = cvtnum(fsblocksize, fssectsize, optarg);
+			break;
+		case 'v':
+			verbose = 1;
+			break;
+		default:
+			return command_usage(&readdir_cmd);
+		}
+	}
+
+	dir = fdopendir(file->fd);
+	if (!dir)
+		return -1;
+
+	if (offset == -1) {
+		rewinddir(dir);
+		offset = telldir(dir);
+	}
+
+	gettimeofday(&t1, NULL);
+	cnt = read_directory(dir, offset, length, verbose, &total);
+	gettimeofday(&t2, NULL);
+
+	t2 = tsub(t2, t1);
+	timestr(&t2, ts, sizeof(ts), 0);
+
+	cvtstr(total, s1, sizeof(s1));
+	cvtstr(tdiv(total, t2), s2, sizeof(s2));
+
+	printf(_("read %llu bytes from offset %lld\n"), total, offset);
+	printf(_("%s, %d ops, %s (%s/sec and %.4f ops/sec)\n"),
+		s1, cnt, ts, s2, tdiv(cnt, t2));
+
+	return 0;
+}
+
+void
+readdir_init(void)
+{
+	readdir_cmd.name = "readdir";
+	readdir_cmd.cfunc = readdir_f;
+	readdir_cmd.argmax = 5;
+	readdir_cmd.flags = CMD_NOMAP_OK|CMD_FOREIGN_OK;
+	readdir_cmd.args = _("[-v][-o offset][-l length]");
+	readdir_cmd.oneline = _("read directory entries");
+
+	add_command(&readdir_cmd);
+}
diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4
index f489f52..8267ba0 100644
--- a/m4/package_libcdev.m4
+++ b/m4/package_libcdev.m4
@@ -170,3 +170,18 @@ AC_DEFUN([AC_HAVE_SYNC_FILE_RANGE],
     AC_SUBST(have_sync_file_range)
   ])
 
+#
+# Check if we have a readdir libc call
+#
+AC_DEFUN([AC_HAVE_READDIR],
+  [ AC_MSG_CHECKING([for readdir])
+    AC_TRY_LINK([
+#include <dirent.h>
+    ], [
+         readdir(0);
+    ], have_readdir=yes
+       AC_MSG_RESULT(yes),
+       AC_MSG_RESULT(no))
+    AC_SUBST(have_readdir)
+  ])
+
-- 
1.8.1.4

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] xfsprogs/io: add readdir command
  2013-07-24 12:44 [PATCH v2] xfsprogs/io: add readdir command Brian Foster
@ 2013-08-08 14:05 ` Mark Tinguely
  2013-08-08 17:38   ` Brian Foster
  2013-08-08 20:39   ` Eric Sandeen
  0 siblings, 2 replies; 5+ messages in thread
From: Mark Tinguely @ 2013-08-08 14:05 UTC (permalink / raw)
  To: Brian Foster; +Cc: xfs

On 07/24/13 07:44, Brian Foster wrote:
> readdir reads the directory entries from an open directory from
> the provided offset (or 0 if not specified). On completion,
> readdir prints summary information regarding the number of
> operations and bytes transferred. Options are available to specify
> the starting offset, length and verbose mode to dump directory
> entry information.
>
> Signed-off-by: Brian Foster<bfoster@redhat.com>
> ---
>
> v2:
> - Convert from getdents to readdir.
> - Use configure mechanism for libc readdir() availability (zab).
> - Add extra dirent fields to verbose output (zab).
>

Just started to look at this.

Shouldn't there be a "closedir(dir);" to close the directory stream and 
release the directory structure?

Could we get a little info for the xfs_io man page?

Looks like a nice feature.

Thanks.

--Mark.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] xfsprogs/io: add readdir command
  2013-08-08 14:05 ` Mark Tinguely
@ 2013-08-08 17:38   ` Brian Foster
  2013-08-08 18:36     ` Mark Tinguely
  2013-08-08 20:39   ` Eric Sandeen
  1 sibling, 1 reply; 5+ messages in thread
From: Brian Foster @ 2013-08-08 17:38 UTC (permalink / raw)
  To: Mark Tinguely; +Cc: xfs

On 08/08/2013 10:05 AM, Mark Tinguely wrote:
> On 07/24/13 07:44, Brian Foster wrote:
>> readdir reads the directory entries from an open directory from
>> the provided offset (or 0 if not specified). On completion,
>> readdir prints summary information regarding the number of
>> operations and bytes transferred. Options are available to specify
>> the starting offset, length and verbose mode to dump directory
>> entry information.
>>
>> Signed-off-by: Brian Foster<bfoster@redhat.com>
>> ---
>>
>> v2:
>> - Convert from getdents to readdir.
>> - Use configure mechanism for libc readdir() availability (zab).
>> - Add extra dirent fields to verbose output (zab).
>>
> 
> Just started to look at this.
> 

Hi Mark,

Thanks for looking at this...

> Shouldn't there be a "closedir(dir);" to close the directory stream and
> release the directory structure?
> 

According to the man page, closedir() would also close the fd. I gave it
a quick test to be sure and I end up with behavior like this:

xfs_io> open /export/test
xfs_io> readdir
[00000000 [00000004 [00000006 [00000009 [00000200 read 104 bytes from
offset 0
104.000000 bytes, 4 ops, 0.0000 sec (5.220 MiB/sec and 210526.3158 ops/sec)
xfs_io> close
close: Bad file descriptor

That said, I'm not sure what the ramifications of repeated readdir
commands might be (i.e., repeated fdopendir() calls on the same fd).
Perhaps the right thing to do here is dup() file->fd prior to
fdopendir() and then add the closedir().

> Could we get a little info for the xfs_io man page?
> 

Ok.

Brian

> Looks like a nice feature.
> 
> Thanks.
> 
> --Mark.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] xfsprogs/io: add readdir command
  2013-08-08 17:38   ` Brian Foster
@ 2013-08-08 18:36     ` Mark Tinguely
  0 siblings, 0 replies; 5+ messages in thread
From: Mark Tinguely @ 2013-08-08 18:36 UTC (permalink / raw)
  To: Brian Foster; +Cc: xfs

On 08/08/13 12:38, Brian Foster wrote:
> On 08/08/2013 10:05 AM, Mark Tinguely wrote:
>> On 07/24/13 07:44, Brian Foster wrote:
>>> readdir reads the directory entries from an open directory from
>>> the provided offset (or 0 if not specified). On completion,
>>> readdir prints summary information regarding the number of
>>> operations and bytes transferred. Options are available to specify
>>> the starting offset, length and verbose mode to dump directory
>>> entry information.
>>>
>>> Signed-off-by: Brian Foster<bfoster@redhat.com>
>>> ---
>>>
>>> v2:
>>> - Convert from getdents to readdir.
>>> - Use configure mechanism for libc readdir() availability (zab).
>>> - Add extra dirent fields to verbose output (zab).
>>>
>>
>> Just started to look at this.
>>
>
> Hi Mark,
>
> Thanks for looking at this...
>
>> Shouldn't there be a "closedir(dir);" to close the directory stream and
>> release the directory structure?
>>
>
> According to the man page, closedir() would also close the fd. I gave it
> a quick test to be sure and I end up with behavior like this:
>
> xfs_io>  open /export/test
> xfs_io>  readdir
> [00000000 [00000004 [00000006 [00000009 [00000200 read 104 bytes from
> offset 0
> 104.000000 bytes, 4 ops, 0.0000 sec (5.220 MiB/sec and 210526.3158 ops/sec)
> xfs_io>  close
> close: Bad file descriptor
>
> That said, I'm not sure what the ramifications of repeated readdir
> commands might be (i.e., repeated fdopendir() calls on the same fd).
> Perhaps the right thing to do here is dup() file->fd prior to
> fdopendir() and then add the closedir().
>
>> Could we get a little info for the xfs_io man page?
>>
>
> Ok.
>
> Brian
>
>> Looks like a nice feature.
>>
>> Thanks.
>>
>> --Mark.
>

I was thinking multiple commands in a xfs_io session.

Thanks for the offset clarification.

--Mark.

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2] xfsprogs/io: add readdir command
  2013-08-08 14:05 ` Mark Tinguely
  2013-08-08 17:38   ` Brian Foster
@ 2013-08-08 20:39   ` Eric Sandeen
  1 sibling, 0 replies; 5+ messages in thread
From: Eric Sandeen @ 2013-08-08 20:39 UTC (permalink / raw)
  To: Mark Tinguely; +Cc: Brian Foster, xfs

On 8/8/13 9:05 AM, Mark Tinguely wrote:

> Could we get a little info for the xfs_io man page?
> 

Yup, otherwise xfs/293 fails :)


# ./check xfs/293
FSTYP         -- xfs (non-debug)
PLATFORM      -- Linux/x86_64 bp-05 3.11.0-rc1+
MKFS_OPTIONS  -- -f -bsize=4096 /dev/sdb2
MOUNT_OPTIONS -- -o context=system_u:object_r:nfs_t:s0 /dev/sdb2 /mnt/scratch

xfs/293 10s ... - output mismatch (see /mnt/test2/git/xfstests/results/xfs/293.out.bad)
    --- tests/xfs/293.out	2013-03-27 12:57:49.318520102 -0500
    +++ /mnt/test2/git/xfstests/results/xfs/293.out.bad	2013-08-08 15:38:30.881221070 -0500
    @@ -1,2 +1,3 @@
     QA output created by 293
     Silence is golden
    +readdir not documented in the xfs_io manpage
     ...
     (Run 'diff -u tests/xfs/293.out /mnt/test2/git/xfstests/results/xfs/293.out.bad' to see the entire diff)
Ran: xfs/293
Failures: xfs/293
Failed 1 of 1 tests


/me pats self on back ;)

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-08-08 20:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-24 12:44 [PATCH v2] xfsprogs/io: add readdir command Brian Foster
2013-08-08 14:05 ` Mark Tinguely
2013-08-08 17:38   ` Brian Foster
2013-08-08 18:36     ` Mark Tinguely
2013-08-08 20:39   ` Eric Sandeen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.