Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/fs/qnx4/inode.c (Version 2.6.25) and /linux/fs/qnx4/inode.c (Version 2.6.25.8)


  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.