juicedata/juicefs · error
set total inodes: %s
Error message
set total inodes: %s
What it means
doSyncVolumeStat recomputes the volume-wide inode count by scanning the inode keyspace and then persists the result into the Redis key `totalInodes` (m.totalInodesKey()). This error wraps a Redis SET failure on that write, so the reported inode total in the volume stats was not saved even though the scan succeeded. It is a Redis-side write failure (connection, cluster, read-only replica, memory, or encoding problem), not a metadata inconsistency.
Source
Thrown at pkg/meta/redis.go:852
func (m *redisMeta) updateStats(space int64, inodes int64) {
atomic.AddInt64(&m.usedSpace, space)
atomic.AddInt64(&m.usedInodes, inodes)
}
func (m *redisMeta) doSyncVolumeStat(ctx Context, used, inodes int64) error {
if m.conf.ReadOnly {
return syscall.EROFS
}
if err := m.doScanSustainedInodes(ctx, func(uid, gid uint32, length uint64) error {
used += align4K(length)
inodes++
return nil
}); err != nil {
return err
}
logger.Debugf("Used space: %s, inodes: %d", humanize.IBytes(uint64(used)), inodes)
if err := m.rdb.Set(ctx, m.totalInodesKey(), strconv.FormatInt(inodes, 10), 0).Err(); err != nil {
return fmt.Errorf("set total inodes: %s", err)
}
return m.rdb.Set(ctx, m.usedSpaceKey(), strconv.FormatInt(used, 10), 0).Err()
}
func (m *redisMeta) doScanSustainedInodes(ctx Context, fn func(uid, gid uint32, length uint64) error) error {
var inoKeys []string
if err := m.scan(ctx, "session[0-9]*", func(keys []string) error {
for i := 0; i < len(keys); i += 1 {
key := keys[i]
inodes, err := m.rdb.SMembers(ctx, key).Result()
if err != nil {
logger.Warnf("SMembers %s: %s", key, err)
continue
}
for _, sinode := range inodes {
ino, err := strconv.ParseInt(sinode, 10, 64)
if err != nil {
logger.Warnf("invalid sustained: %s->%s", key, sinode)View on GitHub (pinned to c9a67b23e8)
Solutions
- Check Redis connectivity and health (redis-cli ping, INFO replication) and ensure the client points at a writable master, not a read-only replica.
- Inspect the wrapped error text after 'set total inodes:' — it contains the exact Redis error (OOM, READONLY, MOVED) and fix that root cause.
- If maxmemory/OOM, raise maxmemory or free memory in Redis.
- Retry the sync operation; the stat scan is idempotent and will recompute the same value.
Example fix
// before
if err := m.rdb.Set(ctx, m.totalInodesKey(), strconv.FormatInt(inodes, 10), 0).Err(); err != nil {
return fmt.Errorf("set total inodes: %s", err)
}
// after (caller-side retry)
for i := 0; i < 3; i++ {
err := syncStats(ctx) // runs doSyncVolumeStat
if err == nil || !strings.Contains(err.Error(), "set total inodes") {
break
}
time.Sleep(time.Second)
} Defensive patterns
Strategy: retry
Validate before calling
if err := rdb.Ping(ctx).Err(); err != nil { return fmt.Errorf("redis unavailable: %w", err) }
if role, _ := rdb.Info(ctx, "replication").Result(); strings.Contains(role, "role:slave") { return errors.New("target is read-only replica") } Try / catch
err := syncVolumeStat(ctx)
if err != nil && strings.Contains(err.Error(), "set total inodes") {
// retry with backoff; wrapped redis error follows the colon
var rErr error
fmt.Sscanf(err.Error(), "set total inodes: %v", &rErr)
retryWithBackoff(3, time.Second, func() error { return syncVolumeStat(ctx) })
} Prevention
- Monitor Redis health (INFO replication, maxmemory) before running gc/fsck-style jobs
- Always point clients at masters, never read-only replicas
- Use sentinel/cluster-aware client configuration for automatic failover
When it happens
Trigger: Any call path that runs doSyncVolumeStat (e.g. syncing usage stats after `juicefs gc`, stat maintenance, or `fsck`-style operations) where `m.rdb.Set(ctx, m.totalInodesKey(), ...)` returns an error from Redis.
Common situations: Redis connection drop mid-operation; writing to a read-only replica after failover; Redis OOM on maxmemory; cluster MOVED/ASK redirection not handled; Lua/keys command disallowed by ACL.
Related errors
- database %s is used by volume %s
- load setting: %s
- new session: %s
- load user/group quotas: %w
- existing format is broken: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/3f9d67eee1973bc6.
Report an issue: GitHub.