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> 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_ 47 if (buffer_req(bh) && !buffer_uptodate(bh))
48 { 48 {
49 printk ("IO error sync 49 printk ("IO error syncing qnx4 inode [%s:%08lx]\n",
50 inode->i_sb->s 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 *in 62 static void qnx4_delete_inode(struct inode *inode)
63 { 63 {
64 QNX4DEBUG(("qnx4: deleting inode [%lu] 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_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 int qnx4_remount(struct super_block *sb 128 static int qnx4_remount(struct super_block *sb, int *flags, char *data);
129 static int qnx4_statfs(struct dentry *, struct 129 static int qnx4_statfs(struct dentry *, struct kstatfs *);
130 130
131 static const struct super_operations qnx4_sops 131 static const struct super_operations qnx4_sops =
132 { 132 {
133 .alloc_inode = qnx4_alloc_inode, 133 .alloc_inode = qnx4_alloc_inode,
134 .destroy_inode = qnx4_destroy_inode, 134 .destroy_inode = qnx4_destroy_inode,
135 .put_super = qnx4_put_super, 135 .put_super = qnx4_put_super,
136 .statfs = qnx4_statfs, 136 .statfs = qnx4_statfs,
137 .remount_fs = qnx4_remount, 137 .remount_fs = qnx4_remount,
138 #ifdef CONFIG_QNX4FS_RW 138 #ifdef CONFIG_QNX4FS_RW
139 .write_inode = qnx4_write_inode, 139 .write_inode = qnx4_write_inode,
140 .delete_inode = qnx4_delete_inode, 140 .delete_inode = qnx4_delete_inode,
141 .write_super = qnx4_write_super, 141 .write_super = qnx4_write_super,
142 #endif 142 #endif
143 }; 143 };
144 144
145 static int qnx4_remount(struct super_block *sb 145 static int qnx4_remount(struct super_block *sb, int *flags, char *data)
146 { 146 {
147 struct qnx4_sb_info *qs; 147 struct qnx4_sb_info *qs;
148 148
149 qs = qnx4_sb(sb); 149 qs = qnx4_sb(sb);
150 qs->Version = QNX4_VERSION; 150 qs->Version = QNX4_VERSION;
151 #ifndef CONFIG_QNX4FS_RW 151 #ifndef CONFIG_QNX4FS_RW
152 *flags |= MS_RDONLY; 152 *flags |= MS_RDONLY;
153 #endif 153 #endif
154 if (*flags & MS_RDONLY) { 154 if (*flags & MS_RDONLY) {
155 return 0; 155 return 0;
156 } 156 }
157 157
158 mark_buffer_dirty(qs->sb_buf); 158 mark_buffer_dirty(qs->sb_buf);
159 159
160 return 0; 160 return 0;
161 } 161 }
162 162
163 static struct buffer_head *qnx4_getblk(struct 163 static struct buffer_head *qnx4_getblk(struct inode *inode, int nr,
164 int cre 164 int create)
165 { 165 {
166 struct buffer_head *result = NULL; 166 struct buffer_head *result = NULL;
167 167
168 if ( nr >= 0 ) 168 if ( nr >= 0 )
169 nr = qnx4_block_map( inode, nr 169 nr = qnx4_block_map( inode, nr );
170 if (nr) { 170 if (nr) {
171 result = sb_getblk(inode->i_sb 171 result = sb_getblk(inode->i_sb, nr);
172 return result; 172 return result;
173 } 173 }
174 if (!create) { 174 if (!create) {
175 return NULL; 175 return NULL;
176 } 176 }
177 #if 0 177 #if 0
178 tmp = qnx4_new_block(inode->i_sb); 178 tmp = qnx4_new_block(inode->i_sb);
179 if (!tmp) { 179 if (!tmp) {
180 return NULL; 180 return NULL;
181 } 181 }
182 result = sb_getblk(inode->i_sb, tmp); 182 result = sb_getblk(inode->i_sb, tmp);
183 if (tst) { 183 if (tst) {
184 qnx4_free_block(inode->i_sb, t 184 qnx4_free_block(inode->i_sb, tmp);
185 brelse(result); 185 brelse(result);
186 goto repeat; 186 goto repeat;
187 } 187 }
188 tst = tmp; 188 tst = tmp;
189 #endif 189 #endif
190 inode->i_ctime = CURRENT_TIME_SEC; 190 inode->i_ctime = CURRENT_TIME_SEC;
191 mark_inode_dirty(inode); 191 mark_inode_dirty(inode);
192 return result; 192 return result;
193 } 193 }
194 194
195 struct buffer_head *qnx4_bread(struct inode *i 195 struct buffer_head *qnx4_bread(struct inode *inode, int block, int create)
196 { 196 {
197 struct buffer_head *bh; 197 struct buffer_head *bh;
198 198
199 bh = qnx4_getblk(inode, block, create) 199 bh = qnx4_getblk(inode, block, create);
200 if (!bh || buffer_uptodate(bh)) { 200 if (!bh || buffer_uptodate(bh)) {
201 return bh; 201 return bh;
202 } 202 }
203 ll_rw_block(READ, 1, &bh); 203 ll_rw_block(READ, 1, &bh);
204 wait_on_buffer(bh); 204 wait_on_buffer(bh);
205 if (buffer_uptodate(bh)) { 205 if (buffer_uptodate(bh)) {
206 return bh; 206 return bh;
207 } 207 }
208 brelse(bh); 208 brelse(bh);
209 209
210 return NULL; 210 return NULL;
211 } 211 }
212 212
213 static int qnx4_get_block( struct inode *inode 213 static int qnx4_get_block( struct inode *inode, sector_t iblock, struct buffer_head *bh, int create )
214 { 214 {
215 unsigned long phys; 215 unsigned long phys;
216 216
217 QNX4DEBUG(("qnx4: qnx4_get_block inode 217 QNX4DEBUG(("qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]\n",inode->i_ino,iblock));
218 218
219 phys = qnx4_block_map( inode, iblock ) 219 phys = qnx4_block_map( inode, iblock );
220 if ( phys ) { 220 if ( phys ) {
221 // logical block is before EOF 221 // logical block is before EOF
222 map_bh(bh, inode->i_sb, phys); 222 map_bh(bh, inode->i_sb, phys);
223 } else if ( create ) { 223 } else if ( create ) {
224 // to be done. 224 // to be done.
225 } 225 }
226 return 0; 226 return 0;
227 } 227 }
228 228
229 unsigned long qnx4_block_map( struct inode *in 229 unsigned long qnx4_block_map( struct inode *inode, long iblock )
230 { 230 {
231 int ix; 231 int ix;
232 long offset, i_xblk; 232 long offset, i_xblk;
233 unsigned long block = 0; 233 unsigned long block = 0;
234 struct buffer_head *bh = NULL; 234 struct buffer_head *bh = NULL;
235 struct qnx4_xblk *xblk = NULL; 235 struct qnx4_xblk *xblk = NULL;
236 struct qnx4_inode_entry *qnx4_inode = 236 struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);
237 u16 nxtnt = le16_to_cpu(qnx4_inode->di 237 u16 nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts);
238 238
239 if ( iblock < le32_to_cpu(qnx4_inode-> 239 if ( iblock < le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size) ) {
240 // iblock is in the first exte 240 // iblock is in the first extent. This is easy.
241 block = le32_to_cpu(qnx4_inode 241 block = le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_blk) + iblock - 1;
242 } else { 242 } else {
243 // iblock is beyond first exte 243 // iblock is beyond first extent. We have to follow the extent chain.
244 i_xblk = le32_to_cpu(qnx4_inod 244 i_xblk = le32_to_cpu(qnx4_inode->di_xblk);
245 offset = iblock - le32_to_cpu( 245 offset = iblock - le32_to_cpu(qnx4_inode->di_first_xtnt.xtnt_size);
246 ix = 0; 246 ix = 0;
247 while ( --nxtnt > 0 ) { 247 while ( --nxtnt > 0 ) {
248 if ( ix == 0 ) { 248 if ( ix == 0 ) {
249 // read next x 249 // read next xtnt block.
250 bh = sb_bread( 250 bh = sb_bread(inode->i_sb, i_xblk - 1);
251 if ( !bh ) { 251 if ( !bh ) {
252 QNX4DE 252 QNX4DEBUG(("qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1));
253 return 253 return -EIO;
254 } 254 }
255 xblk = (struct 255 xblk = (struct qnx4_xblk*)bh->b_data;
256 if ( memcmp( x 256 if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) {
257 QNX4DE 257 QNX4DEBUG(("qnx4: block at %ld is not a valid xtnt\n", qnx4_inode->i_xblk));
258 return 258 return -EIO;
259 } 259 }
260 } 260 }
261 if ( offset < le32_to_ 261 if ( offset < le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size) ) {
262 // got it! 262 // got it!
263 block = le32_t 263 block = le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_blk) + offset - 1;
264 break; 264 break;
265 } 265 }
266 offset -= le32_to_cpu( 266 offset -= le32_to_cpu(xblk->xblk_xtnts[ix].xtnt_size);
267 if ( ++ix >= xblk->xbl 267 if ( ++ix >= xblk->xblk_num_xtnts ) {
268 i_xblk = le32_ 268 i_xblk = le32_to_cpu(xblk->xblk_next_xblk);
269 ix = 0; 269 ix = 0;
270 brelse( bh ); 270 brelse( bh );
271 bh = NULL; 271 bh = NULL;
272 } 272 }
273 } 273 }
274 if ( bh ) 274 if ( bh )
275 brelse( bh ); 275 brelse( bh );
276 } 276 }
277 277
278 QNX4DEBUG(("qnx4: mapping block %ld of 278 QNX4DEBUG(("qnx4: mapping block %ld of inode %ld = %ld\n",iblock,inode->i_ino,block));
279 return block; 279 return block;
280 } 280 }
281 281
282 static int qnx4_statfs(struct dentry *dentry, 282 static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf)
283 { 283 {
284 struct super_block *sb = dentry->d_sb; 284 struct super_block *sb = dentry->d_sb;
285 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; 358 int ret = -EINVAL;
359 359
360 qs = kzalloc(sizeof(struct qnx4_sb_inf 360 qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL);
361 if (!qs) 361 if (!qs)
362 return -ENOMEM; 362 return -ENOMEM;
363 s->s_fs_info = qs; 363 s->s_fs_info = qs;
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_cpup((__le32*) 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 = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
399 if (IS_ERR(root)) { 399 if (IS_ERR(root)) {
400 printk("qnx4: get inode failed 400 printk("qnx4: get inode failed\n");
401 ret = PTR_ERR(root); 401 ret = PTR_ERR(root);
402 goto out; 402 goto out;
403 } 403 }
404 404
405 ret = -ENOMEM; 405 ret = -ENOMEM;
406 s->s_root = d_alloc_root(root); 406 s->s_root = d_alloc_root(root);
407 if (s->s_root == NULL) 407 if (s->s_root == NULL)
408 goto outi; 408 goto outi;
409 409
410 brelse(bh); 410 brelse(bh);
411 411
412 return 0; 412 return 0;
413 413
414 outi: 414 outi:
415 iput(root); 415 iput(root);
416 out: 416 out:
417 brelse(bh); 417 brelse(bh);
418 outnobh: 418 outnobh:
419 kfree(qs); 419 kfree(qs);
420 s->s_fs_info = NULL; 420 s->s_fs_info = NULL;
421 return ret; 421 return ret;
422 } 422 }
423 423
424 static void qnx4_put_super(struct super_block 424 static void qnx4_put_super(struct super_block *sb)
425 { 425 {
426 struct qnx4_sb_info *qs = qnx4_sb(sb); 426 struct qnx4_sb_info *qs = qnx4_sb(sb);
427 kfree( qs->BitMap ); 427 kfree( qs->BitMap );
428 kfree( qs ); 428 kfree( qs );
429 sb->s_fs_info = NULL; 429 sb->s_fs_info = NULL;
430 return; 430 return;
431 } 431 }
432 432
433 static int qnx4_writepage(struct page *page, s 433 static int qnx4_writepage(struct page *page, struct writeback_control *wbc)
434 { 434 {
435 return block_write_full_page(page,qnx4 435 return block_write_full_page(page,qnx4_get_block, wbc);
436 } 436 }
437 437
438 static int qnx4_readpage(struct file *file, st 438 static int qnx4_readpage(struct file *file, struct page *page)
439 { 439 {
440 return block_read_full_page(page,qnx4_ 440 return block_read_full_page(page,qnx4_get_block);
441 } 441 }
442 442
443 static int qnx4_write_begin(struct file *file, 443 static int qnx4_write_begin(struct file *file, struct address_space *mapping,
444 loff_t pos, unsigned l 444 loff_t pos, unsigned len, unsigned flags,
445 struct page **pagep, v 445 struct page **pagep, void **fsdata)
446 { 446 {
447 struct qnx4_inode_info *qnx4_inode = q 447 struct qnx4_inode_info *qnx4_inode = qnx4_i(mapping->host);
448 *pagep = NULL; 448 *pagep = NULL;
449 return cont_write_begin(file, mapping, 449 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
450 qnx4_get_block 450 qnx4_get_block,
451 &qnx4_inode->m 451 &qnx4_inode->mmu_private);
452 } 452 }
453 static sector_t qnx4_bmap(struct address_space 453 static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
454 { 454 {
455 return generic_block_bmap(mapping,bloc 455 return generic_block_bmap(mapping,block,qnx4_get_block);
456 } 456 }
457 static const struct address_space_operations q 457 static const struct address_space_operations qnx4_aops = {
458 .readpage = qnx4_readpage, 458 .readpage = qnx4_readpage,
459 .writepage = qnx4_writepage, 459 .writepage = qnx4_writepage,
460 .sync_page = block_sync_page, 460 .sync_page = block_sync_page,
461 .write_begin = qnx4_write_begin, 461 .write_begin = qnx4_write_begin,
462 .write_end = generic_write_end, 462 .write_end = generic_write_end,
463 .bmap = qnx4_bmap 463 .bmap = qnx4_bmap
464 }; 464 };
465 465
466 struct inode *qnx4_iget(struct super_block *sb 466 struct inode *qnx4_iget(struct super_block *sb, unsigned long ino)
467 { 467 {
468 struct buffer_head *bh; 468 struct buffer_head *bh;
469 struct qnx4_inode_entry *raw_inode; 469 struct qnx4_inode_entry *raw_inode;
470 int block; 470 int block;
471 struct qnx4_inode_entry *qnx4_inode; 471 struct qnx4_inode_entry *qnx4_inode;
472 struct inode *inode; 472 struct inode *inode;
473 473
474 inode = iget_locked(sb, ino); 474 inode = iget_locked(sb, ino);
475 if (!inode) 475 if (!inode)
476 return ERR_PTR(-ENOMEM); 476 return ERR_PTR(-ENOMEM);
477 if (!(inode->i_state & I_NEW)) 477 if (!(inode->i_state & I_NEW))
478 return inode; 478 return inode;
479 479
480 qnx4_inode = qnx4_raw_inode(inode); 480 qnx4_inode = qnx4_raw_inode(inode);
481 inode->i_mode = 0; 481 inode->i_mode = 0;
482 482
483 QNX4DEBUG(("Reading inode : [%d]\n", i 483 QNX4DEBUG(("Reading inode : [%d]\n", ino));
484 if (!ino) { 484 if (!ino) {
485 printk(KERN_ERR "qnx4: bad ino 485 printk(KERN_ERR "qnx4: bad inode number on dev %s: %lu is "
486 "out of range\ 486 "out of range\n",
487 sb->s_id, ino); 487 sb->s_id, ino);
488 iget_failed(inode); 488 iget_failed(inode);
489 return ERR_PTR(-EIO); 489 return ERR_PTR(-EIO);
490 } 490 }
491 block = ino / QNX4_INODES_PER_BLOCK; 491 block = ino / QNX4_INODES_PER_BLOCK;
492 492
493 if (!(bh = sb_bread(sb, block))) { 493 if (!(bh = sb_bread(sb, block))) {
494 printk("qnx4: major problem: u 494 printk("qnx4: major problem: unable to read inode from dev "
495 "%s\n", sb->s_id); 495 "%s\n", sb->s_id);
496 iget_failed(inode); 496 iget_failed(inode);
497 return ERR_PTR(-EIO); 497 return ERR_PTR(-EIO);
498 } 498 }
499 raw_inode = ((struct qnx4_inode_entry 499 raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
500 (ino % QNX4_INODES_PER_BLOCK); 500 (ino % QNX4_INODES_PER_BLOCK);
501 501
502 inode->i_mode = le16_to_cpu(raw_ino 502 inode->i_mode = le16_to_cpu(raw_inode->di_mode);
503 inode->i_uid = (uid_t)le16_to_cpu( 503 inode->i_uid = (uid_t)le16_to_cpu(raw_inode->di_uid);
504 inode->i_gid = (gid_t)le16_to_cpu( 504 inode->i_gid = (gid_t)le16_to_cpu(raw_inode->di_gid);
505 inode->i_nlink = le16_to_cpu(raw_ino 505 inode->i_nlink = le16_to_cpu(raw_inode->di_nlink);
506 inode->i_size = le32_to_cpu(raw_ino 506 inode->i_size = le32_to_cpu(raw_inode->di_size);
507 inode->i_mtime.tv_sec = le32_to_cpu( 507 inode->i_mtime.tv_sec = le32_to_cpu(raw_inode->di_mtime);
508 inode->i_mtime.tv_nsec = 0; 508 inode->i_mtime.tv_nsec = 0;
509 inode->i_atime.tv_sec = le32_to_cpu( 509 inode->i_atime.tv_sec = le32_to_cpu(raw_inode->di_atime);
510 inode->i_atime.tv_nsec = 0; 510 inode->i_atime.tv_nsec = 0;
511 inode->i_ctime.tv_sec = le32_to_cpu( 511 inode->i_ctime.tv_sec = le32_to_cpu(raw_inode->di_ctime);
512 inode->i_ctime.tv_nsec = 0; 512 inode->i_ctime.tv_nsec = 0;
513 inode->i_blocks = le32_to_cpu(raw_ino 513 inode->i_blocks = le32_to_cpu(raw_inode->di_first_xtnt.xtnt_size);
514 514
515 memcpy(qnx4_inode, raw_inode, QNX4_DIR 515 memcpy(qnx4_inode, raw_inode, QNX4_DIR_ENTRY_SIZE);
516 if (S_ISREG(inode->i_mode)) { 516 if (S_ISREG(inode->i_mode)) {
517 inode->i_op = &qnx4_file_inode 517 inode->i_op = &qnx4_file_inode_operations;
518 inode->i_fop = &qnx4_file_oper 518 inode->i_fop = &qnx4_file_operations;
519 inode->i_mapping->a_ops = &qnx 519 inode->i_mapping->a_ops = &qnx4_aops;
520 qnx4_i(inode)->mmu_private = i 520 qnx4_i(inode)->mmu_private = inode->i_size;
521 } else if (S_ISDIR(inode->i_mode)) { 521 } else if (S_ISDIR(inode->i_mode)) {
522 inode->i_op = &qnx4_dir_inode_ 522 inode->i_op = &qnx4_dir_inode_operations;
523 inode->i_fop = &qnx4_dir_opera 523 inode->i_fop = &qnx4_dir_operations;
524 } else if (S_ISLNK(inode->i_mode)) { 524 } else if (S_ISLNK(inode->i_mode)) {
525 inode->i_op = &page_symlink_in 525 inode->i_op = &page_symlink_inode_operations;
526 inode->i_mapping->a_ops = &qnx 526 inode->i_mapping->a_ops = &qnx4_aops;
527 qnx4_i(inode)->mmu_private = i 527 qnx4_i(inode)->mmu_private = inode->i_size;
528 } else { 528 } else {
529 printk(KERN_ERR "qnx4: bad ino 529 printk(KERN_ERR "qnx4: bad inode %lu on dev %s\n",
530 ino, sb->s_id); 530 ino, sb->s_id);
531 iget_failed(inode); 531 iget_failed(inode);
532 brelse(bh); 532 brelse(bh);
533 return ERR_PTR(-EIO); 533 return ERR_PTR(-EIO);
534 } 534 }
535 brelse(bh); 535 brelse(bh);
536 unlock_new_inode(inode); 536 unlock_new_inode(inode);
537 return inode; 537 return inode;
538 } 538 }
539 539
540 static struct kmem_cache *qnx4_inode_cachep; 540 static struct kmem_cache *qnx4_inode_cachep;
541 541
542 static struct inode *qnx4_alloc_inode(struct s 542 static struct inode *qnx4_alloc_inode(struct super_block *sb)
543 { 543 {
544 struct qnx4_inode_info *ei; 544 struct qnx4_inode_info *ei;
545 ei = kmem_cache_alloc(qnx4_inode_cache 545 ei = kmem_cache_alloc(qnx4_inode_cachep, GFP_KERNEL);
546 if (!ei) 546 if (!ei)
547 return NULL; 547 return NULL;
548 return &ei->vfs_inode; 548 return &ei->vfs_inode;
549 } 549 }
550 550
551 static void qnx4_destroy_inode(struct inode *i 551 static void qnx4_destroy_inode(struct inode *inode)
552 { 552 {
553 kmem_cache_free(qnx4_inode_cachep, qnx 553 kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode));
554 } 554 }
555 555
556 static void init_once(struct kmem_cache *cache 556 static void init_once(struct kmem_cache *cachep, void *foo)
557 { 557 {
558 struct qnx4_inode_info *ei = (struct q 558 struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;
559 559
560 inode_init_once(&ei->vfs_inode); 560 inode_init_once(&ei->vfs_inode);
561 } 561 }
562 562
563 static int init_inodecache(void) 563 static int init_inodecache(void)
564 { 564 {
565 qnx4_inode_cachep = kmem_cache_create( 565 qnx4_inode_cachep = kmem_cache_create("qnx4_inode_cache",
566 s 566 sizeof(struct qnx4_inode_info),
567 0 567 0, (SLAB_RECLAIM_ACCOUNT|
568 568 SLAB_MEM_SPREAD),
569 i 569 init_once);
570 if (qnx4_inode_cachep == NULL) 570 if (qnx4_inode_cachep == NULL)
571 return -ENOMEM; 571 return -ENOMEM;
572 return 0; 572 return 0;
573 } 573 }
574 574
575 static void destroy_inodecache(void) 575 static void destroy_inodecache(void)
576 { 576 {
577 kmem_cache_destroy(qnx4_inode_cachep); 577 kmem_cache_destroy(qnx4_inode_cachep);
578 } 578 }
579 579
580 static int qnx4_get_sb(struct file_system_type 580 static int qnx4_get_sb(struct file_system_type *fs_type,
581 int flags, const char *dev_name, void 581 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
582 { 582 {
583 return get_sb_bdev(fs_type, flags, dev 583 return get_sb_bdev(fs_type, flags, dev_name, data, qnx4_fill_super,
584 mnt); 584 mnt);
585 } 585 }
586 586
587 static struct file_system_type qnx4_fs_type = 587 static struct file_system_type qnx4_fs_type = {
588 .owner = THIS_MODULE, 588 .owner = THIS_MODULE,
589 .name = "qnx4", 589 .name = "qnx4",
590 .get_sb = qnx4_get_sb, 590 .get_sb = qnx4_get_sb,
591 .kill_sb = kill_block_super, 591 .kill_sb = kill_block_super,
592 .fs_flags = FS_REQUIRES_DEV, 592 .fs_flags = FS_REQUIRES_DEV,
593 }; 593 };
594 594
595 static int __init init_qnx4_fs(void) 595 static int __init init_qnx4_fs(void)
596 { 596 {
597 int err; 597 int err;
598 598
599 err = init_inodecache(); 599 err = init_inodecache();
600 if (err) 600 if (err)
601 return err; 601 return err;
602 602
603 err = register_filesystem(&qnx4_fs_typ 603 err = register_filesystem(&qnx4_fs_type);
604 if (err) { 604 if (err) {
605 destroy_inodecache(); 605 destroy_inodecache();
606 return err; 606 return err;
607 } 607 }
608 608
609 printk("QNX4 filesystem 0.2.3 register 609 printk("QNX4 filesystem 0.2.3 registered.\n");
610 return 0; 610 return 0;
611 } 611 }
612 612
613 static void __exit exit_qnx4_fs(void) 613 static void __exit exit_qnx4_fs(void)
614 { 614 {
615 unregister_filesystem(&qnx4_fs_type); 615 unregister_filesystem(&qnx4_fs_type);
616 destroy_inodecache(); 616 destroy_inodecache();
617 } 617 }
618 618
619 module_init(init_qnx4_fs) 619 module_init(init_qnx4_fs)
620 module_exit(exit_qnx4_fs) 620 module_exit(exit_qnx4_fs)
621 MODULE_LICENSE("GPL"); 621 MODULE_LICENSE("GPL");
622 622
623 623
|
This page was automatically generated by the
LXR engine.
|