diff options
Diffstat (limited to 'fs/bad_inode.c')
-rw-r--r-- | fs/bad_inode.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/fs/bad_inode.c b/fs/bad_inode.c new file mode 100644 index 000000000000..672a31924f3c --- /dev/null +++ b/fs/bad_inode.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * linux/fs/bad_inode.c | ||
3 | * | ||
4 | * Copyright (C) 1997, Stephen Tweedie | ||
5 | * | ||
6 | * Provide stub functions for unreadable inodes | ||
7 | * | ||
8 | * Fabian Frederick : August 2003 - All file operations assigned to EIO | ||
9 | */ | ||
10 | |||
11 | #include <linux/fs.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/stat.h> | ||
14 | #include <linux/time.h> | ||
15 | #include <linux/smp_lock.h> | ||
16 | #include <linux/namei.h> | ||
17 | |||
18 | static int return_EIO(void) | ||
19 | { | ||
20 | return -EIO; | ||
21 | } | ||
22 | |||
23 | #define EIO_ERROR ((void *) (return_EIO)) | ||
24 | |||
25 | static struct file_operations bad_file_ops = | ||
26 | { | ||
27 | .llseek = EIO_ERROR, | ||
28 | .aio_read = EIO_ERROR, | ||
29 | .read = EIO_ERROR, | ||
30 | .write = EIO_ERROR, | ||
31 | .aio_write = EIO_ERROR, | ||
32 | .readdir = EIO_ERROR, | ||
33 | .poll = EIO_ERROR, | ||
34 | .ioctl = EIO_ERROR, | ||
35 | .mmap = EIO_ERROR, | ||
36 | .open = EIO_ERROR, | ||
37 | .flush = EIO_ERROR, | ||
38 | .release = EIO_ERROR, | ||
39 | .fsync = EIO_ERROR, | ||
40 | .aio_fsync = EIO_ERROR, | ||
41 | .fasync = EIO_ERROR, | ||
42 | .lock = EIO_ERROR, | ||
43 | .readv = EIO_ERROR, | ||
44 | .writev = EIO_ERROR, | ||
45 | .sendfile = EIO_ERROR, | ||
46 | .sendpage = EIO_ERROR, | ||
47 | .get_unmapped_area = EIO_ERROR, | ||
48 | }; | ||
49 | |||
50 | struct inode_operations bad_inode_ops = | ||
51 | { | ||
52 | .create = EIO_ERROR, | ||
53 | .lookup = EIO_ERROR, | ||
54 | .link = EIO_ERROR, | ||
55 | .unlink = EIO_ERROR, | ||
56 | .symlink = EIO_ERROR, | ||
57 | .mkdir = EIO_ERROR, | ||
58 | .rmdir = EIO_ERROR, | ||
59 | .mknod = EIO_ERROR, | ||
60 | .rename = EIO_ERROR, | ||
61 | .readlink = EIO_ERROR, | ||
62 | /* follow_link must be no-op, otherwise unmounting this inode | ||
63 | won't work */ | ||
64 | .truncate = EIO_ERROR, | ||
65 | .permission = EIO_ERROR, | ||
66 | .getattr = EIO_ERROR, | ||
67 | .setattr = EIO_ERROR, | ||
68 | .setxattr = EIO_ERROR, | ||
69 | .getxattr = EIO_ERROR, | ||
70 | .listxattr = EIO_ERROR, | ||
71 | .removexattr = EIO_ERROR, | ||
72 | }; | ||
73 | |||
74 | |||
75 | /* | ||
76 | * When a filesystem is unable to read an inode due to an I/O error in | ||
77 | * its read_inode() function, it can call make_bad_inode() to return a | ||
78 | * set of stubs which will return EIO errors as required. | ||
79 | * | ||
80 | * We only need to do limited initialisation: all other fields are | ||
81 | * preinitialised to zero automatically. | ||
82 | */ | ||
83 | |||
84 | /** | ||
85 | * make_bad_inode - mark an inode bad due to an I/O error | ||
86 | * @inode: Inode to mark bad | ||
87 | * | ||
88 | * When an inode cannot be read due to a media or remote network | ||
89 | * failure this function makes the inode "bad" and causes I/O operations | ||
90 | * on it to fail from this point on. | ||
91 | */ | ||
92 | |||
93 | void make_bad_inode(struct inode * inode) | ||
94 | { | ||
95 | remove_inode_hash(inode); | ||
96 | |||
97 | inode->i_mode = S_IFREG; | ||
98 | inode->i_atime = inode->i_mtime = inode->i_ctime = | ||
99 | current_fs_time(inode->i_sb); | ||
100 | inode->i_op = &bad_inode_ops; | ||
101 | inode->i_fop = &bad_file_ops; | ||
102 | } | ||
103 | EXPORT_SYMBOL(make_bad_inode); | ||
104 | |||
105 | /* | ||
106 | * This tests whether an inode has been flagged as bad. The test uses | ||
107 | * &bad_inode_ops to cover the case of invalidated inodes as well as | ||
108 | * those created by make_bad_inode() above. | ||
109 | */ | ||
110 | |||
111 | /** | ||
112 | * is_bad_inode - is an inode errored | ||
113 | * @inode: inode to test | ||
114 | * | ||
115 | * Returns true if the inode in question has been marked as bad. | ||
116 | */ | ||
117 | |||
118 | int is_bad_inode(struct inode * inode) | ||
119 | { | ||
120 | return (inode->i_op == &bad_inode_ops); | ||
121 | } | ||
122 | |||
123 | EXPORT_SYMBOL(is_bad_inode); | ||