@@ -230,7 +230,7 @@ def walk_extents(self, fsb: int) -> Iterator[tuple[int, int, int, int]]:
230
230
def walk_agi (self ) -> Iterator [c_xfs .xfs_inobt_rec ]:
231
231
yield from self .xfs .walk_agi (self .agi .agi_root , self .num )
232
232
233
- def walk_tree (self , fsb : int , magic : list [int ] | None = None , small : bool = False ):
233
+ def walk_tree (self , fsb : int , magic : list [int ] | None = None , small : bool = False ) -> Iterator [ bytes ] :
234
234
agnum , blknum = fsb_to_bb (fsb , self .sb .sb_agblklog )
235
235
block = agnum * self .xfs .sb .sb_agblocks + blknum
236
236
@@ -248,7 +248,7 @@ def __init__(
248
248
filename : str | None = None ,
249
249
filetype : int | None = None ,
250
250
parent : INode | None = None ,
251
- ):
251
+ ) -> None :
252
252
self .ag = ag
253
253
self .xfs = ag .xfs
254
254
self .inum = inum + (ag .num << ag ._inum_bits )
@@ -325,10 +325,16 @@ def link(self) -> str:
325
325
326
326
if not self ._link :
327
327
if self .inode .di_format != c_xfs .xfs_dinode_fmt .XFS_DINODE_FMT_LOCAL and self .xfs .version == 5 :
328
+ # Almost always, symlinks (max size of 1024) fit within a block. If the block size if 512, we might
329
+ # need three blocks. These three blocks could theoretially be distributed over multiple extents.
330
+ # Linux kernel handles this by using sl_offset to piece the symlink back together.
331
+ # As this edge case of an edge case is very unlikely, it is unsupported until we observe it.
332
+ if len (self .dataruns ()) > 1 :
333
+ raise NotImplementedError (f"{ self !r} has a symlink distributed over multiple extents" )
334
+
328
335
# We do not use open because for non-resident symlinks self.size does not include the symlink header
329
- runs = self .dataruns ()
330
- symlink_size = c_xfs .xfs_dsymlink_hdr .size + self .size
331
- fh = RunlistStream (self .xfs .fh , runs , symlink_size , self .xfs .block_size )
336
+ symlink_size = len (c_xfs .xfs_dsymlink_hdr ) + self .size
337
+ fh = RunlistStream (self .xfs .fh , self .dataruns (), symlink_size , self .xfs .block_size )
332
338
333
339
header = c_xfs .xfs_dsymlink_hdr (fh )
334
340
if header .sl_magic != c_xfs .XFS_SYMLINK_MAGIC :
0 commit comments