MFC:
authorMichael Neumann <mneumann@dragonflybsd.org>
Wed, 30 Jul 2008 07:53:01 +0000 (30 07:53 +0000)
committerMichael Neumann <mneumann@dragonflybsd.org>
Wed, 30 Jul 2008 07:53:01 +0000 (30 07:53 +0000)
Implement mounting of a Hammer filesystem as a root filesystem.

  To mount a Hammer filesystem as root filesystem (e.g. /dev/ad0s1d),
  you have to specify the following in /boot/loader.conf:

      vfs.root.mountfrom="hammer:ad0s1d"

sys/vfs/hammer/hammer.h
sys/vfs/hammer/hammer_ondisk.c
sys/vfs/hammer/hammer_vfsops.c

index 979991d..88299b3 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.117.2.4 2008/07/19 18:46:20 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.117.2.5 2008/07/30 07:53:01 mneumann Exp $
  */
 /*
  * This header file contains structures used internally by the HAMMERFS
@@ -839,7 +839,8 @@ int hammer_unload_volume(hammer_volume_t volume, void *data __unused);
 int    hammer_adjust_volume_mode(hammer_volume_t volume, void *data __unused);
 
 int    hammer_unload_buffer(hammer_buffer_t buffer, void *data __unused);
-int    hammer_install_volume(hammer_mount_t hmp, const char *volname);
+int    hammer_install_volume(hammer_mount_t hmp, const char *volname,
+                       struct vnode *devvp);
 int    hammer_mountcheck_volumes(hammer_mount_t hmp);
 
 int    hammer_ip_lookup(hammer_cursor_t cursor);
index 8d42d7c..b1a1fc9 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/vfs/hammer/hammer_ondisk.c,v 1.69.2.2 2008/07/18 00:21:09 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_ondisk.c,v 1.69.2.3 2008/07/30 07:53:01 mneumann Exp $
  */
 /*
  * Manage HAMMER's on-disk structures.  These routines are primarily
@@ -98,7 +98,8 @@ RB_GENERATE2(hammer_nod_rb_tree, hammer_node, rb_node,
  * Calls made to hammer_load_volume() or single-threaded
  */
 int
-hammer_install_volume(struct hammer_mount *hmp, const char *volname)
+hammer_install_volume(struct hammer_mount *hmp, const char *volname,
+                     struct vnode *devvp)
 {
        struct mount *mp;
        hammer_volume_t volume;
@@ -125,12 +126,18 @@ hammer_install_volume(struct hammer_mount *hmp, const char *volname)
        /*
         * Get the device vnode
         */
-       error = nlookup_init(&nd, volume->vol_name, UIO_SYSSPACE, NLC_FOLLOW);
-       if (error == 0)
-               error = nlookup(&nd);
-       if (error == 0)
-               error = cache_vref(&nd.nl_nch, nd.nl_cred, &volume->devvp);
-       nlookup_done(&nd);
+       if (devvp == NULL) {
+               error = nlookup_init(&nd, volume->vol_name, UIO_SYSSPACE, NLC_FOLLOW);
+               if (error == 0)
+                       error = nlookup(&nd);
+               if (error == 0)
+                       error = cache_vref(&nd.nl_nch, nd.nl_cred, &volume->devvp);
+               nlookup_done(&nd);
+       } else {
+               error = 0;
+               volume->devvp = devvp;
+       }
+
        if (error == 0) {
                if (vn_isdisk(volume->devvp, &error)) {
                        error = vfs_mountedon(volume->devvp);
index 8f9d465..6ed236c 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/vfs/hammer/hammer_vfsops.c,v 1.63.2.4 2008/07/26 05:37:20 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_vfsops.c,v 1.63.2.5 2008/07/30 07:53:01 mneumann Exp $
  */
 
 #include <sys/param.h>
@@ -282,14 +282,29 @@ hammer_vfs_mount(struct mount *mp, char *mntpt, caddr_t data,
        hammer_mount_t hmp;
        hammer_volume_t rootvol;
        struct vnode *rootvp;
+       struct vnode *devvp = NULL;
        const char *upath;      /* volume name in userspace */
        char *path;             /* volume name in system space */
        int error;
        int i;
        int master_id;
-
-       if ((error = copyin(data, &info, sizeof(info))) != 0)
-               return (error);
+       if (mntpt == NULL) {
+               /*
+                * Root mount
+                */
+               if ((error = bdevvp(rootdev, &devvp))) {
+                       kprintf("hammer_mountroot: can't find devvp\n");
+                       return (error);
+               }
+               mp->mnt_flag &= ~MNT_RDONLY; /* mount R/W */
+               bzero(&info, sizeof(info));
+               info.asof = 0;
+               info.hflags = 0;
+               info.nvolumes = 1;
+       } else {
+               if ((error = copyin(data, &info, sizeof(info))) != 0)
+                       return (error);
+       }
 
        /*
         * updating or new mount
@@ -434,11 +449,24 @@ hammer_vfs_mount(struct mount *mp, char *mntpt, caddr_t data,
        path = objcache_get(namei_oc, M_WAITOK);
        hmp->nvolumes = -1;
        for (i = 0; i < info.nvolumes; ++i) {
-               error = copyin(&info.volumes[i], &upath, sizeof(char *));
-               if (error == 0)
-                       error = copyinstr(upath, path, MAXPATHLEN, NULL);
+               if (mntpt == NULL) {
+                       /*
+                        * Root mount.
+                        * Only one volume; and no need for copyin.
+                        */
+                       KKASSERT(info.nvolumes == 1);
+                       ksnprintf(path, MAXPATHLEN, "/dev/%s",
+                                 mp->mnt_stat.f_mntfromname);  
+                       error = 0;
+               } else {
+                       error = copyin(&info.volumes[i], &upath,
+                                      sizeof(char *));
+                       if (error == 0)
+                               error = copyinstr(upath, path,
+                                                 MAXPATHLEN, NULL);
+               }
                if (error == 0)
-                       error = hammer_install_volume(hmp, path);
+                       error = hammer_install_volume(hmp, path, devvp);
                if (error)
                        break;
        }