xref: /kernel/linux/linux-5.10/fs/bad_inode.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  linux/fs/bad_inode.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 1997, Stephen Tweedie
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *  Provide stub functions for unreadable inodes
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci *  Fabian Frederick : August 2003 - All file operations assigned to EIO
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/fs.h>
138c2ecf20Sopenharmony_ci#include <linux/export.h>
148c2ecf20Sopenharmony_ci#include <linux/stat.h>
158c2ecf20Sopenharmony_ci#include <linux/time.h>
168c2ecf20Sopenharmony_ci#include <linux/namei.h>
178c2ecf20Sopenharmony_ci#include <linux/poll.h>
188c2ecf20Sopenharmony_ci#include <linux/fiemap.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistatic int bad_file_open(struct inode *inode, struct file *filp)
218c2ecf20Sopenharmony_ci{
228c2ecf20Sopenharmony_ci	return -EIO;
238c2ecf20Sopenharmony_ci}
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistatic const struct file_operations bad_file_ops =
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci	.open		= bad_file_open,
288c2ecf20Sopenharmony_ci};
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cistatic int bad_inode_create (struct inode *dir, struct dentry *dentry,
318c2ecf20Sopenharmony_ci		umode_t mode, bool excl)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	return -EIO;
348c2ecf20Sopenharmony_ci}
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistatic struct dentry *bad_inode_lookup(struct inode *dir,
378c2ecf20Sopenharmony_ci			struct dentry *dentry, unsigned int flags)
388c2ecf20Sopenharmony_ci{
398c2ecf20Sopenharmony_ci	return ERR_PTR(-EIO);
408c2ecf20Sopenharmony_ci}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_cistatic int bad_inode_link (struct dentry *old_dentry, struct inode *dir,
438c2ecf20Sopenharmony_ci		struct dentry *dentry)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	return -EIO;
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistatic int bad_inode_unlink(struct inode *dir, struct dentry *dentry)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	return -EIO;
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cistatic int bad_inode_symlink (struct inode *dir, struct dentry *dentry,
548c2ecf20Sopenharmony_ci		const char *symname)
558c2ecf20Sopenharmony_ci{
568c2ecf20Sopenharmony_ci	return -EIO;
578c2ecf20Sopenharmony_ci}
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistatic int bad_inode_mkdir(struct inode *dir, struct dentry *dentry,
608c2ecf20Sopenharmony_ci			umode_t mode)
618c2ecf20Sopenharmony_ci{
628c2ecf20Sopenharmony_ci	return -EIO;
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistatic int bad_inode_rmdir (struct inode *dir, struct dentry *dentry)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	return -EIO;
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_cistatic int bad_inode_mknod (struct inode *dir, struct dentry *dentry,
718c2ecf20Sopenharmony_ci			umode_t mode, dev_t rdev)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	return -EIO;
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cistatic int bad_inode_rename2(struct inode *old_dir, struct dentry *old_dentry,
778c2ecf20Sopenharmony_ci			     struct inode *new_dir, struct dentry *new_dentry,
788c2ecf20Sopenharmony_ci			     unsigned int flags)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	return -EIO;
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_cistatic int bad_inode_readlink(struct dentry *dentry, char __user *buffer,
848c2ecf20Sopenharmony_ci		int buflen)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	return -EIO;
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic int bad_inode_permission(struct inode *inode, int mask)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	return -EIO;
928c2ecf20Sopenharmony_ci}
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistatic int bad_inode_getattr(const struct path *path, struct kstat *stat,
958c2ecf20Sopenharmony_ci			     u32 request_mask, unsigned int query_flags)
968c2ecf20Sopenharmony_ci{
978c2ecf20Sopenharmony_ci	return -EIO;
988c2ecf20Sopenharmony_ci}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistatic int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs)
1018c2ecf20Sopenharmony_ci{
1028c2ecf20Sopenharmony_ci	return -EIO;
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer,
1068c2ecf20Sopenharmony_ci			size_t buffer_size)
1078c2ecf20Sopenharmony_ci{
1088c2ecf20Sopenharmony_ci	return -EIO;
1098c2ecf20Sopenharmony_ci}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cistatic const char *bad_inode_get_link(struct dentry *dentry,
1128c2ecf20Sopenharmony_ci				      struct inode *inode,
1138c2ecf20Sopenharmony_ci				      struct delayed_call *done)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	return ERR_PTR(-EIO);
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_cistatic struct posix_acl *bad_inode_get_acl(struct inode *inode, int type)
1198c2ecf20Sopenharmony_ci{
1208c2ecf20Sopenharmony_ci	return ERR_PTR(-EIO);
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_cistatic int bad_inode_fiemap(struct inode *inode,
1248c2ecf20Sopenharmony_ci			    struct fiemap_extent_info *fieinfo, u64 start,
1258c2ecf20Sopenharmony_ci			    u64 len)
1268c2ecf20Sopenharmony_ci{
1278c2ecf20Sopenharmony_ci	return -EIO;
1288c2ecf20Sopenharmony_ci}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic int bad_inode_update_time(struct inode *inode, struct timespec64 *time,
1318c2ecf20Sopenharmony_ci				 int flags)
1328c2ecf20Sopenharmony_ci{
1338c2ecf20Sopenharmony_ci	return -EIO;
1348c2ecf20Sopenharmony_ci}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistatic int bad_inode_atomic_open(struct inode *inode, struct dentry *dentry,
1378c2ecf20Sopenharmony_ci				 struct file *file, unsigned int open_flag,
1388c2ecf20Sopenharmony_ci				 umode_t create_mode)
1398c2ecf20Sopenharmony_ci{
1408c2ecf20Sopenharmony_ci	return -EIO;
1418c2ecf20Sopenharmony_ci}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistatic int bad_inode_tmpfile(struct inode *inode, struct dentry *dentry,
1448c2ecf20Sopenharmony_ci			     umode_t mode)
1458c2ecf20Sopenharmony_ci{
1468c2ecf20Sopenharmony_ci	return -EIO;
1478c2ecf20Sopenharmony_ci}
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_cistatic int bad_inode_set_acl(struct inode *inode, struct posix_acl *acl,
1508c2ecf20Sopenharmony_ci			     int type)
1518c2ecf20Sopenharmony_ci{
1528c2ecf20Sopenharmony_ci	return -EIO;
1538c2ecf20Sopenharmony_ci}
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_cistatic const struct inode_operations bad_inode_ops =
1568c2ecf20Sopenharmony_ci{
1578c2ecf20Sopenharmony_ci	.create		= bad_inode_create,
1588c2ecf20Sopenharmony_ci	.lookup		= bad_inode_lookup,
1598c2ecf20Sopenharmony_ci	.link		= bad_inode_link,
1608c2ecf20Sopenharmony_ci	.unlink		= bad_inode_unlink,
1618c2ecf20Sopenharmony_ci	.symlink	= bad_inode_symlink,
1628c2ecf20Sopenharmony_ci	.mkdir		= bad_inode_mkdir,
1638c2ecf20Sopenharmony_ci	.rmdir		= bad_inode_rmdir,
1648c2ecf20Sopenharmony_ci	.mknod		= bad_inode_mknod,
1658c2ecf20Sopenharmony_ci	.rename		= bad_inode_rename2,
1668c2ecf20Sopenharmony_ci	.readlink	= bad_inode_readlink,
1678c2ecf20Sopenharmony_ci	.permission	= bad_inode_permission,
1688c2ecf20Sopenharmony_ci	.getattr	= bad_inode_getattr,
1698c2ecf20Sopenharmony_ci	.setattr	= bad_inode_setattr,
1708c2ecf20Sopenharmony_ci	.listxattr	= bad_inode_listxattr,
1718c2ecf20Sopenharmony_ci	.get_link	= bad_inode_get_link,
1728c2ecf20Sopenharmony_ci	.get_acl	= bad_inode_get_acl,
1738c2ecf20Sopenharmony_ci	.fiemap		= bad_inode_fiemap,
1748c2ecf20Sopenharmony_ci	.update_time	= bad_inode_update_time,
1758c2ecf20Sopenharmony_ci	.atomic_open	= bad_inode_atomic_open,
1768c2ecf20Sopenharmony_ci	.tmpfile	= bad_inode_tmpfile,
1778c2ecf20Sopenharmony_ci	.set_acl	= bad_inode_set_acl,
1788c2ecf20Sopenharmony_ci};
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci/*
1828c2ecf20Sopenharmony_ci * When a filesystem is unable to read an inode due to an I/O error in
1838c2ecf20Sopenharmony_ci * its read_inode() function, it can call make_bad_inode() to return a
1848c2ecf20Sopenharmony_ci * set of stubs which will return EIO errors as required.
1858c2ecf20Sopenharmony_ci *
1868c2ecf20Sopenharmony_ci * We only need to do limited initialisation: all other fields are
1878c2ecf20Sopenharmony_ci * preinitialised to zero automatically.
1888c2ecf20Sopenharmony_ci */
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci/**
1918c2ecf20Sopenharmony_ci *	make_bad_inode - mark an inode bad due to an I/O error
1928c2ecf20Sopenharmony_ci *	@inode: Inode to mark bad
1938c2ecf20Sopenharmony_ci *
1948c2ecf20Sopenharmony_ci *	When an inode cannot be read due to a media or remote network
1958c2ecf20Sopenharmony_ci *	failure this function makes the inode "bad" and causes I/O operations
1968c2ecf20Sopenharmony_ci *	on it to fail from this point on.
1978c2ecf20Sopenharmony_ci */
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_civoid make_bad_inode(struct inode *inode)
2008c2ecf20Sopenharmony_ci{
2018c2ecf20Sopenharmony_ci	remove_inode_hash(inode);
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	inode->i_mode = S_IFREG;
2048c2ecf20Sopenharmony_ci	inode->i_atime = inode->i_mtime = inode->i_ctime =
2058c2ecf20Sopenharmony_ci		current_time(inode);
2068c2ecf20Sopenharmony_ci	inode->i_op = &bad_inode_ops;
2078c2ecf20Sopenharmony_ci	inode->i_opflags &= ~IOP_XATTR;
2088c2ecf20Sopenharmony_ci	inode->i_fop = &bad_file_ops;
2098c2ecf20Sopenharmony_ci}
2108c2ecf20Sopenharmony_ciEXPORT_SYMBOL(make_bad_inode);
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci/*
2138c2ecf20Sopenharmony_ci * This tests whether an inode has been flagged as bad. The test uses
2148c2ecf20Sopenharmony_ci * &bad_inode_ops to cover the case of invalidated inodes as well as
2158c2ecf20Sopenharmony_ci * those created by make_bad_inode() above.
2168c2ecf20Sopenharmony_ci */
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci/**
2198c2ecf20Sopenharmony_ci *	is_bad_inode - is an inode errored
2208c2ecf20Sopenharmony_ci *	@inode: inode to test
2218c2ecf20Sopenharmony_ci *
2228c2ecf20Sopenharmony_ci *	Returns true if the inode in question has been marked as bad.
2238c2ecf20Sopenharmony_ci */
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_cibool is_bad_inode(struct inode *inode)
2268c2ecf20Sopenharmony_ci{
2278c2ecf20Sopenharmony_ci	return (inode->i_op == &bad_inode_ops);
2288c2ecf20Sopenharmony_ci}
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ciEXPORT_SYMBOL(is_bad_inode);
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_ci/**
2338c2ecf20Sopenharmony_ci * iget_failed - Mark an under-construction inode as dead and release it
2348c2ecf20Sopenharmony_ci * @inode: The inode to discard
2358c2ecf20Sopenharmony_ci *
2368c2ecf20Sopenharmony_ci * Mark an under-construction inode as dead and release it.
2378c2ecf20Sopenharmony_ci */
2388c2ecf20Sopenharmony_civoid iget_failed(struct inode *inode)
2398c2ecf20Sopenharmony_ci{
2408c2ecf20Sopenharmony_ci	make_bad_inode(inode);
2418c2ecf20Sopenharmony_ci	unlock_new_inode(inode);
2428c2ecf20Sopenharmony_ci	iput(inode);
2438c2ecf20Sopenharmony_ci}
2448c2ecf20Sopenharmony_ciEXPORT_SYMBOL(iget_failed);
245