root/fs/super.c

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

DEFINITIONS

This source file includes following definitions.
  1. register_filesystem
  2. unregister_filesystem
  3. fs_index
  4. fs_name
  5. fs_maxindex
  6. sys_sysfs
  7. get_filesystem_list
  8. get_fs_type
  9. __wait_on_super
  10. sync_supers
  11. get_super
  12. put_super
  13. sys_ustat
  14. read_super
  15. get_unnamed_dev
  16. put_unnamed_dev
  17. do_umount
  18. sys_umount
  19. do_mount
  20. do_remount_sb
  21. do_remount
  22. copy_mount_options
  23. sys_mount
  24. mount_root

   1 /*
   2  *  linux/fs/super.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 /*
   8  * super.c contains code to handle the super-block tables.
   9  *
  10  * GK 2/5/95  -  Changed to support mounting the root fs via NFS
  11  */
  12 #include <stdarg.h>
  13 
  14 #include <linux/config.h>
  15 #include <linux/sched.h>
  16 #include <linux/kernel.h>
  17 #include <linux/major.h>
  18 #include <linux/stat.h>
  19 #include <linux/errno.h>
  20 #include <linux/string.h>
  21 #include <linux/locks.h>
  22 #include <linux/mm.h>
  23 
  24 #include <asm/system.h>
  25 #include <asm/segment.h>
  26 #include <asm/bitops.h>
  27  
  28 extern struct file_operations * get_blkfops(unsigned int);
  29 extern struct file_operations * get_chrfops(unsigned int);
  30 
  31 extern void wait_for_keypress(void);
  32 
  33 extern int root_mountflags;
  34 
  35 struct super_block super_blocks[NR_SUPER];
  36 
  37 static int do_remount_sb(struct super_block *sb, int flags, char * data);
  38 
  39 #ifdef CONFIG_ROOT_NFS
  40 extern int nfs_root_mount(struct super_block *sb);
  41 #endif
  42 
  43 /* this is initialized in init/main.c */
  44 kdev_t ROOT_DEV;
  45 
  46 static struct file_system_type * file_systems = NULL;
  47 
  48 int register_filesystem(struct file_system_type * fs)
     /* [previous][next][first][last][top][bottom][index][help] */
  49 {
  50         struct file_system_type ** tmp;
  51 
  52         if (!fs)
  53                 return -EINVAL;
  54         if (fs->next)
  55                 return -EBUSY;
  56         tmp = &file_systems;
  57         while (*tmp) {
  58                 if (strcmp((*tmp)->name, fs->name) == 0)
  59                         return -EBUSY;
  60                 tmp = &(*tmp)->next;
  61         }
  62         *tmp = fs;
  63         return 0;
  64 }
  65 
  66 int unregister_filesystem(struct file_system_type * fs)
     /* [previous][next][first][last][top][bottom][index][help] */
  67 {
  68         struct file_system_type ** tmp;
  69 
  70         tmp = &file_systems;
  71         while (*tmp) {
  72                 if (fs == *tmp) {
  73                         *tmp = fs->next;
  74                         fs->next = NULL;
  75                         return 0;
  76                 }
  77                 tmp = &(*tmp)->next;
  78         }
  79         return -EINVAL;
  80 }
  81 
  82 static int fs_index(const char * __name)
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84         struct file_system_type * tmp;
  85         char * name;
  86         int err, index;
  87 
  88         err = getname(__name, &name);
  89         if (err)
  90                 return err;
  91         index = 0;
  92         for (tmp = file_systems ; tmp ; tmp = tmp->next) {
  93                 if (strcmp(tmp->name, name) == 0) {
  94                         putname(name);
  95                         return index;
  96                 }
  97                 index++;
  98         }
  99         putname(name);
 100         return -EINVAL;
 101 }
 102 
 103 static int fs_name(unsigned int index, char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 104 {
 105         struct file_system_type * tmp;
 106         int err, len;
 107 
 108         tmp = file_systems;
 109         while (tmp && index > 0) {
 110                 tmp = tmp->next;
 111                 index--;
 112         }
 113         if (!tmp)
 114                 return -EINVAL;
 115         len = strlen(tmp->name) + 1;
 116         err = verify_area(VERIFY_WRITE, buf, len);
 117         if (err)
 118                 return err;
 119         memcpy_tofs(buf, tmp->name, len);
 120         return 0;
 121 }
 122 
 123 static int fs_maxindex(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125         struct file_system_type * tmp;
 126         int index;
 127 
 128         index = 0;
 129         for (tmp = file_systems ; tmp ; tmp = tmp->next)
 130                 index++;
 131         return index;
 132 }
 133 
 134 /*
 135  * Whee.. Weird sysv syscall. 
 136  */
 137 asmlinkage int sys_sysfs(int option, ...)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139         va_list args;
 140         int retval = -EINVAL;
 141         unsigned int index;
 142 
 143         va_start(args, option);
 144         switch (option) {
 145                 case 1:
 146                         retval = fs_index(va_arg(args, const char *));
 147                         break;
 148 
 149                 case 2:
 150                         index = va_arg(args, unsigned int);
 151                         retval = fs_name(index, va_arg(args, char *));
 152                         break;
 153 
 154                 case 3:
 155                         retval = fs_maxindex();
 156                         break;
 157         }
 158         va_end(args);
 159         return retval;
 160 }
 161 
 162 int get_filesystem_list(char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 163 {
 164         int len = 0;
 165         struct file_system_type * tmp;
 166 
 167         tmp = file_systems;
 168         while (tmp && len < PAGE_SIZE - 80) {
 169                 len += sprintf(buf+len, "%s\t%s\n",
 170                         tmp->requires_dev ? "" : "nodev",
 171                         tmp->name);
 172                 tmp = tmp->next;
 173         }
 174         return len;
 175 }
 176 
 177 struct file_system_type *get_fs_type(const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 178 {
 179         struct file_system_type * fs = file_systems;
 180         
 181         if (!name)
 182                 return fs;
 183         while (fs) {
 184                 if (!strcmp(name,fs->name))
 185                         break;
 186                 fs = fs->next;
 187         }
 188         return fs;
 189 }
 190 
 191 void __wait_on_super(struct super_block * sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 192 {
 193         struct wait_queue wait = { current, NULL };
 194 
 195         add_wait_queue(&sb->s_wait, &wait);
 196 repeat:
 197         current->state = TASK_UNINTERRUPTIBLE;
 198         if (sb->s_lock) {
 199                 schedule();
 200                 goto repeat;
 201         }
 202         remove_wait_queue(&sb->s_wait, &wait);
 203         current->state = TASK_RUNNING;
 204 }
 205 
 206 void sync_supers(kdev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 207 {
 208         struct super_block * sb;
 209 
 210         for (sb = super_blocks + 0 ; sb < super_blocks + NR_SUPER ; sb++) {
 211                 if (!sb->s_dev)
 212                         continue;
 213                 if (dev && sb->s_dev != dev)
 214                         continue;
 215                 wait_on_super(sb);
 216                 if (!sb->s_dev || !sb->s_dirt)
 217                         continue;
 218                 if (dev && (dev != sb->s_dev))
 219                         continue;
 220                 if (sb->s_op && sb->s_op->write_super)
 221                         sb->s_op->write_super(sb);
 222         }
 223 }
 224 
 225 static struct super_block * get_super(kdev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 226 {
 227         struct super_block * s;
 228 
 229         if (!dev)
 230                 return NULL;
 231         s = 0+super_blocks;
 232         while (s < NR_SUPER+super_blocks)
 233                 if (s->s_dev == dev) {
 234                         wait_on_super(s);
 235                         if (s->s_dev == dev)
 236                                 return s;
 237                         s = 0+super_blocks;
 238                 } else
 239                         s++;
 240         return NULL;
 241 }
 242 
 243 void put_super(kdev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 244 {
 245         struct super_block * sb;
 246 
 247         if (dev == ROOT_DEV) {
 248                 printk("VFS: Root device %s: prepare for armageddon\n",
 249                        kdevname(dev));
 250                 return;
 251         }
 252         if (!(sb = get_super(dev)))
 253                 return;
 254         if (sb->s_covered) {
 255                 printk("VFS: Mounted device %s - tssk, tssk\n",
 256                        kdevname(dev));
 257                 return;
 258         }
 259         if (sb->s_op && sb->s_op->put_super)
 260                 sb->s_op->put_super(sb);
 261 }
 262 
 263 asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265         struct super_block *s;
 266         struct ustat tmp;
 267         struct statfs sbuf;
 268         unsigned long old_fs;
 269         int error;
 270 
 271         s = get_super(to_kdev_t(dev));
 272         if (s == NULL)
 273                 return -EINVAL;
 274 
 275         if (!(s->s_op->statfs))
 276                 return -ENOSYS;
 277 
 278         error = verify_area(VERIFY_WRITE,ubuf,sizeof(struct ustat));
 279         if (error)
 280                 return error;
 281 
 282         old_fs = get_fs();
 283         set_fs(get_ds());
 284         s->s_op->statfs(s,&sbuf,sizeof(struct statfs));
 285         set_fs(old_fs);
 286 
 287         memset(&tmp,0,sizeof(struct ustat));
 288         tmp.f_tfree = sbuf.f_bfree;
 289         tmp.f_tinode = sbuf.f_ffree;
 290 
 291         memcpy_tofs(ubuf,&tmp,sizeof(struct ustat));
 292         return 0;
 293 }
 294 
 295 static struct super_block * read_super(kdev_t dev,const char *name,int flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 296                                        void *data, int silent)
 297 {
 298         struct super_block * s;
 299         struct file_system_type *type;
 300 
 301         if (!dev)
 302                 return NULL;
 303         check_disk_change(dev);
 304         s = get_super(dev);
 305         if (s)
 306                 return s;
 307         if (!(type = get_fs_type(name))) {
 308                 printk("VFS: on device %s: get_fs_type(%s) failed\n",
 309                        kdevname(dev), name);
 310                 return NULL;
 311         }
 312         for (s = 0+super_blocks ;; s++) {
 313                 if (s >= NR_SUPER+super_blocks)
 314                         return NULL;
 315                 if (!(s->s_dev))
 316                         break;
 317         }
 318         s->s_dev = dev;
 319         s->s_flags = flags;
 320         if (!type->read_super(s,data, silent)) {
 321                 s->s_dev = 0;
 322                 return NULL;
 323         }
 324         s->s_dev = dev;
 325         s->s_covered = NULL;
 326         s->s_rd_only = 0;
 327         s->s_dirt = 0;
 328         s->s_type = type;
 329         return s;
 330 }
 331 
 332 /*
 333  * Unnamed block devices are dummy devices used by virtual
 334  * filesystems which don't use real block-devices.  -- jrs
 335  */
 336 
 337 static char unnamed_dev_in_use[256/8] = { 0, };
 338 
 339 kdev_t get_unnamed_dev(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 340 {
 341         int i;
 342 
 343         for (i = 1; i < 256; i++) {
 344                 if (!set_bit(i,unnamed_dev_in_use))
 345                         return MKDEV(UNNAMED_MAJOR, i);
 346         }
 347         return 0;
 348 }
 349 
 350 void put_unnamed_dev(kdev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 351 {
 352         if (!dev)
 353                 return;
 354         if (MAJOR(dev) == UNNAMED_MAJOR &&
 355             clear_bit(MINOR(dev), unnamed_dev_in_use))
 356                 return;
 357         printk("VFS: put_unnamed_dev: freeing unused device %s\n",
 358                         kdevname(dev));
 359 }
 360 
 361 static int do_umount(kdev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 362 {
 363         struct super_block * sb;
 364         int retval;
 365         
 366         if (dev==ROOT_DEV) {
 367                 /* Special case for "unmounting" root.  We just try to remount
 368                    it readonly, and sync() the device. */
 369                 if (!(sb=get_super(dev)))
 370                         return -ENOENT;
 371                 if (!(sb->s_flags & MS_RDONLY)) {
 372                         fsync_dev(dev);
 373                         retval = do_remount_sb(sb, MS_RDONLY, 0);
 374                         if (retval)
 375                                 return retval;
 376                 }
 377                 return 0;
 378         }
 379         if (!(sb=get_super(dev)) || !(sb->s_covered))
 380                 return -ENOENT;
 381         if (!sb->s_covered->i_mount)
 382                 printk("VFS: umount(%s): mounted inode has i_mount=NULL\n",
 383                        kdevname(dev));
 384         if (!fs_may_umount(dev, sb->s_mounted))
 385                 return -EBUSY;
 386         sb->s_covered->i_mount = NULL;
 387         iput(sb->s_covered);
 388         sb->s_covered = NULL;
 389         iput(sb->s_mounted);
 390         sb->s_mounted = NULL;
 391         if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
 392                 sb->s_op->write_super(sb);
 393         put_super(dev);
 394         return 0;
 395 }
 396 
 397 /*
 398  * Now umount can handle mount points as well as block devices.
 399  * This is important for filesystems which use unnamed block devices.
 400  *
 401  * There is a little kludge here with the dummy_inode.  The current
 402  * vfs release functions only use the r_dev field in the inode so
 403  * we give them the info they need without using a real inode.
 404  * If any other fields are ever needed by any block device release
 405  * functions, they should be faked here.  -- jrs
 406  */
 407 
 408 asmlinkage int sys_umount(char * name)
     /* [previous][next][first][last][top][bottom][index][help] */
 409 {
 410         struct inode * inode;
 411         kdev_t dev;
 412         int retval;
 413         struct inode dummy_inode;
 414         struct file_operations * fops;
 415 
 416         if (!suser())
 417                 return -EPERM;
 418         retval = namei(name,&inode);
 419         if (retval) {
 420                 retval = lnamei(name,&inode);
 421                 if (retval)
 422                         return retval;
 423         }
 424         if (S_ISBLK(inode->i_mode)) {
 425                 dev = inode->i_rdev;
 426                 if (IS_NODEV(inode)) {
 427                         iput(inode);
 428                         return -EACCES;
 429                 }
 430         } else {
 431                 if (!inode->i_sb || inode != inode->i_sb->s_mounted) {
 432                         iput(inode);
 433                         return -EINVAL;
 434                 }
 435                 dev = inode->i_sb->s_dev;
 436                 iput(inode);
 437                 memset(&dummy_inode, 0, sizeof(dummy_inode));
 438                 dummy_inode.i_rdev = dev;
 439                 inode = &dummy_inode;
 440         }
 441         if (MAJOR(dev) >= MAX_BLKDEV) {
 442                 iput(inode);
 443                 return -ENXIO;
 444         }
 445         if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
 446                 fops = get_blkfops(MAJOR(dev));
 447                 if (fops && fops->release)
 448                         fops->release(inode,NULL);
 449                 if (MAJOR(dev) == UNNAMED_MAJOR)
 450                         put_unnamed_dev(dev);
 451         }
 452         if (inode != &dummy_inode)
 453                 iput(inode);
 454         if (retval)
 455                 return retval;
 456         fsync_dev(dev);
 457         return 0;
 458 }
 459 
 460 /*
 461  * do_mount() does the actual mounting after sys_mount has done the ugly
 462  * parameter parsing. When enough time has gone by, and everything uses the
 463  * new mount() parameters, sys_mount() can then be cleaned up.
 464  *
 465  * We cannot mount a filesystem if it has active, used, or dirty inodes.
 466  * We also have to flush all inode-data for this device, as the new mount
 467  * might need new info.
 468  */
 469 int do_mount(kdev_t dev, const char * dir, const char * type, int flags, void * data)
     /* [previous][next][first][last][top][bottom][index][help] */
 470 {
 471         struct inode * dir_i;
 472         struct super_block * sb;
 473         int error;
 474 
 475         error = namei(dir,&dir_i);
 476         if (error)
 477                 return error;
 478         if (dir_i->i_count != 1 || dir_i->i_mount) {
 479                 iput(dir_i);
 480                 return -EBUSY;
 481         }
 482         if (!S_ISDIR(dir_i->i_mode)) {
 483                 iput(dir_i);
 484                 return -ENOTDIR;
 485         }
 486         if (!fs_may_mount(dev)) {
 487                 iput(dir_i);
 488                 return -EBUSY;
 489         }
 490         sb = read_super(dev,type,flags,data,0);
 491         if (!sb) {
 492                 iput(dir_i);
 493                 return -EINVAL;
 494         }
 495         if (sb->s_covered) {
 496                 iput(dir_i);
 497                 return -EBUSY;
 498         }
 499         sb->s_covered = dir_i;
 500         dir_i->i_mount = sb->s_mounted;
 501         return 0;               /* we don't iput(dir_i) - see umount */
 502 }
 503 
 504 
 505 /*
 506  * Alters the mount flags of a mounted file system. Only the mount point
 507  * is used as a reference - file system type and the device are ignored.
 508  * FS-specific mount options can't be altered by remounting.
 509  */
 510 
 511 static int do_remount_sb(struct super_block *sb, int flags, char *data)
     /* [previous][next][first][last][top][bottom][index][help] */
 512 {
 513         int retval;
 514         
 515         if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
 516                 return -EACCES;
 517                 /*flags |= MS_RDONLY;*/
 518         /* If we are remounting RDONLY, make sure there are no rw files open */
 519         if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
 520                 if (!fs_may_remount_ro(sb->s_dev))
 521                         return -EBUSY;
 522         if (sb->s_op && sb->s_op->remount_fs) {
 523                 retval = sb->s_op->remount_fs(sb, &flags, data);
 524                 if (retval)
 525                         return retval;
 526         }
 527         sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
 528                 (flags & MS_RMT_MASK);
 529         return 0;
 530 }
 531 
 532 static int do_remount(const char *dir,int flags,char *data)
     /* [previous][next][first][last][top][bottom][index][help] */
 533 {
 534         struct inode *dir_i;
 535         int retval;
 536 
 537         retval = namei(dir,&dir_i);
 538         if (retval)
 539                 return retval;
 540         if (dir_i != dir_i->i_sb->s_mounted) {
 541                 iput(dir_i);
 542                 return -EINVAL;
 543         }
 544         retval = do_remount_sb(dir_i->i_sb, flags, data);
 545         iput(dir_i);
 546         return retval;
 547 }
 548 
 549 static int copy_mount_options (const void * data, unsigned long *where)
     /* [previous][next][first][last][top][bottom][index][help] */
 550 {
 551         int i;
 552         unsigned long page;
 553         struct vm_area_struct * vma;
 554 
 555         *where = 0;
 556         if (!data)
 557                 return 0;
 558 
 559         vma = find_vma(current, (unsigned long) data);
 560         if (!vma || (unsigned long) data < vma->vm_start)
 561                 return -EFAULT;
 562         i = vma->vm_end - (unsigned long) data;
 563         if (PAGE_SIZE <= (unsigned long) i)
 564                 i = PAGE_SIZE-1;
 565         if (!(page = __get_free_page(GFP_KERNEL))) {
 566                 return -ENOMEM;
 567         }
 568         memcpy_fromfs((void *) page,data,i);
 569         *where = page;
 570         return 0;
 571 }
 572 
 573 /*
 574  * Flags is a 16-bit value that allows up to 16 non-fs dependent flags to
 575  * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
 576  *
 577  * data is a (void *) that can point to any structure up to
 578  * PAGE_SIZE-1 bytes, which can contain arbitrary fs-dependent
 579  * information (or be NULL).
 580  *
 581  * NOTE! As old versions of mount() didn't use this setup, the flags
 582  * has to have a special 16-bit magic number in the hight word:
 583  * 0xC0ED. If this magic word isn't present, the flags and data info
 584  * isn't used, as the syscall assumes we are talking to an older
 585  * version that didn't understand them.
 586  */
 587 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
     /* [previous][next][first][last][top][bottom][index][help] */
 588         unsigned long new_flags, void * data)
 589 {
 590         struct file_system_type * fstype;
 591         struct inode * inode;
 592         struct file_operations * fops;
 593         kdev_t dev;
 594         int retval;
 595         const char * t;
 596         unsigned long flags = 0;
 597         unsigned long page = 0;
 598 
 599         if (!suser())
 600                 return -EPERM;
 601         if ((new_flags &
 602              (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
 603                 retval = copy_mount_options (data, &page);
 604                 if (retval < 0)
 605                         return retval;
 606                 retval = do_remount(dir_name,
 607                                     new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
 608                                     (char *) page);
 609                 free_page(page);
 610                 return retval;
 611         }
 612         retval = copy_mount_options (type, &page);
 613         if (retval < 0)
 614                 return retval;
 615         fstype = get_fs_type((char *) page);
 616         free_page(page);
 617         if (!fstype)            
 618                 return -ENODEV;
 619         t = fstype->name;
 620         fops = NULL;
 621         if (fstype->requires_dev) {
 622                 retval = namei(dev_name,&inode);
 623                 if (retval)
 624                         return retval;
 625                 if (!S_ISBLK(inode->i_mode)) {
 626                         iput(inode);
 627                         return -ENOTBLK;
 628                 }
 629                 if (IS_NODEV(inode)) {
 630                         iput(inode);
 631                         return -EACCES;
 632                 }
 633                 dev = inode->i_rdev;
 634                 if (MAJOR(dev) >= MAX_BLKDEV) {
 635                         iput(inode);
 636                         return -ENXIO;
 637                 }
 638                 fops = get_blkfops(MAJOR(dev));
 639                 if (!fops) {
 640                         iput(inode);
 641                         return -ENOTBLK;
 642                 }
 643                 if (fops->open) {
 644                         struct file dummy;      /* allows read-write or read-only flag */
 645                         memset(&dummy, 0, sizeof(dummy));
 646                         dummy.f_inode = inode;
 647                         dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
 648                         retval = fops->open(inode, &dummy);
 649                         if (retval) {
 650                                 iput(inode);
 651                                 return retval;
 652                         }
 653                 }
 654 
 655         } else {
 656                 if (!(dev = get_unnamed_dev()))
 657                         return -EMFILE;
 658                 inode = NULL;
 659         }
 660         page = 0;
 661         if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
 662                 flags = new_flags & ~MS_MGC_MSK;
 663                 retval = copy_mount_options(data, &page);
 664                 if (retval < 0) {
 665                         iput(inode);
 666                         return retval;
 667                 }
 668         }
 669         retval = do_mount(dev,dir_name,t,flags,(void *) page);
 670         free_page(page);
 671         if (retval && fops && fops->release)
 672                 fops->release(inode, NULL);
 673         iput(inode);
 674         return retval;
 675 }
 676 
 677 void mount_root(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 678 {
 679         struct file_system_type * fs_type;
 680         struct super_block * sb;
 681         struct inode * inode, d_inode;
 682         struct file filp;
 683         int retval;
 684 
 685         memset(super_blocks, 0, sizeof(super_blocks));
 686 #ifdef CONFIG_ROOT_NFS
 687         if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
 688                 ROOT_DEV = 0;
 689                 if ((fs_type = get_fs_type("nfs"))) {
 690                         sb = &super_blocks[0];
 691                         sb->s_dev = get_unnamed_dev();
 692                         sb->s_flags = root_mountflags & ~MS_RDONLY;
 693                         if (nfs_root_mount(sb) >= 0) {
 694                                 inode = sb->s_mounted;
 695                                 inode->i_count += 3 ;
 696                                 sb->s_covered = inode;
 697                                 sb->s_rd_only = 0;
 698                                 sb->s_dirt = 0;
 699                                 sb->s_type = fs_type;
 700                                 current->fs->pwd = inode;
 701                                 current->fs->root = inode;
 702                                 ROOT_DEV = sb->s_dev;
 703                                 printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
 704                                 return;
 705                         }
 706                         sb->s_dev = 0;
 707                 }
 708                 if (!ROOT_DEV) {
 709                         printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
 710                         ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
 711                 }
 712         }
 713 #endif
 714 
 715 #ifdef CONFIG_BLK_DEV_FD
 716         if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
 717                 printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
 718                 wait_for_keypress();
 719         }
 720 #endif
 721 
 722         memset(&filp, 0, sizeof(filp));
 723         memset(&d_inode, 0, sizeof(d_inode));
 724         d_inode.i_rdev = ROOT_DEV;
 725         filp.f_inode = &d_inode;
 726         if ( root_mountflags & MS_RDONLY)
 727                 filp.f_mode = 1; /* read only */
 728         else
 729                 filp.f_mode = 3; /* read write */
 730         retval = blkdev_open(&d_inode, &filp);
 731         if(retval == -EROFS){
 732                 root_mountflags |= MS_RDONLY;
 733                 filp.f_mode = 1;
 734                 retval = blkdev_open(&d_inode, &filp);
 735         }
 736 
 737         for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
 738                 if(retval)
 739                         break;
 740                 if (!fs_type->requires_dev)
 741                         continue;
 742                 sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
 743                 if (sb) {
 744                         inode = sb->s_mounted;
 745                         inode->i_count += 3 ;   /* NOTE! it is logically used 4 times, not 1 */
 746                         sb->s_covered = inode;
 747                         sb->s_flags = root_mountflags;
 748                         current->fs->pwd = inode;
 749                         current->fs->root = inode;
 750                         printk ("VFS: Mounted root (%s filesystem)%s.\n",
 751                                 fs_type->name,
 752                                 (sb->s_flags & MS_RDONLY) ? " readonly" : "");
 753                         return;
 754                 }
 755         }
 756         panic("VFS: Unable to mount root fs on %s",
 757                 kdevname(ROOT_DEV));
 758 }

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