func libfuse_readdir()

in component/libfuse/libfuse_handler.go [503:572]


func libfuse_readdir(_ *C.char, buf unsafe.Pointer, filler C.fuse_fill_dir_t, off C.off_t, fi *C.fuse_file_info_t, flag C.fuse_readdir_flags_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::libfuse_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)
			}
		}

		// TODO: Investigate why this works in fuse2 but not fuse3
		// 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
}