Commit 1989e683 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Fix bug with dirent padding.

Add test case with random filename lengths.
parent a9d18e32
...@@ -542,7 +542,6 @@ func (de *DEntryList) AddString(name string, inode uint64, mode uint32) { ...@@ -542,7 +542,6 @@ func (de *DEntryList) AddString(name string, inode uint64, mode uint32) {
func (de *DEntryList) Add(name []byte, inode uint64, mode uint32) { func (de *DEntryList) Add(name []byte, inode uint64, mode uint32) {
de.offset++ de.offset++
dirent := new(Dirent) dirent := new(Dirent)
dirent.Off = de.offset dirent.Off = de.offset
dirent.Ino = inode dirent.Ino = inode
...@@ -553,11 +552,11 @@ func (de *DEntryList) Add(name []byte, inode uint64, mode uint32) { ...@@ -553,11 +552,11 @@ func (de *DEntryList) Add(name []byte, inode uint64, mode uint32) {
if err != nil { if err != nil {
panic("Serialization of Dirent failed") panic("Serialization of Dirent failed")
} }
de.buf.Write([]byte(name)) de.buf.Write(name)
de.buf.WriteByte(0)
n := (len(name) + 1) % 8 // padding padding := 8 - len(name)&7
if n != 0 { if padding < 8 {
de.buf.Write(make([]byte, 8-n)) de.buf.Write(make([]byte, padding))
} }
} }
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"strings" "strings"
"testing" "testing"
"syscall" "syscall"
"rand"
) )
var _ = strings.Join var _ = strings.Join
...@@ -505,18 +506,37 @@ func (self *testCase) testLargeRead() { ...@@ -505,18 +506,37 @@ func (self *testCase) testLargeRead() {
os.Remove(name) os.Remove(name)
} }
func randomLengthString(length int) string {
r := rand.Intn(length)
j := 0
b := make([]byte, r)
for i := 0; i < r; i++ {
j = (j + 1) % 10
b[i] = byte(j) + byte('0')
}
return string(b)
}
func (self *testCase) testLargeDirRead() { func (self *testCase) testLargeDirRead() {
count := 100 created := 100
names := make([]string, count) names := make([]string, created)
subdir := path.Join(self.origDir, "readdirSubdir") subdir := path.Join(self.origDir, "readdirSubdir")
os.Mkdir(subdir, 0700) os.Mkdir(subdir, 0700)
longname := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
for i := 0; i < count; i++ { nameSet := make(map[string]bool)
for i := 0; i < created; i++ {
// Should vary file name length. // Should vary file name length.
name := path.Join(subdir, fmt.Sprintf("file%d", i)) base := fmt.Sprintf("file%d%s", i,
randomLengthString(len(longname)))
name := path.Join(subdir, base)
nameSet[base] = true
f, err := os.Open(name, os.O_WRONLY | os.O_CREATE, 0777) f, err := os.Open(name, os.O_WRONLY | os.O_CREATE, 0777)
if err != nil { if err != nil {
self.tester.Errorf("open write err %v", err) self.tester.Errorf("open write err %v", err)
...@@ -534,6 +554,7 @@ func (self *testCase) testLargeDirRead() { ...@@ -534,6 +554,7 @@ func (self *testCase) testLargeDirRead() {
} }
// Chunked read. // Chunked read.
total := 0 total := 0
readSet := make(map[string] bool)
for { for {
namesRead, err := dir.Readdirnames(20) namesRead, err := dir.Readdirnames(20)
if err != nil { if err != nil {
...@@ -543,13 +564,24 @@ func (self *testCase) testLargeDirRead() { ...@@ -543,13 +564,24 @@ func (self *testCase) testLargeDirRead() {
if len(namesRead) == 0 { if len(namesRead) == 0 {
break break
} }
for _, v := range(namesRead) {
readSet[v] = true
}
total += len(namesRead) total += len(namesRead)
} }
if total != count { if total != created {
self.tester.Errorf("readdir mismatch %v %v", total, count) self.tester.Errorf("readdir mismatch got %v wanted %v", total, created)
}
for k, _ := range(nameSet) {
_, ok := readSet[k]
if !ok {
self.tester.Errorf("Name %v not found", k)
}
} }
dir.Close() dir.Close()
os.RemoveAll(subdir) os.RemoveAll(subdir)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment