Skip to content

Commit e321aa2

Browse files
MagicalTuxclaude
andcommitted
docs: update README for read/write support
Rewrite introduction and examples to reflect the new writer API including AddFS, programmatic file creation, and all supported inode types. Update features list and add limitations section. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0b4269c commit e321aa2

1 file changed

Lines changed: 62 additions & 50 deletions

File tree

README.md

Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
# squashfs
77

8-
This is a read-only implementation of squashfs initially meant to be use with [go-fuse](https://github.com/hanwen/go-fuse/).
8+
A pure Go implementation of SquashFS, supporting both reading and writing of squashfs filesystem images.
99

10-
Since then, golang added `io/fs` and fuse support was moved to a `fuse` tag, which means this module can be either used with go-fuse, or as a simple `io/fs`-compliant squashfs file reader.
10+
The read path implements Go's `io/fs` interface and optionally supports FUSE via the `fuse` build tag. The write path can create squashfs images from an `fs.FS` or programmatically, with support for all file types (regular files, directories, symlinks, devices, fifos, sockets) and compression formats.
1111

1212
## Tags
1313

@@ -59,7 +59,7 @@ LZMA, LZO and LZ4 are also defined by squashfs and can be enabled similarly.
5959

6060
# Example usage
6161

62-
## Basic file access
62+
## Reading a squashfs image
6363

6464
```go
6565
sqfs, err := squashfs.Open("file.squashfs")
@@ -68,67 +68,71 @@ if err != nil {
6868
}
6969
defer sqfs.Close()
7070

71-
// sqfs can be used as a regular fs.FS
71+
// sqfs implements fs.FS, fs.ReadDirFS, and fs.StatFS
7272
data, err := fs.ReadFile(sqfs, "dir/file.txt")
73-
if err != nil {
74-
return err
75-
}
7673

77-
// Or serve files over HTTP
74+
// Serve files over HTTP
7875
http.Handle("/", http.FileServer(sqfs))
76+
77+
// List directory contents
78+
entries, err := sqfs.ReadDir("some/directory")
79+
80+
// Read a symlink target
81+
target, err := sqfs.Readlink("path/to/symlink")
7982
```
8083

81-
## Reading directories
84+
## Creating a squashfs image from a directory
8285

8386
```go
84-
// List directory contents
85-
entries, err := sqfs.ReadDir("some/directory")
87+
out, err := os.Create("output.squashfs")
88+
if err != nil {
89+
return err
90+
}
91+
defer out.Close()
92+
93+
w, err := squashfs.NewWriter(out)
8694
if err != nil {
8795
return err
8896
}
8997

90-
// Process directory entries
91-
for _, entry := range entries {
92-
fmt.Printf("Name: %s, IsDir: %v\n", entry.Name(), entry.IsDir())
93-
94-
// Get more info if needed
95-
info, err := entry.Info()
96-
if err != nil {
97-
return err
98-
}
99-
fmt.Printf("Size: %d, Mode: %s\n", info.Size(), info.Mode())
98+
// Add all files from an existing directory
99+
if err := w.AddFS(os.DirFS("/path/to/source")); err != nil {
100+
return err
100101
}
102+
103+
return w.Finalize()
101104
```
102105

103-
## Reading symlinks
106+
## Creating a squashfs image programmatically
104107

105108
```go
106-
// Read a symlink target
107-
target, err := sqfs.Readlink("path/to/symlink")
109+
w, err := squashfs.NewWriter(out,
110+
squashfs.WithCompression(squashfs.ZSTD),
111+
squashfs.WithBlockSize(262144),
112+
)
108113
if err != nil {
109114
return err
110115
}
111-
fmt.Printf("Symlink points to: %s\n", target)
112-
```
113116

114-
## Custom compression support
117+
// Regular files
118+
w.AddFile("etc/config.json", configData, 0644)
119+
w.SetOwner("etc/config.json", 0, 0)
115120

116-
```go
117-
// Register XZ support (requires "xz" build tag)
118-
import (
119-
"github.com/KarpelesLab/squashfs"
120-
"github.com/ulikunitz/xz"
121-
)
121+
// Directories
122+
w.AddDirectory("var/log", 0755)
122123

123-
// Register XZ decompressor at init time
124-
func init() {
125-
squashfs.RegisterCompHandler(squashfs.XZ, &squashfs.CompHandler{
126-
Decompress: squashfs.MakeDecompressorErr(xz.NewReader),
127-
})
128-
}
129-
```
124+
// Symlinks
125+
w.AddSymlink("usr/lib64", "lib")
130126

131-
For more examples, see the test files in the project.
127+
// Device nodes
128+
w.AddDevice("dev/null", fs.ModeCharDevice|0666, 1<<8|3)
129+
130+
// Named pipes and sockets
131+
w.AddFifo("run/myapp.pipe", 0600)
132+
w.AddSocket("run/myapp.sock", 0600)
133+
134+
return w.Finalize()
135+
```
132136

133137
# File format
134138

@@ -139,13 +143,16 @@ Some documentation is available online on SquashFS.
139143

140144
# Features
141145

142-
* Read-only implementation of squashfs compatible with Go's `io/fs` interface
143-
* Optional FUSE support with the `fuse` build tag
144-
* Support for GZip compression by default, with XZ and ZSTD available via build tags
145-
* Extensible compression support through the RegisterCompHandler API
146-
* Directory index support for fast access to files in large directories
147-
* Symlink support
148-
* CLI tool for exploring and extracting files from SquashFS archives
146+
* Read and write squashfs filesystem images in pure Go
147+
* Read path implements `fs.FS`, `fs.ReadDirFS`, and `fs.StatFS`
148+
* Write path supports all inode types: regular files, directories, symlinks, block/char devices, fifos, sockets
149+
* Full metadata support: permissions (including setuid/setgid/sticky), uid/gid, timestamps
150+
* GZip compression by default, with ZSTD and XZ available via build tags
151+
* Extensible compression through the `RegisterCompHandler` API
152+
* Optional FUSE support via the `fuse` build tag
153+
* Directory index support for fast lookups in large directories
154+
* Writer output validated against the reference `unsquashfs` implementation
155+
* CLI tool for exploring and extracting files from squashfs archives
149156

150157
# CLI Tool
151158

@@ -185,6 +192,11 @@ To install with additional compression support:
185192
go install -tags "xz zstd" github.com/KarpelesLab/squashfs/cmd/sqfs@latest
186193
```
187194

188-
# Performance
195+
# Limitations
196+
197+
The writer does not currently support:
189198

190-
As of November 2024, directory indexes are now used for efficient file lookup in large directories, significantly improving performance for random file access.
199+
* Fragment tables (tail-end packing of small files)
200+
* NFS export tables
201+
* File deduplication
202+
* Extended attributes (xattrs)

0 commit comments

Comments
 (0)