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