Replaced AppendDirent with WriteDirent.

geesefs-0-30-9
Aaron Jacobs 2015-07-29 10:08:16 +10:00
parent c08043788a
commit 6d01ffa44f
2 changed files with 39 additions and 23 deletions

View File

@ -388,20 +388,24 @@ type ReadDirOp struct {
//
// The output data should consist of a sequence of FUSE directory entries in
// the format generated by fuse_add_direntry (http://goo.gl/qCcHCV), which is
// consumed by parse_dirfile (http://goo.gl/2WUmD2). Use
// fuseutil.AppendDirent to generate this data.
//
// It is okay for the final entry to be truncated if it doesn't fit;
// parse_dirfile copes with this by ignoring the partial record.
// consumed by parse_dirfile (http://goo.gl/2WUmD2). Use fuseutil.WriteDirent
// to generate this data.
//
// Each entry returned exposes a directory offset to the user that may later
// show up in ReadDirRequest.Offset. See notes on that field for more
// information.
Dst []byte
// Set by the file system: the number of bytes read into Dst. It is okay for
// this to be less than len(Dst) if there is less data available. A value of
// zero means that the end of the directory has been reached.
// Set by the file system: the number of bytes read into Dst.
//
// It is okay for this to be less than len(Dst) if there are not enough
// entries available or the final entry would not fit.
//
// Zero means that the end of the directory has been reached. This is
// unambiguous because NAME_MAX (https://goo.gl/ZxzKaE) plus the size of
// fuse_dirent (https://goo.gl/WO8s3F) plus the 8-byte alignment of
// FUSE_DIRENT_ALIGN (http://goo.gl/UziWvH) is less than the read size of
// PAGE_SIZE used by fuse_readdir (cf. https://goo.gl/VajtS2).
BytesRead int
}

View File

@ -35,7 +35,7 @@ const (
)
// A struct representing an entry within a directory file, describing a child.
// See notes on fuseops.ReadDirOp and on AppendDirent for details.
// See notes on fuseops.ReadDirOp and on WriteDirent for details.
type Dirent struct {
// The (opaque) offset within the directory file of the entry following this
// one. See notes on fuseops.ReadDirOp.Offset for details.
@ -50,10 +50,11 @@ type Dirent struct {
Type DirentType
}
// Append the supplied directory entry to the given buffer in the format
// expected in fuseops.ReadFileOp.Data, returning the resulting buffer.
func AppendDirent(input []byte, d Dirent) (output []byte) {
// We want to append bytes with the layout of fuse_dirent
// Write the supplied directory entry intto the given buffer in the format
// expected in fuseops.ReadFileOp.Data, returning the number of bytes written.
// Return zero if the entry would not fit.
func WriteDirent(buf []byte, d Dirent) (n int) {
// We want to write bytes with the layout of fuse_dirent
// (http://goo.gl/BmFxob) in host order. The struct must be aligned according
// to FUSE_DIRENT_ALIGN (http://goo.gl/UziWvH), which dictates 8-byte
// alignment.
@ -65,10 +66,23 @@ func AppendDirent(input []byte, d Dirent) (output []byte) {
name [0]byte
}
const alignment = 8
const nameOffset = 8 + 8 + 4 + 4
const direntAlignment = 8
const direntSize = 8 + 8 + 4 + 4
// Write the header into the buffer.
// Compute the number of bytes of padding we'll need to maintain alignment
// for the next entry.
var padLen int
if len(d.Name)%direntAlignment != 0 {
padLen = direntAlignment - (len(d.Name) % direntAlignment)
}
// Do we have enough room?
totalLen := direntSize + len(d.Name) + padLen
if totalLen > len(buf) {
return
}
// Write the header.
de := fuse_dirent{
ino: uint64(d.Inode),
off: uint64(d.Offset),
@ -76,17 +90,15 @@ func AppendDirent(input []byte, d Dirent) (output []byte) {
type_: uint32(d.Type),
}
output = append(input, (*[nameOffset]byte)(unsafe.Pointer(&de))[:]...)
n += copy(buf[n:], (*[direntSize]byte)(unsafe.Pointer(&de))[:])
// Write the name afterward.
output = append(output, d.Name...)
n += copy(buf[n:], d.Name)
// Add any necessary padding.
if len(d.Name)%alignment != 0 {
padLen := alignment - (len(d.Name) % alignment)
var padding [alignment]byte
output = append(output, padding[:padLen]...)
if padLen != 0 {
var padding [direntAlignment]byte
n += copy(buf, padding[:padLen])
}
return