root/xfs/xfs_vfsops-common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xfs_mount_common_sys
  2. xfs_mount_common
  3. xfs_unmount_common
  4. xfs_root_common

    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 }

/* [<][>][^][v][top][bottom][index][help] */