in component/libfuse/libfuse2_handler.go [496:564]
func libfuse2_readdir(_ *C.char, buf unsafe.Pointer, filler C.fuse_fill_dir_t, off C.off_t, fi *C.fuse_file_info_t) C.int {
handle := (*handlemap.Handle)(unsafe.Pointer(uintptr(fi.fh)))
handle.RLock()
val, found := handle.GetValue("cache")
handle.RUnlock()
if !found {
return C.int(C_EIO)
}
off_64 := uint64(off)
cacheInfo := val.(*dirChildCache)
if off_64 == 0 ||
(off_64 >= cacheInfo.eIndex && cacheInfo.token != "") {
attrs, token, err := fuseFS.NextComponent().StreamDir(internal.StreamDirOptions{
Name: handle.Path,
Offset: off_64,
Token: cacheInfo.token,
Count: common.MaxDirListCount,
})
if err != nil {
log.Err("Libfuse::libfuse2_readdir : Path %s, handle: %d, offset %d. Error in retrieval %s", handle.Path, handle.ID, off_64, err.Error())
if os.IsNotExist(err) {
return C.int(C_ENOENT)
} else if os.IsPermission(err) {
return C.int(C_EACCES)
} else {
return C.int(C_EIO)
}
}
if off_64 == 0 {
attrs = append([]*internal.ObjAttr{{Flags: fuseFS.lsFlags, Name: "."}, {Flags: fuseFS.lsFlags, Name: ".."}}, attrs...)
}
cacheInfo.sIndex = off_64
cacheInfo.eIndex = off_64 + uint64(len(attrs))
cacheInfo.length = uint64(len(attrs))
cacheInfo.token = token
cacheInfo.children = cacheInfo.children[:0]
cacheInfo.children = attrs
}
if off_64 >= cacheInfo.eIndex {
// If offset is still beyond the end index limit then we are done iterating
return 0
}
stbuf := C.stat_t{}
idx := C.long(off)
// Populate the stat by calling filler
for segmentIdx := off_64 - cacheInfo.sIndex; segmentIdx < cacheInfo.length; segmentIdx++ {
fuseFS.fillStat(cacheInfo.children[segmentIdx], &stbuf)
name := C.CString(cacheInfo.children[segmentIdx].Name)
if 0 != C.fill_dir_entry(filler, buf, name, &stbuf, idx+1) {
C.free(unsafe.Pointer(name))
break
}
C.free(unsafe.Pointer(name))
idx++
}
return 0
}