Fork me on GitHub

root/fs/minix/super.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. check_superblock
  2. minix_statfs
  3. minix_read_superblock
  4. minix_remount_fs
  5. minix_write_superblock
  6. minix_release_superblock
  7. minix_init

   1 /*
   2  * fiwix/fs/minix/super.c
   3  *
   4  * Copyright 2018-2021, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/kernel.h>
   9 #include <fiwix/types.h>
  10 #include <fiwix/errno.h>
  11 #include <fiwix/fs.h>
  12 #include <fiwix/filesystems.h>
  13 #include <fiwix/fs_minix.h>
  14 #include <fiwix/buffer.h>
  15 #include <fiwix/sched.h>
  16 #include <fiwix/stdio.h>
  17 #include <fiwix/string.h>
  18 
  19 struct fs_operations minix_fsop = {
  20         FSOP_REQUIRES_DEV,
  21         NULL,
  22 
  23         NULL,                   /* open */
  24         NULL,                   /* close */
  25         NULL,                   /* read */
  26         NULL,                   /* write */
  27         NULL,                   /* ioctl */
  28         NULL,                   /* lseek */
  29         NULL,                   /* readdir */
  30         NULL,                   /* mmap */
  31         NULL,                   /* select */
  32 
  33         NULL,                   /* readlink */
  34         NULL,                   /* followlink */
  35         NULL,                   /* bmap */
  36         NULL,                   /* lookup */
  37         NULL,                   /* rmdir */
  38         NULL,                   /* link */
  39         NULL,                   /* unlink */
  40         NULL,                   /* symlink */
  41         NULL,                   /* mkdir */
  42         NULL,                   /* mknod */
  43         NULL,                   /* truncate */
  44         NULL,                   /* create */
  45         NULL,                   /* rename */
  46 
  47         NULL,                   /* read_block */
  48         NULL,                   /* write_block */
  49 
  50         minix_read_inode,
  51         minix_write_inode,
  52         minix_ialloc,
  53         minix_ifree,
  54         minix_statfs,
  55         minix_read_superblock,
  56         minix_remount_fs,
  57         minix_write_superblock,
  58         minix_release_superblock
  59 };
  60 
  61 static void check_superblock(struct minix_super_block *sb)
  62 {
  63         if(!(sb->s_state & MINIX_VALID_FS)) {
  64                 printk("WARNING: filesystem not checked, fsck recommended.\n");
  65         }
  66         if(sb->s_state & MINIX_ERROR_FS) {
  67                 printk("WARNING: filesystem contains errors, fsck recommended.\n");
  68         }
  69 }
  70 
  71 void minix_statfs(struct superblock *sb, struct statfs *statfsbuf)
  72 {
  73         statfsbuf->f_type = sb->u.minix.sb.s_magic;
  74         statfsbuf->f_bsize = sb->s_blocksize;
  75         statfsbuf->f_blocks = sb->u.minix.nzones << sb->u.minix.sb.s_log_zone_size;
  76         statfsbuf->f_bfree = sb->u.minix.nzones - minix_count_free_blocks(sb);
  77         statfsbuf->f_bavail = statfsbuf->f_bfree;
  78 
  79         statfsbuf->f_files = sb->u.minix.sb.s_ninodes;
  80         statfsbuf->f_ffree = sb->u.minix.sb.s_ninodes - minix_count_free_inodes(sb);
  81         /* statfsbuf->f_fsid = ? */
  82         statfsbuf->f_namelen = sb->u.minix.namelen;
  83 }
  84 
  85 int minix_read_superblock(__dev_t dev, struct superblock *sb)
  86 {
  87         struct buffer *buf;
  88         int maps;
  89 
  90         superblock_lock(sb);
  91         if(!(buf = bread(dev, SUPERBLOCK, BLKSIZE_1K))) {
  92                 printk("WARNING: %s(): I/O error on device %d,%d.\n", __FUNCTION__, MAJOR(dev), MINOR(dev));
  93                 superblock_unlock(sb);
  94                 return -EIO;
  95         }
  96         memcpy_b(&sb->u.minix.sb, buf->data, sizeof(struct minix_super_block));
  97 
  98         switch(sb->u.minix.sb.s_magic) {
  99                 case MINIX_SUPER_MAGIC:
 100                         sb->u.minix.namelen = 14;
 101                         sb->u.minix.dirsize = sizeof(__u16) + sb->u.minix.namelen;
 102                         sb->u.minix.version = 1;
 103                         sb->u.minix.nzones = sb->u.minix.sb.s_nzones;
 104                         printk("minix v1 (14 char names) filesystem detected on device %d,%d.\n", MAJOR(dev), MINOR(dev));
 105                         break;
 106                 case MINIX_SUPER_MAGIC2:
 107                         sb->u.minix.namelen = 30;
 108                         sb->u.minix.dirsize = sizeof(__u16) + sb->u.minix.namelen;
 109                         sb->u.minix.version = 1;
 110                         sb->u.minix.nzones = sb->u.minix.sb.s_nzones;
 111                         printk("minix v1 (30 char names) filesystem detected on device %d,%d.\n", MAJOR(dev), MINOR(dev));
 112                         break;
 113                 case MINIX2_SUPER_MAGIC:
 114                         sb->u.minix.namelen = 14;
 115                         sb->u.minix.dirsize = sizeof(__u16) + sb->u.minix.namelen;
 116                         sb->u.minix.version = 2;
 117                         sb->u.minix.nzones = sb->u.minix.sb.s_zones;
 118                         printk("minix v2 (14 char names) filesystem detected on device %d,%d.\n", MAJOR(dev), MINOR(dev));
 119                         break;
 120                 case MINIX2_SUPER_MAGIC2:
 121                         sb->u.minix.namelen = 30;
 122                         sb->u.minix.dirsize = sizeof(__u16) + sb->u.minix.namelen;
 123                         sb->u.minix.version = 2;
 124                         sb->u.minix.nzones = sb->u.minix.sb.s_zones;
 125                         printk("minix v2 (30 char names) filesystem detected on device %d,%d.\n", MAJOR(dev), MINOR(dev));
 126                         break;
 127                 default:
 128                         printk("ERROR: %s(): invalid filesystem type or bad superblock on device %d,%d.\n", __FUNCTION__, MAJOR(dev), MINOR(dev));
 129                         superblock_unlock(sb);
 130                         brelse(buf);
 131                         return -EINVAL;
 132         }
 133 
 134         sb->dev = dev;
 135         sb->fsop = &minix_fsop;
 136         sb->s_blocksize = BLKSIZE_1K << sb->u.minix.sb.s_log_zone_size;
 137 
 138         if(sb->s_blocksize != BLKSIZE_1K) {
 139                 printk("ERROR: %s(): block sizes > %d not supported in this filesystem.\n", __FUNCTION__, BLKSIZE_1K);
 140                 superblock_unlock(sb);
 141                 brelse(buf);
 142                 return -EINVAL;
 143         }
 144 
 145         /*
 146         printk("s_ninodes       = %d\n", sb->u.minix.sb.s_ninodes);
 147         printk("s_nzones        = %d (nzones = %d)\n", sb->u.minix.sb.s_nzones, sb->u.minix.nzones);
 148         printk("s_imap_blocks   = %d\n", sb->u.minix.sb.s_imap_blocks);
 149         printk("s_zmap_blocks   = %d\n", sb->u.minix.sb.s_zmap_blocks);
 150         printk("s_firstdatazone = %d\n", sb->u.minix.sb.s_firstdatazone);
 151         printk("s_log_zone_size = %d\n", sb->u.minix.sb.s_log_zone_size);
 152         printk("s_max_size      = %d\n", sb->u.minix.sb.s_max_size);
 153         printk("s_magic         = %x\n", sb->u.minix.sb.s_magic);
 154         printk("s_state         = %d\n", sb->u.minix.sb.s_state);
 155         printk("s_zones         = %d\n", sb->u.minix.sb.s_zones);
 156         */
 157 
 158         /* Minix fs size is limited to: # of bitmaps * 8192 * 1024 */
 159         if(sb->u.minix.version == 1) {
 160                 maps = V1_MAX_BITMAP_BLOCKS;    /* 64MB limit */
 161         }
 162         if(sb->u.minix.version == 2) {
 163                 maps = V2_MAX_BITMAP_BLOCKS;    /* 1GB limit */
 164         }
 165 
 166         if(sb->u.minix.sb.s_imap_blocks > maps) {
 167                 printk("ERROR: %s(): number of imap blocks (%d) is greater than %d!\n", __FUNCTION__, sb->u.minix.sb.s_imap_blocks, maps);
 168                 superblock_unlock(sb);
 169                 brelse(buf);
 170                 return -EINVAL;
 171         }
 172         if(sb->u.minix.sb.s_zmap_blocks > maps) {
 173                 printk("ERROR: %s(): number of zmap blocks (%d) is greater than %d!\n", __FUNCTION__, sb->u.minix.sb.s_zmap_blocks, maps);
 174                 superblock_unlock(sb);
 175                 brelse(buf);
 176                 return -EINVAL;
 177         }
 178 
 179         superblock_unlock(sb);
 180 
 181         if(!(sb->root = iget(sb, MINIX_ROOT_INO))) {
 182                 printk("ERROR: %s(): unable to get root inode.\n", __FUNCTION__);
 183                 brelse(buf);
 184                 return -EINVAL;
 185         }
 186 
 187         check_superblock(&sb->u.minix.sb);
 188 
 189         if(!(sb->flags & MS_RDONLY)) {
 190                 sb->u.minix.sb.s_state &= ~MINIX_VALID_FS;
 191                 memcpy_b(buf->data, &sb->u.minix.sb, sizeof(struct minix_super_block));
 192                 bwrite(buf);
 193         } else {
 194                 brelse(buf);
 195         }
 196 
 197         return 0;
 198 }
 199 
 200 int minix_remount_fs(struct superblock *sb, int flags)
 201 {
 202         struct buffer *buf;
 203         struct minix_super_block *minixsb;
 204 
 205         if((flags & MS_RDONLY) == (sb->flags & MS_RDONLY)) {
 206                 return 0;
 207         }
 208 
 209         superblock_lock(sb);
 210         if(!(buf = bread(sb->dev, SUPERBLOCK, BLKSIZE_1K))) {
 211                 superblock_unlock(sb);
 212                 return -EIO;
 213         }
 214         minixsb = (struct minix_super_block *)buf->data;
 215 
 216         if(flags & MS_RDONLY) {
 217                 /* switching from RW to RO */
 218                 sb->u.minix.sb.s_state |= MINIX_VALID_FS;
 219                 minixsb->s_state |= MINIX_VALID_FS;
 220         } else {
 221                 /* switching from RO to RW */
 222                 check_superblock(minixsb);
 223                 memcpy_b(&sb->u.minix.sb, minixsb, sizeof(struct minix_super_block));
 224                 sb->u.minix.sb.s_state &= ~MINIX_VALID_FS;
 225                 minixsb->s_state &= ~MINIX_VALID_FS;
 226         }
 227 
 228         sb->dirty = 1;
 229         superblock_unlock(sb);
 230         bwrite(buf);
 231         return 0;
 232 }
 233 
 234 int minix_write_superblock(struct superblock *sb)
 235 {
 236         struct buffer *buf;
 237 
 238         superblock_lock(sb);
 239         if(!(buf = bread(sb->dev, SUPERBLOCK, BLKSIZE_1K))) {
 240                 superblock_unlock(sb);
 241                 return -EIO;
 242         }
 243 
 244         memcpy_b(buf->data, &sb->u.minix.sb, sizeof(struct minix_super_block));
 245         sb->dirty = 0;
 246         superblock_unlock(sb);
 247         bwrite(buf);
 248         return 0;
 249 }
 250 
 251 void minix_release_superblock(struct superblock *sb)
 252 {
 253         if(sb->flags & MS_RDONLY) {
 254                 return;
 255         }
 256 
 257         superblock_lock(sb);
 258 
 259         sb->u.minix.sb.s_state |= MINIX_VALID_FS;
 260         sb->dirty = 1;
 261 
 262         superblock_unlock(sb);
 263 }
 264 
 265 int minix_init(void)
 266 {
 267         return register_filesystem("minix", &minix_fsop);
 268 }

/* [previous][next][first][last][top][bottom][index][help] */