Ticket #42 (closed bug: fixed)

Opened 4 weeks ago

Last modified 4 days ago

duplicate ls entries in dir with 75,000 files

Reported by: carns Assigned to: carns
Priority: major Component: kmod
Version: HEAD Keywords: ls duplicate entries
Cc:

Description

Problem shows up in /bin/ls, but not pvfs2-ls:

$ mkdir /mnt/pvfs2/testdir
$ for i in `seq 1 75000`; do touch /mnt/pvfs2/testdir/$i; done
$ /bin/ls /mnt/pvfs2/testdir |wc
  206071  206071 1224251
$ ./pvfs2-ls /mnt/pvfs2/testdir |wc
  75000   75000  438894

The first few lines if /bin/ls output show this:

1
10
100
1000
10000
10000
10000
10001
10001
10001
...

Change History

04/23/08 10:40:52 changed by carns

Problem first occurs somewhere between 60,000 and 70,000 files.

05/14/08 08:45:24 changed by carns

  • owner changed from slang to carns.

05/14/08 08:45:30 changed by carns

  • status changed from new to assigned.

05/14/08 09:36:58 changed by carns

The problem occurs specifically when entry number 65537 (64*1024 + 1) is added to the directory. If only 65536 entries are present, then the ls works correctly.

05/14/08 11:09:04 changed by carns

Noting possible performance bug to come back to later:

On the client side, the directory is being read until 0 entries are returned. This means that the last two readdir requests are for (num_entries % 32) and (0) respectively. In the former, however, the token in the kernel is not set to READDIR_END. It is instead set to (num_entries). The request therfore goes all the way to the server and generates a pcache miss. The dbpf_keyval_iterate_step_to_position() function is therefore forced to do a db cursor iteration through the entire directory to discover that there are no more entries.

If we set the token in that next to last readdir call to READDIR_END, this call would be short circuited on the client side (no server request needed) and avoid manually iterating through the berkeley db.

05/14/08 11:12:42 changed by carns

As far as correctness problem goes, added log messages to the dbpf_keyval_iterate_step_to_position() call and compared when it is triggered (at end of directory, see previous comment) on a 33 entry directory and a 65537 entry directory. In the former case, it is called with pos set to 33 (as expected). In the latter case, it is first called with pos set to 1 and then later with pos set to 0, which means it is essentially starting over in the directory twice. Need to figure out where this position is getting truncated (it should have been 65537). It was correct at the point of pcache lookup, which includes a session number (4295032833).

05/14/08 12:02:36 changed by carns

Bug fix to correctness problem in cvs; the wrong bitmask was being use to strip the readdir session number out of the token. The bitmask was only allowing positions up to 64K.

05/14/08 12:23:20 changed by carns

Committed performance fix to trunk to skip last readdir operation generated by ls after hitting the end of the directory.

05/14/08 14:04:22 changed by carns

  • status changed from assigned to closed.
  • resolution set to fixed.