Changeset View
Changeset View
Standalone View
Standalone View
swh/fuse/fuse.py
# Copyright (C) 2020 The Software Heritage developers | # Copyright (C) 2020 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import asyncio | import asyncio | ||||
import errno | import errno | ||||
import itertools | |||||
import logging | import logging | ||||
import os | import os | ||||
from pathlib import Path | from pathlib import Path | ||||
import time | import time | ||||
from typing import Any, Dict, List | from typing import Any, Dict, List | ||||
import pyfuse3 | import pyfuse3 | ||||
import pyfuse3_asyncio | import pyfuse3_asyncio | ||||
▲ Show 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | async def opendir(self, inode: int, _ctx: pyfuse3.RequestContext) -> int: | ||||
# Re-use inode as directory handle | # Re-use inode as directory handle | ||||
return inode | return inode | ||||
async def readdir(self, fh: int, offset: int, token: pyfuse3.ReaddirToken) -> None: | async def readdir(self, fh: int, offset: int, token: pyfuse3.ReaddirToken) -> None: | ||||
""" Read entries in an open directory """ | """ Read entries in an open directory """ | ||||
# opendir() uses inode as directory handle | # opendir() uses inode as directory handle | ||||
inode = fh | inode = fh | ||||
# TODO: add cache on direntry list? | |||||
direntry = self.inode2entry(inode) | direntry = self.inode2entry(inode) | ||||
assert isinstance(direntry, FuseDirEntry) | assert isinstance(direntry, FuseDirEntry) | ||||
entries = await self.cache.direntry.get(direntry) | |||||
next_id = offset + 1 | next_id = offset + 1 | ||||
i = 0 | |||||
try: | try: | ||||
async for entry in direntry: | for entry in itertools.islice(entries, offset, None): | ||||
if i < offset: | |||||
i += 1 | |||||
continue | |||||
name = os.fsencode(entry.name) | name = os.fsencode(entry.name) | ||||
attrs = await self.get_attrs(entry) | attrs = await self.get_attrs(entry) | ||||
if not pyfuse3.readdir_reply(token, name, attrs, next_id): | if not pyfuse3.readdir_reply(token, name, attrs, next_id): | ||||
break | break | ||||
next_id += 1 | next_id += 1 | ||||
self._inode2entry[attrs.st_ino] = entry | self._inode2entry[attrs.st_ino] = entry | ||||
except Exception as err: | except Exception as err: | ||||
▲ Show 20 Lines • Show All 79 Lines • Show Last 20 Lines |