This source file includes following definitions.
- lookup_vfsmnt
 
- add_vfsmnt
 
- remove_vfsmnt
 
- register_filesystem
 
- unregister_filesystem
 
- fs_index
 
- fs_name
 
- fs_maxindex
 
- sys_sysfs
 
- get_filesystem_list
 
- get_fs_type
 
- __wait_on_super
 
- sync_supers
 
- get_super
 
- put_super
 
- sys_ustat
 
- read_super
 
- get_unnamed_dev
 
- put_unnamed_dev
 
- do_umount
 
- sys_umount
 
- do_mount
 
- do_remount_sb
 
- do_remount
 
- copy_mount_options
 
- sys_mount
 
- mount_root
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 #include <stdarg.h>
  17 
  18 #include <linux/config.h>
  19 #include <linux/sched.h>
  20 #include <linux/kernel.h>
  21 #include <linux/mount.h>
  22 #include <linux/malloc.h>
  23 #include <linux/major.h>
  24 #include <linux/stat.h>
  25 #include <linux/errno.h>
  26 #include <linux/string.h>
  27 #include <linux/locks.h>
  28 #include <linux/mm.h>
  29 
  30 #include <asm/system.h>
  31 #include <asm/segment.h>
  32 #include <asm/bitops.h>
  33 
  34 #ifdef CONFIG_KERNELD
  35 #include <linux/kerneld.h>
  36 #endif
  37  
  38 extern void wait_for_keypress(void);
  39 extern struct file_operations * get_blkfops(unsigned int major);
  40 extern void blkdev_release (struct inode *);
  41 
  42 extern int root_mountflags;
  43 
  44 static int do_remount_sb(struct super_block *sb, int flags, char * data);
  45 
  46 #ifdef CONFIG_ROOT_NFS
  47 extern int nfs_root_mount(struct super_block *sb);
  48 #endif
  49 
  50 
  51 kdev_t ROOT_DEV;
  52 
  53 struct super_block super_blocks[NR_SUPER];
  54 static struct file_system_type *file_systems = (struct file_system_type *) NULL;
  55 static struct vfsmount *vfsmntlist = (struct vfsmount *) NULL,
  56                        *vfsmnttail = (struct vfsmount *) NULL,
  57                        *mru_vfsmnt = (struct vfsmount *) NULL;
  58 
  59 
  60 
  61 
  62 struct vfsmount *lookup_vfsmnt(kdev_t dev)
     
  63 {
  64         struct vfsmount *lptr;
  65 
  66         if (vfsmntlist == (struct vfsmount *)NULL)
  67                 return ((struct vfsmount *)NULL);
  68 
  69         if (mru_vfsmnt != (struct vfsmount *)NULL &&
  70             mru_vfsmnt->mnt_dev == dev)
  71                 return (mru_vfsmnt);
  72 
  73         for (lptr = vfsmntlist;
  74              lptr != (struct vfsmount *)NULL;
  75              lptr = lptr->mnt_next)
  76                 if (lptr->mnt_dev == dev) {
  77                         mru_vfsmnt = lptr;
  78                         return (lptr);
  79                 }
  80 
  81         return ((struct vfsmount *)NULL);
  82         
  83 }
  84 
  85 struct vfsmount *add_vfsmnt(kdev_t dev, const char *dev_name, const char *dir_name)
     
  86 {
  87         struct vfsmount *lptr;
  88         char *tmp;
  89 
  90         if ((lptr = (struct vfsmount *)
  91              kmalloc(sizeof(struct vfsmount), GFP_KERNEL)) == (struct vfsmount *)NULL)
  92                 return ((struct vfsmount *)NULL);
  93         memset(lptr, 0, sizeof(struct vfsmount));
  94 
  95         lptr->mnt_dev = dev;
  96         lptr->mnt_sem.count = 1;
  97         if (dev_name && !getname(dev_name, &tmp)) {
  98                 if ((lptr->mnt_devname =
  99                     (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
 100                         strcpy(lptr->mnt_devname, tmp);
 101                 putname(tmp);
 102         }
 103         if (dir_name && !getname(dir_name, &tmp)) {
 104                 if ((lptr->mnt_dirname =
 105                     (char *) kmalloc(strlen(tmp)+1, GFP_KERNEL)) != (char *)NULL)
 106                         strcpy(lptr->mnt_dirname, tmp);
 107                 putname(tmp);
 108         }
 109 
 110         if (vfsmntlist == (struct vfsmount *)NULL) {
 111                 vfsmntlist = vfsmnttail = lptr;
 112         } else {
 113                 vfsmnttail->mnt_next = lptr;
 114                 vfsmnttail = lptr;
 115         }
 116         return (lptr);
 117 }
 118 
 119 void remove_vfsmnt(kdev_t dev)
     
 120 {
 121         struct vfsmount *lptr, *tofree;
 122 
 123         if (vfsmntlist == (struct vfsmount *)NULL)
 124                 return;
 125         lptr = vfsmntlist;
 126         if (lptr->mnt_dev == dev) {
 127                 tofree = lptr;
 128                 vfsmntlist = lptr->mnt_next;
 129                 if (vfsmnttail->mnt_dev == dev)
 130                         vfsmnttail = vfsmntlist;
 131         } else {
 132                 while (lptr->mnt_next != (struct vfsmount *)NULL) {
 133                         if (lptr->mnt_next->mnt_dev == dev)
 134                                 break;
 135                         lptr = lptr->mnt_next;
 136                 }
 137                 tofree = lptr->mnt_next;
 138                 if (tofree == (struct vfsmount *)NULL)
 139                         return;
 140                 lptr->mnt_next = lptr->mnt_next->mnt_next;
 141                 if (vfsmnttail->mnt_dev == dev)
 142                         vfsmnttail = lptr;
 143         }
 144         kfree(tofree->mnt_devname);
 145         kfree(tofree->mnt_dirname);
 146         kfree_s(tofree, sizeof(struct vfsmount));
 147 }
 148 
 149 int register_filesystem(struct file_system_type * fs)
     
 150 {
 151         struct file_system_type ** tmp;
 152 
 153         if (!fs)
 154                 return -EINVAL;
 155         if (fs->next)
 156                 return -EBUSY;
 157         tmp = &file_systems;
 158         while (*tmp) {
 159                 if (strcmp((*tmp)->name, fs->name) == 0)
 160                         return -EBUSY;
 161                 tmp = &(*tmp)->next;
 162         }
 163         *tmp = fs;
 164         return 0;
 165 }
 166 
 167 #ifdef CONFIG_MODULES
 168 int unregister_filesystem(struct file_system_type * fs)
     
 169 {
 170         struct file_system_type ** tmp;
 171 
 172         tmp = &file_systems;
 173         while (*tmp) {
 174                 if (fs == *tmp) {
 175                         *tmp = fs->next;
 176                         fs->next = NULL;
 177                         return 0;
 178                 }
 179                 tmp = &(*tmp)->next;
 180         }
 181         return -EINVAL;
 182 }
 183 #endif
 184 
 185 static int fs_index(const char * __name)
     
 186 {
 187         struct file_system_type * tmp;
 188         char * name;
 189         int err, index;
 190 
 191         err = getname(__name, &name);
 192         if (err)
 193                 return err;
 194         index = 0;
 195         for (tmp = file_systems ; tmp ; tmp = tmp->next) {
 196                 if (strcmp(tmp->name, name) == 0) {
 197                         putname(name);
 198                         return index;
 199                 }
 200                 index++;
 201         }
 202         putname(name);
 203         return -EINVAL;
 204 }
 205 
 206 static int fs_name(unsigned int index, char * buf)
     
 207 {
 208         struct file_system_type * tmp;
 209         int err, len;
 210 
 211         tmp = file_systems;
 212         while (tmp && index > 0) {
 213                 tmp = tmp->next;
 214                 index--;
 215         }
 216         if (!tmp)
 217                 return -EINVAL;
 218         len = strlen(tmp->name) + 1;
 219         err = verify_area(VERIFY_WRITE, buf, len);
 220         if (err)
 221                 return err;
 222         memcpy_tofs(buf, tmp->name, len);
 223         return 0;
 224 }
 225 
 226 static int fs_maxindex(void)
     
 227 {
 228         struct file_system_type * tmp;
 229         int index;
 230 
 231         index = 0;
 232         for (tmp = file_systems ; tmp ; tmp = tmp->next)
 233                 index++;
 234         return index;
 235 }
 236 
 237 
 238 
 239 
 240 asmlinkage int sys_sysfs(int option, ...)
     
 241 {
 242         va_list args;
 243         int retval = -EINVAL;
 244         unsigned int index;
 245 
 246         va_start(args, option);
 247         switch (option) {
 248                 case 1:
 249                         retval = fs_index(va_arg(args, const char *));
 250                         break;
 251 
 252                 case 2:
 253                         index = va_arg(args, unsigned int);
 254                         retval = fs_name(index, va_arg(args, char *));
 255                         break;
 256 
 257                 case 3:
 258                         retval = fs_maxindex();
 259                         break;
 260         }
 261         va_end(args);
 262         return retval;
 263 }
 264 
 265 int get_filesystem_list(char * buf)
     
 266 {
 267         int len = 0;
 268         struct file_system_type * tmp;
 269 
 270         tmp = file_systems;
 271         while (tmp && len < PAGE_SIZE - 80) {
 272                 len += sprintf(buf+len, "%s\t%s\n",
 273                         tmp->requires_dev ? "" : "nodev",
 274                         tmp->name);
 275                 tmp = tmp->next;
 276         }
 277         return len;
 278 }
 279 
 280 struct file_system_type *get_fs_type(const char *name)
     
 281 {
 282         struct file_system_type * fs = file_systems;
 283         
 284         if (!name)
 285                 return fs;
 286         for (fs = file_systems; fs && strcmp(fs->name, name); fs = fs->next)
 287                 ;
 288 #ifdef CONFIG_KERNELD
 289         if (!fs && (request_module(name) == 0)) {
 290                 for (fs = file_systems; fs && strcmp(fs->name, name); fs = fs->next)
 291                         ;
 292         }
 293 #endif
 294 
 295         return fs;
 296 }
 297 
 298 void __wait_on_super(struct super_block * sb)
     
 299 {
 300         struct wait_queue wait = { current, NULL };
 301 
 302         add_wait_queue(&sb->s_wait, &wait);
 303 repeat:
 304         current->state = TASK_UNINTERRUPTIBLE;
 305         if (sb->s_lock) {
 306                 schedule();
 307                 goto repeat;
 308         }
 309         remove_wait_queue(&sb->s_wait, &wait);
 310         current->state = TASK_RUNNING;
 311 }
 312 
 313 void sync_supers(kdev_t dev)
     
 314 {
 315         struct super_block * sb;
 316 
 317         for (sb = super_blocks + 0 ; sb < super_blocks + NR_SUPER ; sb++) {
 318                 if (!sb->s_dev)
 319                         continue;
 320                 if (dev && sb->s_dev != dev)
 321                         continue;
 322                 wait_on_super(sb);
 323                 if (!sb->s_dev || !sb->s_dirt)
 324                         continue;
 325                 if (dev && (dev != sb->s_dev))
 326                         continue;
 327                 if (sb->s_op && sb->s_op->write_super)
 328                         sb->s_op->write_super(sb);
 329         }
 330 }
 331 
 332 static struct super_block * get_super(kdev_t dev)
     
 333 {
 334         struct super_block * s;
 335 
 336         if (!dev)
 337                 return NULL;
 338         s = 0+super_blocks;
 339         while (s < NR_SUPER+super_blocks)
 340                 if (s->s_dev == dev) {
 341                         wait_on_super(s);
 342                         if (s->s_dev == dev)
 343                                 return s;
 344                         s = 0+super_blocks;
 345                 } else
 346                         s++;
 347         return NULL;
 348 }
 349 
 350 void put_super(kdev_t dev)
     
 351 {
 352         struct super_block * sb;
 353 
 354         if (dev == ROOT_DEV) {
 355                 printk("VFS: Root device %s: prepare for armageddon\n",
 356                        kdevname(dev));
 357                 return;
 358         }
 359         if (!(sb = get_super(dev)))
 360                 return;
 361         if (sb->s_covered) {
 362                 printk("VFS: Mounted device %s - tssk, tssk\n",
 363                        kdevname(dev));
 364                 return;
 365         }
 366         if (sb->s_op && sb->s_op->put_super)
 367                 sb->s_op->put_super(sb);
 368 }
 369 
 370 asmlinkage int sys_ustat(dev_t dev, struct ustat * ubuf)
     
 371 {
 372         struct super_block *s;
 373         struct ustat tmp;
 374         struct statfs sbuf;
 375         unsigned long old_fs;
 376         int error;
 377 
 378         s = get_super(to_kdev_t(dev));
 379         if (s == NULL)
 380                 return -EINVAL;
 381 
 382         if (!(s->s_op->statfs))
 383                 return -ENOSYS;
 384 
 385         error = verify_area(VERIFY_WRITE,ubuf,sizeof(struct ustat));
 386         if (error)
 387                 return error;
 388 
 389         old_fs = get_fs();
 390         set_fs(get_ds());
 391         s->s_op->statfs(s,&sbuf,sizeof(struct statfs));
 392         set_fs(old_fs);
 393 
 394         memset(&tmp,0,sizeof(struct ustat));
 395         tmp.f_tfree = sbuf.f_bfree;
 396         tmp.f_tinode = sbuf.f_ffree;
 397 
 398         memcpy_tofs(ubuf,&tmp,sizeof(struct ustat));
 399         return 0;
 400 }
 401 
 402 static struct super_block * read_super(kdev_t dev,const char *name,int flags,
     
 403                                        void *data, int silent)
 404 {
 405         struct super_block * s;
 406         struct file_system_type *type;
 407 
 408         if (!dev)
 409                 return NULL;
 410         check_disk_change(dev);
 411         s = get_super(dev);
 412         if (s)
 413                 return s;
 414         if (!(type = get_fs_type(name))) {
 415                 printk("VFS: on device %s: get_fs_type(%s) failed\n",
 416                        kdevname(dev), name);
 417                 return NULL;
 418         }
 419         for (s = 0+super_blocks ;; s++) {
 420                 if (s >= NR_SUPER+super_blocks)
 421                         return NULL;
 422                 if (!(s->s_dev))
 423                         break;
 424         }
 425         s->s_dev = dev;
 426         s->s_flags = flags;
 427         if (!type->read_super(s,data, silent)) {
 428                 s->s_dev = 0;
 429                 return NULL;
 430         }
 431         s->s_dev = dev;
 432         s->s_covered = NULL;
 433         s->s_rd_only = 0;
 434         s->s_dirt = 0;
 435         s->s_type = type;
 436         return s;
 437 }
 438 
 439 
 440 
 441 
 442 
 443 
 444 static char unnamed_dev_in_use[256/8] = { 0, };
 445 
 446 kdev_t get_unnamed_dev(void)
     
 447 {
 448         int i;
 449 
 450         for (i = 1; i < 256; i++) {
 451                 if (!set_bit(i,unnamed_dev_in_use))
 452                         return MKDEV(UNNAMED_MAJOR, i);
 453         }
 454         return 0;
 455 }
 456 
 457 void put_unnamed_dev(kdev_t dev)
     
 458 {
 459         if (!dev)
 460                 return;
 461         if (MAJOR(dev) == UNNAMED_MAJOR &&
 462             clear_bit(MINOR(dev), unnamed_dev_in_use))
 463                 return;
 464         printk("VFS: put_unnamed_dev: freeing unused device %s\n",
 465                         kdevname(dev));
 466 }
 467 
 468 static int do_umount(kdev_t dev)
     
 469 {
 470         struct super_block * sb;
 471         int retval;
 472         
 473         if (dev==ROOT_DEV) {
 474                 
 475 
 476 
 477 
 478                 if (!(sb=get_super(dev)))
 479                         return -ENOENT;
 480                 if (!(sb->s_flags & MS_RDONLY)) {
 481                         
 482 
 483 
 484 
 485 
 486 
 487                         quota_off(dev, -1);
 488                         fsync_dev(dev);
 489                         retval = do_remount_sb(sb, MS_RDONLY, 0);
 490                         if (retval)
 491                                 return retval;
 492                 }
 493                 return 0;
 494         }
 495         if (!(sb=get_super(dev)) || !(sb->s_covered))
 496                 return -ENOENT;
 497         if (!sb->s_covered->i_mount)
 498                 printk("VFS: umount(%s): mounted inode has i_mount=NULL\n",
 499                        kdevname(dev));
 500         
 501 
 502 
 503 
 504 
 505         quota_off(dev, -1);
 506         if (!fs_may_umount(dev, sb->s_mounted))
 507                 return -EBUSY;
 508         sb->s_covered->i_mount = NULL;
 509         iput(sb->s_covered);
 510         sb->s_covered = NULL;
 511         iput(sb->s_mounted);
 512         sb->s_mounted = NULL;
 513         if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
 514                 sb->s_op->write_super(sb);
 515         put_super(dev);
 516         remove_vfsmnt(dev);
 517         return 0;
 518 }
 519 
 520 
 521 
 522 
 523 
 524 
 525 
 526 
 527 
 528 
 529 
 530 
 531 asmlinkage int sys_umount(char * name)
     
 532 {
 533         struct inode * inode;
 534         kdev_t dev;
 535         int retval;
 536         struct inode dummy_inode;
 537 
 538         if (!suser())
 539                 return -EPERM;
 540         retval = namei(name, &inode);
 541         if (retval) {
 542                 retval = lnamei(name, &inode);
 543                 if (retval)
 544                         return retval;
 545         }
 546         if (S_ISBLK(inode->i_mode)) {
 547                 dev = inode->i_rdev;
 548                 if (IS_NODEV(inode)) {
 549                         iput(inode);
 550                         return -EACCES;
 551                 }
 552         } else {
 553                 if (!inode->i_sb || inode != inode->i_sb->s_mounted) {
 554                         iput(inode);
 555                         return -EINVAL;
 556                 }
 557                 dev = inode->i_sb->s_dev;
 558                 iput(inode);
 559                 memset(&dummy_inode, 0, sizeof(dummy_inode));
 560                 dummy_inode.i_rdev = dev;
 561                 inode = &dummy_inode;
 562         }
 563         if (MAJOR(dev) >= MAX_BLKDEV) {
 564                 iput(inode);
 565                 return -ENXIO;
 566         }
 567         if (!(retval = do_umount(dev)) && dev != ROOT_DEV) {
 568                 blkdev_release (inode);
 569                 if (MAJOR(dev) == UNNAMED_MAJOR)
 570                         put_unnamed_dev(dev);
 571         }
 572         if (inode != &dummy_inode)
 573                 iput(inode);
 574         if (retval)
 575                 return retval;
 576         fsync_dev(dev);
 577         return 0;
 578 }
 579 
 580 
 581 
 582 
 583 
 584 
 585 
 586 
 587 
 588 
 589 
 590 int do_mount(kdev_t dev, const char * dev_name, const char * dir_name, const char * type, int flags, void * data)
     
 591 {
 592         struct inode * dir_i;
 593         struct super_block * sb;
 594         struct vfsmount *vfsmnt;
 595         int error;
 596 
 597         error = namei(dir_name, &dir_i);
 598         if (error)
 599                 return error;
 600         if (dir_i->i_count != 1 || dir_i->i_mount) {
 601                 iput(dir_i);
 602                 return -EBUSY;
 603         }
 604         if (!S_ISDIR(dir_i->i_mode)) {
 605                 iput(dir_i);
 606                 return -ENOTDIR;
 607         }
 608         if (!fs_may_mount(dev)) {
 609                 iput(dir_i);
 610                 return -EBUSY;
 611         }
 612         sb = read_super(dev,type,flags,data,0);
 613         if (!sb) {
 614                 iput(dir_i);
 615                 return -EINVAL;
 616         }
 617         if (sb->s_covered) {
 618                 iput(dir_i);
 619                 return -EBUSY;
 620         }
 621         vfsmnt = add_vfsmnt(dev, dev_name, dir_name);
 622         vfsmnt->mnt_sb = sb;
 623         sb->s_covered = dir_i;
 624         dir_i->i_mount = sb->s_mounted;
 625         return 0;               
 626 }
 627 
 628 
 629 
 630 
 631 
 632 
 633 
 634 
 635 static int do_remount_sb(struct super_block *sb, int flags, char *data)
     
 636 {
 637         int retval;
 638         
 639         if (!(flags & MS_RDONLY) && sb->s_dev && is_read_only(sb->s_dev))
 640                 return -EACCES;
 641                 
 642         
 643         if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
 644                 if (!fs_may_remount_ro(sb->s_dev))
 645                         return -EBUSY;
 646         if (sb->s_op && sb->s_op->remount_fs) {
 647                 retval = sb->s_op->remount_fs(sb, &flags, data);
 648                 if (retval)
 649                         return retval;
 650         }
 651         sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
 652                 (flags & MS_RMT_MASK);
 653         return 0;
 654 }
 655 
 656 static int do_remount(const char *dir,int flags,char *data)
     
 657 {
 658         struct inode *dir_i;
 659         int retval;
 660 
 661         retval = namei(dir, &dir_i);
 662         if (retval)
 663                 return retval;
 664         if (dir_i != dir_i->i_sb->s_mounted) {
 665                 iput(dir_i);
 666                 return -EINVAL;
 667         }
 668         retval = do_remount_sb(dir_i->i_sb, flags, data);
 669         iput(dir_i);
 670         return retval;
 671 }
 672 
 673 static int copy_mount_options (const void * data, unsigned long *where)
     
 674 {
 675         int i;
 676         unsigned long page;
 677         struct vm_area_struct * vma;
 678 
 679         *where = 0;
 680         if (!data)
 681                 return 0;
 682 
 683         vma = find_vma(current, (unsigned long) data);
 684         if (!vma || (unsigned long) data < vma->vm_start)
 685                 return -EFAULT;
 686         i = vma->vm_end - (unsigned long) data;
 687         if (PAGE_SIZE <= (unsigned long) i)
 688                 i = PAGE_SIZE-1;
 689         if (!(page = __get_free_page(GFP_KERNEL))) {
 690                 return -ENOMEM;
 691         }
 692         memcpy_fromfs((void *) page,data,i);
 693         *where = page;
 694         return 0;
 695 }
 696 
 697 
 698 
 699 
 700 
 701 
 702 
 703 
 704 
 705 
 706 
 707 
 708 
 709 
 710 
 711 asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
     
 712         unsigned long new_flags, void * data)
 713 {
 714         struct file_system_type * fstype;
 715         struct inode * inode;
 716         struct file_operations * fops;
 717         kdev_t dev;
 718         int retval;
 719         const char * t;
 720         unsigned long flags = 0;
 721         unsigned long page = 0;
 722 
 723         if (!suser())
 724                 return -EPERM;
 725         if ((new_flags &
 726              (MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
 727                 retval = copy_mount_options (data, &page);
 728                 if (retval < 0)
 729                         return retval;
 730                 retval = do_remount(dir_name,
 731                                     new_flags & ~MS_MGC_MSK & ~MS_REMOUNT,
 732                                     (char *) page);
 733                 free_page(page);
 734                 return retval;
 735         }
 736         retval = copy_mount_options (type, &page);
 737         if (retval < 0)
 738                 return retval;
 739         fstype = get_fs_type((char *) page);
 740         free_page(page);
 741         if (!fstype)            
 742                 return -ENODEV;
 743         t = fstype->name;
 744         fops = NULL;
 745         if (fstype->requires_dev) {
 746                 retval = namei(dev_name, &inode);
 747                 if (retval)
 748                         return retval;
 749                 if (!S_ISBLK(inode->i_mode)) {
 750                         iput(inode);
 751                         return -ENOTBLK;
 752                 }
 753                 if (IS_NODEV(inode)) {
 754                         iput(inode);
 755                         return -EACCES;
 756                 }
 757                 dev = inode->i_rdev;
 758                 if (MAJOR(dev) >= MAX_BLKDEV) {
 759                         iput(inode);
 760                         return -ENXIO;
 761                 }
 762                 fops = get_blkfops(MAJOR(dev));
 763                 if (!fops) {
 764                         iput(inode);
 765                         return -ENOTBLK;
 766                 }
 767                 if (fops->open) {
 768                         struct file dummy;      
 769                         memset(&dummy, 0, sizeof(dummy));
 770                         dummy.f_inode = inode;
 771                         dummy.f_mode = (new_flags & MS_RDONLY) ? 1 : 3;
 772                         retval = fops->open(inode, &dummy);
 773                         if (retval) {
 774                                 iput(inode);
 775                                 return retval;
 776                         }
 777                 }
 778 
 779         } else {
 780                 if (!(dev = get_unnamed_dev()))
 781                         return -EMFILE;
 782                 inode = NULL;
 783         }
 784         page = 0;
 785         if ((new_flags & MS_MGC_MSK) == MS_MGC_VAL) {
 786                 flags = new_flags & ~MS_MGC_MSK;
 787                 retval = copy_mount_options(data, &page);
 788                 if (retval < 0) {
 789                         iput(inode);
 790                         return retval;
 791                 }
 792         }
 793         retval = do_mount(dev,dev_name,dir_name,t,flags,(void *) page);
 794         free_page(page);
 795         if (retval && fops && fops->release)
 796                 fops->release(inode, NULL);
 797         iput(inode);
 798         return retval;
 799 }
 800 
 801 void mount_root(void)
     
 802 {
 803         struct file_system_type * fs_type;
 804         struct super_block * sb;
 805         struct vfsmount *vfsmnt;
 806         struct inode * inode, d_inode;
 807         struct file filp;
 808         int retval;
 809   
 810         memset(super_blocks, 0, sizeof(super_blocks));
 811 #ifdef CONFIG_ROOT_NFS
 812         if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) {
 813                 ROOT_DEV = 0;
 814                 if ((fs_type = get_fs_type("nfs"))) {
 815                         sb = &super_blocks[0];
 816                         sb->s_dev = get_unnamed_dev();
 817                         sb->s_flags = root_mountflags & ~MS_RDONLY;
 818                         if (nfs_root_mount(sb) >= 0) {
 819                                 inode = sb->s_mounted;
 820                                 inode->i_count += 3 ;
 821                                 sb->s_covered = inode;
 822                                 sb->s_rd_only = 0;
 823                                 sb->s_dirt = 0;
 824                                 sb->s_type = fs_type;
 825                                 current->fs->pwd = inode;
 826                                 current->fs->root = inode;
 827                                 ROOT_DEV = sb->s_dev;
 828                                 printk (KERN_NOTICE "VFS: Mounted root (nfs filesystem).\n");
 829                                 return;
 830                         }
 831                         sb->s_dev = 0;
 832                 }
 833                 if (!ROOT_DEV) {
 834                         printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
 835                         ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
 836                 }
 837         }
 838 #endif
 839 
 840 #ifdef CONFIG_BLK_DEV_FD
 841         if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) {
 842                 printk(KERN_NOTICE "VFS: Insert root floppy and press ENTER\n");
 843                 wait_for_keypress();
 844         }
 845 #endif
 846 
 847         memset(&filp, 0, sizeof(filp));
 848         memset(&d_inode, 0, sizeof(d_inode));
 849         d_inode.i_rdev = ROOT_DEV;
 850         filp.f_inode = &d_inode;
 851         if ( root_mountflags & MS_RDONLY)
 852                 filp.f_mode = 1; 
 853         else
 854                 filp.f_mode = 3; 
 855         retval = blkdev_open(&d_inode, &filp);
 856         if(retval == -EROFS){
 857                 root_mountflags |= MS_RDONLY;
 858                 filp.f_mode = 1;
 859                 retval = blkdev_open(&d_inode, &filp);
 860         }
 861 
 862         for (fs_type = file_systems ; fs_type ; fs_type = fs_type->next) {
 863                 if(retval)
 864                         break;
 865                 if (!fs_type->requires_dev)
 866                         continue;
 867                 sb = read_super(ROOT_DEV,fs_type->name,root_mountflags,NULL,1);
 868                 if (sb) {
 869                         inode = sb->s_mounted;
 870                         inode->i_count += 3 ;   
 871                         sb->s_covered = inode;
 872                         sb->s_flags = root_mountflags;
 873                         current->fs->pwd = inode;
 874                         current->fs->root = inode;
 875                         printk ("VFS: Mounted root (%s filesystem)%s.\n",
 876                                 fs_type->name,
 877                                 (sb->s_flags & MS_RDONLY) ? " readonly" : "");
 878                         vfsmnt = add_vfsmnt(ROOT_DEV, "rootfs", "/");
 879                         vfsmnt->mnt_sb = sb;
 880                         return;
 881                 }
 882         }
 883         panic("VFS: Unable to mount root fs on %s",
 884                 kdevname(ROOT_DEV));
 885 }