root/fs/super.c

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

DEFINITIONS

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

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

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