Print this page
PSARC 2008/290 lofi mount
6384817 Need persistent lofi based mounts and direct mount(1m) support for lofi
*** 17,27 ****
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
! * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
--- 17,27 ----
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
! * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
*** 35,45 ****
* software developed by the University of California, Berkeley, and its
* contributors.
*/
! #pragma ident "@(#)ufs_vfsops.c 2.275 07/10/25 SMI"
#include <sys/types.h>
#include <sys/t_lock.h>
#include <sys/param.h>
#include <sys/systm.h>
--- 35,45 ----
* software developed by the University of California, Berkeley, and its
* contributors.
*/
! #pragma ident "@(#)ufs_vfsops.c 2.276 08/05/07 SMI"
#include <sys/types.h>
#include <sys/t_lock.h>
#include <sys/param.h>
#include <sys/systm.h>
*** 264,273 ****
--- 264,275 ----
{
char *data = uap->dataptr;
int datalen = uap->datalen;
dev_t dev;
struct vnode *bvp;
+ struct vnode *lvp = NULL;
+ struct vnode *svp = NULL;
struct pathname dpn;
int error;
enum whymountroot why = ROOT_INIT;
struct ufs_args args;
int oflag, aflag;
*** 306,315 ****
--- 308,327 ----
return (EFAULT);
datalen = sizeof (struct ufs_args);
} else {
datalen = 0;
}
+
+ if ((vfsp->vfs_flag & VFS_RDONLY) != 0 ||
+ (uap->flags & MS_RDONLY) != 0) {
+ oflag = FREAD;
+ aflag = VREAD;
+ } else {
+ oflag = FREAD | FWRITE;
+ aflag = VREAD | VWRITE;
+ }
+
/*
* Read in the mount point pathname
* (so we can record the directory the file system was last mounted on).
*/
if (error = pn_get(uap->dir, fromspace, &dpn))
*** 316,372 ****
return (error);
/*
* Resolve path name of special file being mounted.
*/
! if (error = lookupname(uap->spec, fromspace, FOLLOW, NULL, &bvp)) {
pn_free(&dpn);
return (error);
}
! if (bvp->v_type != VBLK) {
! VN_RELE(bvp);
pn_free(&dpn);
return (ENOTBLK);
}
dev = bvp->v_rdev;
if (getmajor(dev) >= devcnt) {
pn_free(&dpn);
! VN_RELE(bvp);
return (ENXIO);
}
if (uap->flags & MS_REMOUNT)
why = ROOT_REMOUNT;
/*
! * In SunCluster, requests to a global device are satisfied by
! * a local device. We substitute the global pxfs node with a
! * local spec node here.
*/
if (IS_PXFSVP(bvp)) {
! VN_RELE(bvp);
bvp = makespecvp(dev, VBLK);
! }
!
! /*
! * Open block device mounted on. We need this to
! * check whether the caller has sufficient rights to
! * access the device in question.
! * When bio is fixed for vnodes this can all be vnode
! * operations.
! */
! if ((vfsp->vfs_flag & VFS_RDONLY) != 0 ||
! (uap->flags & MS_RDONLY) != 0) {
! oflag = FREAD;
! aflag = VREAD;
} else {
! oflag = FREAD | FWRITE;
! aflag = VREAD | VWRITE;
}
! if ((error = VOP_ACCESS(bvp, aflag, 0, cr, NULL)) != 0 ||
! (error = secpolicy_spec_open(cr, bvp, oflag)) != 0) {
pn_free(&dpn);
! VN_RELE(bvp);
return (error);
}
/*
* Ensure that this device isn't already mounted or in progress on a
--- 328,404 ----
return (error);
/*
* Resolve path name of special file being mounted.
*/
! if (error = lookupname(uap->spec, fromspace, FOLLOW, NULL, &svp)) {
pn_free(&dpn);
return (error);
}
!
! error = vfs_get_lofi(vfsp, &lvp);
!
! if (error > 0) {
! VN_RELE(svp);
pn_free(&dpn);
+ return (error);
+ } else if (error == 0) {
+ bvp = lvp;
+ } else {
+ bvp = svp;
+
+ if (svp->v_type != VBLK) {
+ VN_RELE(svp);
+ pn_free(&dpn);
return (ENOTBLK);
}
+
+ if ((error = secpolicy_spec_open(cr, svp, oflag)) != 0) {
+ VN_RELE(svp);
+ pn_free(&dpn);
+ return (error);
+ }
+ }
+
dev = bvp->v_rdev;
if (getmajor(dev) >= devcnt) {
pn_free(&dpn);
! if (lvp != NULL)
! VN_RELE(lvp);
! if (svp != NULL)
! VN_RELE(svp);
return (ENXIO);
}
if (uap->flags & MS_REMOUNT)
why = ROOT_REMOUNT;
/*
! * In SunCluster, requests to a global device are satisfied by a
! * local device. We substitute the global pxfs node with a local
! * spec node here.
! *
! * Open device/file mounted on. We need this to check whether
! * the caller has sufficient rights to access the resource in
! * question. When bio is fixed for vnodes this can all be vnode
! * operations.
*/
if (IS_PXFSVP(bvp)) {
! ASSERT(lvp == NULL);
! VN_RELE(svp);
! svp = NULL;
bvp = makespecvp(dev, VBLK);
! error = VOP_ACCESS(bvp, aflag, 0, cr, NULL);
} else {
! error = VOP_ACCESS(svp, aflag, 0, cr, NULL);
}
!
! if (error != 0) {
pn_free(&dpn);
! if (lvp != NULL)
! VN_RELE(lvp);
! if (svp != NULL)
! VN_RELE(svp);
return (error);
}
/*
* Ensure that this device isn't already mounted or in progress on a
*** 375,391 ****
*/
if ((uap->flags & MS_NOCHECK) == 0) {
if ((uap->flags & MS_GLOBAL) == 0 &&
vfs_devmounting(dev, vfsp)) {
pn_free(&dpn);
! VN_RELE(bvp);
return (EBUSY);
}
if (vfs_devismounted(dev)) {
if ((uap->flags & MS_REMOUNT) == 0) {
pn_free(&dpn);
! VN_RELE(bvp);
return (EBUSY);
}
}
}
--- 407,429 ----
*/
if ((uap->flags & MS_NOCHECK) == 0) {
if ((uap->flags & MS_GLOBAL) == 0 &&
vfs_devmounting(dev, vfsp)) {
pn_free(&dpn);
! if (lvp != NULL)
! VN_RELE(lvp);
! if (svp != NULL)
! VN_RELE(svp);
return (EBUSY);
}
if (vfs_devismounted(dev)) {
if ((uap->flags & MS_REMOUNT) == 0) {
pn_free(&dpn);
! if (lvp != NULL)
! VN_RELE(lvp);
! if (svp != NULL)
! VN_RELE(svp);
return (EBUSY);
}
}
}
*** 402,414 ****
/*
* Mount the filesystem, free the device vnode on error.
*/
error = mountfs(vfsp, why, bvp, dpn.pn_path, cr, 0, &args, datalen);
pn_free(&dpn);
if (error) {
! VN_RELE(bvp);
}
if (error == 0)
vfs_set_feature(vfsp, VFSFT_XVATTR);
return (error);
}
/*
--- 440,463 ----
/*
* Mount the filesystem, free the device vnode on error.
*/
error = mountfs(vfsp, why, bvp, dpn.pn_path, cr, 0, &args, datalen);
pn_free(&dpn);
+
if (error) {
! if (lvp != NULL)
! VN_RELE(lvp);
! if (svp != NULL)
! VN_RELE(svp);
! } else {
! /*
! * If lofi, drop our reference to the original file.
! */
! if (lvp != NULL)
! VN_RELE(svp);
}
+
if (error == 0)
vfs_set_feature(vfsp, VFSFT_XVATTR);
return (error);
}
/*