All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@kernel.org>
To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: Christian Brauner <christian@brauner.io>, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH] efs: Remove EFS
Date: Thu, 25 Jun 2026 12:42:50 -0700	[thread overview]
Message-ID: <20260625194250.GD6060@frogsfrogsfrogs> (raw)
In-Reply-To: <20260618211822.3599089-1-willy@infradead.org>

On Thu, Jun 18, 2026 at 10:18:19PM +0100, Matthew Wilcox (Oracle) wrote:
> The kernel EFS code has been unmaintained for over twenty years.
> It was superseded on IRIX around thirty years ago.  I haven't seen an
> EFS filesystem in the wild since 1999.  Userspace tools to read EFS
> filesystems exist, such as https://github.com/jkbenaim/efsextract
> 
> There's no benefit to keeping this filesystem in the kernel, and it only
> increases the maintenance burden for tree-wide changes.
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>

Fine with me!  It's a great thing to remove orphaned code when we have
safer alternatives available.

Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> ---
>  MAINTAINERS                    |   5 -
>  fs/Kconfig                     |   1 -
>  fs/Makefile                    |   1 -
>  fs/efs/Kconfig                 |  16 --
>  fs/efs/Makefile                |   8 -
>  fs/efs/dir.c                   | 105 ----------
>  fs/efs/efs.h                   | 144 -------------
>  fs/efs/file.c                  |  57 -----
>  fs/efs/inode.c                 | 315 ----------------------------
>  fs/efs/namei.c                 | 120 -----------
>  fs/efs/super.c                 | 368 ---------------------------------
>  fs/efs/symlink.c               |  50 -----
>  include/linux/efs_vh.h         |  54 -----
>  include/uapi/linux/efs_fs_sb.h |  63 ------
>  14 files changed, 1307 deletions(-)
>  delete mode 100644 fs/efs/Kconfig
>  delete mode 100644 fs/efs/Makefile
>  delete mode 100644 fs/efs/dir.c
>  delete mode 100644 fs/efs/efs.h
>  delete mode 100644 fs/efs/file.c
>  delete mode 100644 fs/efs/inode.c
>  delete mode 100644 fs/efs/namei.c
>  delete mode 100644 fs/efs/super.c
>  delete mode 100644 fs/efs/symlink.c
>  delete mode 100644 include/linux/efs_vh.h
>  delete mode 100644 include/uapi/linux/efs_fs_sb.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 629b22c6c21e..3c74e23921d2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -9427,11 +9427,6 @@ L:	linux-fbdev@vger.kernel.org
>  S:	Maintained
>  F:	drivers/video/fbdev/efifb.c
>  
> -EFS FILESYSTEM
> -S:	Orphan
> -W:	http://aeschi.ch.eu.org/efs/
> -F:	fs/efs/
> -
>  EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
>  L:	netdev@vger.kernel.org
>  S:	Orphan
> diff --git a/fs/Kconfig b/fs/Kconfig
> index 43cb06de297f..8089639db25c 100644
> --- a/fs/Kconfig
> +++ b/fs/Kconfig
> @@ -315,7 +315,6 @@ source "fs/hfs/Kconfig"
>  source "fs/hfsplus/Kconfig"
>  source "fs/befs/Kconfig"
>  source "fs/bfs/Kconfig"
> -source "fs/efs/Kconfig"
>  source "fs/jffs2/Kconfig"
>  # UBIFS File system configuration
>  source "fs/ubifs/Kconfig"
> diff --git a/fs/Makefile b/fs/Makefile
> index ae1b07f9c6a0..3a11a7d87832 100644
> --- a/fs/Makefile
> +++ b/fs/Makefile
> @@ -93,7 +93,6 @@ obj-$(CONFIG_HPFS_FS)		+= hpfs/
>  obj-$(CONFIG_NTFS_FS)		+= ntfs/
>  obj-$(CONFIG_NTFS3_FS)		+= ntfs3/
>  obj-$(CONFIG_UFS_FS)		+= ufs/
> -obj-$(CONFIG_EFS_FS)		+= efs/
>  obj-$(CONFIG_JFFS2_FS)		+= jffs2/
>  obj-$(CONFIG_UBIFS_FS)		+= ubifs/
>  obj-$(CONFIG_AFFS_FS)		+= affs/
> diff --git a/fs/efs/Kconfig b/fs/efs/Kconfig
> deleted file mode 100644
> index 0833e533df9d..000000000000
> --- a/fs/efs/Kconfig
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -config EFS_FS
> -	tristate "EFS file system support (read only)"
> -	depends on BLOCK
> -	select BUFFER_HEAD
> -	help
> -	  EFS is an older file system used for non-ISO9660 CD-ROMs and hard
> -	  disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer
> -	  uses the XFS file system for hard disk partitions however).
> -
> -	  This implementation only offers read-only access. If you don't know
> -	  what all this is about, it's safe to say N. For more information
> -	  about EFS see its home page at <http://aeschi.ch.eu.org/efs/>.
> -
> -	  To compile the EFS file system support as a module, choose M here: the
> -	  module will be called efs.
> diff --git a/fs/efs/Makefile b/fs/efs/Makefile
> deleted file mode 100644
> index 85e5b88f9471..000000000000
> --- a/fs/efs/Makefile
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -# SPDX-License-Identifier: GPL-2.0-only
> -#
> -# Makefile for the linux efs-filesystem routines.
> -#
> -
> -obj-$(CONFIG_EFS_FS) += efs.o
> -
> -efs-objs := super.o inode.o namei.o dir.o file.o symlink.o
> diff --git a/fs/efs/dir.c b/fs/efs/dir.c
> deleted file mode 100644
> index 35ad0092c115..000000000000
> --- a/fs/efs/dir.c
> +++ /dev/null
> @@ -1,105 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * dir.c
> - *
> - * Copyright (c) 1999 Al Smith
> - */
> -
> -#include <linux/buffer_head.h>
> -#include <linux/filelock.h>
> -#include "efs.h"
> -
> -static int efs_readdir(struct file *, struct dir_context *);
> -
> -const struct file_operations efs_dir_operations = {
> -	.llseek		= generic_file_llseek,
> -	.read		= generic_read_dir,
> -	.iterate_shared	= efs_readdir,
> -	.setlease	= generic_setlease,
> -};
> -
> -const struct inode_operations efs_dir_inode_operations = {
> -	.lookup		= efs_lookup,
> -};
> -
> -static int efs_readdir(struct file *file, struct dir_context *ctx)
> -{
> -	struct inode *inode = file_inode(file);
> -	efs_block_t		block;
> -	int			slot;
> -
> -	if (inode->i_size & (EFS_DIRBSIZE-1))
> -		pr_warn("%s(): directory size not a multiple of EFS_DIRBSIZE\n",
> -			__func__);
> -
> -	/* work out where this entry can be found */
> -	block = ctx->pos >> EFS_DIRBSIZE_BITS;
> -
> -	/* each block contains at most 256 slots */
> -	slot  = ctx->pos & 0xff;
> -
> -	/* look at all blocks */
> -	while (block < inode->i_blocks) {
> -		struct efs_dir		*dirblock;
> -		struct buffer_head *bh;
> -
> -		/* read the dir block */
> -		bh = sb_bread(inode->i_sb, efs_bmap(inode, block));
> -
> -		if (!bh) {
> -			pr_err("%s(): failed to read dir block %d\n",
> -			       __func__, block);
> -			break;
> -		}
> -
> -		dirblock = (struct efs_dir *) bh->b_data; 
> -
> -		if (be16_to_cpu(dirblock->magic) != EFS_DIRBLK_MAGIC) {
> -			pr_err("%s(): invalid directory block\n", __func__);
> -			brelse(bh);
> -			break;
> -		}
> -
> -		for (; slot < dirblock->slots; slot++) {
> -			struct efs_dentry *dirslot;
> -			efs_ino_t inodenum;
> -			const char *nameptr;
> -			int namelen;
> -
> -			if (dirblock->space[slot] == 0)
> -				continue;
> -
> -			dirslot  = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot));
> -
> -			inodenum = be32_to_cpu(dirslot->inode);
> -			namelen  = dirslot->namelen;
> -			nameptr  = dirslot->name;
> -			pr_debug("%s(): block %d slot %d/%d: inode %u, name \"%s\", namelen %u\n",
> -				 __func__, block, slot, dirblock->slots-1,
> -				 inodenum, nameptr, namelen);
> -			if (!namelen)
> -				continue;
> -			/* found the next entry */
> -			ctx->pos = (block << EFS_DIRBSIZE_BITS) | slot;
> -
> -			/* sanity check */
> -			if (nameptr - (char *) dirblock + namelen > EFS_DIRBSIZE) {
> -				pr_warn("directory entry %d exceeds directory block\n",
> -					slot);
> -				continue;
> -			}
> -
> -			/* copy filename and data in dirslot */
> -			if (!dir_emit(ctx, nameptr, namelen, inodenum, DT_UNKNOWN)) {
> -				brelse(bh);
> -				return 0;
> -			}
> -		}
> -		brelse(bh);
> -
> -		slot = 0;
> -		block++;
> -	}
> -	ctx->pos = (block << EFS_DIRBSIZE_BITS) | slot;
> -	return 0;
> -}
> diff --git a/fs/efs/efs.h b/fs/efs/efs.h
> deleted file mode 100644
> index 918d2b9abb76..000000000000
> --- a/fs/efs/efs.h
> +++ /dev/null
> @@ -1,144 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * Copyright (c) 1999 Al Smith, <Al.Smith@aeschi.ch.eu.org>
> - *
> - * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
> - * Portions derived from IRIX header files (c) 1988 Silicon Graphics
> - */
> -#ifndef _EFS_EFS_H_
> -#define _EFS_EFS_H_
> -
> -#ifdef pr_fmt
> -#undef pr_fmt
> -#endif
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> -
> -#include <linux/fs.h>
> -#include <linux/uaccess.h>
> -
> -#define EFS_VERSION "1.0a"
> -
> -/* 1 block is 512 bytes */
> -#define	EFS_BLOCKSIZE_BITS	9
> -#define	EFS_BLOCKSIZE		(1 << EFS_BLOCKSIZE_BITS)
> -
> -typedef	int32_t		efs_block_t;
> -typedef uint32_t	efs_ino_t;
> -
> -#define	EFS_DIRECTEXTENTS	12
> -
> -/*
> - * layout of an extent, in memory and on disk. 8 bytes exactly.
> - */
> -typedef union extent_u {
> -	unsigned char raw[8];
> -	struct extent_s {
> -		unsigned int	ex_magic:8;	/* magic # (zero) */
> -		unsigned int	ex_bn:24;	/* basic block */
> -		unsigned int	ex_length:8;	/* numblocks in this extent */
> -		unsigned int	ex_offset:24;	/* logical offset into file */
> -	} cooked;
> -} efs_extent;
> -
> -typedef struct edevs {
> -	__be16		odev;
> -	__be32		ndev;
> -} efs_devs;
> -
> -/*
> - * extent based filesystem inode as it appears on disk.  The efs inode
> - * is exactly 128 bytes long.
> - */
> -struct	efs_dinode {
> -	__be16		di_mode;	/* mode and type of file */
> -	__be16		di_nlink;	/* number of links to file */
> -	__be16		di_uid;		/* owner's user id */
> -	__be16		di_gid;		/* owner's group id */
> -	__be32		di_size;	/* number of bytes in file */
> -	__be32		di_atime;	/* time last accessed */
> -	__be32		di_mtime;	/* time last modified */
> -	__be32		di_ctime;	/* time created */
> -	__be32		di_gen;		/* generation number */
> -	__be16		di_numextents;	/* # of extents */
> -	u_char		di_version;	/* version of inode */
> -	u_char		di_spare;	/* spare - used by AFS */
> -	union di_addr {
> -		efs_extent	di_extents[EFS_DIRECTEXTENTS];
> -		efs_devs	di_dev;	/* device for IFCHR/IFBLK */
> -	} di_u;
> -};
> -
> -/* efs inode storage in memory */
> -struct efs_inode_info {
> -	int		numextents;
> -	int		lastextent;
> -
> -	efs_extent	extents[EFS_DIRECTEXTENTS];
> -	struct inode	vfs_inode;
> -};
> -
> -#include <linux/efs_fs_sb.h>
> -
> -#define EFS_DIRBSIZE_BITS	EFS_BLOCKSIZE_BITS
> -#define EFS_DIRBSIZE		(1 << EFS_DIRBSIZE_BITS)
> -
> -struct efs_dentry {
> -	__be32		inode;
> -	unsigned char	namelen;
> -	char		name[3];
> -};
> -
> -#define EFS_DENTSIZE	(sizeof(struct efs_dentry) - 3 + 1)
> -#define EFS_MAXNAMELEN  ((1 << (sizeof(char) * 8)) - 1)
> -
> -#define EFS_DIRBLK_HEADERSIZE	4
> -#define EFS_DIRBLK_MAGIC	0xbeef	/* moo */
> -
> -struct efs_dir {
> -	__be16	magic;
> -	unsigned char	firstused;
> -	unsigned char	slots;
> -
> -	unsigned char	space[EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE];
> -};
> -
> -#define EFS_MAXENTS \
> -	((EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE) / \
> -	 (EFS_DENTSIZE + sizeof(char)))
> -
> -#define EFS_SLOTAT(dir, slot) EFS_REALOFF((dir)->space[slot])
> -
> -#define EFS_REALOFF(offset) ((offset << 1))
> -
> -
> -static inline struct efs_inode_info *INODE_INFO(struct inode *inode)
> -{
> -	return container_of(inode, struct efs_inode_info, vfs_inode);
> -}
> -
> -static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb)
> -{
> -	return sb->s_fs_info;
> -}
> -
> -struct statfs;
> -struct fid;
> -
> -extern const struct inode_operations efs_dir_inode_operations;
> -extern const struct file_operations efs_dir_operations;
> -extern const struct address_space_operations efs_symlink_aops;
> -
> -extern struct inode *efs_iget(struct super_block *, unsigned long);
> -extern efs_block_t efs_map_block(struct inode *, efs_block_t);
> -extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
> -
> -extern struct dentry *efs_lookup(struct inode *, struct dentry *, unsigned int);
> -extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
> -		int fh_len, int fh_type);
> -extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
> -		int fh_len, int fh_type);
> -extern struct dentry *efs_get_parent(struct dentry *);
> -extern int efs_bmap(struct inode *, int);
> -
> -#endif /* _EFS_EFS_H_ */
> diff --git a/fs/efs/file.c b/fs/efs/file.c
> deleted file mode 100644
> index 9e641da6fab2..000000000000
> --- a/fs/efs/file.c
> +++ /dev/null
> @@ -1,57 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * file.c
> - *
> - * Copyright (c) 1999 Al Smith
> - *
> - * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
> - */
> -
> -#include <linux/buffer_head.h>
> -#include "efs.h"
> -
> -int efs_get_block(struct inode *inode, sector_t iblock,
> -		  struct buffer_head *bh_result, int create)
> -{
> -	int error = -EROFS;
> -	long phys;
> -
> -	if (create)
> -		return error;
> -	if (iblock >= inode->i_blocks) {
> -#ifdef DEBUG
> -		/*
> -		 * i have no idea why this happens as often as it does
> -		 */
> -		pr_warn("%s(): block %d >= %ld (filesize %ld)\n",
> -			__func__, block, inode->i_blocks, inode->i_size);
> -#endif
> -		return 0;
> -	}
> -	phys = efs_map_block(inode, iblock);
> -	if (phys)
> -		map_bh(bh_result, inode->i_sb, phys);
> -	return 0;
> -}
> -
> -int efs_bmap(struct inode *inode, efs_block_t block) {
> -
> -	if (block < 0) {
> -		pr_warn("%s(): block < 0\n", __func__);
> -		return 0;
> -	}
> -
> -	/* are we about to read past the end of a file ? */
> -	if (!(block < inode->i_blocks)) {
> -#ifdef DEBUG
> -		/*
> -		 * i have no idea why this happens as often as it does
> -		 */
> -		pr_warn("%s(): block %d >= %ld (filesize %ld)\n",
> -			__func__, block, inode->i_blocks, inode->i_size);
> -#endif
> -		return 0;
> -	}
> -
> -	return efs_map_block(inode, block);
> -}
> diff --git a/fs/efs/inode.c b/fs/efs/inode.c
> deleted file mode 100644
> index 4b132729e638..000000000000
> --- a/fs/efs/inode.c
> +++ /dev/null
> @@ -1,315 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * inode.c
> - *
> - * Copyright (c) 1999 Al Smith
> - *
> - * Portions derived from work (c) 1995,1996 Christian Vogelgsang,
> - *              and from work (c) 1998 Mike Shaver.
> - */
> -
> -#include <linux/buffer_head.h>
> -#include <linux/module.h>
> -#include <linux/fs.h>
> -#include "efs.h"
> -#include <linux/efs_fs_sb.h>
> -
> -static int efs_read_folio(struct file *file, struct folio *folio)
> -{
> -	return block_read_full_folio(folio, efs_get_block);
> -}
> -
> -static sector_t _efs_bmap(struct address_space *mapping, sector_t block)
> -{
> -	return generic_block_bmap(mapping,block,efs_get_block);
> -}
> -
> -static const struct address_space_operations efs_aops = {
> -	.read_folio = efs_read_folio,
> -	.bmap = _efs_bmap
> -};
> -
> -static inline void extent_copy(efs_extent *src, efs_extent *dst) {
> -	/*
> -	 * this is slightly evil. it doesn't just copy
> -	 * efs_extent from src to dst, it also mangles
> -	 * the bits so that dst ends up in cpu byte-order.
> -	 */
> -
> -	dst->cooked.ex_magic  =  (unsigned int) src->raw[0];
> -	dst->cooked.ex_bn     = ((unsigned int) src->raw[1] << 16) |
> -				((unsigned int) src->raw[2] <<  8) |
> -				((unsigned int) src->raw[3] <<  0);
> -	dst->cooked.ex_length =  (unsigned int) src->raw[4];
> -	dst->cooked.ex_offset = ((unsigned int) src->raw[5] << 16) |
> -				((unsigned int) src->raw[6] <<  8) |
> -				((unsigned int) src->raw[7] <<  0);
> -	return;
> -}
> -
> -struct inode *efs_iget(struct super_block *super, unsigned long ino)
> -{
> -	int i, inode_index;
> -	dev_t device;
> -	u32 rdev;
> -	struct buffer_head *bh;
> -	struct efs_sb_info    *sb = SUPER_INFO(super);
> -	struct efs_inode_info *in;
> -	efs_block_t block, offset;
> -	struct efs_dinode *efs_inode;
> -	struct inode *inode;
> -
> -	inode = iget_locked(super, ino);
> -	if (!inode)
> -		return ERR_PTR(-ENOMEM);
> -	if (!(inode_state_read_once(inode) & I_NEW))
> -		return inode;
> -
> -	in = INODE_INFO(inode);
> -
> -	/*
> -	** EFS layout:
> -	**
> -	** |   cylinder group    |   cylinder group    |   cylinder group ..etc
> -	** |inodes|data          |inodes|data          |inodes|data       ..etc
> -	**
> -	** work out the inode block index, (considering initially that the
> -	** inodes are stored as consecutive blocks). then work out the block
> -	** number of that inode given the above layout, and finally the
> -	** offset of the inode within that block.
> -	*/
> -
> -	inode_index = inode->i_ino /
> -		(EFS_BLOCKSIZE / sizeof(struct efs_dinode));
> -
> -	block = sb->fs_start + sb->first_block + 
> -		(sb->group_size * (inode_index / sb->inode_blocks)) +
> -		(inode_index % sb->inode_blocks);
> -
> -	offset = (inode->i_ino %
> -			(EFS_BLOCKSIZE / sizeof(struct efs_dinode))) *
> -		sizeof(struct efs_dinode);
> -
> -	bh = sb_bread(inode->i_sb, block);
> -	if (!bh) {
> -		pr_warn("%s() failed at block %d\n", __func__, block);
> -		goto read_inode_error;
> -	}
> -
> -	efs_inode = (struct efs_dinode *) (bh->b_data + offset);
> -    
> -	inode->i_mode  = be16_to_cpu(efs_inode->di_mode);
> -	set_nlink(inode, be16_to_cpu(efs_inode->di_nlink));
> -	i_uid_write(inode, (uid_t)be16_to_cpu(efs_inode->di_uid));
> -	i_gid_write(inode, (gid_t)be16_to_cpu(efs_inode->di_gid));
> -	inode->i_size  = be32_to_cpu(efs_inode->di_size);
> -	inode_set_atime(inode, be32_to_cpu(efs_inode->di_atime), 0);
> -	inode_set_mtime(inode, be32_to_cpu(efs_inode->di_mtime), 0);
> -	inode_set_ctime(inode, be32_to_cpu(efs_inode->di_ctime), 0);
> -
> -	/* this is the number of blocks in the file */
> -	if (inode->i_size == 0) {
> -		inode->i_blocks = 0;
> -	} else {
> -		inode->i_blocks = ((inode->i_size - 1) >> EFS_BLOCKSIZE_BITS) + 1;
> -	}
> -
> -	rdev = be16_to_cpu(efs_inode->di_u.di_dev.odev);
> -	if (rdev == 0xffff) {
> -		rdev = be32_to_cpu(efs_inode->di_u.di_dev.ndev);
> -		if (sysv_major(rdev) > 0xfff)
> -			device = 0;
> -		else
> -			device = MKDEV(sysv_major(rdev), sysv_minor(rdev));
> -	} else
> -		device = old_decode_dev(rdev);
> -
> -	/* get the number of extents for this object */
> -	in->numextents = be16_to_cpu(efs_inode->di_numextents);
> -	in->lastextent = 0;
> -
> -	/* copy the extents contained within the inode to memory */
> -	for(i = 0; i < EFS_DIRECTEXTENTS; i++) {
> -		extent_copy(&(efs_inode->di_u.di_extents[i]), &(in->extents[i]));
> -		if (i < in->numextents && in->extents[i].cooked.ex_magic != 0) {
> -			pr_warn("extent %d has bad magic number in inode %llu\n",
> -				i, inode->i_ino);
> -			brelse(bh);
> -			goto read_inode_error;
> -		}
> -	}
> -
> -	brelse(bh);
> -	pr_debug("efs_iget(): inode %llu, extents %d, mode %o\n",
> -		 inode->i_ino, in->numextents, inode->i_mode);
> -	switch (inode->i_mode & S_IFMT) {
> -		case S_IFDIR: 
> -			inode->i_op = &efs_dir_inode_operations; 
> -			inode->i_fop = &efs_dir_operations; 
> -			break;
> -		case S_IFREG:
> -			inode->i_fop = &generic_ro_fops;
> -			inode->i_data.a_ops = &efs_aops;
> -			break;
> -		case S_IFLNK:
> -			inode->i_op = &page_symlink_inode_operations;
> -			inode_nohighmem(inode);
> -			inode->i_data.a_ops = &efs_symlink_aops;
> -			break;
> -		case S_IFCHR:
> -		case S_IFBLK:
> -		case S_IFIFO:
> -			init_special_inode(inode, inode->i_mode, device);
> -			break;
> -		default:
> -			pr_warn("unsupported inode mode %o\n", inode->i_mode);
> -			goto read_inode_error;
> -			break;
> -	}
> -
> -	unlock_new_inode(inode);
> -	return inode;
> -        
> -read_inode_error:
> -	pr_warn("failed to read inode %llu\n", inode->i_ino);
> -	iget_failed(inode);
> -	return ERR_PTR(-EIO);
> -}
> -
> -static inline efs_block_t
> -efs_extent_check(efs_extent *ptr, efs_block_t block, struct efs_sb_info *sb) {
> -	efs_block_t start;
> -	efs_block_t length;
> -	efs_block_t offset;
> -
> -	/*
> -	 * given an extent and a logical block within a file,
> -	 * can this block be found within this extent ?
> -	 */
> -	start  = ptr->cooked.ex_bn;
> -	length = ptr->cooked.ex_length;
> -	offset = ptr->cooked.ex_offset;
> -
> -	if ((block >= offset) && (block < offset+length)) {
> -		return(sb->fs_start + start + block - offset);
> -	} else {
> -		return 0;
> -	}
> -}
> -
> -efs_block_t efs_map_block(struct inode *inode, efs_block_t block) {
> -	struct efs_sb_info    *sb = SUPER_INFO(inode->i_sb);
> -	struct efs_inode_info *in = INODE_INFO(inode);
> -	struct buffer_head    *bh = NULL;
> -
> -	int cur, last, first = 1;
> -	int ibase, ioffset, dirext, direxts, indext, indexts;
> -	efs_block_t iblock, result = 0, lastblock = 0;
> -	efs_extent ext, *exts;
> -
> -	last = in->lastextent;
> -
> -	if (in->numextents <= EFS_DIRECTEXTENTS) {
> -		/* first check the last extent we returned */
> -		if ((result = efs_extent_check(&in->extents[last], block, sb)))
> -			return result;
> -    
> -		/* if we only have one extent then nothing can be found */
> -		if (in->numextents == 1) {
> -			pr_err("%s() failed to map (1 extent)\n", __func__);
> -			return 0;
> -		}
> -
> -		direxts = in->numextents;
> -
> -		/*
> -		 * check the stored extents in the inode
> -		 * start with next extent and check forwards
> -		 */
> -		for(dirext = 1; dirext < direxts; dirext++) {
> -			cur = (last + dirext) % in->numextents;
> -			if ((result = efs_extent_check(&in->extents[cur], block, sb))) {
> -				in->lastextent = cur;
> -				return result;
> -			}
> -		}
> -
> -		pr_err("%s() failed to map block %u (dir)\n", __func__, block);
> -		return 0;
> -	}
> -
> -	pr_debug("%s(): indirect search for logical block %u\n",
> -		 __func__, block);
> -	direxts = in->extents[0].cooked.ex_offset;
> -	indexts = in->numextents;
> -
> -	for(indext = 0; indext < indexts; indext++) {
> -		cur = (last + indext) % indexts;
> -
> -		/*
> -		 * work out which direct extent contains `cur'.
> -		 *
> -		 * also compute ibase: i.e. the number of the first
> -		 * indirect extent contained within direct extent `cur'.
> -		 *
> -		 */
> -		ibase = 0;
> -		for(dirext = 0; cur < ibase && dirext < direxts; dirext++) {
> -			ibase += in->extents[dirext].cooked.ex_length *
> -				(EFS_BLOCKSIZE / sizeof(efs_extent));
> -		}
> -
> -		if (dirext == direxts) {
> -			/* should never happen */
> -			pr_err("couldn't find direct extent for indirect extent %d (block %u)\n",
> -			       cur, block);
> -			if (bh) brelse(bh);
> -			return 0;
> -		}
> -		
> -		/* work out block number and offset of this indirect extent */
> -		iblock = sb->fs_start + in->extents[dirext].cooked.ex_bn +
> -			(cur - ibase) /
> -			(EFS_BLOCKSIZE / sizeof(efs_extent));
> -		ioffset = (cur - ibase) %
> -			(EFS_BLOCKSIZE / sizeof(efs_extent));
> -
> -		if (first || lastblock != iblock) {
> -			if (bh) brelse(bh);
> -
> -			bh = sb_bread(inode->i_sb, iblock);
> -			if (!bh) {
> -				pr_err("%s() failed at block %d\n",
> -				       __func__, iblock);
> -				return 0;
> -			}
> -			pr_debug("%s(): read indirect extent block %d\n",
> -				 __func__, iblock);
> -			first = 0;
> -			lastblock = iblock;
> -		}
> -
> -		exts = (efs_extent *) bh->b_data;
> -
> -		extent_copy(&(exts[ioffset]), &ext);
> -
> -		if (ext.cooked.ex_magic != 0) {
> -			pr_err("extent %d has bad magic number in block %d\n",
> -			       cur, iblock);
> -			if (bh) brelse(bh);
> -			return 0;
> -		}
> -
> -		if ((result = efs_extent_check(&ext, block, sb))) {
> -			if (bh) brelse(bh);
> -			in->lastextent = cur;
> -			return result;
> -		}
> -	}
> -	if (bh) brelse(bh);
> -	pr_err("%s() failed to map block %u (indir)\n", __func__, block);
> -	return 0;
> -}  
> -
> -MODULE_DESCRIPTION("Extent File System (efs)");
> -MODULE_LICENSE("GPL");
> diff --git a/fs/efs/namei.c b/fs/efs/namei.c
> deleted file mode 100644
> index 38961ee1d1af..000000000000
> --- a/fs/efs/namei.c
> +++ /dev/null
> @@ -1,120 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * namei.c
> - *
> - * Copyright (c) 1999 Al Smith
> - *
> - * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
> - */
> -
> -#include <linux/buffer_head.h>
> -#include <linux/string.h>
> -#include <linux/exportfs.h>
> -#include "efs.h"
> -
> -
> -static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len)
> -{
> -	struct buffer_head *bh;
> -
> -	int			slot, namelen;
> -	char			*nameptr;
> -	struct efs_dir		*dirblock;
> -	struct efs_dentry	*dirslot;
> -	efs_ino_t		inodenum;
> -	efs_block_t		block;
> - 
> -	if (inode->i_size & (EFS_DIRBSIZE-1))
> -		pr_warn("%s(): directory size not a multiple of EFS_DIRBSIZE\n",
> -			__func__);
> -
> -	for(block = 0; block < inode->i_blocks; block++) {
> -
> -		bh = sb_bread(inode->i_sb, efs_bmap(inode, block));
> -		if (!bh) {
> -			pr_err("%s(): failed to read dir block %d\n",
> -			       __func__, block);
> -			return 0;
> -		}
> -    
> -		dirblock = (struct efs_dir *) bh->b_data;
> -
> -		if (be16_to_cpu(dirblock->magic) != EFS_DIRBLK_MAGIC) {
> -			pr_err("%s(): invalid directory block\n", __func__);
> -			brelse(bh);
> -			return 0;
> -		}
> -
> -		for (slot = 0; slot < dirblock->slots; slot++) {
> -			dirslot  = (struct efs_dentry *) (((char *) bh->b_data) + EFS_SLOTAT(dirblock, slot));
> -
> -			namelen  = dirslot->namelen;
> -			nameptr  = dirslot->name;
> -
> -			if ((namelen == len) && (!memcmp(name, nameptr, len))) {
> -				inodenum = be32_to_cpu(dirslot->inode);
> -				brelse(bh);
> -				return inodenum;
> -			}
> -		}
> -		brelse(bh);
> -	}
> -	return 0;
> -}
> -
> -struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
> -{
> -	efs_ino_t inodenum;
> -	struct inode *inode = NULL;
> -
> -	inodenum = efs_find_entry(dir, dentry->d_name.name, dentry->d_name.len);
> -	if (inodenum)
> -		inode = efs_iget(dir->i_sb, inodenum);
> -
> -	return d_splice_alias(inode, dentry);
> -}
> -
> -static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino,
> -		u32 generation)
> -{
> -	struct inode *inode;
> -
> -	if (ino == 0)
> -		return ERR_PTR(-ESTALE);
> -	inode = efs_iget(sb, ino);
> -	if (IS_ERR(inode))
> -		return ERR_CAST(inode);
> -
> -	if (generation && inode->i_generation != generation) {
> -		iput(inode);
> -		return ERR_PTR(-ESTALE);
> -	}
> -
> -	return inode;
> -}
> -
> -struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
> -		int fh_len, int fh_type)
> -{
> -	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
> -				    efs_nfs_get_inode);
> -}
> -
> -struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
> -		int fh_len, int fh_type)
> -{
> -	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
> -				    efs_nfs_get_inode);
> -}
> -
> -struct dentry *efs_get_parent(struct dentry *child)
> -{
> -	struct dentry *parent = ERR_PTR(-ENOENT);
> -	efs_ino_t ino;
> -
> -	ino = efs_find_entry(d_inode(child), "..", 2);
> -	if (ino)
> -		parent = d_obtain_alias(efs_iget(child->d_sb, ino));
> -
> -	return parent;
> -}
> diff --git a/fs/efs/super.c b/fs/efs/super.c
> deleted file mode 100644
> index 11fea3bbce7c..000000000000
> --- a/fs/efs/super.c
> +++ /dev/null
> @@ -1,368 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * super.c
> - *
> - * Copyright (c) 1999 Al Smith
> - *
> - * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
> - */
> -
> -#include <linux/init.h>
> -#include <linux/module.h>
> -#include <linux/exportfs.h>
> -#include <linux/slab.h>
> -#include <linux/buffer_head.h>
> -#include <linux/vfs.h>
> -#include <linux/blkdev.h>
> -#include <linux/fs_context.h>
> -#include "efs.h"
> -#include <linux/efs_vh.h>
> -#include <linux/efs_fs_sb.h>
> -
> -static int efs_statfs(struct dentry *dentry, struct kstatfs *buf);
> -static int efs_init_fs_context(struct fs_context *fc);
> -
> -static void efs_kill_sb(struct super_block *s)
> -{
> -	struct efs_sb_info *sbi = SUPER_INFO(s);
> -	kill_block_super(s);
> -	kfree(sbi);
> -}
> -
> -static struct pt_types sgi_pt_types[] = {
> -	{0x00,		"SGI vh"},
> -	{0x01,		"SGI trkrepl"},
> -	{0x02,		"SGI secrepl"},
> -	{0x03,		"SGI raw"},
> -	{0x04,		"SGI bsd"},
> -	{SGI_SYSV,	"SGI sysv"},
> -	{0x06,		"SGI vol"},
> -	{SGI_EFS,	"SGI efs"},
> -	{0x08,		"SGI lv"},
> -	{0x09,		"SGI rlv"},
> -	{0x0A,		"SGI xfs"},
> -	{0x0B,		"SGI xfslog"},
> -	{0x0C,		"SGI xlv"},
> -	{0x82,		"Linux swap"},
> -	{0x83,		"Linux native"},
> -	{0,		NULL}
> -};
> -
> -/*
> - * File system definition and registration.
> - */
> -static struct file_system_type efs_fs_type = {
> -	.owner			= THIS_MODULE,
> -	.name			= "efs",
> -	.kill_sb		= efs_kill_sb,
> -	.fs_flags		= FS_REQUIRES_DEV,
> -	.init_fs_context	= efs_init_fs_context,
> -};
> -MODULE_ALIAS_FS("efs");
> -
> -static struct kmem_cache * efs_inode_cachep;
> -
> -static struct inode *efs_alloc_inode(struct super_block *sb)
> -{
> -	struct efs_inode_info *ei;
> -	ei = alloc_inode_sb(sb, efs_inode_cachep, GFP_KERNEL);
> -	if (!ei)
> -		return NULL;
> -	return &ei->vfs_inode;
> -}
> -
> -static void efs_free_inode(struct inode *inode)
> -{
> -	kmem_cache_free(efs_inode_cachep, INODE_INFO(inode));
> -}
> -
> -static void init_once(void *foo)
> -{
> -	struct efs_inode_info *ei = (struct efs_inode_info *) foo;
> -
> -	inode_init_once(&ei->vfs_inode);
> -}
> -
> -static int __init init_inodecache(void)
> -{
> -	efs_inode_cachep = kmem_cache_create("efs_inode_cache",
> -				sizeof(struct efs_inode_info), 0,
> -				SLAB_RECLAIM_ACCOUNT|SLAB_ACCOUNT,
> -				init_once);
> -	if (efs_inode_cachep == NULL)
> -		return -ENOMEM;
> -	return 0;
> -}
> -
> -static void destroy_inodecache(void)
> -{
> -	/*
> -	 * Make sure all delayed rcu free inodes are flushed before we
> -	 * destroy cache.
> -	 */
> -	rcu_barrier();
> -	kmem_cache_destroy(efs_inode_cachep);
> -}
> -
> -static const struct super_operations efs_superblock_operations = {
> -	.alloc_inode	= efs_alloc_inode,
> -	.free_inode	= efs_free_inode,
> -	.statfs		= efs_statfs,
> -};
> -
> -static const struct export_operations efs_export_ops = {
> -	.encode_fh	= generic_encode_ino32_fh,
> -	.fh_to_dentry	= efs_fh_to_dentry,
> -	.fh_to_parent	= efs_fh_to_parent,
> -	.get_parent	= efs_get_parent,
> -};
> -
> -static int __init init_efs_fs(void) {
> -	int err;
> -	pr_info(EFS_VERSION" - http://aeschi.ch.eu.org/efs/\n");
> -	err = init_inodecache();
> -	if (err)
> -		goto out1;
> -	err = register_filesystem(&efs_fs_type);
> -	if (err)
> -		goto out;
> -	return 0;
> -out:
> -	destroy_inodecache();
> -out1:
> -	return err;
> -}
> -
> -static void __exit exit_efs_fs(void) {
> -	unregister_filesystem(&efs_fs_type);
> -	destroy_inodecache();
> -}
> -
> -module_init(init_efs_fs)
> -module_exit(exit_efs_fs)
> -
> -static efs_block_t efs_validate_vh(struct volume_header *vh) {
> -	int		i;
> -	__be32		cs, *ui;
> -	int		csum;
> -	efs_block_t	sblock = 0; /* shuts up gcc */
> -	struct pt_types	*pt_entry;
> -	int		pt_type, slice = -1;
> -
> -	if (be32_to_cpu(vh->vh_magic) != VHMAGIC) {
> -		/*
> -		 * assume that we're dealing with a partition and allow
> -		 * read_super() to try and detect a valid superblock
> -		 * on the next block.
> -		 */
> -		return 0;
> -	}
> -
> -	ui = ((__be32 *) (vh + 1)) - 1;
> -	for(csum = 0; ui >= ((__be32 *) vh);) {
> -		cs = *ui--;
> -		csum += be32_to_cpu(cs);
> -	}
> -	if (csum) {
> -		pr_warn("SGI disklabel: checksum bad, label corrupted\n");
> -		return 0;
> -	}
> -
> -#ifdef DEBUG
> -	pr_debug("bf: \"%16s\"\n", vh->vh_bootfile);
> -
> -	for(i = 0; i < NVDIR; i++) {
> -		int	j;
> -		char	name[VDNAMESIZE+1];
> -
> -		for(j = 0; j < VDNAMESIZE; j++) {
> -			name[j] = vh->vh_vd[i].vd_name[j];
> -		}
> -		name[j] = (char) 0;
> -
> -		if (name[0]) {
> -			pr_debug("vh: %8s block: 0x%08x size: 0x%08x\n",
> -				name, (int) be32_to_cpu(vh->vh_vd[i].vd_lbn),
> -				(int) be32_to_cpu(vh->vh_vd[i].vd_nbytes));
> -		}
> -	}
> -#endif
> -
> -	for(i = 0; i < NPARTAB; i++) {
> -		pt_type = (int) be32_to_cpu(vh->vh_pt[i].pt_type);
> -		for(pt_entry = sgi_pt_types; pt_entry->pt_name; pt_entry++) {
> -			if (pt_type == pt_entry->pt_type) break;
> -		}
> -#ifdef DEBUG
> -		if (be32_to_cpu(vh->vh_pt[i].pt_nblks)) {
> -			pr_debug("pt %2d: start: %08d size: %08d type: 0x%02x (%s)\n",
> -				 i, (int)be32_to_cpu(vh->vh_pt[i].pt_firstlbn),
> -				 (int)be32_to_cpu(vh->vh_pt[i].pt_nblks),
> -				 pt_type, (pt_entry->pt_name) ?
> -				 pt_entry->pt_name : "unknown");
> -		}
> -#endif
> -		if (IS_EFS(pt_type)) {
> -			sblock = be32_to_cpu(vh->vh_pt[i].pt_firstlbn);
> -			slice = i;
> -		}
> -	}
> -
> -	if (slice == -1) {
> -		pr_notice("partition table contained no EFS partitions\n");
> -#ifdef DEBUG
> -	} else {
> -		pr_info("using slice %d (type %s, offset 0x%x)\n", slice,
> -			(pt_entry->pt_name) ? pt_entry->pt_name : "unknown",
> -			sblock);
> -#endif
> -	}
> -	return sblock;
> -}
> -
> -static int efs_validate_super(struct efs_sb_info *sb, struct efs_super *super) {
> -
> -	if (!IS_EFS_MAGIC(be32_to_cpu(super->fs_magic)))
> -		return -1;
> -
> -	sb->fs_magic     = be32_to_cpu(super->fs_magic);
> -	sb->total_blocks = be32_to_cpu(super->fs_size);
> -	sb->first_block  = be32_to_cpu(super->fs_firstcg);
> -	sb->group_size   = be32_to_cpu(super->fs_cgfsize);
> -	sb->data_free    = be32_to_cpu(super->fs_tfree);
> -	sb->inode_free   = be32_to_cpu(super->fs_tinode);
> -	sb->inode_blocks = be16_to_cpu(super->fs_cgisize);
> -	sb->total_groups = be16_to_cpu(super->fs_ncg);
> -    
> -	return 0;    
> -}
> -
> -static int efs_fill_super(struct super_block *s, struct fs_context *fc)
> -{
> -	struct efs_sb_info *sb;
> -	struct buffer_head *bh;
> -	struct inode *root;
> -
> -	sb = kzalloc_obj(struct efs_sb_info);
> -	if (!sb)
> -		return -ENOMEM;
> -	s->s_fs_info = sb;
> -	s->s_time_min = 0;
> -	s->s_time_max = U32_MAX;
> -
> -	s->s_magic		= EFS_SUPER_MAGIC;
> -	if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) {
> -		pr_err("device does not support %d byte blocks\n",
> -			EFS_BLOCKSIZE);
> -		return invalf(fc, "device does not support %d byte blocks\n",
> -			      EFS_BLOCKSIZE);
> -	}
> -
> -	/* read the vh (volume header) block */
> -	bh = sb_bread(s, 0);
> -
> -	if (!bh) {
> -		pr_err("cannot read volume header\n");
> -		return -EIO;
> -	}
> -
> -	/*
> -	 * if this returns zero then we didn't find any partition table.
> -	 * this isn't (yet) an error - just assume for the moment that
> -	 * the device is valid and go on to search for a superblock.
> -	 */
> -	sb->fs_start = efs_validate_vh((struct volume_header *) bh->b_data);
> -	brelse(bh);
> -
> -	if (sb->fs_start == -1) {
> -		return -EINVAL;
> -	}
> -
> -	bh = sb_bread(s, sb->fs_start + EFS_SUPER);
> -	if (!bh) {
> -		pr_err("cannot read superblock\n");
> -		return -EIO;
> -	}
> -
> -	if (efs_validate_super(sb, (struct efs_super *) bh->b_data)) {
> -#ifdef DEBUG
> -		pr_warn("invalid superblock at block %u\n",
> -			sb->fs_start + EFS_SUPER);
> -#endif
> -		brelse(bh);
> -		return -EINVAL;
> -	}
> -	brelse(bh);
> -
> -	if (!sb_rdonly(s)) {
> -#ifdef DEBUG
> -		pr_info("forcing read-only mode\n");
> -#endif
> -		s->s_flags |= SB_RDONLY;
> -	}
> -	s->s_op   = &efs_superblock_operations;
> -	s->s_export_op = &efs_export_ops;
> -	root = efs_iget(s, EFS_ROOTINODE);
> -	if (IS_ERR(root)) {
> -		pr_err("get root inode failed\n");
> -		return PTR_ERR(root);
> -	}
> -
> -	s->s_root = d_make_root(root);
> -	if (!(s->s_root)) {
> -		pr_err("get root dentry failed\n");
> -		return -ENOMEM;
> -	}
> -
> -	return 0;
> -}
> -
> -static int efs_get_tree(struct fs_context *fc)
> -{
> -	return get_tree_bdev(fc, efs_fill_super);
> -}
> -
> -static int efs_reconfigure(struct fs_context *fc)
> -{
> -	sync_filesystem(fc->root->d_sb);
> -	fc->sb_flags |= SB_RDONLY;
> -
> -	return 0;
> -}
> -
> -static const struct fs_context_operations efs_context_opts = {
> -	.get_tree	= efs_get_tree,
> -	.reconfigure	= efs_reconfigure,
> -};
> -
> -/*
> - * Set up the filesystem mount context.
> - */
> -static int efs_init_fs_context(struct fs_context *fc)
> -{
> -	fc->ops = &efs_context_opts;
> -
> -	return 0;
> -}
> -
> -static int efs_statfs(struct dentry *dentry, struct kstatfs *buf) {
> -	struct super_block *sb = dentry->d_sb;
> -	struct efs_sb_info *sbi = SUPER_INFO(sb);
> -	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
> -
> -	buf->f_type    = EFS_SUPER_MAGIC;	/* efs magic number */
> -	buf->f_bsize   = EFS_BLOCKSIZE;		/* blocksize */
> -	buf->f_blocks  = sbi->total_groups *	/* total data blocks */
> -			(sbi->group_size - sbi->inode_blocks);
> -	buf->f_bfree   = sbi->data_free;	/* free data blocks */
> -	buf->f_bavail  = sbi->data_free;	/* free blocks for non-root */
> -	buf->f_files   = sbi->total_groups *	/* total inodes */
> -			sbi->inode_blocks *
> -			(EFS_BLOCKSIZE / sizeof(struct efs_dinode));
> -	buf->f_ffree   = sbi->inode_free;	/* free inodes */
> -	buf->f_fsid    = u64_to_fsid(id);
> -	buf->f_namelen = EFS_MAXNAMELEN;	/* max filename length */
> -
> -	return 0;
> -}
> -
> diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c
> deleted file mode 100644
> index 7749feded722..000000000000
> --- a/fs/efs/symlink.c
> +++ /dev/null
> @@ -1,50 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0
> -/*
> - * symlink.c
> - *
> - * Copyright (c) 1999 Al Smith
> - *
> - * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
> - */
> -
> -#include <linux/string.h>
> -#include <linux/pagemap.h>
> -#include <linux/buffer_head.h>
> -#include "efs.h"
> -
> -static int efs_symlink_read_folio(struct file *file, struct folio *folio)
> -{
> -	char *link = folio_address(folio);
> -	struct buffer_head *bh;
> -	struct inode *inode = folio->mapping->host;
> -	efs_block_t size = inode->i_size;
> -	int err;
> -  
> -	err = -ENAMETOOLONG;
> -	if (size > 2 * EFS_BLOCKSIZE)
> -		goto fail;
> -  
> -	/* read first 512 bytes of link target */
> -	err = -EIO;
> -	bh = sb_bread(inode->i_sb, efs_bmap(inode, 0));
> -	if (!bh)
> -		goto fail;
> -	memcpy(link, bh->b_data, (size > EFS_BLOCKSIZE) ? EFS_BLOCKSIZE : size);
> -	brelse(bh);
> -	if (size > EFS_BLOCKSIZE) {
> -		bh = sb_bread(inode->i_sb, efs_bmap(inode, 1));
> -		if (!bh)
> -			goto fail;
> -		memcpy(link + EFS_BLOCKSIZE, bh->b_data, size - EFS_BLOCKSIZE);
> -		brelse(bh);
> -	}
> -	link[size] = '\0';
> -	err = 0;
> -fail:
> -	folio_end_read(folio, err == 0);
> -	return err;
> -}
> -
> -const struct address_space_operations efs_symlink_aops = {
> -	.read_folio	= efs_symlink_read_folio
> -};
> diff --git a/include/linux/efs_vh.h b/include/linux/efs_vh.h
> deleted file mode 100644
> index 206c5270f7b8..000000000000
> --- a/include/linux/efs_vh.h
> +++ /dev/null
> @@ -1,54 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * efs_vh.h
> - *
> - * Copyright (c) 1999 Al Smith
> - *
> - * Portions derived from IRIX header files (c) 1985 MIPS Computer Systems, Inc.
> - */
> -
> -#ifndef __EFS_VH_H__
> -#define __EFS_VH_H__
> -
> -#define VHMAGIC		0xbe5a941	/* volume header magic number */
> -#define NPARTAB		16		/* 16 unix partitions */
> -#define NVDIR		15		/* max of 15 directory entries */
> -#define BFNAMESIZE	16		/* max 16 chars in boot file name */
> -#define VDNAMESIZE	8
> -
> -struct volume_directory {
> -	char	vd_name[VDNAMESIZE];	/* name */
> -	__be32	vd_lbn;			/* logical block number */
> -	__be32	vd_nbytes;		/* file length in bytes */
> -};
> -
> -struct partition_table {	/* one per logical partition */
> -	__be32	pt_nblks;	/* # of logical blks in partition */
> -	__be32	pt_firstlbn;	/* first lbn of partition */
> -	__be32	pt_type;	/* use of partition */
> -};
> -
> -struct volume_header {
> -	__be32	vh_magic;			/* identifies volume header */
> -	__be16	vh_rootpt;			/* root partition number */
> -	__be16	vh_swappt;			/* swap partition number */
> -	char	vh_bootfile[BFNAMESIZE];	/* name of file to boot */
> -	char	pad[48];			/* device param space */
> -	struct volume_directory vh_vd[NVDIR];	/* other vol hdr contents */
> -	struct partition_table  vh_pt[NPARTAB];	/* device partition layout */
> -	__be32	vh_csum;			/* volume header checksum */
> -	__be32	vh_fill;			/* fill out to 512 bytes */
> -};
> -
> -/* partition type sysv is used for EFS format CD-ROM partitions */
> -#define SGI_SYSV	0x05
> -#define SGI_EFS		0x07
> -#define IS_EFS(x)	(((x) == SGI_EFS) || ((x) == SGI_SYSV))
> -
> -struct pt_types {
> -	int	pt_type;
> -	char	*pt_name;
> -};
> -
> -#endif /* __EFS_VH_H__ */
> -
> diff --git a/include/uapi/linux/efs_fs_sb.h b/include/uapi/linux/efs_fs_sb.h
> deleted file mode 100644
> index 6bad29a10faa..000000000000
> --- a/include/uapi/linux/efs_fs_sb.h
> +++ /dev/null
> @@ -1,63 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> -/*
> - * efs_fs_sb.h
> - *
> - * Copyright (c) 1999 Al Smith
> - *
> - * Portions derived from IRIX header files (c) 1988 Silicon Graphics
> - */
> -
> -#ifndef __EFS_FS_SB_H__
> -#define __EFS_FS_SB_H__
> -
> -#include <linux/types.h>
> -#include <linux/magic.h>
> -
> -/* EFS superblock magic numbers */
> -#define EFS_MAGIC	0x072959
> -#define EFS_NEWMAGIC	0x07295a
> -
> -#define IS_EFS_MAGIC(x)	((x == EFS_MAGIC) || (x == EFS_NEWMAGIC))
> -
> -#define EFS_SUPER		1
> -#define EFS_ROOTINODE		2
> -
> -/* efs superblock on disk */
> -struct efs_super {
> -	__be32		fs_size;        /* size of filesystem, in sectors */
> -	__be32		fs_firstcg;     /* bb offset to first cg */
> -	__be32		fs_cgfsize;     /* size of cylinder group in bb's */
> -	__be16		fs_cgisize;     /* bb's of inodes per cylinder group */
> -	__be16		fs_sectors;     /* sectors per track */
> -	__be16		fs_heads;       /* heads per cylinder */
> -	__be16		fs_ncg;         /* # of cylinder groups in filesystem */
> -	__be16		fs_dirty;       /* fs needs to be fsck'd */
> -	__be32		fs_time;        /* last super-block update */
> -	__be32		fs_magic;       /* magic number */
> -	char		fs_fname[6];    /* file system name */
> -	char		fs_fpack[6];    /* file system pack name */
> -	__be32		fs_bmsize;      /* size of bitmap in bytes */
> -	__be32		fs_tfree;       /* total free data blocks */
> -	__be32		fs_tinode;      /* total free inodes */
> -	__be32		fs_bmblock;     /* bitmap location. */
> -	__be32		fs_replsb;      /* Location of replicated superblock. */
> -	__be32		fs_lastialloc;  /* last allocated inode */
> -	char		fs_spare[20];   /* space for expansion - MUST BE ZERO */
> -	__be32		fs_checksum;    /* checksum of volume portion of fs */
> -};
> -
> -/* efs superblock information in memory */
> -struct efs_sb_info {
> -	__u32	fs_magic;	/* superblock magic number */
> -	__u32	fs_start;	/* first block of filesystem */
> -	__u32	first_block;	/* first data block in filesystem */
> -	__u32	total_blocks;	/* total number of blocks in filesystem */
> -	__u32	group_size;	/* # of blocks a group consists of */ 
> -	__u32	data_free;	/* # of free data blocks */
> -	__u32	inode_free;	/* # of free inodes */
> -	__u16	inode_blocks;	/* # of blocks used for inodes in every grp */
> -	__u16	total_groups;	/* # of groups */
> -};
> -
> -#endif /* __EFS_FS_SB_H__ */
> -
> -- 
> 2.47.3
> 
> 

      parent reply	other threads:[~2026-06-25 19:42 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-18 21:18 [PATCH] efs: Remove EFS Matthew Wilcox (Oracle)
2026-06-19  9:28 ` Jori Koolstra
2026-06-19 10:06   ` Pedro Falcato
2026-06-19 10:19     ` Jori Koolstra
2026-06-21 21:44       ` Matthew Wilcox
2026-06-23  9:17         ` Jori Koolstra
2026-06-25 19:42 ` Darrick J. Wong [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260625194250.GD6060@frogsfrogsfrogs \
    --to=djwong@kernel.org \
    --cc=christian@brauner.io \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=willy@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.