Annotation of sys/xfs/xfs_vfsops-common.c, Revision 1.1
1.1 ! nbrk 1: /*
! 2: * Copyright (c) 1995 - 2002 Kungliga Tekniska Högskolan
! 3: * (Royal Institute of Technology, Stockholm, Sweden).
! 4: * All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: *
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: *
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: *
! 17: * 3. Neither the name of the Institute nor the names of its contributors
! 18: * may be used to endorse or promote products derived from this software
! 19: * without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 31: * SUCH DAMAGE.
! 32: */
! 33:
! 34: #include <xfs/xfs_locl.h>
! 35:
! 36: RCSID("$arla: xfs_vfsops-common.c,v 1.40 2003/06/02 18:26:40 lha Exp $");
! 37:
! 38: /*
! 39: * NNPFS vfs operations.
! 40: */
! 41:
! 42: #include <xfs/xfs_common.h>
! 43: #include <xfs/xfs_message.h>
! 44: #include <xfs/xfs_fs.h>
! 45: #include <xfs/xfs_dev.h>
! 46: #include <xfs/xfs_deb.h>
! 47: #include <xfs/xfs_syscalls.h>
! 48: #include <xfs/xfs_vfsops.h>
! 49:
! 50: #ifdef HAVE_KERNEL_UDEV2DEV
! 51: #define VA_RDEV_TO_DEV(x) udev2dev(x, 0) /* XXX what is the 0 */
! 52: #else
! 53: #define VA_RDEV_TO_DEV(x) x
! 54: #endif
! 55:
! 56:
! 57: struct xfs xfs[NNNPFS];
! 58:
! 59: /*
! 60: * path and data is in system memory
! 61: */
! 62:
! 63: int
! 64: xfs_mount_common_sys(struct mount *mp,
! 65: const char *path,
! 66: void *data,
! 67: struct nameidata *ndp,
! 68: d_thread_t *p)
! 69: {
! 70: struct vnode *devvp;
! 71: dev_t dev;
! 72: int error;
! 73: struct vattr vat;
! 74:
! 75: NNPFSDEB(XDEBVFOPS, ("xfs_mount: "
! 76: "struct mount mp = %lx path = '%s' data = '%s'\n",
! 77: (unsigned long)mp, path, (char *)data));
! 78:
! 79: #ifdef ARLA_KNFS
! 80: NNPFSDEB(XDEBVFOPS, ("xfs_mount: mount flags = %x\n", mp->mnt_flag));
! 81:
! 82: /*
! 83: * mountd(8) flushes all export entries when it starts
! 84: * right now we ignore it (but should not)
! 85: */
! 86:
! 87: if (mp->mnt_flag & MNT_UPDATE ||
! 88: mp->mnt_flag & MNT_DELEXPORT) {
! 89:
! 90: NNPFSDEB(XDEBVFOPS,
! 91: ("xfs_mount: ignoreing MNT_UPDATE or MNT_DELEXPORT\n"));
! 92: return 0;
! 93: }
! 94: #endif
! 95:
! 96: NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, data, p);
! 97: error = namei(ndp);
! 98: if (error) {
! 99: NNPFSDEB(XDEBVFOPS, ("namei failed, errno = %d\n", error));
! 100: return error;
! 101: }
! 102:
! 103: devvp = ndp->ni_vp;
! 104:
! 105: if (devvp->v_type != VCHR) {
! 106: vput(devvp);
! 107: NNPFSDEB(XDEBVFOPS, ("not VCHR (%d)\n", devvp->v_type));
! 108: return ENXIO;
! 109: }
! 110: #if defined(__osf__)
! 111: VOP_GETATTR(devvp, &vat, ndp->ni_cred, error);
! 112: #elif defined(HAVE_FREEBSD_THREAD)
! 113: error = VOP_GETATTR(devvp, &vat, p->td_proc->p_ucred, p);
! 114: #else
! 115: error = VOP_GETATTR(devvp, &vat, p->p_ucred, p);
! 116: #endif
! 117: vput(devvp);
! 118: if (error) {
! 119: NNPFSDEB(XDEBVFOPS, ("VOP_GETATTR failed, error = %d\n", error));
! 120: return error;
! 121: }
! 122:
! 123: dev = VA_RDEV_TO_DEV(vat.va_rdev);
! 124:
! 125: NNPFSDEB(XDEBVFOPS, ("dev = %d.%d\n", major(dev), minor(dev)));
! 126:
! 127: if (!xfs_is_xfs_dev (dev)) {
! 128: NNPFSDEB(XDEBVFOPS, ("%s is not a xfs device\n", (char *)data));
! 129: return ENXIO;
! 130: }
! 131:
! 132: if (xfs[minor(dev)].status & NNPFS_MOUNTED)
! 133: return EBUSY;
! 134:
! 135: xfs[minor(dev)].status = NNPFS_MOUNTED;
! 136: xfs[minor(dev)].mp = mp;
! 137: xfs[minor(dev)].root = 0;
! 138: xfs[minor(dev)].nnodes = 0;
! 139: xfs[minor(dev)].fd = minor(dev);
! 140:
! 141: nnfs_init_head(&xfs[minor(dev)].nodehead);
! 142:
! 143: VFS_TO_NNPFS(mp) = &xfs[minor(dev)];
! 144: #if defined(HAVE_KERNEL_VFS_GETNEWFSID)
! 145: #if defined(HAVE_TWO_ARGUMENT_VFS_GETNEWFSID)
! 146: vfs_getnewfsid(mp, MOUNT_AFS);
! 147: #else
! 148: vfs_getnewfsid(mp);
! 149: #endif /* HAVE_TWO_ARGUMENT_VFS_GETNEWFSID */
! 150: #endif /* HAVE_KERNEL_VFS_GETNEWFSID */
! 151:
! 152: mp->mnt_stat.f_bsize = DEV_BSIZE;
! 153: #ifndef __osf__
! 154: mp->mnt_stat.f_iosize = DEV_BSIZE;
! 155: mp->mnt_stat.f_owner = 0;
! 156: #endif
! 157: mp->mnt_stat.f_blocks = 4711 * 4711;
! 158: mp->mnt_stat.f_bfree = 4711 * 4711;
! 159: mp->mnt_stat.f_bavail = 4711 * 4711;
! 160: mp->mnt_stat.f_files = 4711;
! 161: mp->mnt_stat.f_ffree = 4711;
! 162: mp->mnt_stat.f_flags = mp->mnt_flag;
! 163:
! 164: #ifdef __osf__
! 165: mp->mnt_stat.f_fsid.val[0] = dev;
! 166: mp->mnt_stat.f_fsid.val[1] = MOUNT_NNPFS;
! 167:
! 168: MALLOC(mp->m_stat.f_mntonname, char *, strlen(path) + 1,
! 169: M_PATHNAME, M_WAITOK);
! 170: strcpy(mp->m_stat.f_mntonname, path);
! 171:
! 172: MALLOC(mp->m_stat.f_mntfromname, char *, sizeof("arla"),
! 173: M_PATHNAME, M_WAITOK);
! 174: strcpy(mp->m_stat.f_mntfromname, "arla");
! 175: #else /* __osf__ */
! 176: strncpy(mp->mnt_stat.f_mntonname,
! 177: path,
! 178: sizeof(mp->mnt_stat.f_mntonname));
! 179:
! 180: strncpy(mp->mnt_stat.f_mntfromname,
! 181: data,
! 182: sizeof(mp->mnt_stat.f_mntfromname));
! 183:
! 184: strncpy(mp->mnt_stat.f_fstypename,
! 185: "xfs",
! 186: sizeof(mp->mnt_stat.f_fstypename));
! 187: #endif /* __osf__ */
! 188:
! 189: return 0;
! 190: }
! 191:
! 192: int
! 193: xfs_mount_common(struct mount *mp,
! 194: const char *user_path,
! 195: void *user_data,
! 196: struct nameidata *ndp,
! 197: d_thread_t *p)
! 198: {
! 199: char *path = NULL;
! 200: char *data = NULL;
! 201: size_t count;
! 202: int error = 0;
! 203:
! 204: data = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
! 205: if (data == NULL) {
! 206: error = ENOMEM;
! 207: goto done;
! 208: }
! 209: path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
! 210: if (path == NULL) {
! 211: error = ENOMEM;
! 212: goto done;
! 213: }
! 214:
! 215: error = copyinstr(user_path, path, MAXPATHLEN, &count);
! 216: if (error)
! 217: goto done;
! 218:
! 219: error = copyinstr(user_data, data, MAXPATHLEN, &count);
! 220: if (error)
! 221: goto done;
! 222: error = xfs_mount_common_sys (mp, path, data, ndp, p);
! 223: done:
! 224: free(data, M_TEMP);
! 225: free(path, M_TEMP);
! 226: return(error);
! 227: }
! 228:
! 229: #ifdef HAVE_KERNEL_DOFORCE
! 230: extern int doforce;
! 231: #endif
! 232:
! 233: int
! 234: xfs_unmount_common(struct mount *mp, int mntflags)
! 235: {
! 236: struct xfs *xfsp = VFS_TO_NNPFS(mp);
! 237: int flags = 0;
! 238: int error;
! 239:
! 240: if (mntflags & MNT_FORCE) {
! 241: #ifdef HAVE_KERNEL_DOFORCE
! 242: if (!doforce)
! 243: return EINVAL;
! 244: #endif
! 245: flags |= FORCECLOSE;
! 246: }
! 247:
! 248: error = free_all_xfs_nodes(xfsp, flags, 1);
! 249: if (error)
! 250: return error;
! 251:
! 252: xfsp->status = 0;
! 253: NNPFS_TO_VFS(xfsp) = NULL;
! 254: return 0;
! 255: }
! 256:
! 257: int
! 258: xfs_root_common(struct mount *mp, struct vnode **vpp,
! 259: d_thread_t *proc, struct ucred *cred)
! 260: {
! 261: struct xfs *xfsp = VFS_TO_NNPFS(mp);
! 262: struct xfs_message_getroot msg;
! 263: int error;
! 264:
! 265: do {
! 266: if (xfsp->root != NULL) {
! 267: *vpp = XNODE_TO_VNODE(xfsp->root);
! 268: xfs_do_vget(*vpp, LK_EXCLUSIVE, proc);
! 269: return 0;
! 270: }
! 271: msg.header.opcode = NNPFS_MSG_GETROOT;
! 272: msg.cred.uid = cred->cr_uid;
! 273: msg.cred.pag = xfs_get_pag(cred);
! 274: error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), proc);
! 275: if (error == 0)
! 276: error = ((struct xfs_message_wakeup *) & msg)->error;
! 277: } while (error == 0);
! 278: /*
! 279: * Failed to get message through, need to pretend that all went well
! 280: * and return a fake dead vnode to be able to unmount.
! 281: */
! 282:
! 283: if ((error = xfs_make_dead_vnode(mp, vpp)))
! 284: return error;
! 285:
! 286: NNPFS_MAKE_VROOT(*vpp);
! 287: return 0;
! 288: }
CVSweb