Commit 2b7e5bcbd9e03f7236d2869f4261059074ea50a2

Authored by David Howells
Committed by Linus Torvalds
1 parent a1d4aebbfa

iget: stop QNX4 from using iget() and read_inode()

Stop the QNX4 filesystem from using iget() and read_inode().  Replace
qnx4_read_inode() with qnx4_iget(), and call that instead of iget().
qnx4_iget() then uses iget_locked() directly and returns a proper error code
instead of an inode in the event of an error.

qnx4_fill_super() returns any error incurred when getting the root inode
instead of EINVAL.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Anders Larsen <al@alarsen.net>
Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 3 changed files with 38 additions and 18 deletions Inline Diff

1 /* 1 /*
2 * QNX4 file system, Linux implementation. 2 * QNX4 file system, Linux implementation.
3 * 3 *
4 * Version : 0.2.1 4 * Version : 0.2.1
5 * 5 *
6 * Using parts of the xiafs filesystem. 6 * Using parts of the xiafs filesystem.
7 * 7 *
8 * History : 8 * History :
9 * 9 *
10 * 01-06-1998 by Richard Frowijn : first release. 10 * 01-06-1998 by Richard Frowijn : first release.
11 * 20-06-1998 by Frank Denis : Linux 2.1.99+ support, boot signature, misc. 11 * 20-06-1998 by Frank Denis : Linux 2.1.99+ support, boot signature, misc.
12 * 30-06-1998 by Frank Denis : first step to write inodes. 12 * 30-06-1998 by Frank Denis : first step to write inodes.
13 */ 13 */
14 14
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/types.h> 16 #include <linux/types.h>
17 #include <linux/string.h> 17 #include <linux/string.h>
18 #include <linux/errno.h> 18 #include <linux/errno.h>
19 #include <linux/slab.h> 19 #include <linux/slab.h>
20 #include <linux/fs.h> 20 #include <linux/fs.h>
21 #include <linux/qnx4_fs.h> 21 #include <linux/qnx4_fs.h>
22 #include <linux/init.h> 22 #include <linux/init.h>
23 #include <linux/highuid.h> 23 #include <linux/highuid.h>
24 #include <linux/smp_lock.h> 24 #include <linux/smp_lock.h>
25 #include <linux/pagemap.h> 25 #include <linux/pagemap.h>
26 #include <linux/buffer_head.h> 26 #include <linux/buffer_head.h>
27 #include <linux/vfs.h> 27 #include <linux/vfs.h>
28 #include <asm/uaccess.h> 28 #include <asm/uaccess.h>
29 29
30 #define QNX4_VERSION 4 30 #define QNX4_VERSION 4
31 #define QNX4_BMNAME ".bitmap" 31 #define QNX4_BMNAME ".bitmap"
32 32
33 static const struct super_operations qnx4_sops; 33 static const struct super_operations qnx4_sops;
34 34
35 #ifdef CONFIG_QNX4FS_RW 35 #ifdef CONFIG_QNX4FS_RW
36 36
37 int qnx4_sync_inode(struct inode *inode) 37 int qnx4_sync_inode(struct inode *inode)
38 { 38 {
39 int err = 0; 39 int err = 0;
40 # if 0 40 # if 0
41 struct buffer_head *bh; 41 struct buffer_head *bh;
42 42
43 bh = qnx4_update_inode(inode); 43 bh = qnx4_update_inode(inode);
44 if (bh && buffer_dirty(bh)) 44 if (bh && buffer_dirty(bh))
45 { 45 {
46 sync_dirty_buffer(bh); 46 sync_dirty_buffer(bh);
47 if (buffer_req(bh) && !buffer_uptodate(bh)) 47 if (buffer_req(bh) && !buffer_uptodate(bh))
48 { 48 {
49 printk ("IO error syncing qnx4 inode [%s:%08lx]\n", 49 printk ("IO error syncing qnx4 inode [%s:%08lx]\n",
50 inode->i_sb->s_id, inode->i_ino); 50 inode->i_sb->s_id, inode->i_ino);
51 err = -1; 51 err = -1;
52 } 52 }
53 brelse (bh); 53 brelse (bh);
54 } else if (!bh) { 54 } else if (!bh) {
55 err = -1; 55 err = -1;
56 } 56 }
57 # endif 57 # endif
58 58
59 return err; 59 return err;
60 } 60 }
61 61
62 static void qnx4_delete_inode(struct inode *inode) 62 static void qnx4_delete_inode(struct inode *inode)
63 { 63 {
64 QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino)); 64 QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino));
65 truncate_inode_pages(&inode->i_data, 0); 65 truncate_inode_pages(&inode->i_data, 0);
66 inode->i_size = 0; 66 inode->i_size = 0;
67 qnx4_truncate(inode); 67 qnx4_truncate(inode);
68 lock_kernel(); 68 lock_kernel();
69 qnx4_free_inode(inode); 69 qnx4_free_inode(inode);
70 unlock_kernel(); 70 unlock_kernel();
71 } 71 }
72 72
73 static void qnx4_write_super(struct super_block *sb) 73 static void qnx4_write_super(struct super_block *sb)
74 { 74 {
75 lock_kernel(); 75 lock_kernel();
76 QNX4DEBUG(("qnx4: write_super\n")); 76 QNX4DEBUG(("qnx4: write_super\n"));
77 sb->s_dirt = 0; 77 sb->s_dirt = 0;
78 unlock_kernel(); 78 unlock_kernel();
79 } 79 }
80 80
81 static int qnx4_write_inode(struct inode *inode, int unused) 81 static int qnx4_write_inode(struct inode *inode, int unused)
82 { 82 {
83 struct qnx4_inode_entry *raw_inode; 83 struct qnx4_inode_entry *raw_inode;
84 int block, ino; 84 int block, ino;
85 struct buffer_head *bh; 85 struct buffer_head *bh;
86 ino = inode->i_ino; 86 ino = inode->i_ino;
87 87
88 QNX4DEBUG(("qnx4: write inode 1.\n")); 88 QNX4DEBUG(("qnx4: write inode 1.\n"));
89 if (inode->i_nlink == 0) { 89 if (inode->i_nlink == 0) {
90 return 0; 90 return 0;
91 } 91 }
92 if (!ino) { 92 if (!ino) {
93 printk("qnx4: bad inode number on dev %s: %d is out of range\n", 93 printk("qnx4: bad inode number on dev %s: %d is out of range\n",
94 inode->i_sb->s_id, ino); 94 inode->i_sb->s_id, ino);
95 return -EIO; 95 return -EIO;
96 } 96 }
97 QNX4DEBUG(("qnx4: write inode 2.\n")); 97 QNX4DEBUG(("qnx4: write inode 2.\n"));
98 block = ino / QNX4_INODES_PER_BLOCK; 98 block = ino / QNX4_INODES_PER_BLOCK;
99 lock_kernel(); 99 lock_kernel();
100 if (!(bh = sb_bread(inode->i_sb, block))) { 100 if (!(bh = sb_bread(inode->i_sb, block))) {
101 printk("qnx4: major problem: unable to read inode from dev " 101 printk("qnx4: major problem: unable to read inode from dev "
102 "%s\n", inode->i_sb->s_id); 102 "%s\n", inode->i_sb->s_id);
103 unlock_kernel(); 103 unlock_kernel();
104 return -EIO; 104 return -EIO;
105 } 105 }
106 raw_inode = ((struct qnx4_inode_entry *) bh->b_data) + 106 raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
107 (ino % QNX4_INODES_PER_BLOCK); 107 (ino % QNX4_INODES_PER_BLOCK);
108 raw_inode->di_mode = cpu_to_le16(inode->i_mode); 108 raw_inode->di_mode = cpu_to_le16(inode->i_mode);
109 raw_inode->di_uid = cpu_to_le16(fs_high2lowuid(inode->i_uid)); 109 raw_inode->di_uid = cpu_to_le16(fs_high2lowuid(inode->i_uid));
110 raw_inode->di_gid = cpu_to_le16(fs_high2lowgid(inode->i_gid)); 110 raw_inode->di_gid = cpu_to_le16(fs_high2lowgid(inode->i_gid));
111 raw_inode->di_nlink = cpu_to_le16(inode->i_nlink); 111 raw_inode->di_nlink = cpu_to_le16(inode->i_nlink);
112 raw_inode->di_size = cpu_to_le32(inode->i_size); 112 raw_inode->di_size = cpu_to_le32(inode->i_size);
113 raw_inode->di_mtime = cpu_to_le32(inode->i_mtime.tv_sec); 113 raw_inode->di_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
114 raw_inode->di_atime = cpu_to_le32(inode->i_atime.tv_sec); 114 raw_inode->di_atime = cpu_to_le32(inode->i_atime.tv_sec);
115 raw_inode->di_ctime = cpu_to_le32(inode->i_ctime.tv_sec); 115 raw_inode->di_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
116 raw_inode->di_first_xtnt.xtnt_size = cpu_to_le32(inode->i_blocks); 116 raw_inode->di_first_xtnt.xtnt_size = cpu_to_le32(inode->i_blocks);
117 mark_buffer_dirty(bh); 117 mark_buffer_dirty(bh);
118 brelse(bh); 118 brelse(bh);
119 unlock_kernel(); 119 unlock_kernel();
120 return 0; 120 return 0;
121 } 121 }
122 122
123 #endif 123 #endif
124 124
125 static void qnx4_put_super(struct super_block *sb); 125 static void qnx4_put_super(struct super_block *sb);
126 static struct inode *qnx4_alloc_inode(struct super_block *sb); 126 static struct inode *qnx4_alloc_inode(struct super_block *sb);
127 static void qnx4_destroy_inode(struct inode *inode); 127 static void qnx4_destroy_inode(struct inode *inode);
128 static void qnx4_read_inode(struct inode *);
129 static int qnx4_remount(struct super_block *sb, int *flags, char *data); 128 static int qnx4_remount(struct super_block *sb, int *flags, char *data);
130 static int qnx4_statfs(struct dentry *, struct kstatfs *); 129 static int qnx4_statfs(struct dentry *, struct kstatfs *);
131 130
132 static const struct super_operations qnx4_sops = 131 static const struct super_operations qnx4_sops =
133 { 132 {
134 .alloc_inode = qnx4_alloc_inode, 133 .alloc_inode = qnx4_alloc_inode,
135 .destroy_inode = qnx4_destroy_inode, 134 .destroy_inode = qnx4_destroy_inode,
136 .read_inode = qnx4_read_inode,
137 .put_super = qnx4_put_super, 135 .put_super = qnx4_put_super,
138 .statfs = qnx4_statfs, 136 .statfs = qnx4_statfs,
139 .remount_fs = qnx4_remount, 137 .remount_fs = qnx4_remount,
140 #ifdef CONFIG_QNX4FS_RW 138 #ifdef CONFIG_QNX4FS_RW
141 .write_inode = qnx4_write_inode, 139 .write_inode = qnx4_write_inode,
142 .delete_inode = qnx4_delete_inode, 140 .delete_inode = qnx4_delete_inode,
143 .write_super = qnx4_write_super, 141 .write_super = qnx4_write_super,
144 #endif 142 #endif
145 }; 143 };
146 144
147 static int qnx4_remount(struct super_block *sb, int *flags, char *data) 145 static int qnx4_remount(struct super_block *sb, int *flags, char *data)
148 { 146 {
149 struct qnx4_sb_info *qs; 147 struct qnx4_sb_info *qs;
150 148
151 qs = qnx4_sb(sb); 149 qs = qnx4_sb(sb);
152 qs->Version = QNX4_VERSION; 150 qs->Version = QNX4_VERSION;
153 #ifndef CONFIG_QNX4FS_RW 151 #ifndef CONFIG_QNX4FS_RW
154 *flags |= MS_RDONLY; 152 *flags |= MS_RDONLY;
155 #endif 153 #endif
156 if (*flags & MS_RDONLY) { 154 if (*flags & MS_RDONLY) {
157 return 0; 155 return 0;
158 } 156 }
159 157
160 mark_buffer_dirty(qs->sb_buf); 158 mark_buffer_dirty(qs->sb_buf);
161 159
162 return 0; 160 return 0;
163 } 161 }
164 162
165 static struct buffer_head *qnx4_getblk(struct inode *inode, int nr, 163 static struct buffer_head *qnx4_getblk(struct inode *inode, int nr,
166 int create) 164 int create)
167 { 165 {
168 struct buffer_head *result = NULL; 166 struct buffer_head *result = NULL;
169 167
170 if ( nr >= 0 ) 168 if ( nr >= 0 )
171 nr = qnx4_block_map( inode, nr ); 169 nr = qnx4_block_map( inode, nr );
172 if (nr) { 170 if (nr) {
173 result = sb_getblk(inode->i_sb, nr); 171 result = sb_getblk(inode->i_sb, nr);
174 return result; 172 return result;
175 } 173 }
176 if (!create) { 174 if (!create) {
177 return NULL; 175 return NULL;
178 } 176 }
179 #if 0 177 #if 0
180 tmp = qnx4_new_block(inode->i_sb); 178 tmp = qnx4_new_block(inode->i_sb);
181 if (!tmp) { 179 if (!tmp) {
182 return NULL; 180 return NULL;
183 } 181 }
184 result = sb_getblk(inode->i_sb, tmp); 182 result = sb_getblk(inode->i_sb, tmp);
185 if (tst) { 183 if (tst) {
186 qnx4_free_block(inode->i_sb, tmp); 184 qnx4_free_block(inode->i_sb, tmp);
187 brelse(result); 185 brelse(result);
188 goto repeat; 186 goto repeat;
189 } 187 }
190 tst = tmp; 188 tst = tmp;
191 #endif 189 #endif
192 inode->i_ctime = CURRENT_TIME_SEC; 190 inode->i_ctime = CURRENT_TIME_SEC;
193 mark_inode_dirty(inode); 191 mark_inode_dirty(inode);
194 return result; 192 return result;
195 } 193 }
196 194
197 struct buffer_head *qnx4_bread(struct inode *inode, int block, int create) 195 struct buffer_head *qnx4_bread(struct inode *inode, int block, int create)
198 { 196 {
199 struct buffer_head *bh; 197 struct buffer_head *bh;
200 198
201 bh = qnx4_getblk(inode, block, create); 199 bh = qnx4_getblk(inode, block, create);
202 if (!bh || buffer_uptodate(bh)) { 200 if (!bh || buffer_uptodate(bh)) {
203 return bh; 201 return bh;
204 } 202 }
205 ll_rw_block(READ, 1, &bh); 203 ll_rw_block(READ, 1, &bh);
206 wait_on_buffer(bh); 204 wait_on_buffer(bh);
207 if (buffer_uptodate(bh)) { 205 if (buffer_uptodate(bh)) {
208 return bh; 206 return bh;
209 } 207 }
210 brelse(bh); 208 brelse(bh);
211 209
212 return NULL; 210 return NULL;
213 } 211 }
214 212
215 static int qnx4_get_block( struct inode *inode, sector_t iblock, struct buffer_head *bh, int create ) 213 static int qnx4_get_block( struct inode *inode, sector_t iblock, struct buffer_head *bh, int create )
216 { 214 {
217 unsigned long phys; 215 unsigned long phys;
218 216
219 QNX4DEBUG(("qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]\n",inode->i_ino,iblock)); 217 QNX4DEBUG(("qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]\n",inode->i_ino,iblock));
220 218
221 phys = qnx4_block_map( inode, iblock ); 219 phys = qnx4_block_map( inode, iblock );
222 if ( phys ) { 220 if ( phys ) {
223 // logical block is before EOF 221 // logical block is before EOF
224 map_bh(bh, inode->i_sb, phys); 222 map_bh(bh, inode->i_sb, phys);
225 } else if ( create ) { 223 } else if ( create ) {
226 // to be done. 224 // to be done.
227 } 225 }
228 return 0; 226 return 0;
229 } 227 }
230 228
231 unsigned long qnx4_block_map( struct inode *inode, long iblock ) 229 unsigned long qnx4_block_map( struct inode *inode, long iblock )
232 { 230 {
233 int ix; 231 int ix;
234 long offset, i_xblk; 232 long offset, i_xblk;
235 unsigned long block = 0; 233 unsigned long block = 0;
236 struct buffer_head *bh = NULL; 234 struct buffer_head *bh = NULL;
237 struct qnx4_xblk *xblk = NULL; 235 struct qnx4_xblk *xblk = NULL;
238 struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode); 236 struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);
239 u16 nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts); 237 u16 nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts);
240 238
241 if ( iblock < le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size) ) { 239 if ( iblock < le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size) ) {
242 // iblock is in the first extent. This is easy. 240 // iblock is in the first extent. This is easy.
243 block = le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_blk) + iblock - 1; 241 block = le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_blk) + iblock - 1;
244 } else { 242 } else {
245 // iblock is beyond first extent. We have to follow the extent chain. 243 // iblock is beyond first extent. We have to follow the extent chain.
246 i_xblk = le32_to_cpu(qnx4_inode->di_xblk); 244 i_xblk = le32_to_cpu(qnx4_inode->di_xblk);
247 offset = iblock - le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size); 245 offset = iblock - le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size);
248 ix = 0; 246 ix = 0;
249 while ( --nxtnt > 0 ) { 247 while ( --nxtnt > 0 ) {
250 if ( ix == 0 ) { 248 if ( ix == 0 ) {
251 // read next xtnt block. 249 // read next xtnt block.
252 bh = sb_bread(inode->i_sb, i_xblk - 1); 250 bh = sb_bread(inode->i_sb, i_xblk - 1);
253 if ( !bh ) { 251 if ( !bh ) {
254 QNX4DEBUG(("qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1)); 252 QNX4DEBUG(("qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1));
255 return -EIO; 253 return -EIO;
256 } 254 }
257 xblk = (struct qnx4_xblk*)bh->b_data; 255 xblk = (struct qnx4_xblk*)bh->b_data;
258 if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) { 256 if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) {
259 QNX4DEBUG(("qnx4: block at %ld is not a valid xtnt\n", qnx4_inode->i_xblk)); 257 QNX4DEBUG(("qnx4: block at %ld is not a valid xtnt\n", qnx4_inode->i_xblk));
260 return -EIO; 258 return -EIO;
261 } 259 }
262 } 260 }
263 if ( offset < le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size) ) { 261 if ( offset < le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size) ) {
264 // got it! 262 // got it!
265 block = le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_blk) + offset - 1; 263 block = le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_blk) + offset - 1;
266 break; 264 break;
267 } 265 }
268 offset -= le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size); 266 offset -= le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size);
269 if ( ++ix >= xblk->xblk_num_xtnts ) { 267 if ( ++ix >= xblk->xblk_num_xtnts ) {
270 i_xblk = le32_to_cpu(xblk->xblk_next_xblk); 268 i_xblk = le32_to_cpu(xblk->xblk_next_xblk);
271 ix = 0; 269 ix = 0;
272 brelse( bh ); 270 brelse( bh );
273 bh = NULL; 271 bh = NULL;
274 } 272 }
275 } 273 }
276 if ( bh ) 274 if ( bh )
277 brelse( bh ); 275 brelse( bh );
278 } 276 }
279 277
280 QNX4DEBUG(("qnx4: mapping block %ld of inode %ld = %ld\n",iblock,inode->i_ino,block)); 278 QNX4DEBUG(("qnx4: mapping block %ld of inode %ld = %ld\n",iblock,inode->i_ino,block));
281 return block; 279 return block;
282 } 280 }
283 281
284 static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf) 282 static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf)
285 { 283 {
286 struct super_block *sb = dentry->d_sb; 284 struct super_block *sb = dentry->d_sb;
287 285
288 lock_kernel(); 286 lock_kernel();
289 287
290 buf->f_type = sb->s_magic; 288 buf->f_type = sb->s_magic;
291 buf->f_bsize = sb->s_blocksize; 289 buf->f_bsize = sb->s_blocksize;
292 buf->f_blocks = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size) * 8; 290 buf->f_blocks = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size) * 8;
293 buf->f_bfree = qnx4_count_free_blocks(sb); 291 buf->f_bfree = qnx4_count_free_blocks(sb);
294 buf->f_bavail = buf->f_bfree; 292 buf->f_bavail = buf->f_bfree;
295 buf->f_namelen = QNX4_NAME_MAX; 293 buf->f_namelen = QNX4_NAME_MAX;
296 294
297 unlock_kernel(); 295 unlock_kernel();
298 296
299 return 0; 297 return 0;
300 } 298 }
301 299
302 /* 300 /*
303 * Check the root directory of the filesystem to make sure 301 * Check the root directory of the filesystem to make sure
304 * it really _is_ a qnx4 filesystem, and to check the size 302 * it really _is_ a qnx4 filesystem, and to check the size
305 * of the directory entry. 303 * of the directory entry.
306 */ 304 */
307 static const char *qnx4_checkroot(struct super_block *sb) 305 static const char *qnx4_checkroot(struct super_block *sb)
308 { 306 {
309 struct buffer_head *bh; 307 struct buffer_head *bh;
310 struct qnx4_inode_entry *rootdir; 308 struct qnx4_inode_entry *rootdir;
311 int rd, rl; 309 int rd, rl;
312 int i, j; 310 int i, j;
313 int found = 0; 311 int found = 0;
314 312
315 if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/') { 313 if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/') {
316 return "no qnx4 filesystem (no root dir)."; 314 return "no qnx4 filesystem (no root dir).";
317 } else { 315 } else {
318 QNX4DEBUG(("QNX4 filesystem found on dev %s.\n", sb->s_id)); 316 QNX4DEBUG(("QNX4 filesystem found on dev %s.\n", sb->s_id));
319 rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1; 317 rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1;
320 rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size); 318 rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size);
321 for (j = 0; j < rl; j++) { 319 for (j = 0; j < rl; j++) {
322 bh = sb_bread(sb, rd + j); /* root dir, first block */ 320 bh = sb_bread(sb, rd + j); /* root dir, first block */
323 if (bh == NULL) { 321 if (bh == NULL) {
324 return "unable to read root entry."; 322 return "unable to read root entry.";
325 } 323 }
326 for (i = 0; i < QNX4_INODES_PER_BLOCK; i++) { 324 for (i = 0; i < QNX4_INODES_PER_BLOCK; i++) {
327 rootdir = (struct qnx4_inode_entry *) (bh->b_data + i * QNX4_DIR_ENTRY_SIZE); 325 rootdir = (struct qnx4_inode_entry *) (bh->b_data + i * QNX4_DIR_ENTRY_SIZE);
328 if (rootdir->di_fname != NULL) { 326 if (rootdir->di_fname != NULL) {
329 QNX4DEBUG(("Rootdir entry found : [%s]\n", rootdir->di_fname)); 327 QNX4DEBUG(("Rootdir entry found : [%s]\n", rootdir->di_fname));
330 if (!strncmp(rootdir->di_fname, QNX4_BMNAME, sizeof QNX4_BMNAME)) { 328 if (!strncmp(rootdir->di_fname, QNX4_BMNAME, sizeof QNX4_BMNAME)) {
331 found = 1; 329 found = 1;
332 qnx4_sb(sb)->BitMap = kmalloc( sizeof( struct qnx4_inode_entry ), GFP_KERNEL ); 330 qnx4_sb(sb)->BitMap = kmalloc( sizeof( struct qnx4_inode_entry ), GFP_KERNEL );
333 if (!qnx4_sb(sb)->BitMap) { 331 if (!qnx4_sb(sb)->BitMap) {
334 brelse (bh); 332 brelse (bh);
335 return "not enough memory for bitmap inode"; 333 return "not enough memory for bitmap inode";
336 } 334 }
337 memcpy( qnx4_sb(sb)->BitMap, rootdir, sizeof( struct qnx4_inode_entry ) ); /* keep bitmap inode known */ 335 memcpy( qnx4_sb(sb)->BitMap, rootdir, sizeof( struct qnx4_inode_entry ) ); /* keep bitmap inode known */
338 break; 336 break;
339 } 337 }
340 } 338 }
341 } 339 }
342 brelse(bh); 340 brelse(bh);
343 if (found != 0) { 341 if (found != 0) {
344 break; 342 break;
345 } 343 }
346 } 344 }
347 if (found == 0) { 345 if (found == 0) {
348 return "bitmap file not found."; 346 return "bitmap file not found.";
349 } 347 }
350 } 348 }
351 return NULL; 349 return NULL;
352 } 350 }
353 351
354 static int qnx4_fill_super(struct super_block *s, void *data, int silent) 352 static int qnx4_fill_super(struct super_block *s, void *data, int silent)
355 { 353 {
356 struct buffer_head *bh; 354 struct buffer_head *bh;
357 struct inode *root; 355 struct inode *root;
358 const char *errmsg; 356 const char *errmsg;
359 struct qnx4_sb_info *qs; 357 struct qnx4_sb_info *qs;
358 int ret = -EINVAL;
360 359
361 qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL); 360 qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL);
362 if (!qs) 361 if (!qs)
363 return -ENOMEM; 362 return -ENOMEM;
364 s->s_fs_info = qs; 363 s->s_fs_info = qs;
365 364
366 sb_set_blocksize(s, QNX4_BLOCK_SIZE); 365 sb_set_blocksize(s, QNX4_BLOCK_SIZE);
367 366
368 /* Check the superblock signature. Since the qnx4 code is 367 /* Check the superblock signature. Since the qnx4 code is
369 dangerous, we should leave as quickly as possible 368 dangerous, we should leave as quickly as possible
370 if we don't belong here... */ 369 if we don't belong here... */
371 bh = sb_bread(s, 1); 370 bh = sb_bread(s, 1);
372 if (!bh) { 371 if (!bh) {
373 printk("qnx4: unable to read the superblock\n"); 372 printk("qnx4: unable to read the superblock\n");
374 goto outnobh; 373 goto outnobh;
375 } 374 }
376 if ( le32_to_cpup((__le32*) bh->b_data) != QNX4_SUPER_MAGIC ) { 375 if ( le32_to_cpup((__le32*) bh->b_data) != QNX4_SUPER_MAGIC ) {
377 if (!silent) 376 if (!silent)
378 printk("qnx4: wrong fsid in superblock.\n"); 377 printk("qnx4: wrong fsid in superblock.\n");
379 goto out; 378 goto out;
380 } 379 }
381 s->s_op = &qnx4_sops; 380 s->s_op = &qnx4_sops;
382 s->s_magic = QNX4_SUPER_MAGIC; 381 s->s_magic = QNX4_SUPER_MAGIC;
383 #ifndef CONFIG_QNX4FS_RW 382 #ifndef CONFIG_QNX4FS_RW
384 s->s_flags |= MS_RDONLY; /* Yup, read-only yet */ 383 s->s_flags |= MS_RDONLY; /* Yup, read-only yet */
385 #endif 384 #endif
386 qnx4_sb(s)->sb_buf = bh; 385 qnx4_sb(s)->sb_buf = bh;
387 qnx4_sb(s)->sb = (struct qnx4_super_block *) bh->b_data; 386 qnx4_sb(s)->sb = (struct qnx4_super_block *) bh->b_data;
388 387
389 388
390 /* check before allocating dentries, inodes, .. */ 389 /* check before allocating dentries, inodes, .. */
391 errmsg = qnx4_checkroot(s); 390 errmsg = qnx4_checkroot(s);
392 if (errmsg != NULL) { 391 if (errmsg != NULL) {
393 if (!silent) 392 if (!silent)
394 printk("qnx4: %s\n", errmsg); 393 printk("qnx4: %s\n", errmsg);
395 goto out; 394 goto out;
396 } 395 }
397 396
398 /* does root not have inode number QNX4_ROOT_INO ?? */ 397 /* does root not have inode number QNX4_ROOT_INO ?? */
399 root = iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); 398 root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
400 if (!root) { 399 if (IS_ERR(root)) {
401 printk("qnx4: get inode failed\n"); 400 printk("qnx4: get inode failed\n");
401 ret = PTR_ERR(root);
402 goto out; 402 goto out;
403 } 403 }
404 404
405 ret = -ENOMEM;
405 s->s_root = d_alloc_root(root); 406 s->s_root = d_alloc_root(root);
406 if (s->s_root == NULL) 407 if (s->s_root == NULL)
407 goto outi; 408 goto outi;
408 409
409 brelse(bh); 410 brelse(bh);
410 411
411 return 0; 412 return 0;
412 413
413 outi: 414 outi:
414 iput(root); 415 iput(root);
415 out: 416 out:
416 brelse(bh); 417 brelse(bh);
417 outnobh: 418 outnobh:
418 kfree(qs); 419 kfree(qs);
419 s->s_fs_info = NULL; 420 s->s_fs_info = NULL;
420 return -EINVAL; 421 return ret;
421 } 422 }
422 423
423 static void qnx4_put_super(struct super_block *sb) 424 static void qnx4_put_super(struct super_block *sb)
424 { 425 {
425 struct qnx4_sb_info *qs = qnx4_sb(sb); 426 struct qnx4_sb_info *qs = qnx4_sb(sb);
426 kfree( qs->BitMap ); 427 kfree( qs->BitMap );
427 kfree( qs ); 428 kfree( qs );
428 sb->s_fs_info = NULL; 429 sb->s_fs_info = NULL;
429 return; 430 return;
430 } 431 }
431 432
432 static int qnx4_writepage(struct page *page, struct writeback_control *wbc) 433 static int qnx4_writepage(struct page *page, struct writeback_control *wbc)
433 { 434 {
434 return block_write_full_page(page,qnx4_get_block, wbc); 435 return block_write_full_page(page,qnx4_get_block, wbc);
435 } 436 }
436 437
437 static int qnx4_readpage(struct file *file, struct page *page) 438 static int qnx4_readpage(struct file *file, struct page *page)
438 { 439 {
439 return block_read_full_page(page,qnx4_get_block); 440 return block_read_full_page(page,qnx4_get_block);
440 } 441 }
441 442
442 static int qnx4_write_begin(struct file *file, struct address_space *mapping, 443 static int qnx4_write_begin(struct file *file, struct address_space *mapping,
443 loff_t pos, unsigned len, unsigned flags, 444 loff_t pos, unsigned len, unsigned flags,
444 struct page **pagep, void **fsdata) 445 struct page **pagep, void **fsdata)
445 { 446 {
446 struct qnx4_inode_info *qnx4_inode = qnx4_i(mapping->host); 447 struct qnx4_inode_info *qnx4_inode = qnx4_i(mapping->host);
447 *pagep = NULL; 448 *pagep = NULL;
448 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata, 449 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
449 qnx4_get_block, 450 qnx4_get_block,
450 &qnx4_inode->mmu_private); 451 &qnx4_inode->mmu_private);
451 } 452 }
452 static sector_t qnx4_bmap(struct address_space *mapping, sector_t block) 453 static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
453 { 454 {
454 return generic_block_bmap(mapping,block,qnx4_get_block); 455 return generic_block_bmap(mapping,block,qnx4_get_block);
455 } 456 }
456 static const struct address_space_operations qnx4_aops = { 457 static const struct address_space_operations qnx4_aops = {
457 .readpage = qnx4_readpage, 458 .readpage = qnx4_readpage,
458 .writepage = qnx4_writepage, 459 .writepage = qnx4_writepage,
459 .sync_page = block_sync_page, 460 .sync_page = block_sync_page,
460 .write_begin = qnx4_write_begin, 461 .write_begin = qnx4_write_begin,
461 .write_end = generic_write_end, 462 .write_end = generic_write_end,
462 .bmap = qnx4_bmap 463 .bmap = qnx4_bmap
463 }; 464 };
464 465
465 static void qnx4_read_inode(struct inode *inode) 466 struct inode *qnx4_iget(struct super_block *sb, unsigned long ino)
466 { 467 {
467 struct buffer_head *bh; 468 struct buffer_head *bh;
468 struct qnx4_inode_entry *raw_inode; 469 struct qnx4_inode_entry *raw_inode;
469 int block, ino; 470 int block;
470 struct super_block *sb = inode->i_sb; 471 struct qnx4_inode_entry *qnx4_inode;
471 struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode); 472 struct inode *inode;
472 473
473 ino = inode->i_ino; 474 inode = iget_locked(sb, ino);
475 if (!inode)
476 return ERR_PTR(-ENOMEM);
477 if (!(inode->i_state & I_NEW))
478 return inode;
479
480 qnx4_inode = qnx4_raw_inode(inode);
474 inode->i_mode = 0; 481 inode->i_mode = 0;
475 482
476 QNX4DEBUG(("Reading inode : [%d]\n", ino)); 483 QNX4DEBUG(("Reading inode : [%d]\n", ino));
477 if (!ino) { 484 if (!ino) {
478 printk("qnx4: bad inode number on dev %s: %d is out of range\n", 485 printk(KERN_ERR "qnx4: bad inode number on dev %s: %lu is "
486 "out of range\n",
479 sb->s_id, ino); 487 sb->s_id, ino);
480 return; 488 iget_failed(inode);
489 return ERR_PTR(-EIO);
481 } 490 }
482 block = ino / QNX4_INODES_PER_BLOCK; 491 block = ino / QNX4_INODES_PER_BLOCK;
483 492
484 if (!(bh = sb_bread(sb, block))) { 493 if (!(bh = sb_bread(sb, block))) {
485 printk("qnx4: major problem: unable to read inode from dev " 494 printk("qnx4: major problem: unable to read inode from dev "
486 "%s\n", sb->s_id); 495 "%s\n", sb->s_id);
487 return; 496 iget_failed(inode);
497 return ERR_PTR(-EIO);
488 } 498 }
489 raw_inode = ((struct qnx4_inode_entry *) bh->b_data) + 499 raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
490 (ino % QNX4_INODES_PER_BLOCK); 500 (ino % QNX4_INODES_PER_BLOCK);
491 501
492 inode->i_mode = le16_to_cpu(raw_inode->di_mode); 502 inode->i_mode = le16_to_cpu(raw_inode->di_mode);
493 inode->i_uid = (uid_t)le16_to_cpu(raw_inode->di_uid); 503 inode->i_uid = (uid_t)le16_to_cpu(raw_inode->di_uid);
494 inode->i_gid = (gid_t)le16_to_cpu(raw_inode->di_gid); 504 inode->i_gid = (gid_t)le16_to_cpu(raw_inode->di_gid);
495 inode->i_nlink = le16_to_cpu(raw_inode->di_nlink); 505 inode->i_nlink = le16_to_cpu(raw_inode->di_nlink);
496 inode->i_size = le32_to_cpu(raw_inode->di_size); 506 inode->i_size = le32_to_cpu(raw_inode->di_size);
497 inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->di_mtime); 507 inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->di_mtime);
498 inode->i_mtime.tv_nsec = 0; 508 inode->i_mtime.tv_nsec = 0;
499 inode->i_atime.tv_sec = le32_to_cpu(raw_inode->di_atime); 509 inode->i_atime.tv_sec = le32_to_cpu(raw_inode->di_atime);
500 inode->i_atime.tv_nsec = 0; 510 inode->i_atime.tv_nsec = 0;
501 inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->di_ctime); 511 inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->di_ctime);
502 inode->i_ctime.tv_nsec = 0; 512 inode->i_ctime.tv_nsec = 0;
503 inode->i_blocks = le32_to_cpu(raw_inode->di_first_xtnt.xtnt_size); 513 inode->i_blocks = le32_to_cpu(raw_inode->di_first_xtnt.xtnt_size);
504 514
505 memcpy(qnx4_inode, raw_inode, QNX4_DIR_ENTRY_SIZE); 515 memcpy(qnx4_inode, raw_inode, QNX4_DIR_ENTRY_SIZE);
506 if (S_ISREG(inode->i_mode)) { 516 if (S_ISREG(inode->i_mode)) {
507 inode->i_op = &qnx4_file_inode_operations; 517 inode->i_op = &qnx4_file_inode_operations;
508 inode->i_fop = &qnx4_file_operations; 518 inode->i_fop = &qnx4_file_operations;
509 inode->i_mapping->a_ops = &qnx4_aops; 519 inode->i_mapping->a_ops = &qnx4_aops;
510 qnx4_i(inode)->mmu_private = inode->i_size; 520 qnx4_i(inode)->mmu_private = inode->i_size;
511 } else if (S_ISDIR(inode->i_mode)) { 521 } else if (S_ISDIR(inode->i_mode)) {
512 inode->i_op = &qnx4_dir_inode_operations; 522 inode->i_op = &qnx4_dir_inode_operations;
513 inode->i_fop = &qnx4_dir_operations; 523 inode->i_fop = &qnx4_dir_operations;
514 } else if (S_ISLNK(inode->i_mode)) { 524 } else if (S_ISLNK(inode->i_mode)) {
515 inode->i_op = &page_symlink_inode_operations; 525 inode->i_op = &page_symlink_inode_operations;
516 inode->i_mapping->a_ops = &qnx4_aops; 526 inode->i_mapping->a_ops = &qnx4_aops;
517 qnx4_i(inode)->mmu_private = inode->i_size; 527 qnx4_i(inode)->mmu_private = inode->i_size;
518 } else 528 } else {
519 printk("qnx4: bad inode %d on dev %s\n",ino,sb->s_id); 529 printk(KERN_ERR "qnx4: bad inode %lu on dev %s\n",
530 ino, sb->s_id);
531 iget_failed(inode);
532 brelse(bh);
533 return ERR_PTR(-EIO);
534 }
520 brelse(bh); 535 brelse(bh);
536 unlock_new_inode(inode);
537 return inode;
521 } 538 }
522 539
523 static struct kmem_cache *qnx4_inode_cachep; 540 static struct kmem_cache *qnx4_inode_cachep;
524 541
525 static struct inode *qnx4_alloc_inode(struct super_block *sb) 542 static struct inode *qnx4_alloc_inode(struct super_block *sb)
526 { 543 {
527 struct qnx4_inode_info *ei; 544 struct qnx4_inode_info *ei;
528 ei = kmem_cache_alloc(qnx4_inode_cachep, GFP_KERNEL); 545 ei = kmem_cache_alloc(qnx4_inode_cachep, GFP_KERNEL);
529 if (!ei) 546 if (!ei)
530 return NULL; 547 return NULL;
531 return &ei->vfs_inode; 548 return &ei->vfs_inode;
532 } 549 }
533 550
534 static void qnx4_destroy_inode(struct inode *inode) 551 static void qnx4_destroy_inode(struct inode *inode)
535 { 552 {
536 kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); 553 kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode));
537 } 554 }
538 555
539 static void init_once(struct kmem_cache *cachep, void *foo) 556 static void init_once(struct kmem_cache *cachep, void *foo)
540 { 557 {
541 struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; 558 struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;
542 559
543 inode_init_once(&ei->vfs_inode); 560 inode_init_once(&ei->vfs_inode);
544 } 561 }
545 562
546 static int init_inodecache(void) 563 static int init_inodecache(void)
547 { 564 {
548 qnx4_inode_cachep = kmem_cache_create("qnx4_inode_cache", 565 qnx4_inode_cachep = kmem_cache_create("qnx4_inode_cache",
549 sizeof(struct qnx4_inode_info), 566 sizeof(struct qnx4_inode_info),
550 0, (SLAB_RECLAIM_ACCOUNT| 567 0, (SLAB_RECLAIM_ACCOUNT|
551 SLAB_MEM_SPREAD), 568 SLAB_MEM_SPREAD),
552 init_once); 569 init_once);
553 if (qnx4_inode_cachep == NULL) 570 if (qnx4_inode_cachep == NULL)
554 return -ENOMEM; 571 return -ENOMEM;
555 return 0; 572 return 0;
556 } 573 }
557 574
558 static void destroy_inodecache(void) 575 static void destroy_inodecache(void)
559 { 576 {
560 kmem_cache_destroy(qnx4_inode_cachep); 577 kmem_cache_destroy(qnx4_inode_cachep);
561 } 578 }
562 579
563 static int qnx4_get_sb(struct file_system_type *fs_type, 580 static int qnx4_get_sb(struct file_system_type *fs_type,
564 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 581 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
565 { 582 {
566 return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super, 583 return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super,
567 mnt); 584 mnt);
568 } 585 }
569 586
570 static struct file_system_type qnx4_fs_type = { 587 static struct file_system_type qnx4_fs_type = {
571 .owner = THIS_MODULE, 588 .owner = THIS_MODULE,
572 .name = "qnx4", 589 .name = "qnx4",
573 .get_sb = qnx4_get_sb, 590 .get_sb = qnx4_get_sb,
574 .kill_sb = kill_block_super, 591 .kill_sb = kill_block_super,
575 .fs_flags = FS_REQUIRES_DEV, 592 .fs_flags = FS_REQUIRES_DEV,
576 }; 593 };
577 594
578 static int __init init_qnx4_fs(void) 595 static int __init init_qnx4_fs(void)
579 { 596 {
580 int err; 597 int err;
581 598
582 err = init_inodecache(); 599 err = init_inodecache();
583 if (err) 600 if (err)
584 return err; 601 return err;
585 602
586 err = register_filesystem(&qnx4_fs_type); 603 err = register_filesystem(&qnx4_fs_type);
587 if (err) { 604 if (err) {
588 destroy_inodecache(); 605 destroy_inodecache();
589 return err; 606 return err;
590 } 607 }
591 608
592 printk("QNX4 filesystem 0.2.3 registered.\n"); 609 printk("QNX4 filesystem 0.2.3 registered.\n");
593 return 0; 610 return 0;
594 } 611 }
595 612
596 static void __exit exit_qnx4_fs(void) 613 static void __exit exit_qnx4_fs(void)
597 { 614 {
598 unregister_filesystem(&qnx4_fs_type); 615 unregister_filesystem(&qnx4_fs_type);
599 destroy_inodecache(); 616 destroy_inodecache();
600 } 617 }
601 618
602 module_init(init_qnx4_fs) 619 module_init(init_qnx4_fs)
603 module_exit(exit_qnx4_fs) 620 module_exit(exit_qnx4_fs)
604 MODULE_LICENSE("GPL"); 621 MODULE_LICENSE("GPL");
1 /* 1 /*
2 * QNX4 file system, Linux implementation. 2 * QNX4 file system, Linux implementation.
3 * 3 *
4 * Version : 0.2.1 4 * Version : 0.2.1
5 * 5 *
6 * Using parts of the xiafs filesystem. 6 * Using parts of the xiafs filesystem.
7 * 7 *
8 * History : 8 * History :
9 * 9 *
10 * 01-06-1998 by Richard Frowijn : first release. 10 * 01-06-1998 by Richard Frowijn : first release.
11 * 21-06-1998 by Frank Denis : dcache support, fixed error codes. 11 * 21-06-1998 by Frank Denis : dcache support, fixed error codes.
12 * 04-07-1998 by Frank Denis : first step for rmdir/unlink. 12 * 04-07-1998 by Frank Denis : first step for rmdir/unlink.
13 */ 13 */
14 14
15 #include <linux/time.h> 15 #include <linux/time.h>
16 #include <linux/fs.h> 16 #include <linux/fs.h>
17 #include <linux/qnx4_fs.h> 17 #include <linux/qnx4_fs.h>
18 #include <linux/kernel.h> 18 #include <linux/kernel.h>
19 #include <linux/string.h> 19 #include <linux/string.h>
20 #include <linux/stat.h> 20 #include <linux/stat.h>
21 #include <linux/fcntl.h> 21 #include <linux/fcntl.h>
22 #include <linux/errno.h> 22 #include <linux/errno.h>
23 #include <linux/smp_lock.h> 23 #include <linux/smp_lock.h>
24 #include <linux/buffer_head.h> 24 #include <linux/buffer_head.h>
25 25
26 26
27 /* 27 /*
28 * check if the filename is correct. For some obscure reason, qnx writes a 28 * check if the filename is correct. For some obscure reason, qnx writes a
29 * new file twice in the directory entry, first with all possible options at 0 29 * new file twice in the directory entry, first with all possible options at 0
30 * and for a second time the way it is, they want us not to access the qnx 30 * and for a second time the way it is, they want us not to access the qnx
31 * filesystem when whe are using linux. 31 * filesystem when whe are using linux.
32 */ 32 */
33 static int qnx4_match(int len, const char *name, 33 static int qnx4_match(int len, const char *name,
34 struct buffer_head *bh, unsigned long *offset) 34 struct buffer_head *bh, unsigned long *offset)
35 { 35 {
36 struct qnx4_inode_entry *de; 36 struct qnx4_inode_entry *de;
37 int namelen, thislen; 37 int namelen, thislen;
38 38
39 if (bh == NULL) { 39 if (bh == NULL) {
40 printk("qnx4: matching unassigned buffer !\n"); 40 printk("qnx4: matching unassigned buffer !\n");
41 return 0; 41 return 0;
42 } 42 }
43 de = (struct qnx4_inode_entry *) (bh->b_data + *offset); 43 de = (struct qnx4_inode_entry *) (bh->b_data + *offset);
44 *offset += QNX4_DIR_ENTRY_SIZE; 44 *offset += QNX4_DIR_ENTRY_SIZE;
45 if ((de->di_status & QNX4_FILE_LINK) != 0) { 45 if ((de->di_status & QNX4_FILE_LINK) != 0) {
46 namelen = QNX4_NAME_MAX; 46 namelen = QNX4_NAME_MAX;
47 } else { 47 } else {
48 namelen = QNX4_SHORT_NAME_MAX; 48 namelen = QNX4_SHORT_NAME_MAX;
49 } 49 }
50 /* "" means "." ---> so paths like "/usr/lib//libc.a" work */ 50 /* "" means "." ---> so paths like "/usr/lib//libc.a" work */
51 if (!len && (de->di_fname[0] == '.') && (de->di_fname[1] == '\0')) { 51 if (!len && (de->di_fname[0] == '.') && (de->di_fname[1] == '\0')) {
52 return 1; 52 return 1;
53 } 53 }
54 thislen = strlen( de->di_fname ); 54 thislen = strlen( de->di_fname );
55 if ( thislen > namelen ) 55 if ( thislen > namelen )
56 thislen = namelen; 56 thislen = namelen;
57 if (len != thislen) { 57 if (len != thislen) {
58 return 0; 58 return 0;
59 } 59 }
60 if (strncmp(name, de->di_fname, len) == 0) { 60 if (strncmp(name, de->di_fname, len) == 0) {
61 if ((de->di_status & (QNX4_FILE_USED|QNX4_FILE_LINK)) != 0) { 61 if ((de->di_status & (QNX4_FILE_USED|QNX4_FILE_LINK)) != 0) {
62 return 1; 62 return 1;
63 } 63 }
64 } 64 }
65 return 0; 65 return 0;
66 } 66 }
67 67
68 static struct buffer_head *qnx4_find_entry(int len, struct inode *dir, 68 static struct buffer_head *qnx4_find_entry(int len, struct inode *dir,
69 const char *name, struct qnx4_inode_entry **res_dir, int *ino) 69 const char *name, struct qnx4_inode_entry **res_dir, int *ino)
70 { 70 {
71 unsigned long block, offset, blkofs; 71 unsigned long block, offset, blkofs;
72 struct buffer_head *bh; 72 struct buffer_head *bh;
73 73
74 *res_dir = NULL; 74 *res_dir = NULL;
75 if (!dir->i_sb) { 75 if (!dir->i_sb) {
76 printk("qnx4: no superblock on dir.\n"); 76 printk("qnx4: no superblock on dir.\n");
77 return NULL; 77 return NULL;
78 } 78 }
79 bh = NULL; 79 bh = NULL;
80 block = offset = blkofs = 0; 80 block = offset = blkofs = 0;
81 while (blkofs * QNX4_BLOCK_SIZE + offset < dir->i_size) { 81 while (blkofs * QNX4_BLOCK_SIZE + offset < dir->i_size) {
82 if (!bh) { 82 if (!bh) {
83 bh = qnx4_bread(dir, blkofs, 0); 83 bh = qnx4_bread(dir, blkofs, 0);
84 if (!bh) { 84 if (!bh) {
85 blkofs++; 85 blkofs++;
86 continue; 86 continue;
87 } 87 }
88 } 88 }
89 *res_dir = (struct qnx4_inode_entry *) (bh->b_data + offset); 89 *res_dir = (struct qnx4_inode_entry *) (bh->b_data + offset);
90 if (qnx4_match(len, name, bh, &offset)) { 90 if (qnx4_match(len, name, bh, &offset)) {
91 block = qnx4_block_map( dir, blkofs ); 91 block = qnx4_block_map( dir, blkofs );
92 *ino = block * QNX4_INODES_PER_BLOCK + 92 *ino = block * QNX4_INODES_PER_BLOCK +
93 (offset / QNX4_DIR_ENTRY_SIZE) - 1; 93 (offset / QNX4_DIR_ENTRY_SIZE) - 1;
94 return bh; 94 return bh;
95 } 95 }
96 if (offset < bh->b_size) { 96 if (offset < bh->b_size) {
97 continue; 97 continue;
98 } 98 }
99 brelse(bh); 99 brelse(bh);
100 bh = NULL; 100 bh = NULL;
101 offset = 0; 101 offset = 0;
102 blkofs++; 102 blkofs++;
103 } 103 }
104 brelse(bh); 104 brelse(bh);
105 *res_dir = NULL; 105 *res_dir = NULL;
106 return NULL; 106 return NULL;
107 } 107 }
108 108
109 struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) 109 struct dentry * qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
110 { 110 {
111 int ino; 111 int ino;
112 struct qnx4_inode_entry *de; 112 struct qnx4_inode_entry *de;
113 struct qnx4_link_info *lnk; 113 struct qnx4_link_info *lnk;
114 struct buffer_head *bh; 114 struct buffer_head *bh;
115 const char *name = dentry->d_name.name; 115 const char *name = dentry->d_name.name;
116 int len = dentry->d_name.len; 116 int len = dentry->d_name.len;
117 struct inode *foundinode = NULL; 117 struct inode *foundinode = NULL;
118 118
119 lock_kernel(); 119 lock_kernel();
120 if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino))) 120 if (!(bh = qnx4_find_entry(len, dir, name, &de, &ino)))
121 goto out; 121 goto out;
122 /* The entry is linked, let's get the real info */ 122 /* The entry is linked, let's get the real info */
123 if ((de->di_status & QNX4_FILE_LINK) == QNX4_FILE_LINK) { 123 if ((de->di_status & QNX4_FILE_LINK) == QNX4_FILE_LINK) {
124 lnk = (struct qnx4_link_info *) de; 124 lnk = (struct qnx4_link_info *) de;
125 ino = (le32_to_cpu(lnk->dl_inode_blk) - 1) * 125 ino = (le32_to_cpu(lnk->dl_inode_blk) - 1) *
126 QNX4_INODES_PER_BLOCK + 126 QNX4_INODES_PER_BLOCK +
127 lnk->dl_inode_ndx; 127 lnk->dl_inode_ndx;
128 } 128 }
129 brelse(bh); 129 brelse(bh);
130 130
131 if ((foundinode = iget(dir->i_sb, ino)) == NULL) { 131 foundinode = qnx4_iget(dir->i_sb, ino);
132 if (IS_ERR(foundinode)) {
132 unlock_kernel(); 133 unlock_kernel();
133 QNX4DEBUG(("qnx4: lookup->iget -> NULL\n")); 134 QNX4DEBUG(("qnx4: lookup->iget -> error %ld\n",
134 return ERR_PTR(-EACCES); 135 PTR_ERR(foundinode)));
136 return ERR_CAST(foundinode);
135 } 137 }
136 out: 138 out:
137 unlock_kernel(); 139 unlock_kernel();
138 d_add(dentry, foundinode); 140 d_add(dentry, foundinode);
139 141
140 return NULL; 142 return NULL;
141 } 143 }
142 144
143 #ifdef CONFIG_QNX4FS_RW 145 #ifdef CONFIG_QNX4FS_RW
144 int qnx4_create(struct inode *dir, struct dentry *dentry, int mode, 146 int qnx4_create(struct inode *dir, struct dentry *dentry, int mode,
145 struct nameidata *nd) 147 struct nameidata *nd)
146 { 148 {
147 QNX4DEBUG(("qnx4: qnx4_create\n")); 149 QNX4DEBUG(("qnx4: qnx4_create\n"));
148 if (dir == NULL) { 150 if (dir == NULL) {
149 return -ENOENT; 151 return -ENOENT;
150 } 152 }
151 return -ENOSPC; 153 return -ENOSPC;
152 } 154 }
153 155
154 int qnx4_rmdir(struct inode *dir, struct dentry *dentry) 156 int qnx4_rmdir(struct inode *dir, struct dentry *dentry)
155 { 157 {
156 struct buffer_head *bh; 158 struct buffer_head *bh;
157 struct qnx4_inode_entry *de; 159 struct qnx4_inode_entry *de;
158 struct inode *inode; 160 struct inode *inode;
159 int retval; 161 int retval;
160 int ino; 162 int ino;
161 163
162 QNX4DEBUG(("qnx4: qnx4_rmdir [%s]\n", dentry->d_name.name)); 164 QNX4DEBUG(("qnx4: qnx4_rmdir [%s]\n", dentry->d_name.name));
163 lock_kernel(); 165 lock_kernel();
164 bh = qnx4_find_entry(dentry->d_name.len, dir, dentry->d_name.name, 166 bh = qnx4_find_entry(dentry->d_name.len, dir, dentry->d_name.name,
165 &de, &ino); 167 &de, &ino);
166 if (bh == NULL) { 168 if (bh == NULL) {
167 unlock_kernel(); 169 unlock_kernel();
168 return -ENOENT; 170 return -ENOENT;
169 } 171 }
170 inode = dentry->d_inode; 172 inode = dentry->d_inode;
171 if (inode->i_ino != ino) { 173 if (inode->i_ino != ino) {
172 retval = -EIO; 174 retval = -EIO;
173 goto end_rmdir; 175 goto end_rmdir;
174 } 176 }
175 #if 0 177 #if 0
176 if (!empty_dir(inode)) { 178 if (!empty_dir(inode)) {
177 retval = -ENOTEMPTY; 179 retval = -ENOTEMPTY;
178 goto end_rmdir; 180 goto end_rmdir;
179 } 181 }
180 #endif 182 #endif
181 if (inode->i_nlink != 2) { 183 if (inode->i_nlink != 2) {
182 QNX4DEBUG(("empty directory has nlink!=2 (%d)\n", inode->i_nlink)); 184 QNX4DEBUG(("empty directory has nlink!=2 (%d)\n", inode->i_nlink));
183 } 185 }
184 QNX4DEBUG(("qnx4: deleting directory\n")); 186 QNX4DEBUG(("qnx4: deleting directory\n"));
185 de->di_status = 0; 187 de->di_status = 0;
186 memset(de->di_fname, 0, sizeof de->di_fname); 188 memset(de->di_fname, 0, sizeof de->di_fname);
187 de->di_mode = 0; 189 de->di_mode = 0;
188 mark_buffer_dirty(bh); 190 mark_buffer_dirty(bh);
189 clear_nlink(inode); 191 clear_nlink(inode);
190 mark_inode_dirty(inode); 192 mark_inode_dirty(inode);
191 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; 193 inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
192 inode_dec_link_count(dir); 194 inode_dec_link_count(dir);
193 retval = 0; 195 retval = 0;
194 196
195 end_rmdir: 197 end_rmdir:
196 brelse(bh); 198 brelse(bh);
197 199
198 unlock_kernel(); 200 unlock_kernel();
199 return retval; 201 return retval;
200 } 202 }
201 203
202 int qnx4_unlink(struct inode *dir, struct dentry *dentry) 204 int qnx4_unlink(struct inode *dir, struct dentry *dentry)
203 { 205 {
204 struct buffer_head *bh; 206 struct buffer_head *bh;
205 struct qnx4_inode_entry *de; 207 struct qnx4_inode_entry *de;
206 struct inode *inode; 208 struct inode *inode;
207 int retval; 209 int retval;
208 int ino; 210 int ino;
209 211
210 QNX4DEBUG(("qnx4: qnx4_unlink [%s]\n", dentry->d_name.name)); 212 QNX4DEBUG(("qnx4: qnx4_unlink [%s]\n", dentry->d_name.name));
211 lock_kernel(); 213 lock_kernel();
212 bh = qnx4_find_entry(dentry->d_name.len, dir, dentry->d_name.name, 214 bh = qnx4_find_entry(dentry->d_name.len, dir, dentry->d_name.name,
213 &de, &ino); 215 &de, &ino);
214 if (bh == NULL) { 216 if (bh == NULL) {
215 unlock_kernel(); 217 unlock_kernel();
216 return -ENOENT; 218 return -ENOENT;
217 } 219 }
218 inode = dentry->d_inode; 220 inode = dentry->d_inode;
219 if (inode->i_ino != ino) { 221 if (inode->i_ino != ino) {
220 retval = -EIO; 222 retval = -EIO;
221 goto end_unlink; 223 goto end_unlink;
222 } 224 }
223 retval = -EPERM; 225 retval = -EPERM;
224 if (!inode->i_nlink) { 226 if (!inode->i_nlink) {
225 QNX4DEBUG(("Deleting nonexistent file (%s:%lu), %d\n", 227 QNX4DEBUG(("Deleting nonexistent file (%s:%lu), %d\n",
226 inode->i_sb->s_id, 228 inode->i_sb->s_id,
227 inode->i_ino, inode->i_nlink)); 229 inode->i_ino, inode->i_nlink));
228 inode->i_nlink = 1; 230 inode->i_nlink = 1;
229 } 231 }
230 de->di_status = 0; 232 de->di_status = 0;
231 memset(de->di_fname, 0, sizeof de->di_fname); 233 memset(de->di_fname, 0, sizeof de->di_fname);
232 de->di_mode = 0; 234 de->di_mode = 0;
233 mark_buffer_dirty(bh); 235 mark_buffer_dirty(bh);
234 dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC; 236 dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
235 mark_inode_dirty(dir); 237 mark_inode_dirty(dir);
236 inode->i_ctime = dir->i_ctime; 238 inode->i_ctime = dir->i_ctime;
237 inode_dec_link_count(inode); 239 inode_dec_link_count(inode);
238 retval = 0; 240 retval = 0;
239 241
240 end_unlink: 242 end_unlink:
241 unlock_kernel(); 243 unlock_kernel();
242 brelse(bh); 244 brelse(bh);
243 245
244 return retval; 246 return retval;
245 } 247 }
246 #endif 248 #endif
247 249
include/linux/qnx4_fs.h
1 /* 1 /*
2 * Name : qnx4_fs.h 2 * Name : qnx4_fs.h
3 * Author : Richard Frowijn 3 * Author : Richard Frowijn
4 * Function : qnx4 global filesystem definitions 4 * Function : qnx4 global filesystem definitions
5 * Version : 1.0.2 5 * Version : 1.0.2
6 * Last modified : 2000-01-31 6 * Last modified : 2000-01-31
7 * 7 *
8 * History : 23-03-1998 created 8 * History : 23-03-1998 created
9 */ 9 */
10 #ifndef _LINUX_QNX4_FS_H 10 #ifndef _LINUX_QNX4_FS_H
11 #define _LINUX_QNX4_FS_H 11 #define _LINUX_QNX4_FS_H
12 12
13 #include <linux/qnxtypes.h> 13 #include <linux/qnxtypes.h>
14 #include <linux/magic.h> 14 #include <linux/magic.h>
15 15
16 #define QNX4_ROOT_INO 1 16 #define QNX4_ROOT_INO 1
17 17
18 #define QNX4_MAX_XTNTS_PER_XBLK 60 18 #define QNX4_MAX_XTNTS_PER_XBLK 60
19 /* for di_status */ 19 /* for di_status */
20 #define QNX4_FILE_USED 0x01 20 #define QNX4_FILE_USED 0x01
21 #define QNX4_FILE_MODIFIED 0x02 21 #define QNX4_FILE_MODIFIED 0x02
22 #define QNX4_FILE_BUSY 0x04 22 #define QNX4_FILE_BUSY 0x04
23 #define QNX4_FILE_LINK 0x08 23 #define QNX4_FILE_LINK 0x08
24 #define QNX4_FILE_INODE 0x10 24 #define QNX4_FILE_INODE 0x10
25 #define QNX4_FILE_FSYSCLEAN 0x20 25 #define QNX4_FILE_FSYSCLEAN 0x20
26 26
27 #define QNX4_I_MAP_SLOTS 8 27 #define QNX4_I_MAP_SLOTS 8
28 #define QNX4_Z_MAP_SLOTS 64 28 #define QNX4_Z_MAP_SLOTS 64
29 #define QNX4_VALID_FS 0x0001 /* Clean fs. */ 29 #define QNX4_VALID_FS 0x0001 /* Clean fs. */
30 #define QNX4_ERROR_FS 0x0002 /* fs has errors. */ 30 #define QNX4_ERROR_FS 0x0002 /* fs has errors. */
31 #define QNX4_BLOCK_SIZE 0x200 /* blocksize of 512 bytes */ 31 #define QNX4_BLOCK_SIZE 0x200 /* blocksize of 512 bytes */
32 #define QNX4_BLOCK_SIZE_BITS 9 /* blocksize shift */ 32 #define QNX4_BLOCK_SIZE_BITS 9 /* blocksize shift */
33 #define QNX4_DIR_ENTRY_SIZE 0x040 /* dir entry size of 64 bytes */ 33 #define QNX4_DIR_ENTRY_SIZE 0x040 /* dir entry size of 64 bytes */
34 #define QNX4_DIR_ENTRY_SIZE_BITS 6 /* dir entry size shift */ 34 #define QNX4_DIR_ENTRY_SIZE_BITS 6 /* dir entry size shift */
35 #define QNX4_XBLK_ENTRY_SIZE 0x200 /* xblk entry size */ 35 #define QNX4_XBLK_ENTRY_SIZE 0x200 /* xblk entry size */
36 #define QNX4_INODES_PER_BLOCK 0x08 /* 512 / 64 */ 36 #define QNX4_INODES_PER_BLOCK 0x08 /* 512 / 64 */
37 37
38 /* for filenames */ 38 /* for filenames */
39 #define QNX4_SHORT_NAME_MAX 16 39 #define QNX4_SHORT_NAME_MAX 16
40 #define QNX4_NAME_MAX 48 40 #define QNX4_NAME_MAX 48
41 41
42 /* 42 /*
43 * This is the original qnx4 inode layout on disk. 43 * This is the original qnx4 inode layout on disk.
44 */ 44 */
45 struct qnx4_inode_entry { 45 struct qnx4_inode_entry {
46 char di_fname[QNX4_SHORT_NAME_MAX]; 46 char di_fname[QNX4_SHORT_NAME_MAX];
47 qnx4_off_t di_size; 47 qnx4_off_t di_size;
48 qnx4_xtnt_t di_first_xtnt; 48 qnx4_xtnt_t di_first_xtnt;
49 __le32 di_xblk; 49 __le32 di_xblk;
50 __le32 di_ftime; 50 __le32 di_ftime;
51 __le32 di_mtime; 51 __le32 di_mtime;
52 __le32 di_atime; 52 __le32 di_atime;
53 __le32 di_ctime; 53 __le32 di_ctime;
54 qnx4_nxtnt_t di_num_xtnts; 54 qnx4_nxtnt_t di_num_xtnts;
55 qnx4_mode_t di_mode; 55 qnx4_mode_t di_mode;
56 qnx4_muid_t di_uid; 56 qnx4_muid_t di_uid;
57 qnx4_mgid_t di_gid; 57 qnx4_mgid_t di_gid;
58 qnx4_nlink_t di_nlink; 58 qnx4_nlink_t di_nlink;
59 __u8 di_zero[4]; 59 __u8 di_zero[4];
60 qnx4_ftype_t di_type; 60 qnx4_ftype_t di_type;
61 __u8 di_status; 61 __u8 di_status;
62 }; 62 };
63 63
64 struct qnx4_link_info { 64 struct qnx4_link_info {
65 char dl_fname[QNX4_NAME_MAX]; 65 char dl_fname[QNX4_NAME_MAX];
66 __le32 dl_inode_blk; 66 __le32 dl_inode_blk;
67 __u8 dl_inode_ndx; 67 __u8 dl_inode_ndx;
68 __u8 dl_spare[10]; 68 __u8 dl_spare[10];
69 __u8 dl_status; 69 __u8 dl_status;
70 }; 70 };
71 71
72 struct qnx4_xblk { 72 struct qnx4_xblk {
73 __le32 xblk_next_xblk; 73 __le32 xblk_next_xblk;
74 __le32 xblk_prev_xblk; 74 __le32 xblk_prev_xblk;
75 __u8 xblk_num_xtnts; 75 __u8 xblk_num_xtnts;
76 __u8 xblk_spare[3]; 76 __u8 xblk_spare[3];
77 __le32 xblk_num_blocks; 77 __le32 xblk_num_blocks;
78 qnx4_xtnt_t xblk_xtnts[QNX4_MAX_XTNTS_PER_XBLK]; 78 qnx4_xtnt_t xblk_xtnts[QNX4_MAX_XTNTS_PER_XBLK];
79 char xblk_signature[8]; 79 char xblk_signature[8];
80 qnx4_xtnt_t xblk_first_xtnt; 80 qnx4_xtnt_t xblk_first_xtnt;
81 }; 81 };
82 82
83 struct qnx4_super_block { 83 struct qnx4_super_block {
84 struct qnx4_inode_entry RootDir; 84 struct qnx4_inode_entry RootDir;
85 struct qnx4_inode_entry Inode; 85 struct qnx4_inode_entry Inode;
86 struct qnx4_inode_entry Boot; 86 struct qnx4_inode_entry Boot;
87 struct qnx4_inode_entry AltBoot; 87 struct qnx4_inode_entry AltBoot;
88 }; 88 };
89 89
90 #ifdef __KERNEL__ 90 #ifdef __KERNEL__
91 91
92 #define QNX4_DEBUG 0 92 #define QNX4_DEBUG 0
93 93
94 #if QNX4_DEBUG 94 #if QNX4_DEBUG
95 #define QNX4DEBUG(X) printk X 95 #define QNX4DEBUG(X) printk X
96 #else 96 #else
97 #define QNX4DEBUG(X) (void) 0 97 #define QNX4DEBUG(X) (void) 0
98 #endif 98 #endif
99 99
100 struct qnx4_sb_info { 100 struct qnx4_sb_info {
101 struct buffer_head *sb_buf; /* superblock buffer */ 101 struct buffer_head *sb_buf; /* superblock buffer */
102 struct qnx4_super_block *sb; /* our superblock */ 102 struct qnx4_super_block *sb; /* our superblock */
103 unsigned int Version; /* may be useful */ 103 unsigned int Version; /* may be useful */
104 struct qnx4_inode_entry *BitMap; /* useful */ 104 struct qnx4_inode_entry *BitMap; /* useful */
105 }; 105 };
106 106
107 struct qnx4_inode_info { 107 struct qnx4_inode_info {
108 struct qnx4_inode_entry raw; 108 struct qnx4_inode_entry raw;
109 loff_t mmu_private; 109 loff_t mmu_private;
110 struct inode vfs_inode; 110 struct inode vfs_inode;
111 }; 111 };
112 112
113 extern struct inode *qnx4_iget(struct super_block *, unsigned long);
113 extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd); 114 extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd);
114 extern unsigned long qnx4_count_free_blocks(struct super_block *sb); 115 extern unsigned long qnx4_count_free_blocks(struct super_block *sb);
115 extern unsigned long qnx4_block_map(struct inode *inode, long iblock); 116 extern unsigned long qnx4_block_map(struct inode *inode, long iblock);
116 117
117 extern struct buffer_head *qnx4_bread(struct inode *, int, int); 118 extern struct buffer_head *qnx4_bread(struct inode *, int, int);
118 119
119 extern const struct inode_operations qnx4_file_inode_operations; 120 extern const struct inode_operations qnx4_file_inode_operations;
120 extern const struct inode_operations qnx4_dir_inode_operations; 121 extern const struct inode_operations qnx4_dir_inode_operations;
121 extern const struct file_operations qnx4_file_operations; 122 extern const struct file_operations qnx4_file_operations;
122 extern const struct file_operations qnx4_dir_operations; 123 extern const struct file_operations qnx4_dir_operations;
123 extern int qnx4_is_free(struct super_block *sb, long block); 124 extern int qnx4_is_free(struct super_block *sb, long block);
124 extern int qnx4_set_bitmap(struct super_block *sb, long block, int busy); 125 extern int qnx4_set_bitmap(struct super_block *sb, long block, int busy);
125 extern int qnx4_create(struct inode *inode, struct dentry *dentry, int mode, struct nameidata *nd); 126 extern int qnx4_create(struct inode *inode, struct dentry *dentry, int mode, struct nameidata *nd);
126 extern void qnx4_truncate(struct inode *inode); 127 extern void qnx4_truncate(struct inode *inode);
127 extern void qnx4_free_inode(struct inode *inode); 128 extern void qnx4_free_inode(struct inode *inode);
128 extern int qnx4_unlink(struct inode *dir, struct dentry *dentry); 129 extern int qnx4_unlink(struct inode *dir, struct dentry *dentry);
129 extern int qnx4_rmdir(struct inode *dir, struct dentry *dentry); 130 extern int qnx4_rmdir(struct inode *dir, struct dentry *dentry);
130 extern int qnx4_sync_file(struct file *file, struct dentry *dentry, int); 131 extern int qnx4_sync_file(struct file *file, struct dentry *dentry, int);
131 extern int qnx4_sync_inode(struct inode *inode); 132 extern int qnx4_sync_inode(struct inode *inode);
132 133
133 static inline struct qnx4_sb_info *qnx4_sb(struct super_block *sb) 134 static inline struct qnx4_sb_info *qnx4_sb(struct super_block *sb)
134 { 135 {
135 return sb->s_fs_info; 136 return sb->s_fs_info;
136 } 137 }
137 138
138 static inline struct qnx4_inode_info *qnx4_i(struct inode *inode) 139 static inline struct qnx4_inode_info *qnx4_i(struct inode *inode)
139 { 140 {
140 return container_of(inode, struct qnx4_inode_info, vfs_inode); 141 return container_of(inode, struct qnx4_inode_info, vfs_inode);
141 } 142 }
142 143
143 static inline struct qnx4_inode_entry *qnx4_raw_inode(struct inode *inode) 144 static inline struct qnx4_inode_entry *qnx4_raw_inode(struct inode *inode)
144 { 145 {
145 return &qnx4_i(inode)->raw; 146 return &qnx4_i(inode)->raw;
146 } 147 }
147 148
148 #endif /* __KERNEL__ */ 149 #endif /* __KERNEL__ */
149 150
150 #endif 151 #endif
151 152