Diff markup
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 relea 10 * 01-06-1998 by Richard Frowijn : first release.
11 * 20-06-1998 by Frank Denis : Linux 2.1.99+ s 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 w 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> <<
17 #include <linux/string.h> <<
18 #include <linux/errno.h> <<
19 #include <linux/slab.h> <<
20 #include <linux/fs.h> <<
21 #include <linux/qnx4_fs.h> <<
22 #include <linux/init.h> 16 #include <linux/init.h>
>> 17 #include <linux/slab.h>
23 #include <linux/highuid.h> 18 #include <linux/highuid.h>
24 #include <linux/smp_lock.h> 19 #include <linux/smp_lock.h>
25 #include <linux/pagemap.h> 20 #include <linux/pagemap.h>
26 #include <linux/buffer_head.h> 21 #include <linux/buffer_head.h>
27 #include <linux/vfs.h> !! 22 #include <linux/writeback.h>
28 #include <asm/uaccess.h> !! 23 #include <linux/statfs.h>
>> 24 #include "qnx4.h"
29 25
30 #define QNX4_VERSION 4 26 #define QNX4_VERSION 4
31 #define QNX4_BMNAME ".bitmap" 27 #define QNX4_BMNAME ".bitmap"
32 28
33 static const struct super_operations qnx4_sops 29 static const struct super_operations qnx4_sops;
34 30
35 #ifdef CONFIG_QNX4FS_RW 31 #ifdef CONFIG_QNX4FS_RW
36 32
37 int qnx4_sync_inode(struct inode *inode) <<
38 { <<
39 int err = 0; <<
40 # if 0 <<
41 struct buffer_head *bh; <<
42 <<
43 bh = qnx4_update_inode(inode); <<
44 if (bh && buffer_dirty(bh)) <<
45 { <<
46 sync_dirty_buffer(bh); <<
47 if (buffer_req(bh) && !buffer_ <<
48 { <<
49 printk ("IO error sync <<
50 inode->i_sb->s <<
51 err = -1; <<
52 } <<
53 brelse (bh); <<
54 } else if (!bh) { <<
55 err = -1; <<
56 } <<
57 # endif <<
58 <<
59 return err; <<
60 } <<
61 <<
62 static void qnx4_delete_inode(struct inode *in 33 static void qnx4_delete_inode(struct inode *inode)
63 { 34 {
64 QNX4DEBUG(("qnx4: deleting inode [%lu] 35 QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode->i_ino));
65 truncate_inode_pages(&inode->i_data, 0 36 truncate_inode_pages(&inode->i_data, 0);
66 inode->i_size = 0; 37 inode->i_size = 0;
67 qnx4_truncate(inode); 38 qnx4_truncate(inode);
68 lock_kernel(); 39 lock_kernel();
69 qnx4_free_inode(inode); 40 qnx4_free_inode(inode);
70 unlock_kernel(); 41 unlock_kernel();
71 } 42 }
72 43
73 static void qnx4_write_super(struct super_bloc !! 44 static int qnx4_write_inode(struct inode *inode, int do_sync)
74 { <<
75 lock_kernel(); <<
76 QNX4DEBUG(("qnx4: write_super\n")); <<
77 sb->s_dirt = 0; <<
78 unlock_kernel(); <<
79 } <<
80 <<
81 static int qnx4_write_inode(struct inode *inod <<
82 { 45 {
83 struct qnx4_inode_entry *raw_inode; 46 struct qnx4_inode_entry *raw_inode;
84 int block, ino; 47 int block, ino;
85 struct buffer_head *bh; 48 struct buffer_head *bh;
86 ino = inode->i_ino; 49 ino = inode->i_ino;
87 50
88 QNX4DEBUG(("qnx4: write inode 1.\n")); 51 QNX4DEBUG(("qnx4: write inode 1.\n"));
89 if (inode->i_nlink == 0) { 52 if (inode->i_nlink == 0) {
90 return 0; 53 return 0;
91 } 54 }
92 if (!ino) { 55 if (!ino) {
93 printk("qnx4: bad inode number 56 printk("qnx4: bad inode number on dev %s: %d is out of range\n",
94 inode->i_sb->s_id, ino) 57 inode->i_sb->s_id, ino);
95 return -EIO; 58 return -EIO;
96 } 59 }
97 QNX4DEBUG(("qnx4: write inode 2.\n")); 60 QNX4DEBUG(("qnx4: write inode 2.\n"));
98 block = ino / QNX4_INODES_PER_BLOCK; 61 block = ino / QNX4_INODES_PER_BLOCK;
99 lock_kernel(); 62 lock_kernel();
100 if (!(bh = sb_bread(inode->i_sb, block 63 if (!(bh = sb_bread(inode->i_sb, block))) {
101 printk("qnx4: major problem: u 64 printk("qnx4: major problem: unable to read inode from dev "
102 "%s\n", inode->i_sb->s_ 65 "%s\n", inode->i_sb->s_id);
103 unlock_kernel(); 66 unlock_kernel();
104 return -EIO; 67 return -EIO;
105 } 68 }
106 raw_inode = ((struct qnx4_inode_entry 69 raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
107 (ino % QNX4_INODES_PER_BLOCK); 70 (ino % QNX4_INODES_PER_BLOCK);
108 raw_inode->di_mode = cpu_to_le16(inod 71 raw_inode->di_mode = cpu_to_le16(inode->i_mode);
109 raw_inode->di_uid = cpu_to_le16(fs_h 72 raw_inode->di_uid = cpu_to_le16(fs_high2lowuid(inode->i_uid));
110 raw_inode->di_gid = cpu_to_le16(fs_h 73 raw_inode->di_gid = cpu_to_le16(fs_high2lowgid(inode->i_gid));
111 raw_inode->di_nlink = cpu_to_le16(inod 74 raw_inode->di_nlink = cpu_to_le16(inode->i_nlink);
112 raw_inode->di_size = cpu_to_le32(inod 75 raw_inode->di_size = cpu_to_le32(inode->i_size);
113 raw_inode->di_mtime = cpu_to_le32(inod 76 raw_inode->di_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
114 raw_inode->di_atime = cpu_to_le32(inod 77 raw_inode->di_atime = cpu_to_le32(inode->i_atime.tv_sec);
115 raw_inode->di_ctime = cpu_to_le32(inod 78 raw_inode->di_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
116 raw_inode->di_first_xtnt.xtnt_size = c 79 raw_inode->di_first_xtnt.xtnt_size = cpu_to_le32(inode->i_blocks);
117 mark_buffer_dirty(bh); 80 mark_buffer_dirty(bh);
>> 81 if (do_sync) {
>> 82 sync_dirty_buffer(bh);
>> 83 if (buffer_req(bh) && !buffer_uptodate(bh)) {
>> 84 printk("qnx4: IO error syncing inode [%s:%08x]\n",
>> 85 inode->i_sb->s_id, ino);
>> 86 brelse(bh);
>> 87 unlock_kernel();
>> 88 return -EIO;
>> 89 }
>> 90 }
118 brelse(bh); 91 brelse(bh);
119 unlock_kernel(); 92 unlock_kernel();
120 return 0; 93 return 0;
121 } 94 }
122 95
123 #endif 96 #endif
124 97
125 static void qnx4_put_super(struct super_block 98 static void qnx4_put_super(struct super_block *sb);
126 static struct inode *qnx4_alloc_inode(struct s 99 static struct inode *qnx4_alloc_inode(struct super_block *sb);
127 static void qnx4_destroy_inode(struct inode *i 100 static void qnx4_destroy_inode(struct inode *inode);
128 static int qnx4_remount(struct super_block *sb 101 static int qnx4_remount(struct super_block *sb, int *flags, char *data);
129 static int qnx4_statfs(struct dentry *, struct 102 static int qnx4_statfs(struct dentry *, struct kstatfs *);
130 103
131 static const struct super_operations qnx4_sops 104 static const struct super_operations qnx4_sops =
132 { 105 {
133 .alloc_inode = qnx4_alloc_inode, 106 .alloc_inode = qnx4_alloc_inode,
134 .destroy_inode = qnx4_destroy_inode, 107 .destroy_inode = qnx4_destroy_inode,
135 .put_super = qnx4_put_super, 108 .put_super = qnx4_put_super,
136 .statfs = qnx4_statfs, 109 .statfs = qnx4_statfs,
137 .remount_fs = qnx4_remount, 110 .remount_fs = qnx4_remount,
138 #ifdef CONFIG_QNX4FS_RW 111 #ifdef CONFIG_QNX4FS_RW
139 .write_inode = qnx4_write_inode, 112 .write_inode = qnx4_write_inode,
140 .delete_inode = qnx4_delete_inode, 113 .delete_inode = qnx4_delete_inode,
141 .write_super = qnx4_write_super, <<
142 #endif 114 #endif
143 }; 115 };
144 116
145 static int qnx4_remount(struct super_block *sb 117 static int qnx4_remount(struct super_block *sb, int *flags, char *data)
146 { 118 {
147 struct qnx4_sb_info *qs; 119 struct qnx4_sb_info *qs;
148 120
149 qs = qnx4_sb(sb); 121 qs = qnx4_sb(sb);
150 qs->Version = QNX4_VERSION; 122 qs->Version = QNX4_VERSION;
151 #ifndef CONFIG_QNX4FS_RW 123 #ifndef CONFIG_QNX4FS_RW
152 *flags |= MS_RDONLY; 124 *flags |= MS_RDONLY;
153 #endif 125 #endif
154 if (*flags & MS_RDONLY) { 126 if (*flags & MS_RDONLY) {
155 return 0; 127 return 0;
156 } 128 }
157 129
158 mark_buffer_dirty(qs->sb_buf); 130 mark_buffer_dirty(qs->sb_buf);
159 131
160 return 0; 132 return 0;
161 } 133 }
162 134
163 static struct buffer_head *qnx4_getblk(struct 135 static struct buffer_head *qnx4_getblk(struct inode *inode, int nr,
164 int cre 136 int create)
165 { 137 {
166 struct buffer_head *result = NULL; 138 struct buffer_head *result = NULL;
167 139
168 if ( nr >= 0 ) 140 if ( nr >= 0 )
169 nr = qnx4_block_map( inode, nr 141 nr = qnx4_block_map( inode, nr );
170 if (nr) { 142 if (nr) {
171 result = sb_getblk(inode->i_sb 143 result = sb_getblk(inode->i_sb, nr);
172 return result; 144 return result;
173 } 145 }
174 if (!create) { 146 if (!create) {
175 return NULL; 147 return NULL;
176 } 148 }
177 #if 0 149 #if 0
178 tmp = qnx4_new_block(inode->i_sb); 150 tmp = qnx4_new_block(inode->i_sb);
179 if (!tmp) { 151 if (!tmp) {
180 return NULL; 152 return NULL;
181 } 153 }
182 result = sb_getblk(inode->i_sb, tmp); 154 result = sb_getblk(inode->i_sb, tmp);
183 if (tst) { 155 if (tst) {
184 qnx4_free_block(inode->i_sb, t 156 qnx4_free_block(inode->i_sb, tmp);
185 brelse(result); 157 brelse(result);
186 goto repeat; 158 goto repeat;
187 } 159 }
188 tst = tmp; 160 tst = tmp;
189 #endif 161 #endif
190 inode->i_ctime = CURRENT_TIME_SEC; 162 inode->i_ctime = CURRENT_TIME_SEC;
191 mark_inode_dirty(inode); 163 mark_inode_dirty(inode);
192 return result; 164 return result;
193 } 165 }
194 166
195 struct buffer_head *qnx4_bread(struct inode *i 167 struct buffer_head *qnx4_bread(struct inode *inode, int block, int create)
196 { 168 {
197 struct buffer_head *bh; 169 struct buffer_head *bh;
198 170
199 bh = qnx4_getblk(inode, block, create) 171 bh = qnx4_getblk(inode, block, create);
200 if (!bh || buffer_uptodate(bh)) { 172 if (!bh || buffer_uptodate(bh)) {
201 return bh; 173 return bh;
202 } 174 }
203 ll_rw_block(READ, 1, &bh); 175 ll_rw_block(READ, 1, &bh);
204 wait_on_buffer(bh); 176 wait_on_buffer(bh);
205 if (buffer_uptodate(bh)) { 177 if (buffer_uptodate(bh)) {
206 return bh; 178 return bh;
207 } 179 }
208 brelse(bh); 180 brelse(bh);
209 181
210 return NULL; 182 return NULL;
211 } 183 }
212 184
213 static int qnx4_get_block( struct inode *inode 185 static int qnx4_get_block( struct inode *inode, sector_t iblock, struct buffer_head *bh, int create )
214 { 186 {
215 unsigned long phys; 187 unsigned long phys;
216 188
217 QNX4DEBUG(("qnx4: qnx4_get_block inode 189 QNX4DEBUG(("qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]\n",inode->i_ino,iblock));
218 190
219 phys = qnx4_block_map( inode, iblock ) 191 phys = qnx4_block_map( inode, iblock );
220 if ( phys ) { 192 if ( phys ) {
221 // logical block is before EOF 193 // logical block is before EOF
222 map_bh(bh, inode->i_sb, phys); 194 map_bh(bh, inode->i_sb, phys);
223 } else if ( create ) { 195 } else if ( create ) {
224 // to be done. 196 // to be done.
225 } 197 }
226 return 0; 198 return 0;
227 } 199 }
228 200
229 unsigned long qnx4_block_map( struct inode *in 201 unsigned long qnx4_block_map( struct inode *inode, long iblock )
230 { 202 {
231 int ix; 203 int ix;
232 long offset, i_xblk; 204 long offset, i_xblk;
233 unsigned long block = 0; 205 unsigned long block = 0;
234 struct buffer_head *bh = NULL; 206 struct buffer_head *bh = NULL;
235 struct qnx4_xblk *xblk = NULL; 207 struct qnx4_xblk *xblk = NULL;
236 struct qnx4_inode_entry *qnx4_inode = 208 struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);
237 u16 nxtnt = le16_to_cpu(qnx4_inode->di 209 u16 nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts);
238 210
239 if ( iblock < le32_to_cpu(qnx4_inode-> 211 if ( iblock < le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size) ) {
240 // iblock is in the first exte 212 // iblock is in the first extent. This is easy.
241 block = le32_to_cpu(qnx4_inode 213 block = le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_blk) + iblock - 1;
242 } else { 214 } else {
243 // iblock is beyond first exte 215 // iblock is beyond first extent. We have to follow the extent chain.
244 i_xblk = le32_to_cpu(qnx4_inod 216 i_xblk = le32_to_cpu(qnx4_inode->di_xblk);
245 offset = iblock - le32_to_cpu( 217 offset = iblock - le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size);
246 ix = 0; 218 ix = 0;
247 while ( --nxtnt > 0 ) { 219 while ( --nxtnt > 0 ) {
248 if ( ix == 0 ) { 220 if ( ix == 0 ) {
249 // read next x 221 // read next xtnt block.
250 bh = sb_bread( 222 bh = sb_bread(inode->i_sb, i_xblk - 1);
251 if ( !bh ) { 223 if ( !bh ) {
252 QNX4DE 224 QNX4DEBUG(("qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1));
253 return 225 return -EIO;
254 } 226 }
255 xblk = (struct 227 xblk = (struct qnx4_xblk*)bh->b_data;
256 if ( memcmp( x 228 if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) {
257 QNX4DE 229 QNX4DEBUG(("qnx4: block at %ld is not a valid xtnt\n", qnx4_inode->i_xblk));
258 return 230 return -EIO;
259 } 231 }
260 } 232 }
261 if ( offset < le32_to_ 233 if ( offset < le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size) ) {
262 // got it! 234 // got it!
263 block = le32_t 235 block = le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_blk) + offset - 1;
264 break; 236 break;
265 } 237 }
266 offset -= le32_to_cpu( 238 offset -= le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size);
267 if ( ++ix >= xblk->xbl 239 if ( ++ix >= xblk->xblk_num_xtnts ) {
268 i_xblk = le32_ 240 i_xblk = le32_to_cpu(xblk->xblk_next_xblk);
269 ix = 0; 241 ix = 0;
270 brelse( bh ); 242 brelse( bh );
271 bh = NULL; 243 bh = NULL;
272 } 244 }
273 } 245 }
274 if ( bh ) 246 if ( bh )
275 brelse( bh ); 247 brelse( bh );
276 } 248 }
277 249
278 QNX4DEBUG(("qnx4: mapping block %ld of 250 QNX4DEBUG(("qnx4: mapping block %ld of inode %ld = %ld\n",iblock,inode->i_ino,block));
279 return block; 251 return block;
280 } 252 }
281 253
282 static int qnx4_statfs(struct dentry *dentry, 254 static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf)
283 { 255 {
284 struct super_block *sb = dentry->d_sb; 256 struct super_block *sb = dentry->d_sb;
>> 257 u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
285 258
286 lock_kernel(); 259 lock_kernel();
287 260
288 buf->f_type = sb->s_magic; 261 buf->f_type = sb->s_magic;
289 buf->f_bsize = sb->s_blocksize; 262 buf->f_bsize = sb->s_blocksize;
290 buf->f_blocks = le32_to_cpu(qnx4_sb(s 263 buf->f_blocks = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size) * 8;
291 buf->f_bfree = qnx4_count_free_block 264 buf->f_bfree = qnx4_count_free_blocks(sb);
292 buf->f_bavail = buf->f_bfree; 265 buf->f_bavail = buf->f_bfree;
293 buf->f_namelen = QNX4_NAME_MAX; 266 buf->f_namelen = QNX4_NAME_MAX;
>> 267 buf->f_fsid.val[0] = (u32)id;
>> 268 buf->f_fsid.val[1] = (u32)(id >> 32);
294 269
295 unlock_kernel(); 270 unlock_kernel();
296 271
297 return 0; 272 return 0;
298 } 273 }
299 274
300 /* 275 /*
301 * Check the root directory of the filesystem 276 * Check the root directory of the filesystem to make sure
302 * it really _is_ a qnx4 filesystem, and to ch 277 * it really _is_ a qnx4 filesystem, and to check the size
303 * of the directory entry. 278 * of the directory entry.
304 */ 279 */
305 static const char *qnx4_checkroot(struct super 280 static const char *qnx4_checkroot(struct super_block *sb)
306 { 281 {
307 struct buffer_head *bh; 282 struct buffer_head *bh;
308 struct qnx4_inode_entry *rootdir; 283 struct qnx4_inode_entry *rootdir;
309 int rd, rl; 284 int rd, rl;
310 int i, j; 285 int i, j;
311 int found = 0; 286 int found = 0;
312 287
313 if (*(qnx4_sb(sb)->sb->RootDir.di_fnam 288 if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/') {
314 return "no qnx4 filesystem (no 289 return "no qnx4 filesystem (no root dir).";
315 } else { 290 } else {
316 QNX4DEBUG(("QNX4 filesystem fo 291 QNX4DEBUG(("QNX4 filesystem found on dev %s.\n", sb->s_id));
317 rd = le32_to_cpu(qnx4_sb(sb)-> 292 rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1;
318 rl = le32_to_cpu(qnx4_sb(sb)-> 293 rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size);
319 for (j = 0; j < rl; j++) { 294 for (j = 0; j < rl; j++) {
320 bh = sb_bread(sb, rd + 295 bh = sb_bread(sb, rd + j); /* root dir, first block */
321 if (bh == NULL) { 296 if (bh == NULL) {
322 return "unable 297 return "unable to read root entry.";
323 } 298 }
324 for (i = 0; i < QNX4_I 299 for (i = 0; i < QNX4_INODES_PER_BLOCK; i++) {
325 rootdir = (str 300 rootdir = (struct qnx4_inode_entry *) (bh->b_data + i * QNX4_DIR_ENTRY_SIZE);
326 if (rootdir->d 301 if (rootdir->di_fname != NULL) {
327 QNX4DE 302 QNX4DEBUG(("Rootdir entry found : [%s]\n", rootdir->di_fname));
328 if (!s 303 if (!strncmp(rootdir->di_fname, QNX4_BMNAME, sizeof QNX4_BMNAME)) {
329 304 found = 1;
330 305 qnx4_sb(sb)->BitMap = kmalloc( sizeof( struct qnx4_inode_entry ), GFP_KERNEL );
331 306 if (!qnx4_sb(sb)->BitMap) {
332 307 brelse (bh);
333 308 return "not enough memory for bitmap inode";
334 309 }
335 310 memcpy( qnx4_sb(sb)->BitMap, rootdir, sizeof( struct qnx4_inode_entry ) ); /* keep bitmap inode known */
336 311 break;
337 } 312 }
338 } 313 }
339 } 314 }
340 brelse(bh); 315 brelse(bh);
341 if (found != 0) { 316 if (found != 0) {
342 break; 317 break;
343 } 318 }
344 } 319 }
345 if (found == 0) { 320 if (found == 0) {
346 return "bitmap file no 321 return "bitmap file not found.";
347 } 322 }
348 } 323 }
349 return NULL; 324 return NULL;
350 } 325 }
351 326
352 static int qnx4_fill_super(struct super_block 327 static int qnx4_fill_super(struct super_block *s, void *data, int silent)
353 { 328 {
354 struct buffer_head *bh; 329 struct buffer_head *bh;
355 struct inode *root; 330 struct inode *root;
356 const char *errmsg; 331 const char *errmsg;
357 struct qnx4_sb_info *qs; 332 struct qnx4_sb_info *qs;
358 int ret = -EINVAL; 333 int ret = -EINVAL;
359 334
360 qs = kzalloc(sizeof(struct qnx4_sb_inf 335 qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL);
361 if (!qs) 336 if (!qs)
362 return -ENOMEM; 337 return -ENOMEM;
363 s->s_fs_info = qs; 338 s->s_fs_info = qs;
364 339
365 sb_set_blocksize(s, QNX4_BLOCK_SIZE); 340 sb_set_blocksize(s, QNX4_BLOCK_SIZE);
366 341
367 /* Check the superblock signature. Sin 342 /* Check the superblock signature. Since the qnx4 code is
368 dangerous, we should leave as quick 343 dangerous, we should leave as quickly as possible
369 if we don't belong here... */ 344 if we don't belong here... */
370 bh = sb_bread(s, 1); 345 bh = sb_bread(s, 1);
371 if (!bh) { 346 if (!bh) {
372 printk("qnx4: unable to read t 347 printk("qnx4: unable to read the superblock\n");
373 goto outnobh; 348 goto outnobh;
374 } 349 }
375 if ( le32_to_cpup((__le32*) bh->b_data 350 if ( le32_to_cpup((__le32*) bh->b_data) != QNX4_SUPER_MAGIC ) {
376 if (!silent) 351 if (!silent)
377 printk("qnx4: wrong fs 352 printk("qnx4: wrong fsid in superblock.\n");
378 goto out; 353 goto out;
379 } 354 }
380 s->s_op = &qnx4_sops; 355 s->s_op = &qnx4_sops;
381 s->s_magic = QNX4_SUPER_MAGIC; 356 s->s_magic = QNX4_SUPER_MAGIC;
382 #ifndef CONFIG_QNX4FS_RW 357 #ifndef CONFIG_QNX4FS_RW
383 s->s_flags |= MS_RDONLY; /* Yup 358 s->s_flags |= MS_RDONLY; /* Yup, read-only yet */
384 #endif 359 #endif
385 qnx4_sb(s)->sb_buf = bh; 360 qnx4_sb(s)->sb_buf = bh;
386 qnx4_sb(s)->sb = (struct qnx4_super_bl 361 qnx4_sb(s)->sb = (struct qnx4_super_block *) bh->b_data;
387 362
388 363
389 /* check before allocating dentries, i 364 /* check before allocating dentries, inodes, .. */
390 errmsg = qnx4_checkroot(s); 365 errmsg = qnx4_checkroot(s);
391 if (errmsg != NULL) { 366 if (errmsg != NULL) {
392 if (!silent) 367 if (!silent)
393 printk("qnx4: %s\n", e 368 printk("qnx4: %s\n", errmsg);
394 goto out; 369 goto out;
395 } 370 }
396 371
397 /* does root not have inode number QNX 372 /* does root not have inode number QNX4_ROOT_INO ?? */
398 root = qnx4_iget(s, QNX4_ROOT_INO * QN 373 root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
399 if (IS_ERR(root)) { 374 if (IS_ERR(root)) {
400 printk("qnx4: get inode failed 375 printk("qnx4: get inode failed\n");
401 ret = PTR_ERR(root); 376 ret = PTR_ERR(root);
402 goto out; 377 goto out;
403 } 378 }
404 379
405 ret = -ENOMEM; 380 ret = -ENOMEM;
406 s->s_root = d_alloc_root(root); 381 s->s_root = d_alloc_root(root);
407 if (s->s_root == NULL) 382 if (s->s_root == NULL)
408 goto outi; 383 goto outi;
409 384
410 brelse(bh); 385 brelse(bh);
411 386
412 return 0; 387 return 0;
413 388
414 outi: 389 outi:
415 iput(root); 390 iput(root);
416 out: 391 out:
417 brelse(bh); 392 brelse(bh);
418 outnobh: 393 outnobh:
419 kfree(qs); 394 kfree(qs);
420 s->s_fs_info = NULL; 395 s->s_fs_info = NULL;
421 return ret; 396 return ret;
422 } 397 }
423 398
424 static void qnx4_put_super(struct super_block 399 static void qnx4_put_super(struct super_block *sb)
425 { 400 {
426 struct qnx4_sb_info *qs = qnx4_sb(sb); 401 struct qnx4_sb_info *qs = qnx4_sb(sb);
427 kfree( qs->BitMap ); 402 kfree( qs->BitMap );
428 kfree( qs ); 403 kfree( qs );
429 sb->s_fs_info = NULL; 404 sb->s_fs_info = NULL;
430 return; 405 return;
431 } 406 }
432 407
433 static int qnx4_writepage(struct page *page, s 408 static int qnx4_writepage(struct page *page, struct writeback_control *wbc)
434 { 409 {
435 return block_write_full_page(page,qnx4 410 return block_write_full_page(page,qnx4_get_block, wbc);
436 } 411 }
437 412
438 static int qnx4_readpage(struct file *file, st 413 static int qnx4_readpage(struct file *file, struct page *page)
439 { 414 {
440 return block_read_full_page(page,qnx4_ 415 return block_read_full_page(page,qnx4_get_block);
441 } 416 }
442 417
443 static int qnx4_write_begin(struct file *file, 418 static int qnx4_write_begin(struct file *file, struct address_space *mapping,
444 loff_t pos, unsigned l 419 loff_t pos, unsigned len, unsigned flags,
445 struct page **pagep, v 420 struct page **pagep, void **fsdata)
446 { 421 {
447 struct qnx4_inode_info *qnx4_inode = q 422 struct qnx4_inode_info *qnx4_inode = qnx4_i(mapping->host);
448 *pagep = NULL; 423 *pagep = NULL;
449 return cont_write_begin(file, mapping, 424 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
450 qnx4_get_block 425 qnx4_get_block,
451 &qnx4_inode->m 426 &qnx4_inode->mmu_private);
452 } 427 }
453 static sector_t qnx4_bmap(struct address_space 428 static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
454 { 429 {
455 return generic_block_bmap(mapping,bloc 430 return generic_block_bmap(mapping,block,qnx4_get_block);
456 } 431 }
457 static const struct address_space_operations q 432 static const struct address_space_operations qnx4_aops = {
458 .readpage = qnx4_readpage, 433 .readpage = qnx4_readpage,
459 .writepage = qnx4_writepage, 434 .writepage = qnx4_writepage,
460 .sync_page = block_sync_page, 435 .sync_page = block_sync_page,
461 .write_begin = qnx4_write_begin, 436 .write_begin = qnx4_write_begin,
462 .write_end = generic_write_end, 437 .write_end = generic_write_end,
463 .bmap = qnx4_bmap 438 .bmap = qnx4_bmap
464 }; 439 };
465 440
466 struct inode *qnx4_iget(struct super_block *sb 441 struct inode *qnx4_iget(struct super_block *sb, unsigned long ino)
467 { 442 {
468 struct buffer_head *bh; 443 struct buffer_head *bh;
469 struct qnx4_inode_entry *raw_inode; 444 struct qnx4_inode_entry *raw_inode;
470 int block; 445 int block;
471 struct qnx4_inode_entry *qnx4_inode; 446 struct qnx4_inode_entry *qnx4_inode;
472 struct inode *inode; 447 struct inode *inode;
473 448
474 inode = iget_locked(sb, ino); 449 inode = iget_locked(sb, ino);
475 if (!inode) 450 if (!inode)
476 return ERR_PTR(-ENOMEM); 451 return ERR_PTR(-ENOMEM);
477 if (!(inode->i_state & I_NEW)) 452 if (!(inode->i_state & I_NEW))
478 return inode; 453 return inode;
479 454
480 qnx4_inode = qnx4_raw_inode(inode); 455 qnx4_inode = qnx4_raw_inode(inode);
481 inode->i_mode = 0; 456 inode->i_mode = 0;
482 457
483 QNX4DEBUG(("Reading inode : [%d]\n", i 458 QNX4DEBUG(("Reading inode : [%d]\n", ino));
484 if (!ino) { 459 if (!ino) {
485 printk(KERN_ERR "qnx4: bad ino 460 printk(KERN_ERR "qnx4: bad inode number on dev %s: %lu is "
486 "out of range\ 461 "out of range\n",
487 sb->s_id, ino); 462 sb->s_id, ino);
488 iget_failed(inode); 463 iget_failed(inode);
489 return ERR_PTR(-EIO); 464 return ERR_PTR(-EIO);
490 } 465 }
491 block = ino / QNX4_INODES_PER_BLOCK; 466 block = ino / QNX4_INODES_PER_BLOCK;
492 467
493 if (!(bh = sb_bread(sb, block))) { 468 if (!(bh = sb_bread(sb, block))) {
494 printk("qnx4: major problem: u 469 printk("qnx4: major problem: unable to read inode from dev "
495 "%s\n", sb->s_id); 470 "%s\n", sb->s_id);
496 iget_failed(inode); 471 iget_failed(inode);
497 return ERR_PTR(-EIO); 472 return ERR_PTR(-EIO);
498 } 473 }
499 raw_inode = ((struct qnx4_inode_entry 474 raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
500 (ino % QNX4_INODES_PER_BLOCK); 475 (ino % QNX4_INODES_PER_BLOCK);
501 476
502 inode->i_mode = le16_to_cpu(raw_ino 477 inode->i_mode = le16_to_cpu(raw_inode->di_mode);
503 inode->i_uid = (uid_t)le16_to_cpu( 478 inode->i_uid = (uid_t)le16_to_cpu(raw_inode->di_uid);
504 inode->i_gid = (gid_t)le16_to_cpu( 479 inode->i_gid = (gid_t)le16_to_cpu(raw_inode->di_gid);
505 inode->i_nlink = le16_to_cpu(raw_ino 480 inode->i_nlink = le16_to_cpu(raw_inode->di_nlink);
506 inode->i_size = le32_to_cpu(raw_ino 481 inode->i_size = le32_to_cpu(raw_inode->di_size);
507 inode->i_mtime.tv_sec = le32_to_cpu( 482 inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->di_mtime);
508 inode->i_mtime.tv_nsec = 0; 483 inode->i_mtime.tv_nsec = 0;
509 inode->i_atime.tv_sec = le32_to_cpu( 484 inode->i_atime.tv_sec = le32_to_cpu(raw_inode->di_atime);
510 inode->i_atime.tv_nsec = 0; 485 inode->i_atime.tv_nsec = 0;
511 inode->i_ctime.tv_sec = le32_to_cpu( 486 inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->di_ctime);
512 inode->i_ctime.tv_nsec = 0; 487 inode->i_ctime.tv_nsec = 0;
513 inode->i_blocks = le32_to_cpu(raw_ino 488 inode->i_blocks = le32_to_cpu(raw_inode->di_first_xtnt.xtnt_size);
514 489
515 memcpy(qnx4_inode, raw_inode, QNX4_DIR 490 memcpy(qnx4_inode, raw_inode, QNX4_DIR_ENTRY_SIZE);
516 if (S_ISREG(inode->i_mode)) { 491 if (S_ISREG(inode->i_mode)) {
517 inode->i_op = &qnx4_file_inode 492 inode->i_op = &qnx4_file_inode_operations;
518 inode->i_fop = &qnx4_file_oper 493 inode->i_fop = &qnx4_file_operations;
519 inode->i_mapping->a_ops = &qnx 494 inode->i_mapping->a_ops = &qnx4_aops;
520 qnx4_i(inode)->mmu_private = i 495 qnx4_i(inode)->mmu_private = inode->i_size;
521 } else if (S_ISDIR(inode->i_mode)) { 496 } else if (S_ISDIR(inode->i_mode)) {
522 inode->i_op = &qnx4_dir_inode_ 497 inode->i_op = &qnx4_dir_inode_operations;
523 inode->i_fop = &qnx4_dir_opera 498 inode->i_fop = &qnx4_dir_operations;
524 } else if (S_ISLNK(inode->i_mode)) { 499 } else if (S_ISLNK(inode->i_mode)) {
525 inode->i_op = &page_symlink_in 500 inode->i_op = &page_symlink_inode_operations;
526 inode->i_mapping->a_ops = &qnx 501 inode->i_mapping->a_ops = &qnx4_aops;
527 qnx4_i(inode)->mmu_private = i 502 qnx4_i(inode)->mmu_private = inode->i_size;
528 } else { 503 } else {
529 printk(KERN_ERR "qnx4: bad ino 504 printk(KERN_ERR "qnx4: bad inode %lu on dev %s\n",
530 ino, sb->s_id); 505 ino, sb->s_id);
531 iget_failed(inode); 506 iget_failed(inode);
532 brelse(bh); 507 brelse(bh);
533 return ERR_PTR(-EIO); 508 return ERR_PTR(-EIO);
534 } 509 }
535 brelse(bh); 510 brelse(bh);
536 unlock_new_inode(inode); 511 unlock_new_inode(inode);
537 return inode; 512 return inode;
538 } 513 }
539 514
540 static struct kmem_cache *qnx4_inode_cachep; 515 static struct kmem_cache *qnx4_inode_cachep;
541 516
542 static struct inode *qnx4_alloc_inode(struct s 517 static struct inode *qnx4_alloc_inode(struct super_block *sb)
543 { 518 {
544 struct qnx4_inode_info *ei; 519 struct qnx4_inode_info *ei;
545 ei = kmem_cache_alloc(qnx4_inode_cache 520 ei = kmem_cache_alloc(qnx4_inode_cachep, GFP_KERNEL);
546 if (!ei) 521 if (!ei)
547 return NULL; 522 return NULL;
548 return &ei->vfs_inode; 523 return &ei->vfs_inode;
549 } 524 }
550 525
551 static void qnx4_destroy_inode(struct inode *i 526 static void qnx4_destroy_inode(struct inode *inode)
552 { 527 {
553 kmem_cache_free(qnx4_inode_cachep, qnx 528 kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode));
554 } 529 }
555 530
556 static void init_once(struct kmem_cache *cache !! 531 static void init_once(void *foo)
557 { 532 {
558 struct qnx4_inode_info *ei = (struct q 533 struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;
559 534
560 inode_init_once(&ei->vfs_inode); 535 inode_init_once(&ei->vfs_inode);
561 } 536 }
562 537
563 static int init_inodecache(void) 538 static int init_inodecache(void)
564 { 539 {
565 qnx4_inode_cachep = kmem_cache_create( 540 qnx4_inode_cachep = kmem_cache_create("qnx4_inode_cache",
566 s 541 sizeof(struct qnx4_inode_info),
567 0 542 0, (SLAB_RECLAIM_ACCOUNT|
568 543 SLAB_MEM_SPREAD),
569 i 544 init_once);
570 if (qnx4_inode_cachep == NULL) 545 if (qnx4_inode_cachep == NULL)
571 return -ENOMEM; 546 return -ENOMEM;
572 return 0; 547 return 0;
573 } 548 }
574 549
575 static void destroy_inodecache(void) 550 static void destroy_inodecache(void)
576 { 551 {
577 kmem_cache_destroy(qnx4_inode_cachep); 552 kmem_cache_destroy(qnx4_inode_cachep);
578 } 553 }
579 554
580 static int qnx4_get_sb(struct file_system_type 555 static int qnx4_get_sb(struct file_system_type *fs_type,
581 int flags, const char *dev_name, void 556 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
582 { 557 {
583 return get_sb_bdev(fs_type, flags, dev 558 return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super,
584 mnt); 559 mnt);
585 } 560 }
586 561
587 static struct file_system_type qnx4_fs_type = 562 static struct file_system_type qnx4_fs_type = {
588 .owner = THIS_MODULE, 563 .owner = THIS_MODULE,
589 .name = "qnx4", 564 .name = "qnx4",
590 .get_sb = qnx4_get_sb, 565 .get_sb = qnx4_get_sb,
591 .kill_sb = kill_block_super, 566 .kill_sb = kill_block_super,
592 .fs_flags = FS_REQUIRES_DEV, 567 .fs_flags = FS_REQUIRES_DEV,
593 }; 568 };
594 569
595 static int __init init_qnx4_fs(void) 570 static int __init init_qnx4_fs(void)
596 { 571 {
597 int err; 572 int err;
598 573
599 err = init_inodecache(); 574 err = init_inodecache();
600 if (err) 575 if (err)
601 return err; 576 return err;
602 577
603 err = register_filesystem(&qnx4_fs_typ 578 err = register_filesystem(&qnx4_fs_type);
604 if (err) { 579 if (err) {
605 destroy_inodecache(); 580 destroy_inodecache();
606 return err; 581 return err;
607 } 582 }
608 583
609 printk("QNX4 filesystem 0.2.3 register 584 printk("QNX4 filesystem 0.2.3 registered.\n");
610 return 0; 585 return 0;
611 } 586 }
612 587
613 static void __exit exit_qnx4_fs(void) 588 static void __exit exit_qnx4_fs(void)
614 { 589 {
615 unregister_filesystem(&qnx4_fs_type); 590 unregister_filesystem(&qnx4_fs_type);
616 destroy_inodecache(); 591 destroy_inodecache();
617 } 592 }
618 593
619 module_init(init_qnx4_fs) 594 module_init(init_qnx4_fs)
620 module_exit(exit_qnx4_fs) 595 module_exit(exit_qnx4_fs)
621 MODULE_LICENSE("GPL"); 596 MODULE_LICENSE("GPL");
622 597
623 598
|
This page was automatically generated by the
LXR engine.
|