xref: /openbmc/linux/fs/bad_inode.c (revision 913e9928)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *  linux/fs/bad_inode.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *  Copyright (C) 1997, Stephen Tweedie
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  *  Provide stub functions for unreadable inodes
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  *  Fabian Frederick : August 2003 - All file operations assigned to EIO
101da177e4SLinus Torvalds  */
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include <linux/fs.h>
13630d9c47SPaul Gortmaker #include <linux/export.h>
141da177e4SLinus Torvalds #include <linux/stat.h>
151da177e4SLinus Torvalds #include <linux/time.h>
161da177e4SLinus Torvalds #include <linux/namei.h>
17be6aab0eSEric Sandeen #include <linux/poll.h>
1810c5db28SChristoph Hellwig #include <linux/fiemap.h>
191da177e4SLinus Torvalds 
bad_file_open(struct inode * inode,struct file * filp)20be6aab0eSEric Sandeen static int bad_file_open(struct inode *inode, struct file *filp)
21be6aab0eSEric Sandeen {
22be6aab0eSEric Sandeen 	return -EIO;
23be6aab0eSEric Sandeen }
24be6aab0eSEric Sandeen 
254b6f5d20SArjan van de Ven static const struct file_operations bad_file_ops =
261da177e4SLinus Torvalds {
27be6aab0eSEric Sandeen 	.open		= bad_file_open,
281da177e4SLinus Torvalds };
291da177e4SLinus Torvalds 
bad_inode_create(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode,bool excl)306c960e68SChristian Brauner static int bad_inode_create(struct mnt_idmap *idmap,
31549c7297SChristian Brauner 			    struct inode *dir, struct dentry *dentry,
32ebfc3b49SAl Viro 			    umode_t mode, bool excl)
33be6aab0eSEric Sandeen {
34be6aab0eSEric Sandeen 	return -EIO;
35be6aab0eSEric Sandeen }
36be6aab0eSEric Sandeen 
bad_inode_lookup(struct inode * dir,struct dentry * dentry,unsigned int flags)37be6aab0eSEric Sandeen static struct dentry *bad_inode_lookup(struct inode *dir,
3800cd8dd3SAl Viro 			struct dentry *dentry, unsigned int flags)
39be6aab0eSEric Sandeen {
40be6aab0eSEric Sandeen 	return ERR_PTR(-EIO);
41be6aab0eSEric Sandeen }
42be6aab0eSEric Sandeen 
bad_inode_link(struct dentry * old_dentry,struct inode * dir,struct dentry * dentry)43be6aab0eSEric Sandeen static int bad_inode_link (struct dentry *old_dentry, struct inode *dir,
44be6aab0eSEric Sandeen 		struct dentry *dentry)
45be6aab0eSEric Sandeen {
46be6aab0eSEric Sandeen 	return -EIO;
47be6aab0eSEric Sandeen }
48be6aab0eSEric Sandeen 
bad_inode_unlink(struct inode * dir,struct dentry * dentry)49be6aab0eSEric Sandeen static int bad_inode_unlink(struct inode *dir, struct dentry *dentry)
50be6aab0eSEric Sandeen {
51be6aab0eSEric Sandeen 	return -EIO;
52be6aab0eSEric Sandeen }
53be6aab0eSEric Sandeen 
bad_inode_symlink(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,const char * symname)547a77db95SChristian Brauner static int bad_inode_symlink(struct mnt_idmap *idmap,
55549c7297SChristian Brauner 			     struct inode *dir, struct dentry *dentry,
56be6aab0eSEric Sandeen 			     const char *symname)
57be6aab0eSEric Sandeen {
58be6aab0eSEric Sandeen 	return -EIO;
59be6aab0eSEric Sandeen }
60be6aab0eSEric Sandeen 
bad_inode_mkdir(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode)61c54bd91eSChristian Brauner static int bad_inode_mkdir(struct mnt_idmap *idmap, struct inode *dir,
62549c7297SChristian Brauner 			   struct dentry *dentry, umode_t mode)
63be6aab0eSEric Sandeen {
64be6aab0eSEric Sandeen 	return -EIO;
65be6aab0eSEric Sandeen }
66be6aab0eSEric Sandeen 
bad_inode_rmdir(struct inode * dir,struct dentry * dentry)67be6aab0eSEric Sandeen static int bad_inode_rmdir (struct inode *dir, struct dentry *dentry)
68be6aab0eSEric Sandeen {
69be6aab0eSEric Sandeen 	return -EIO;
70be6aab0eSEric Sandeen }
71be6aab0eSEric Sandeen 
bad_inode_mknod(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode,dev_t rdev)725ebb29beSChristian Brauner static int bad_inode_mknod(struct mnt_idmap *idmap, struct inode *dir,
73549c7297SChristian Brauner 			   struct dentry *dentry, umode_t mode, dev_t rdev)
74be6aab0eSEric Sandeen {
75be6aab0eSEric Sandeen 	return -EIO;
76be6aab0eSEric Sandeen }
77be6aab0eSEric Sandeen 
bad_inode_rename2(struct mnt_idmap * idmap,struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)78e18275aeSChristian Brauner static int bad_inode_rename2(struct mnt_idmap *idmap,
79549c7297SChristian Brauner 			     struct inode *old_dir, struct dentry *old_dentry,
80a0dbc566SMiklos Szeredi 			     struct inode *new_dir, struct dentry *new_dentry,
81a0dbc566SMiklos Szeredi 			     unsigned int flags)
82be6aab0eSEric Sandeen {
83be6aab0eSEric Sandeen 	return -EIO;
84be6aab0eSEric Sandeen }
85be6aab0eSEric Sandeen 
bad_inode_readlink(struct dentry * dentry,char __user * buffer,int buflen)86be6aab0eSEric Sandeen static int bad_inode_readlink(struct dentry *dentry, char __user *buffer,
87be6aab0eSEric Sandeen 		int buflen)
88be6aab0eSEric Sandeen {
89be6aab0eSEric Sandeen 	return -EIO;
90be6aab0eSEric Sandeen }
91be6aab0eSEric Sandeen 
bad_inode_permission(struct mnt_idmap * idmap,struct inode * inode,int mask)924609e1f1SChristian Brauner static int bad_inode_permission(struct mnt_idmap *idmap,
93549c7297SChristian Brauner 				struct inode *inode, int mask)
94be6aab0eSEric Sandeen {
95be6aab0eSEric Sandeen 	return -EIO;
96be6aab0eSEric Sandeen }
97be6aab0eSEric Sandeen 
bad_inode_getattr(struct mnt_idmap * idmap,const struct path * path,struct kstat * stat,u32 request_mask,unsigned int query_flags)98b74d24f7SChristian Brauner static int bad_inode_getattr(struct mnt_idmap *idmap,
99549c7297SChristian Brauner 			     const struct path *path, struct kstat *stat,
100a528d35eSDavid Howells 			     u32 request_mask, unsigned int query_flags)
101be6aab0eSEric Sandeen {
102be6aab0eSEric Sandeen 	return -EIO;
103be6aab0eSEric Sandeen }
104be6aab0eSEric Sandeen 
bad_inode_setattr(struct mnt_idmap * idmap,struct dentry * direntry,struct iattr * attrs)105c1632a0fSChristian Brauner static int bad_inode_setattr(struct mnt_idmap *idmap,
106549c7297SChristian Brauner 			     struct dentry *direntry, struct iattr *attrs)
107be6aab0eSEric Sandeen {
108be6aab0eSEric Sandeen 	return -EIO;
109be6aab0eSEric Sandeen }
110be6aab0eSEric Sandeen 
bad_inode_listxattr(struct dentry * dentry,char * buffer,size_t buffer_size)111be6aab0eSEric Sandeen static ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer,
112be6aab0eSEric Sandeen 			size_t buffer_size)
113be6aab0eSEric Sandeen {
114be6aab0eSEric Sandeen 	return -EIO;
115be6aab0eSEric Sandeen }
116be6aab0eSEric Sandeen 
bad_inode_get_link(struct dentry * dentry,struct inode * inode,struct delayed_call * done)1173f9ca755SMiklos Szeredi static const char *bad_inode_get_link(struct dentry *dentry,
1183f9ca755SMiklos Szeredi 				      struct inode *inode,
1193f9ca755SMiklos Szeredi 				      struct delayed_call *done)
1203f9ca755SMiklos Szeredi {
1213f9ca755SMiklos Szeredi 	return ERR_PTR(-EIO);
1223f9ca755SMiklos Szeredi }
1233f9ca755SMiklos Szeredi 
bad_inode_get_acl(struct inode * inode,int type,bool rcu)1240cad6246SMiklos Szeredi static struct posix_acl *bad_inode_get_acl(struct inode *inode, int type, bool rcu)
1253f9ca755SMiklos Szeredi {
1263f9ca755SMiklos Szeredi 	return ERR_PTR(-EIO);
1273f9ca755SMiklos Szeredi }
1283f9ca755SMiklos Szeredi 
bad_inode_fiemap(struct inode * inode,struct fiemap_extent_info * fieinfo,u64 start,u64 len)1293f9ca755SMiklos Szeredi static int bad_inode_fiemap(struct inode *inode,
1303f9ca755SMiklos Szeredi 			    struct fiemap_extent_info *fieinfo, u64 start,
1313f9ca755SMiklos Szeredi 			    u64 len)
1323f9ca755SMiklos Szeredi {
1333f9ca755SMiklos Szeredi 	return -EIO;
1343f9ca755SMiklos Szeredi }
1353f9ca755SMiklos Szeredi 
bad_inode_update_time(struct inode * inode,int flags)136*913e9928SJeff Layton static int bad_inode_update_time(struct inode *inode, int flags)
1373f9ca755SMiklos Szeredi {
1383f9ca755SMiklos Szeredi 	return -EIO;
1393f9ca755SMiklos Szeredi }
1403f9ca755SMiklos Szeredi 
bad_inode_atomic_open(struct inode * inode,struct dentry * dentry,struct file * file,unsigned int open_flag,umode_t create_mode)1413f9ca755SMiklos Szeredi static int bad_inode_atomic_open(struct inode *inode, struct dentry *dentry,
1423f9ca755SMiklos Szeredi 				 struct file *file, unsigned int open_flag,
14344907d79SAl Viro 				 umode_t create_mode)
1443f9ca755SMiklos Szeredi {
1453f9ca755SMiklos Szeredi 	return -EIO;
1463f9ca755SMiklos Szeredi }
1473f9ca755SMiklos Szeredi 
bad_inode_tmpfile(struct mnt_idmap * idmap,struct inode * inode,struct file * file,umode_t mode)148011e2b71SChristian Brauner static int bad_inode_tmpfile(struct mnt_idmap *idmap,
149863f144fSMiklos Szeredi 			     struct inode *inode, struct file *file,
1503f9ca755SMiklos Szeredi 			     umode_t mode)
1513f9ca755SMiklos Szeredi {
1523f9ca755SMiklos Szeredi 	return -EIO;
1533f9ca755SMiklos Szeredi }
1543f9ca755SMiklos Szeredi 
bad_inode_set_acl(struct mnt_idmap * idmap,struct dentry * dentry,struct posix_acl * acl,int type)15513e83a49SChristian Brauner static int bad_inode_set_acl(struct mnt_idmap *idmap,
156138060baSChristian Brauner 			     struct dentry *dentry, struct posix_acl *acl,
1573f9ca755SMiklos Szeredi 			     int type)
1583f9ca755SMiklos Szeredi {
1593f9ca755SMiklos Szeredi 	return -EIO;
1603f9ca755SMiklos Szeredi }
1613f9ca755SMiklos Szeredi 
162754661f1SArjan van de Ven static const struct inode_operations bad_inode_ops =
1631da177e4SLinus Torvalds {
164be6aab0eSEric Sandeen 	.create		= bad_inode_create,
165be6aab0eSEric Sandeen 	.lookup		= bad_inode_lookup,
166be6aab0eSEric Sandeen 	.link		= bad_inode_link,
167be6aab0eSEric Sandeen 	.unlink		= bad_inode_unlink,
168be6aab0eSEric Sandeen 	.symlink	= bad_inode_symlink,
169be6aab0eSEric Sandeen 	.mkdir		= bad_inode_mkdir,
170be6aab0eSEric Sandeen 	.rmdir		= bad_inode_rmdir,
171be6aab0eSEric Sandeen 	.mknod		= bad_inode_mknod,
1722773bf00SMiklos Szeredi 	.rename		= bad_inode_rename2,
173be6aab0eSEric Sandeen 	.readlink	= bad_inode_readlink,
174be6aab0eSEric Sandeen 	.permission	= bad_inode_permission,
175be6aab0eSEric Sandeen 	.getattr	= bad_inode_getattr,
176be6aab0eSEric Sandeen 	.setattr	= bad_inode_setattr,
177be6aab0eSEric Sandeen 	.listxattr	= bad_inode_listxattr,
1783f9ca755SMiklos Szeredi 	.get_link	= bad_inode_get_link,
179cac2f8b8SChristian Brauner 	.get_inode_acl	= bad_inode_get_acl,
1803f9ca755SMiklos Szeredi 	.fiemap		= bad_inode_fiemap,
1813f9ca755SMiklos Szeredi 	.update_time	= bad_inode_update_time,
1823f9ca755SMiklos Szeredi 	.atomic_open	= bad_inode_atomic_open,
1833f9ca755SMiklos Szeredi 	.tmpfile	= bad_inode_tmpfile,
1843f9ca755SMiklos Szeredi 	.set_acl	= bad_inode_set_acl,
1851da177e4SLinus Torvalds };
1861da177e4SLinus Torvalds 
1871da177e4SLinus Torvalds 
1881da177e4SLinus Torvalds /*
1891da177e4SLinus Torvalds  * When a filesystem is unable to read an inode due to an I/O error in
1901da177e4SLinus Torvalds  * its read_inode() function, it can call make_bad_inode() to return a
1911da177e4SLinus Torvalds  * set of stubs which will return EIO errors as required.
1921da177e4SLinus Torvalds  *
1931da177e4SLinus Torvalds  * We only need to do limited initialisation: all other fields are
1941da177e4SLinus Torvalds  * preinitialised to zero automatically.
1951da177e4SLinus Torvalds  */
1961da177e4SLinus Torvalds 
1971da177e4SLinus Torvalds /**
1981da177e4SLinus Torvalds  *	make_bad_inode - mark an inode bad due to an I/O error
1991da177e4SLinus Torvalds  *	@inode: Inode to mark bad
2001da177e4SLinus Torvalds  *
2011da177e4SLinus Torvalds  *	When an inode cannot be read due to a media or remote network
2021da177e4SLinus Torvalds  *	failure this function makes the inode "bad" and causes I/O operations
2031da177e4SLinus Torvalds  *	on it to fail from this point on.
2041da177e4SLinus Torvalds  */
2051da177e4SLinus Torvalds 
make_bad_inode(struct inode * inode)2061da177e4SLinus Torvalds void make_bad_inode(struct inode *inode)
2071da177e4SLinus Torvalds {
2081da177e4SLinus Torvalds 	remove_inode_hash(inode);
2091da177e4SLinus Torvalds 
2101da177e4SLinus Torvalds 	inode->i_mode = S_IFREG;
2112276e5baSJeff Layton 	inode->i_atime = inode->i_mtime = inode_set_ctime_current(inode);
2121da177e4SLinus Torvalds 	inode->i_op = &bad_inode_ops;
2135f6e59aeSAndreas Gruenbacher 	inode->i_opflags &= ~IOP_XATTR;
2141da177e4SLinus Torvalds 	inode->i_fop = &bad_file_ops;
2151da177e4SLinus Torvalds }
2161da177e4SLinus Torvalds EXPORT_SYMBOL(make_bad_inode);
2171da177e4SLinus Torvalds 
2181da177e4SLinus Torvalds /*
2191da177e4SLinus Torvalds  * This tests whether an inode has been flagged as bad. The test uses
2201da177e4SLinus Torvalds  * &bad_inode_ops to cover the case of invalidated inodes as well as
2211da177e4SLinus Torvalds  * those created by make_bad_inode() above.
2221da177e4SLinus Torvalds  */
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds /**
2251da177e4SLinus Torvalds  *	is_bad_inode - is an inode errored
2261da177e4SLinus Torvalds  *	@inode: inode to test
2271da177e4SLinus Torvalds  *
2281da177e4SLinus Torvalds  *	Returns true if the inode in question has been marked as bad.
2291da177e4SLinus Torvalds  */
2301da177e4SLinus Torvalds 
is_bad_inode(struct inode * inode)2310e3ef1feSYaowei Bai bool is_bad_inode(struct inode *inode)
2321da177e4SLinus Torvalds {
2331da177e4SLinus Torvalds 	return (inode->i_op == &bad_inode_ops);
2341da177e4SLinus Torvalds }
2351da177e4SLinus Torvalds 
2361da177e4SLinus Torvalds EXPORT_SYMBOL(is_bad_inode);
237b46980feSDavid Howells 
238b46980feSDavid Howells /**
239b46980feSDavid Howells  * iget_failed - Mark an under-construction inode as dead and release it
240b46980feSDavid Howells  * @inode: The inode to discard
241b46980feSDavid Howells  *
242b46980feSDavid Howells  * Mark an under-construction inode as dead and release it.
243b46980feSDavid Howells  */
iget_failed(struct inode * inode)244b46980feSDavid Howells void iget_failed(struct inode *inode)
245b46980feSDavid Howells {
246b46980feSDavid Howells 	make_bad_inode(inode);
247b46980feSDavid Howells 	unlock_new_inode(inode);
248b46980feSDavid Howells 	iput(inode);
249b46980feSDavid Howells }
250b46980feSDavid Howells EXPORT_SYMBOL(iget_failed);
251