linux/fs/omfs/inode.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Optimized MPEG FS - inode and super operations.
   4 * Copyright (C) 2006 Bob Copeland <me@bobcopeland.com>
   5 */
   6#include <linux/module.h>
   7#include <linux/sched.h>
   8#include <linux/slab.h>
   9#include <linux/fs.h>
  10#include <linux/vfs.h>
  11#include <linux/cred.h>
  12#include <linux/parser.h>
  13#include <linux/buffer_head.h>
  14#include <linux/vmalloc.h>
  15#include <linux/writeback.h>
  16#include <linux/seq_file.h>
  17#include <linux/crc-itu-t.h>
  18#include "omfs.h"
  19
  20MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>");
  21MODULE_DESCRIPTION("OMFS (ReplayTV/Karma) Filesystem for Linux");
  22MODULE_LICENSE("GPL");
  23
  24struct buffer_head *omfs_bread(struct super_block *sb, sector_t block)
  25{
  26        struct omfs_sb_info *sbi = OMFS_SB(sb);
  27        if (block >= sbi->s_num_blocks)
  28                return NULL;
  29
  30        return sb_bread(sb, clus_to_blk(sbi, block));
  31}
  32
  33struct inode *omfs_new_inode(struct inode *dir, umode_t mode)
  34{
  35        struct inode *inode;
  36        u64 new_block;
  37        int err;
  38        int len;
  39        struct omfs_sb_info *sbi = OMFS_SB(dir->i_sb);
  40
  41        inode = new_inode(dir->i_sb);
  42        if (!inode)
  43                return ERR_PTR(-ENOMEM);
  44
  45        err = omfs_allocate_range(dir->i_sb, sbi->s_mirrors, sbi->s_mirrors,
  46                        &new_block, &len);
  47        if (err)
  48                goto fail;
  49
  50        inode->i_ino = new_block;
  51        inode_init_owner(&init_user_ns, inode, NULL, mode);
  52        inode->i_mapping->a_ops = &omfs_aops;
  53
  54        inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
  55        switch (mode & S_IFMT) {
  56        case S_IFDIR:
  57                inode->i_op = &omfs_dir_inops;
  58                inode->i_fop = &omfs_dir_operations;
  59                inode->i_size = sbi->s_sys_blocksize;
  60                inc_nlink(inode);
  61                break;
  62        case S_IFREG:
  63                inode->i_op = &omfs_file_inops;
  64                inode->i_fop = &omfs_file_operations;
  65                inode->i_size = 0;
  66                break;
  67        }
  68
  69        insert_inode_hash(inode);
  70        mark_inode_dirty(inode);
  71        return inode;
  72fail:
  73        make_bad_inode(inode);
  74        iput(inode);
  75        return ERR_PTR(err);
  76}
  77
  78/*
  79 * Update the header checksums for a dirty inode based on its contents.
  80 * Caller is expected to hold the buffer head underlying oi and mark it
  81 * dirty.
  82 */
  83static void omfs_update_checksums(struct omfs_inode *oi)
  84{
  85        int xor, i, ofs = 0, count;
  86        u16 crc = 0;
  87        unsigned char *ptr = (unsigned char *) oi;
  88
  89        count = be32_to_cpu(oi->i_head.h_body_size);
  90        ofs = sizeof(struct omfs_header);
  91
  92        crc = crc_itu_t(crc, ptr + ofs, count);
  93        oi->i_head.h_crc = cpu_to_be16(crc);
  94
  95        xor = ptr[0];
  96        for (i = 1; i < OMFS_XOR_COUNT; i++)
  97                xor ^= ptr[i];
  98
  99        oi->i_head.h_check_xor = xor;
 100}
 101
 102static int __omfs_write_inode(struct inode *inode, int wait)
 103{
 104        struct omfs_inode *oi;
 105        struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
 106        struct buffer_head *bh, *bh2;
 107        u64 ctime;
 108        int i;
 109        int ret = -EIO;
 110        int sync_failed = 0;
 111
 112        /* get current inode since we may have written sibling ptrs etc. */
 113        bh = omfs_bread(inode->i_sb, inode->i_ino);
 114        if (!bh)
 115                goto out;
 116
 117        oi = (struct omfs_inode *) bh->b_data;
 118
 119        oi->i_head.h_self = cpu_to_be64(inode->i_ino);
 120        if (S_ISDIR(inode->i_mode))
 121                oi->i_type = OMFS_DIR;
 122        else if (S_ISREG(inode->i_mode))
 123                oi->i_type = OMFS_FILE;
 124        else {
 125                printk(KERN_WARNING "omfs: unknown file type: %d\n",
 126                        inode->i_mode);
 127                goto out_brelse;
 128        }
 129
 130        oi->i_head.h_body_size = cpu_to_be32(sbi->s_sys_blocksize -
 131                sizeof(struct omfs_header));
 132        oi->i_head.h_version = 1;
 133        oi->i_head.h_type = OMFS_INODE_NORMAL;
 134        oi->i_head.h_magic = OMFS_IMAGIC;
 135        oi->i_size = cpu_to_be64(inode->i_size);
 136
 137        ctime = inode->i_ctime.tv_sec * 1000LL +
 138                ((inode->i_ctime.tv_nsec + 999)/1000);
 139        oi->i_ctime = cpu_to_be64(ctime);
 140
 141        omfs_update_checksums(oi);
 142
 143        mark_buffer_dirty(bh);
 144        if (wait) {
 145                sync_dirty_buffer(bh);
 146                if (buffer_req(bh) && !buffer_uptodate(bh))
 147                        sync_failed = 1;
 148        }
 149
 150        /* if mirroring writes, copy to next fsblock */
 151        for (i = 1; i < sbi->s_mirrors; i++) {
 152                bh2 = omfs_bread(inode->i_sb, inode->i_ino + i);
 153                if (!bh2)
 154                        goto out_brelse;
 155
 156                memcpy(bh2->b_data, bh->b_data, bh->b_size);
 157                mark_buffer_dirty(bh2);
 158                if (wait) {
 159                        sync_dirty_buffer(bh2);
 160                        if (buffer_req(bh2) && !buffer_uptodate(bh2))
 161                                sync_failed = 1;
 162                }
 163                brelse(bh2);
 164        }
 165        ret = (sync_failed) ? -EIO : 0;
 166out_brelse:
 167        brelse(bh);
 168out:
 169        return ret;
 170}
 171
 172static int omfs_write_inode(struct inode *inode, struct writeback_control *wbc)
 173{
 174        return __omfs_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
 175}
 176
 177int omfs_sync_inode(struct inode *inode)
 178{
 179        return __omfs_write_inode(inode, 1);
 180}
 181
 182/*
 183 * called when an entry is deleted, need to clear the bits in the
 184 * bitmaps.
 185 */
 186static void omfs_evict_inode(struct inode *inode)
 187{
 188        truncate_inode_pages_final(&inode->i_data);
 189        clear_inode(inode);
 190
 191        if (inode->i_nlink)
 192                return;
 193
 194        if (S_ISREG(inode->i_mode)) {
 195                inode->i_size = 0;
 196                omfs_shrink_inode(inode);
 197        }
 198
 199        omfs_clear_range(inode->i_sb, inode->i_ino, 2);
 200}
 201
 202struct inode *omfs_iget(struct super_block *sb, ino_t ino)
 203{
 204        struct omfs_sb_info *sbi = OMFS_SB(sb);
 205        struct omfs_inode *oi;
 206        struct buffer_head *bh;
 207        u64 ctime;
 208        unsigned long nsecs;
 209        struct inode *inode;
 210
 211        inode = iget_locked(sb, ino);
 212        if (!inode)
 213                return ERR_PTR(-ENOMEM);
 214        if (!(inode->i_state & I_NEW))
 215                return inode;
 216
 217        bh = omfs_bread(inode->i_sb, ino);
 218        if (!bh)
 219                goto iget_failed;
 220
 221        oi = (struct omfs_inode *)bh->b_data;
 222
 223        /* check self */
 224        if (ino != be64_to_cpu(oi->i_head.h_self))
 225                goto fail_bh;
 226
 227        inode->i_uid = sbi->s_uid;
 228        inode->i_gid = sbi->s_gid;
 229
 230        ctime = be64_to_cpu(oi->i_ctime);
 231        nsecs = do_div(ctime, 1000) * 1000L;
 232
 233        inode->i_atime.tv_sec = ctime;
 234        inode->i_mtime.tv_sec = ctime;
 235        inode->i_ctime.tv_sec = ctime;
 236        inode->i_atime.tv_nsec = nsecs;
 237        inode->i_mtime.tv_nsec = nsecs;
 238        inode->i_ctime.tv_nsec = nsecs;
 239
 240        inode->i_mapping->a_ops = &omfs_aops;
 241
 242        switch (oi->i_type) {
 243        case OMFS_DIR:
 244                inode->i_mode = S_IFDIR | (S_IRWXUGO & ~sbi->s_dmask);
 245                inode->i_op = &omfs_dir_inops;
 246                inode->i_fop = &omfs_dir_operations;
 247                inode->i_size = sbi->s_sys_blocksize;
 248                inc_nlink(inode);
 249                break;
 250        case OMFS_FILE:
 251                inode->i_mode = S_IFREG | (S_IRWXUGO & ~sbi->s_fmask);
 252                inode->i_fop = &omfs_file_operations;
 253                inode->i_size = be64_to_cpu(oi->i_size);
 254                break;
 255        }
 256        brelse(bh);
 257        unlock_new_inode(inode);
 258        return inode;
 259fail_bh:
 260        brelse(bh);
 261iget_failed:
 262        iget_failed(inode);
 263        return ERR_PTR(-EIO);
 264}
 265
 266static void omfs_put_super(struct super_block *sb)
 267{
 268        struct omfs_sb_info *sbi = OMFS_SB(sb);
 269        kfree(sbi->s_imap);
 270        kfree(sbi);
 271        sb->s_fs_info = NULL;
 272}
 273
 274static int omfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 275{
 276        struct super_block *s = dentry->d_sb;
 277        struct omfs_sb_info *sbi = OMFS_SB(s);
 278        u64 id = huge_encode_dev(s->s_bdev->bd_dev);
 279
 280        buf->f_type = OMFS_MAGIC;
 281        buf->f_bsize = sbi->s_blocksize;
 282        buf->f_blocks = sbi->s_num_blocks;
 283        buf->f_files = sbi->s_num_blocks;
 284        buf->f_namelen = OMFS_NAMELEN;
 285        buf->f_fsid = u64_to_fsid(id);
 286
 287        buf->f_bfree = buf->f_bavail = buf->f_ffree =
 288                omfs_count_free(s);
 289
 290        return 0;
 291}
 292
 293/*
 294 * Display the mount options in /proc/mounts.
 295 */
 296static int omfs_show_options(struct seq_file *m, struct dentry *root)
 297{
 298        struct omfs_sb_info *sbi = OMFS_SB(root->d_sb);
 299        umode_t cur_umask = current_umask();
 300
 301        if (!uid_eq(sbi->s_uid, current_uid()))
 302                seq_printf(m, ",uid=%u",
 303                           from_kuid_munged(&init_user_ns, sbi->s_uid));
 304        if (!gid_eq(sbi->s_gid, current_gid()))
 305                seq_printf(m, ",gid=%u",
 306                           from_kgid_munged(&init_user_ns, sbi->s_gid));
 307
 308        if (sbi->s_dmask == sbi->s_fmask) {
 309                if (sbi->s_fmask != cur_umask)
 310                        seq_printf(m, ",umask=%o", sbi->s_fmask);
 311        } else {
 312                if (sbi->s_dmask != cur_umask)
 313                        seq_printf(m, ",dmask=%o", sbi->s_dmask);
 314                if (sbi->s_fmask != cur_umask)
 315                        seq_printf(m, ",fmask=%o", sbi->s_fmask);
 316        }
 317
 318        return 0;
 319}
 320
 321static const struct super_operations omfs_sops = {
 322        .write_inode    = omfs_write_inode,
 323        .evict_inode    = omfs_evict_inode,
 324        .put_super      = omfs_put_super,
 325        .statfs         = omfs_statfs,
 326        .show_options   = omfs_show_options,
 327};
 328
 329/*
 330 * For Rio Karma, there is an on-disk free bitmap whose location is
 331 * stored in the root block.  For ReplayTV, there is no such free bitmap
 332 * so we have to walk the tree.  Both inodes and file data are allocated
 333 * from the same map.  This array can be big (300k) so we allocate
 334 * in units of the blocksize.
 335 */
 336static int omfs_get_imap(struct super_block *sb)
 337{
 338        unsigned int bitmap_size, array_size;
 339        int count;
 340        struct omfs_sb_info *sbi = OMFS_SB(sb);
 341        struct buffer_head *bh;
 342        unsigned long **ptr;
 343        sector_t block;
 344
 345        bitmap_size = DIV_ROUND_UP(sbi->s_num_blocks, 8);
 346        array_size = DIV_ROUND_UP(bitmap_size, sb->s_blocksize);
 347
 348        if (sbi->s_bitmap_ino == ~0ULL)
 349                goto out;
 350
 351        sbi->s_imap_size = array_size;
 352        sbi->s_imap = kcalloc(array_size, sizeof(unsigned long *), GFP_KERNEL);
 353        if (!sbi->s_imap)
 354                goto nomem;
 355
 356        block = clus_to_blk(sbi, sbi->s_bitmap_ino);
 357        if (block >= sbi->s_num_blocks)
 358                goto nomem;
 359
 360        ptr = sbi->s_imap;
 361        for (count = bitmap_size; count > 0; count -= sb->s_blocksize) {
 362                bh = sb_bread(sb, block++);
 363                if (!bh)
 364                        goto nomem_free;
 365                *ptr = kmemdup(bh->b_data, sb->s_blocksize, GFP_KERNEL);
 366                if (!*ptr) {
 367                        brelse(bh);
 368                        goto nomem_free;
 369                }
 370                if (count < sb->s_blocksize)
 371                        memset((void *)*ptr + count, 0xff,
 372                                sb->s_blocksize - count);
 373                brelse(bh);
 374                ptr++;
 375        }
 376out:
 377        return 0;
 378
 379nomem_free:
 380        for (count = 0; count < array_size; count++)
 381                kfree(sbi->s_imap[count]);
 382
 383        kfree(sbi->s_imap);
 384nomem:
 385        sbi->s_imap = NULL;
 386        sbi->s_imap_size = 0;
 387        return -ENOMEM;
 388}
 389
 390enum {
 391        Opt_uid, Opt_gid, Opt_umask, Opt_dmask, Opt_fmask, Opt_err
 392};
 393
 394static const match_table_t tokens = {
 395        {Opt_uid, "uid=%u"},
 396        {Opt_gid, "gid=%u"},
 397        {Opt_umask, "umask=%o"},
 398        {Opt_dmask, "dmask=%o"},
 399        {Opt_fmask, "fmask=%o"},
 400        {Opt_err, NULL},
 401};
 402
 403static int parse_options(char *options, struct omfs_sb_info *sbi)
 404{
 405        char *p;
 406        substring_t args[MAX_OPT_ARGS];
 407        int option;
 408
 409        if (!options)
 410                return 1;
 411
 412        while ((p = strsep(&options, ",")) != NULL) {
 413                int token;
 414                if (!*p)
 415                        continue;
 416
 417                token = match_token(p, tokens, args);
 418                switch (token) {
 419                case Opt_uid:
 420                        if (match_int(&args[0], &option))
 421                                return 0;
 422                        sbi->s_uid = make_kuid(current_user_ns(), option);
 423                        if (!uid_valid(sbi->s_uid))
 424                                return 0;
 425                        break;
 426                case Opt_gid:
 427                        if (match_int(&args[0], &option))
 428                                return 0;
 429                        sbi->s_gid = make_kgid(current_user_ns(), option);
 430                        if (!gid_valid(sbi->s_gid))
 431                                return 0;
 432                        break;
 433                case Opt_umask:
 434                        if (match_octal(&args[0], &option))
 435                                return 0;
 436                        sbi->s_fmask = sbi->s_dmask = option;
 437                        break;
 438                case Opt_dmask:
 439                        if (match_octal(&args[0], &option))
 440                                return 0;
 441                        sbi->s_dmask = option;
 442                        break;
 443                case Opt_fmask:
 444                        if (match_octal(&args[0], &option))
 445                                return 0;
 446                        sbi->s_fmask = option;
 447                        break;
 448                default:
 449                        return 0;
 450                }
 451        }
 452        return 1;
 453}
 454
 455static int omfs_fill_super(struct super_block *sb, void *data, int silent)
 456{
 457        struct buffer_head *bh, *bh2;
 458        struct omfs_super_block *omfs_sb;
 459        struct omfs_root_block *omfs_rb;
 460        struct omfs_sb_info *sbi;
 461        struct inode *root;
 462        int ret = -EINVAL;
 463
 464        sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL);
 465        if (!sbi)
 466                return -ENOMEM;
 467
 468        sb->s_fs_info = sbi;
 469
 470        sbi->s_uid = current_uid();
 471        sbi->s_gid = current_gid();
 472        sbi->s_dmask = sbi->s_fmask = current_umask();
 473
 474        if (!parse_options((char *) data, sbi))
 475                goto end;
 476
 477        sb->s_maxbytes = 0xffffffff;
 478
 479        sb->s_time_gran = NSEC_PER_MSEC;
 480        sb->s_time_min = 0;
 481        sb->s_time_max = U64_MAX / MSEC_PER_SEC;
 482
 483        sb_set_blocksize(sb, 0x200);
 484
 485        bh = sb_bread(sb, 0);
 486        if (!bh)
 487                goto end;
 488
 489        omfs_sb = (struct omfs_super_block *)bh->b_data;
 490
 491        if (omfs_sb->s_magic != cpu_to_be32(OMFS_MAGIC)) {
 492                if (!silent)
 493                        printk(KERN_ERR "omfs: Invalid superblock (%x)\n",
 494                                   omfs_sb->s_magic);
 495                goto out_brelse_bh;
 496        }
 497        sb->s_magic = OMFS_MAGIC;
 498
 499        sbi->s_num_blocks = be64_to_cpu(omfs_sb->s_num_blocks);
 500        sbi->s_blocksize = be32_to_cpu(omfs_sb->s_blocksize);
 501        sbi->s_mirrors = be32_to_cpu(omfs_sb->s_mirrors);
 502        sbi->s_root_ino = be64_to_cpu(omfs_sb->s_root_block);
 503        sbi->s_sys_blocksize = be32_to_cpu(omfs_sb->s_sys_blocksize);
 504        mutex_init(&sbi->s_bitmap_lock);
 505
 506        if (sbi->s_num_blocks > OMFS_MAX_BLOCKS) {
 507                printk(KERN_ERR "omfs: sysblock number (%llx) is out of range\n",
 508                       (unsigned long long)sbi->s_num_blocks);
 509                goto out_brelse_bh;
 510        }
 511
 512        if (sbi->s_sys_blocksize > PAGE_SIZE) {
 513                printk(KERN_ERR "omfs: sysblock size (%d) is out of range\n",
 514                        sbi->s_sys_blocksize);
 515                goto out_brelse_bh;
 516        }
 517
 518        if (sbi->s_blocksize < sbi->s_sys_blocksize ||
 519            sbi->s_blocksize > OMFS_MAX_BLOCK_SIZE) {
 520                printk(KERN_ERR "omfs: block size (%d) is out of range\n",
 521                        sbi->s_blocksize);
 522                goto out_brelse_bh;
 523        }
 524
 525        /*
 526         * Use sys_blocksize as the fs block since it is smaller than a
 527         * page while the fs blocksize can be larger.
 528         */
 529        sb_set_blocksize(sb, sbi->s_sys_blocksize);
 530
 531        /*
 532         * ...and the difference goes into a shift.  sys_blocksize is always
 533         * a power of two factor of blocksize.
 534         */
 535        sbi->s_block_shift = get_bitmask_order(sbi->s_blocksize) -
 536                get_bitmask_order(sbi->s_sys_blocksize);
 537
 538        bh2 = omfs_bread(sb, be64_to_cpu(omfs_sb->s_root_block));
 539        if (!bh2)
 540                goto out_brelse_bh;
 541
 542        omfs_rb = (struct omfs_root_block *)bh2->b_data;
 543
 544        sbi->s_bitmap_ino = be64_to_cpu(omfs_rb->r_bitmap);
 545        sbi->s_clustersize = be32_to_cpu(omfs_rb->r_clustersize);
 546
 547        if (sbi->s_num_blocks != be64_to_cpu(omfs_rb->r_num_blocks)) {
 548                printk(KERN_ERR "omfs: block count discrepancy between "
 549                        "super and root blocks (%llx, %llx)\n",
 550                        (unsigned long long)sbi->s_num_blocks,
 551                        (unsigned long long)be64_to_cpu(omfs_rb->r_num_blocks));
 552                goto out_brelse_bh2;
 553        }
 554
 555        if (sbi->s_bitmap_ino != ~0ULL &&
 556            sbi->s_bitmap_ino > sbi->s_num_blocks) {
 557                printk(KERN_ERR "omfs: free space bitmap location is corrupt "
 558                        "(%llx, total blocks %llx)\n",
 559                        (unsigned long long) sbi->s_bitmap_ino,
 560                        (unsigned long long) sbi->s_num_blocks);
 561                goto out_brelse_bh2;
 562        }
 563        if (sbi->s_clustersize < 1 ||
 564            sbi->s_clustersize > OMFS_MAX_CLUSTER_SIZE) {
 565                printk(KERN_ERR "omfs: cluster size out of range (%d)",
 566                        sbi->s_clustersize);
 567                goto out_brelse_bh2;
 568        }
 569
 570        ret = omfs_get_imap(sb);
 571        if (ret)
 572                goto out_brelse_bh2;
 573
 574        sb->s_op = &omfs_sops;
 575
 576        root = omfs_iget(sb, be64_to_cpu(omfs_rb->r_root_dir));
 577        if (IS_ERR(root)) {
 578                ret = PTR_ERR(root);
 579                goto out_brelse_bh2;
 580        }
 581
 582        sb->s_root = d_make_root(root);
 583        if (!sb->s_root) {
 584                ret = -ENOMEM;
 585                goto out_brelse_bh2;
 586        }
 587        printk(KERN_DEBUG "omfs: Mounted volume %s\n", omfs_rb->r_name);
 588
 589        ret = 0;
 590out_brelse_bh2:
 591        brelse(bh2);
 592out_brelse_bh:
 593        brelse(bh);
 594end:
 595        if (ret)
 596                kfree(sbi);
 597        return ret;
 598}
 599
 600static struct dentry *omfs_mount(struct file_system_type *fs_type,
 601                        int flags, const char *dev_name, void *data)
 602{
 603        return mount_bdev(fs_type, flags, dev_name, data, omfs_fill_super);
 604}
 605
 606static struct file_system_type omfs_fs_type = {
 607        .owner = THIS_MODULE,
 608        .name = "omfs",
 609        .mount = omfs_mount,
 610        .kill_sb = kill_block_super,
 611        .fs_flags = FS_REQUIRES_DEV,
 612};
 613MODULE_ALIAS_FS("omfs");
 614
 615static int __init init_omfs_fs(void)
 616{
 617        return register_filesystem(&omfs_fs_type);
 618}
 619
 620static void __exit exit_omfs_fs(void)
 621{
 622        unregister_filesystem(&omfs_fs_type);
 623}
 624
 625module_init(init_omfs_fs);
 626module_exit(exit_omfs_fs);
 627