root/fs/qnx4/inode.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qnx4_remount
  2. qnx4_get_block
  3. try_extent
  4. qnx4_block_map
  5. qnx4_statfs
  6. qnx4_checkroot
  7. qnx4_fill_super
  8. qnx4_kill_sb
  9. qnx4_readpage
  10. qnx4_bmap
  11. qnx4_iget
  12. qnx4_alloc_inode
  13. qnx4_free_inode
  14. init_once
  15. init_inodecache
  16. destroy_inodecache
  17. qnx4_mount
  18. init_qnx4_fs
  19. exit_qnx4_fs

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * QNX4 file system, Linux implementation.
   4  *
   5  * Version : 0.2.1
   6  *
   7  * Using parts of the xiafs filesystem.
   8  *
   9  * History :
  10  *
  11  * 01-06-1998 by Richard Frowijn : first release.
  12  * 20-06-1998 by Frank Denis : Linux 2.1.99+ support, boot signature, misc.
  13  * 30-06-1998 by Frank Denis : first step to write inodes.
  14  */
  15 
  16 #include <linux/module.h>
  17 #include <linux/init.h>
  18 #include <linux/slab.h>
  19 #include <linux/highuid.h>
  20 #include <linux/pagemap.h>
  21 #include <linux/buffer_head.h>
  22 #include <linux/writeback.h>
  23 #include <linux/statfs.h>
  24 #include "qnx4.h"
  25 
  26 #define QNX4_VERSION  4
  27 #define QNX4_BMNAME   ".bitmap"
  28 
  29 static const struct super_operations qnx4_sops;
  30 
  31 static struct inode *qnx4_alloc_inode(struct super_block *sb);
  32 static void qnx4_free_inode(struct inode *inode);
  33 static int qnx4_remount(struct super_block *sb, int *flags, char *data);
  34 static int qnx4_statfs(struct dentry *, struct kstatfs *);
  35 
  36 static const struct super_operations qnx4_sops =
  37 {
  38         .alloc_inode    = qnx4_alloc_inode,
  39         .free_inode     = qnx4_free_inode,
  40         .statfs         = qnx4_statfs,
  41         .remount_fs     = qnx4_remount,
  42 };
  43 
  44 static int qnx4_remount(struct super_block *sb, int *flags, char *data)
  45 {
  46         struct qnx4_sb_info *qs;
  47 
  48         sync_filesystem(sb);
  49         qs = qnx4_sb(sb);
  50         qs->Version = QNX4_VERSION;
  51         *flags |= SB_RDONLY;
  52         return 0;
  53 }
  54 
  55 static int qnx4_get_block( struct inode *inode, sector_t iblock, struct buffer_head *bh, int create )
  56 {
  57         unsigned long phys;
  58 
  59         QNX4DEBUG((KERN_INFO "qnx4: qnx4_get_block inode=[%ld] iblock=[%ld]\n",inode->i_ino,iblock));
  60 
  61         phys = qnx4_block_map( inode, iblock );
  62         if ( phys ) {
  63                 // logical block is before EOF
  64                 map_bh(bh, inode->i_sb, phys);
  65         }
  66         return 0;
  67 }
  68 
  69 static inline u32 try_extent(qnx4_xtnt_t *extent, u32 *offset)
  70 {
  71         u32 size = le32_to_cpu(extent->xtnt_size);
  72         if (*offset < size)
  73                 return le32_to_cpu(extent->xtnt_blk) + *offset - 1;
  74         *offset -= size;
  75         return 0;
  76 }
  77 
  78 unsigned long qnx4_block_map( struct inode *inode, long iblock )
  79 {
  80         int ix;
  81         long i_xblk;
  82         struct buffer_head *bh = NULL;
  83         struct qnx4_xblk *xblk = NULL;
  84         struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode);
  85         u16 nxtnt = le16_to_cpu(qnx4_inode->di_num_xtnts);
  86         u32 offset = iblock;
  87         u32 block = try_extent(&qnx4_inode->di_first_xtnt, &offset);
  88 
  89         if (block) {
  90                 // iblock is in the first extent. This is easy.
  91         } else {
  92                 // iblock is beyond first extent. We have to follow the extent chain.
  93                 i_xblk = le32_to_cpu(qnx4_inode->di_xblk);
  94                 ix = 0;
  95                 while ( --nxtnt > 0 ) {
  96                         if ( ix == 0 ) {
  97                                 // read next xtnt block.
  98                                 bh = sb_bread(inode->i_sb, i_xblk - 1);
  99                                 if ( !bh ) {
 100                                         QNX4DEBUG((KERN_ERR "qnx4: I/O error reading xtnt block [%ld])\n", i_xblk - 1));
 101                                         return -EIO;
 102                                 }
 103                                 xblk = (struct qnx4_xblk*)bh->b_data;
 104                                 if ( memcmp( xblk->xblk_signature, "IamXblk", 7 ) ) {
 105                                         QNX4DEBUG((KERN_ERR "qnx4: block at %ld is not a valid xtnt\n", qnx4_inode->i_xblk));
 106                                         return -EIO;
 107                                 }
 108                         }
 109                         block = try_extent(&xblk->xblk_xtnts[ix], &offset);
 110                         if (block) {
 111                                 // got it!
 112                                 break;
 113                         }
 114                         if ( ++ix >= xblk->xblk_num_xtnts ) {
 115                                 i_xblk = le32_to_cpu(xblk->xblk_next_xblk);
 116                                 ix = 0;
 117                                 brelse( bh );
 118                                 bh = NULL;
 119                         }
 120                 }
 121                 if ( bh )
 122                         brelse( bh );
 123         }
 124 
 125         QNX4DEBUG((KERN_INFO "qnx4: mapping block %ld of inode %ld = %ld\n",iblock,inode->i_ino,block));
 126         return block;
 127 }
 128 
 129 static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf)
 130 {
 131         struct super_block *sb = dentry->d_sb;
 132         u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
 133 
 134         buf->f_type    = sb->s_magic;
 135         buf->f_bsize   = sb->s_blocksize;
 136         buf->f_blocks  = le32_to_cpu(qnx4_sb(sb)->BitMap->di_size) * 8;
 137         buf->f_bfree   = qnx4_count_free_blocks(sb);
 138         buf->f_bavail  = buf->f_bfree;
 139         buf->f_namelen = QNX4_NAME_MAX;
 140         buf->f_fsid.val[0] = (u32)id;
 141         buf->f_fsid.val[1] = (u32)(id >> 32);
 142 
 143         return 0;
 144 }
 145 
 146 /*
 147  * Check the root directory of the filesystem to make sure
 148  * it really _is_ a qnx4 filesystem, and to check the size
 149  * of the directory entry.
 150  */
 151 static const char *qnx4_checkroot(struct super_block *sb,
 152                                   struct qnx4_super_block *s)
 153 {
 154         struct buffer_head *bh;
 155         struct qnx4_inode_entry *rootdir;
 156         int rd, rl;
 157         int i, j;
 158 
 159         if (s->RootDir.di_fname[0] != '/' || s->RootDir.di_fname[1] != '\0')
 160                 return "no qnx4 filesystem (no root dir).";
 161         QNX4DEBUG((KERN_NOTICE "QNX4 filesystem found on dev %s.\n", sb->s_id));
 162         rd = le32_to_cpu(s->RootDir.di_first_xtnt.xtnt_blk) - 1;
 163         rl = le32_to_cpu(s->RootDir.di_first_xtnt.xtnt_size);
 164         for (j = 0; j < rl; j++) {
 165                 bh = sb_bread(sb, rd + j);      /* root dir, first block */
 166                 if (bh == NULL)
 167                         return "unable to read root entry.";
 168                 rootdir = (struct qnx4_inode_entry *) bh->b_data;
 169                 for (i = 0; i < QNX4_INODES_PER_BLOCK; i++, rootdir++) {
 170                         QNX4DEBUG((KERN_INFO "rootdir entry found : [%s]\n", rootdir->di_fname));
 171                         if (strcmp(rootdir->di_fname, QNX4_BMNAME) != 0)
 172                                 continue;
 173                         qnx4_sb(sb)->BitMap = kmemdup(rootdir,
 174                                                       sizeof(struct qnx4_inode_entry),
 175                                                       GFP_KERNEL);
 176                         brelse(bh);
 177                         if (!qnx4_sb(sb)->BitMap)
 178                                 return "not enough memory for bitmap inode";
 179                         /* keep bitmap inode known */
 180                         return NULL;
 181                 }
 182                 brelse(bh);
 183         }
 184         return "bitmap file not found.";
 185 }
 186 
 187 static int qnx4_fill_super(struct super_block *s, void *data, int silent)
 188 {
 189         struct buffer_head *bh;
 190         struct inode *root;
 191         const char *errmsg;
 192         struct qnx4_sb_info *qs;
 193 
 194         qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL);
 195         if (!qs)
 196                 return -ENOMEM;
 197         s->s_fs_info = qs;
 198 
 199         sb_set_blocksize(s, QNX4_BLOCK_SIZE);
 200 
 201         s->s_op = &qnx4_sops;
 202         s->s_magic = QNX4_SUPER_MAGIC;
 203         s->s_flags |= SB_RDONLY;        /* Yup, read-only yet */
 204         s->s_time_min = 0;
 205         s->s_time_max = U32_MAX;
 206 
 207         /* Check the superblock signature. Since the qnx4 code is
 208            dangerous, we should leave as quickly as possible
 209            if we don't belong here... */
 210         bh = sb_bread(s, 1);
 211         if (!bh) {
 212                 printk(KERN_ERR "qnx4: unable to read the superblock\n");
 213                 return -EINVAL;
 214         }
 215 
 216         /* check before allocating dentries, inodes, .. */
 217         errmsg = qnx4_checkroot(s, (struct qnx4_super_block *) bh->b_data);
 218         brelse(bh);
 219         if (errmsg != NULL) {
 220                 if (!silent)
 221                         printk(KERN_ERR "qnx4: %s\n", errmsg);
 222                 return -EINVAL;
 223         }
 224 
 225         /* does root not have inode number QNX4_ROOT_INO ?? */
 226         root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK);
 227         if (IS_ERR(root)) {
 228                 printk(KERN_ERR "qnx4: get inode failed\n");
 229                 return PTR_ERR(root);
 230         }
 231 
 232         s->s_root = d_make_root(root);
 233         if (s->s_root == NULL)
 234                 return -ENOMEM;
 235 
 236         return 0;
 237 }
 238 
 239 static void qnx4_kill_sb(struct super_block *sb)
 240 {
 241         struct qnx4_sb_info *qs = qnx4_sb(sb);
 242         kill_block_super(sb);
 243         if (qs) {
 244                 kfree(qs->BitMap);
 245                 kfree(qs);
 246         }
 247 }
 248 
 249 static int qnx4_readpage(struct file *file, struct page *page)
 250 {
 251         return block_read_full_page(page,qnx4_get_block);
 252 }
 253 
 254 static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
 255 {
 256         return generic_block_bmap(mapping,block,qnx4_get_block);
 257 }
 258 static const struct address_space_operations qnx4_aops = {
 259         .readpage       = qnx4_readpage,
 260         .bmap           = qnx4_bmap
 261 };
 262 
 263 struct inode *qnx4_iget(struct super_block *sb, unsigned long ino)
 264 {
 265         struct buffer_head *bh;
 266         struct qnx4_inode_entry *raw_inode;
 267         int block;
 268         struct qnx4_inode_entry *qnx4_inode;
 269         struct inode *inode;
 270 
 271         inode = iget_locked(sb, ino);
 272         if (!inode)
 273                 return ERR_PTR(-ENOMEM);
 274         if (!(inode->i_state & I_NEW))
 275                 return inode;
 276 
 277         qnx4_inode = qnx4_raw_inode(inode);
 278         inode->i_mode = 0;
 279 
 280         QNX4DEBUG((KERN_INFO "reading inode : [%d]\n", ino));
 281         if (!ino) {
 282                 printk(KERN_ERR "qnx4: bad inode number on dev %s: %lu is "
 283                                 "out of range\n",
 284                        sb->s_id, ino);
 285                 iget_failed(inode);
 286                 return ERR_PTR(-EIO);
 287         }
 288         block = ino / QNX4_INODES_PER_BLOCK;
 289 
 290         if (!(bh = sb_bread(sb, block))) {
 291                 printk(KERN_ERR "qnx4: major problem: unable to read inode from dev "
 292                        "%s\n", sb->s_id);
 293                 iget_failed(inode);
 294                 return ERR_PTR(-EIO);
 295         }
 296         raw_inode = ((struct qnx4_inode_entry *) bh->b_data) +
 297             (ino % QNX4_INODES_PER_BLOCK);
 298 
 299         inode->i_mode    = le16_to_cpu(raw_inode->di_mode);
 300         i_uid_write(inode, (uid_t)le16_to_cpu(raw_inode->di_uid));
 301         i_gid_write(inode, (gid_t)le16_to_cpu(raw_inode->di_gid));
 302         set_nlink(inode, le16_to_cpu(raw_inode->di_nlink));
 303         inode->i_size    = le32_to_cpu(raw_inode->di_size);
 304         inode->i_mtime.tv_sec   = le32_to_cpu(raw_inode->di_mtime);
 305         inode->i_mtime.tv_nsec = 0;
 306         inode->i_atime.tv_sec   = le32_to_cpu(raw_inode->di_atime);
 307         inode->i_atime.tv_nsec = 0;
 308         inode->i_ctime.tv_sec   = le32_to_cpu(raw_inode->di_ctime);
 309         inode->i_ctime.tv_nsec = 0;
 310         inode->i_blocks  = le32_to_cpu(raw_inode->di_first_xtnt.xtnt_size);
 311 
 312         memcpy(qnx4_inode, raw_inode, QNX4_DIR_ENTRY_SIZE);
 313         if (S_ISREG(inode->i_mode)) {
 314                 inode->i_fop = &generic_ro_fops;
 315                 inode->i_mapping->a_ops = &qnx4_aops;
 316                 qnx4_i(inode)->mmu_private = inode->i_size;
 317         } else if (S_ISDIR(inode->i_mode)) {
 318                 inode->i_op = &qnx4_dir_inode_operations;
 319                 inode->i_fop = &qnx4_dir_operations;
 320         } else if (S_ISLNK(inode->i_mode)) {
 321                 inode->i_op = &page_symlink_inode_operations;
 322                 inode_nohighmem(inode);
 323                 inode->i_mapping->a_ops = &qnx4_aops;
 324                 qnx4_i(inode)->mmu_private = inode->i_size;
 325         } else {
 326                 printk(KERN_ERR "qnx4: bad inode %lu on dev %s\n",
 327                         ino, sb->s_id);
 328                 iget_failed(inode);
 329                 brelse(bh);
 330                 return ERR_PTR(-EIO);
 331         }
 332         brelse(bh);
 333         unlock_new_inode(inode);
 334         return inode;
 335 }
 336 
 337 static struct kmem_cache *qnx4_inode_cachep;
 338 
 339 static struct inode *qnx4_alloc_inode(struct super_block *sb)
 340 {
 341         struct qnx4_inode_info *ei;
 342         ei = kmem_cache_alloc(qnx4_inode_cachep, GFP_KERNEL);
 343         if (!ei)
 344                 return NULL;
 345         return &ei->vfs_inode;
 346 }
 347 
 348 static void qnx4_free_inode(struct inode *inode)
 349 {
 350         kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode));
 351 }
 352 
 353 static void init_once(void *foo)
 354 {
 355         struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;
 356 
 357         inode_init_once(&ei->vfs_inode);
 358 }
 359 
 360 static int init_inodecache(void)
 361 {
 362         qnx4_inode_cachep = kmem_cache_create("qnx4_inode_cache",
 363                                              sizeof(struct qnx4_inode_info),
 364                                              0, (SLAB_RECLAIM_ACCOUNT|
 365                                                 SLAB_MEM_SPREAD|SLAB_ACCOUNT),
 366                                              init_once);
 367         if (qnx4_inode_cachep == NULL)
 368                 return -ENOMEM;
 369         return 0;
 370 }
 371 
 372 static void destroy_inodecache(void)
 373 {
 374         /*
 375          * Make sure all delayed rcu free inodes are flushed before we
 376          * destroy cache.
 377          */
 378         rcu_barrier();
 379         kmem_cache_destroy(qnx4_inode_cachep);
 380 }
 381 
 382 static struct dentry *qnx4_mount(struct file_system_type *fs_type,
 383         int flags, const char *dev_name, void *data)
 384 {
 385         return mount_bdev(fs_type, flags, dev_name, data, qnx4_fill_super);
 386 }
 387 
 388 static struct file_system_type qnx4_fs_type = {
 389         .owner          = THIS_MODULE,
 390         .name           = "qnx4",
 391         .mount          = qnx4_mount,
 392         .kill_sb        = qnx4_kill_sb,
 393         .fs_flags       = FS_REQUIRES_DEV,
 394 };
 395 MODULE_ALIAS_FS("qnx4");
 396 
 397 static int __init init_qnx4_fs(void)
 398 {
 399         int err;
 400 
 401         err = init_inodecache();
 402         if (err)
 403                 return err;
 404 
 405         err = register_filesystem(&qnx4_fs_type);
 406         if (err) {
 407                 destroy_inodecache();
 408                 return err;
 409         }
 410 
 411         printk(KERN_INFO "QNX4 filesystem 0.2.3 registered.\n");
 412         return 0;
 413 }
 414 
 415 static void __exit exit_qnx4_fs(void)
 416 {
 417         unregister_filesystem(&qnx4_fs_type);
 418         destroy_inodecache();
 419 }
 420 
 421 module_init(init_qnx4_fs)
 422 module_exit(exit_qnx4_fs)
 423 MODULE_LICENSE("GPL");
 424 

/* [<][>][^][v][top][bottom][index][help] */