Skip to content

Commit b26d87b

Browse files
MagicalTuxclaude
andcommitted
feat: add fragment table, file dedup, xattrs, and CloneInode
Fragment table: file tails smaller than blockSize are packed into shared fragment blocks, significantly reducing image size for many small files. Fragment table written as compressed metadata with indirect pointer table. File deduplication: CloneInode(newPath, existingPath) creates entries that share underlying data for any inode type. AddFS auto-detects hard links via dev+ino on Unix platforms. Cloned files promoted to XFileType. Extended attributes: SetXattr(path, name, value) API for programmatic use. AddFS reads xattrs via XattrFS interface or platform syscalls. Xattr table serialized per squashfs spec with k-v metadata, ID table, and header. Inodes with xattrs auto-promoted to extended types. Also: directory entry type field now uses Basic() for extended types, all extended inode types (XFile, XSymlink, XDev, XFifo, XSocket) serialized in writeInode, XDirType xattrIdx no longer hardcoded. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e321aa2 commit b26d87b

9 files changed

Lines changed: 867 additions & 57 deletions

README.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,4 @@ go install -tags "xz zstd" github.com/KarpelesLab/squashfs/cmd/sqfs@latest
194194

195195
# Limitations
196196

197-
The writer does not currently support:
198-
199-
* Fragment tables (tail-end packing of small files)
200-
* NFS export tables
201-
* File deduplication
202-
* Extended attributes (xattrs)
197+
* NFS export tables are not implemented

hardlink.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package squashfs
2+
3+
// devIno uniquely identifies a file on a device for hard link detection.
4+
type devIno struct {
5+
dev uint64
6+
ino uint64
7+
}

hardlink_other.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//go:build !unix
2+
3+
package squashfs
4+
5+
// getDevIno is a no-op on non-Unix platforms.
6+
func getDevIno(sys any) (devIno, bool) {
7+
return devIno{}, false
8+
}

hardlink_unix.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//go:build unix
2+
3+
package squashfs
4+
5+
import "syscall"
6+
7+
// getDevIno extracts the device and inode numbers from a FileInfo.Sys() value.
8+
func getDevIno(sys any) (devIno, bool) {
9+
if sys == nil {
10+
return devIno{}, false
11+
}
12+
st, ok := sys.(*syscall.Stat_t)
13+
if !ok {
14+
return devIno{}, false
15+
}
16+
return devIno{dev: uint64(st.Dev), ino: uint64(st.Ino)}, true
17+
}

0 commit comments

Comments
 (0)