From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EE5223C3C1B for ; Mon, 13 Apr 2026 12:24:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776083057; cv=none; b=OElTH+9XKomCzOf4sMEMnGLAdGbZdORGWMYyfG9XlUpfzNihX2UuBQxeTYwR9FGIOpKUsprH8j06BR4CeOYwhzKTbjQUIyJEXUveajxwlCg5hHZO1CHnxR+glTmEVtWVE7BADLfECMpN+kJQjkU/osnUDgAhunZf1b0ce9EvcPk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776083057; c=relaxed/simple; bh=eoBWd0CwY2rxkNA7j7plxEIALTZd5Ed5qQyEAxq5t70=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Q6pNcMLMe90AG4pKMxQe/JdiNHX794Vo5LGJ1b8SJG+KaGMZTzYUpivCft6WZgF7AdSdNyqNZ1QC4jr0lmwStCkz18pk+w0bhdeYXAfg+0TXFGy/ARDYWZiUvLNKzGE19kLa0y/kjhpOw7fij0aeKSGIedst/X+G8Su2oDLUg50= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=hackers.camp; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.221.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=hackers.camp Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-43d6fc30460so63185f8f.1 for ; Mon, 13 Apr 2026 05:24:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776083054; x=1776687854; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=omQOYkth1PndWLeQgJXqHU9j0qjA0S/orRkDREdZgpk=; b=DAyz01ERp3XuqLaegjD1cx2vGId3OOPfC88V+ywj9rTSpnFMKC9tTpFsa5WGTtU3m/ pV9LjVjijz8TxbQX/vvPECd0vtdd9F91c2y1rK+jgCEr36BnieGMlcPlV7kH69p7qYjX MIYWkKR+bzpoZkdVfUYWqTTWTLFxDTU4FAzHOkogp9Uj0L7JD1Qga+22aUILes28JpuK bkgLPvV0HZK3svBLQ5ChbH2lXcCX/avDZzAqm8iPpmxRMuf7dcsP7PVFM/6V+DtS0YET renunDty5qkejYkXGF6sojNj5wxqZec2F4uJ4wrqEBPiSkKmiN9m/EpQMoycR8WIx0M1 KG5w== X-Gm-Message-State: AOJu0YyZ8LyeADbOfT+SfCr6l+PpUm5hTJw3HBleuTz+HxubuFk/YFtp jkdnC7y/yt8CDRJBsRpqmnCJobYs3e5zFMcEWhwQobbgGC3ZfuswuKOvJPUO2kOxZO8= X-Gm-Gg: AeBDievSsq0M+gE1ktFoNrFbjQVL6N5rMsu3xOy587PZjiLlJq9a4SCR8W9sz2LzV/v Lg9V3mWxK+9gvQzTByQJujv3nApzsKMhXOaIyGUSmZp6VFYZev/2DDGCnBcXHS+dAB6scYHwS+K XYeOSx69gi6IwC0nw3tly+SZKoXKX1pc01AqPqAfmzfVb6JIcIHArn7fJ9zfzNTLBJpZTGsUyyJ B5uyLtYClJNaZfgXcssYbQCEVPSDXJ7iuP0XBdXcZNnmB5FyaWwa0vBsYNbf1rH5HvYYWaHlQEA mHM7dHuxlNmXnV6qvahp/5vZRwS7Q5oVPqyA+a0tw7xWjrGdXdm9pmOFjjZa0ne/ay23rEj72n6 t0S09fuQm295K2IZKrAPNBPW2cSjI78F98EfV2RppnJCxS9icZqEwD874VOOJO2fd0LPNh+CmMv 0tdlWvStURZu6uCEHmmYp5K6QsouOfWeXgqcDKiB8Rh5nP2GfbACbxehai1jXME7+EGg== X-Received: by 2002:a05:600c:5487:b0:486:b967:5c9b with SMTP id 5b1f17b1804b1-488d6833355mr91538435e9.3.1776083054261; Mon, 13 Apr 2026 05:24:14 -0700 (PDT) Received: from spartian-1.home ([2a01:cb1c:784:2f00:708:2805:7128:7a75]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-488d532ed4dsm278260915e9.4.2026.04.13.05.24.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Apr 2026 05:24:13 -0700 (PDT) From: Aurelien DESBRIERES To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, brauner@kernel.org, aurelien@hackers.camp Subject: [RFC PATCH 01/10] ftrfs: add on-disk format and in-memory data structures Date: Mon, 13 Apr 2026 16:23:47 +0200 Message-ID: <20260413142357.515792-2-aurelien@hackers.camp> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260413142357.515792-1-aurelien@hackers.camp> References: <20260413142357.515792-1-aurelien@hackers.camp> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Aurélien DESBRIERES Add the core header defining FTRFS on-disk layout and in-memory VFS structures. On-disk layout: Block 0 : superblock (magic 0x46545246, CRC32-protected) Block 1..N : inode table (128 bytes/inode, CRC32 per inode) Block N+1..end : data blocks (CRC32 per block, RS FEC planned) Structures: ftrfs_super_block : on-disk superblock ftrfs_inode : on-disk inode (12 direct + 1 indirect + 1 dindirect) ftrfs_dir_entry : on-disk directory entry (256-byte name) ftrfs_sb_info : in-memory superblock info (VFS sb->s_fs_info) ftrfs_inode_info : in-memory inode (embedded VFS inode) FTRFS targets POSIX-compatible block devices (MRAM, NOR flash, eMMC) for use in radiation-intensive environments (space applications). Signed-off-by: Aurélien DESBRIERES --- fs/ftrfs/ftrfs.h | 168 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 fs/ftrfs/ftrfs.h diff --git a/fs/ftrfs/ftrfs.h b/fs/ftrfs/ftrfs.h new file mode 100644 index 000000000..82502c9fb --- /dev/null +++ b/fs/ftrfs/ftrfs.h @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * FTRFS — Fault-Tolerant Radiation-Robust Filesystem + * Based on: Fuchs, Langer, Trinitis — ARCS 2015 + * + * Author: roastercode - Aurelien DESBRIERES + */ + +#ifndef _FTRFS_H +#define _FTRFS_H + +#include +#include +#include + +/* Magic number: 'FTRF' */ +#define FTRFS_MAGIC 0x46545246 + +/* Block size: 4096 bytes */ +#define FTRFS_BLOCK_SIZE 4096 +#define FTRFS_BLOCK_SHIFT 12 + +/* RS FEC: 16 parity bytes per 239-byte subblock (RS(255,239)) */ +#define FTRFS_RS_PARITY 16 +#define FTRFS_SUBBLOCK_DATA 239 +#define FTRFS_SUBBLOCK_TOTAL (FTRFS_SUBBLOCK_DATA + FTRFS_RS_PARITY) + +/* Filesystem limits */ +#define FTRFS_MAX_FILENAME 255 +#define FTRFS_DIRECT_BLOCKS 12 +#define FTRFS_INDIRECT_BLOCKS 1 +#define FTRFS_DINDIRECT_BLOCKS 1 + +/* + * On-disk superblock — block 0 + * Total size: fits in one 4096-byte block + */ +struct ftrfs_super_block { + __le32 s_magic; /* FTRFS_MAGIC */ + __le32 s_block_size; /* Block size in bytes */ + __le64 s_block_count; /* Total blocks */ + __le64 s_free_blocks; /* Free blocks */ + __le64 s_inode_count; /* Total inodes */ + __le64 s_free_inodes; /* Free inodes */ + __le64 s_inode_table_blk; /* Block where inode table starts */ + __le64 s_data_start_blk; /* First data block */ + __le32 s_version; /* Filesystem version */ + __le32 s_flags; /* Flags */ + __le32 s_crc32; /* CRC32 of this superblock */ + __u8 s_uuid[16]; /* UUID */ + __u8 s_label[32]; /* Volume label */ + __u8 s_pad[3948]; /* Padding to 4096 bytes */ +} __packed; + +/* + * On-disk inode + * Size: 128 bytes + */ +struct ftrfs_inode { + __le16 i_mode; /* File mode */ + __le16 i_uid; /* Owner UID */ + __le16 i_gid; /* Owner GID */ + __le16 i_nlink; /* Hard link count */ + __le64 i_size; /* File size in bytes */ + __le64 i_atime; /* Access time (ns) */ + __le64 i_mtime; /* Modification time (ns) */ + __le64 i_ctime; /* Change time (ns) */ + __le32 i_blocks; /* Block count */ + __le32 i_flags; /* Inode flags */ + __le64 i_direct[FTRFS_DIRECT_BLOCKS]; /* Direct block pointers */ + __le64 i_indirect; /* Single indirect */ + __le64 i_dindirect; /* Double indirect */ + __le32 i_crc32; /* CRC32 of inode */ + __u8 i_pad[2]; /* Padding to 128 bytes */ +} __packed; + +/* Inode flags */ +#define FTRFS_INODE_FL_RS_ENABLED 0x0001 /* RS FEC enabled */ +#define FTRFS_INODE_FL_VERIFIED 0x0002 /* Integrity verified */ + +/* + * On-disk directory entry + */ +struct ftrfs_dir_entry { + __le64 d_ino; /* Inode number */ + __le16 d_rec_len; /* Record length */ + __u8 d_name_len; /* Name length */ + __u8 d_file_type; /* File type */ + char d_name[FTRFS_MAX_FILENAME + 1]; /* Filename */ +} __packed; + +/* + * In-memory superblock info (stored in sb->s_fs_info) + */ +struct ftrfs_sb_info { + /* Block allocator */ + unsigned long *s_block_bitmap; /* In-memory free block bitmap */ + unsigned long s_nblocks; /* Number of data blocks */ + unsigned long s_data_start; /* First data block number */ + struct ftrfs_super_block *s_ftrfs_sb; /* On-disk superblock copy */ + struct buffer_head *s_sbh; /* Buffer head for superblock */ + spinlock_t s_lock; /* Superblock lock */ + unsigned long s_free_blocks; + unsigned long s_free_inodes; +}; + +/* + * In-memory inode info (embedded in VFS inode via container_of) + */ +struct ftrfs_inode_info { + __le64 i_direct[FTRFS_DIRECT_BLOCKS]; + __le64 i_indirect; + __le64 i_dindirect; + __u32 i_flags; + struct inode vfs_inode; /* Must be last */ +}; + +static inline struct ftrfs_inode_info *FTRFS_I(struct inode *inode) +{ + return container_of(inode, struct ftrfs_inode_info, vfs_inode); +} + +static inline struct ftrfs_sb_info *FTRFS_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} + +/* Function prototypes */ +/* super.c */ +int ftrfs_fill_super(struct super_block *sb, struct fs_context *fc); + +/* inode.c */ +struct inode *ftrfs_iget(struct super_block *sb, unsigned long ino); +struct inode *ftrfs_new_inode(struct inode *dir, umode_t mode); + +/* dir.c */ +extern const struct file_operations ftrfs_dir_operations; +extern const struct inode_operations ftrfs_dir_inode_operations; + +/* file.c */ +extern const struct file_operations ftrfs_file_operations; +extern const struct inode_operations ftrfs_file_inode_operations; + +/* edac.c */ +__u32 ftrfs_crc32(const void *buf, size_t len); +int ftrfs_rs_encode(uint8_t *data, uint8_t *parity); +int ftrfs_rs_decode(uint8_t *data, uint8_t *parity); + +/* block.c */ + +#endif /* _FTRFS_H */ + +/* + */ + +/* alloc.c */ +int ftrfs_setup_bitmap(struct super_block *sb); +void ftrfs_destroy_bitmap(struct super_block *sb); +u64 ftrfs_alloc_block(struct super_block *sb); +void ftrfs_free_block(struct super_block *sb, u64 block); +u64 ftrfs_alloc_inode_num(struct super_block *sb); + +/* dir.c */ +struct dentry *ftrfs_lookup(struct inode *dir, struct dentry *dentry, + unsigned int flags); + +/* namei.c */ +int ftrfs_write_inode(struct inode *inode, struct writeback_control *wbc); -- 2.52.0