root/xfs/xfs_vfsops-bsd.c

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

DEFINITIONS

This source file includes following definitions.
  1. xfs_mount_caddr
  2. xfs_start
  3. xfs_unmount
  4. xfs_root
  5. xfs_quotactl
  6. xfs_statfs
  7. xfs_sync
  8. xfs_vget
  9. common_fhtovp
  10. xfs_fhtovp
  11. xfs_fhtovp
  12. xfs_checkexp
  13. xfs_vptofh
  14. xfs_dead_lookup
  15. xfs_fhlookup
  16. xfs_fhopen

    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-bsd.c,v 1.72 2002/12/19 10:30:17 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_vfsops.h>
   48 #include <xfs/xfs_vfsops-bsd.h>
   49 #include <xfs/xfs_vnodeops.h>
   50 
   51 int
   52 xfs_mount_caddr(struct mount *mp,
   53                 const char *user_path,
   54                 caddr_t user_data,
   55                 struct nameidata *ndp,
   56                 d_thread_t *p)
   57 {
   58     return xfs_mount_common(mp, user_path, user_data, ndp, p);
   59 }
   60 
   61 int
   62 xfs_start(struct mount * mp, int flags, d_thread_t * p)
   63 {
   64     NNPFSDEB(XDEBVFOPS, ("xfs_start mp = %lx, flags = %d, proc = %lx\n", 
   65                        (unsigned long)mp, flags, (unsigned long)p));
   66     return 0;
   67 }
   68 
   69 
   70 int
   71 xfs_unmount(struct mount * mp, int mntflags, d_thread_t *p)
   72 {
   73     NNPFSDEB(XDEBVFOPS, ("xfs_umount: mp = %lx, mntflags = %d, proc = %lx\n", 
   74                        (unsigned long)mp, mntflags, (unsigned long)p));
   75     return xfs_unmount_common(mp, mntflags);
   76 }
   77 
   78 int
   79 xfs_root(struct mount *mp, struct vnode **vpp)
   80 {
   81     NNPFSDEB(XDEBVFOPS, ("xfs_root mp = %lx\n", (unsigned long)mp));
   82 #ifdef HAVE_FREEBSD_THREAD
   83     return xfs_root_common(mp, vpp, xfs_curthread(), xfs_curthread()->td_proc->p_ucred);
   84 #else
   85     return xfs_root_common(mp, vpp, xfs_curproc(), xfs_curproc()->p_ucred);
   86 #endif
   87 }
   88 
   89 int
   90 xfs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg, d_thread_t *p)
   91 {
   92     NNPFSDEB(XDEBVFOPS, ("xfs_quotactl: mp = %lx, cmd = %d, uid = %u, "
   93                        "arg = %lx, proc = %lx\n", 
   94                        (unsigned long)mp, cmd, uid,
   95                        (unsigned long)arg, (unsigned long)p));
   96     return EOPNOTSUPP;
   97 }
   98 
   99 int
  100 xfs_statfs(struct mount *mp, struct statfs *sbp, d_thread_t *p)
  101 {
  102     NNPFSDEB(XDEBVFOPS, ("xfs_statfs: mp = %lx, sbp = %lx, proc = %lx\n", 
  103                        (unsigned long)mp,
  104                        (unsigned long)sbp,
  105                        (unsigned long)p));
  106     bcopy(&mp->mnt_stat, sbp, sizeof(*sbp));
  107     return 0;
  108 }
  109 
  110 int
  111 xfs_sync(struct mount *mp, int waitfor, struct ucred *cred, d_thread_t *p)
  112 {
  113     NNPFSDEB(XDEBVFOPS, ("xfs_sync: mp = %lx, waitfor = %d, "
  114                        "cred = %lx, proc = %lx\n",
  115                        (unsigned long)mp,
  116                        waitfor,
  117                        (unsigned long)cred,
  118                        (unsigned long)p));
  119     return 0;
  120 }
  121 
  122 int
  123 xfs_vget(struct mount * mp,
  124 #ifdef __APPLE__
  125          void *ino,
  126 #else
  127          ino_t ino,
  128 #endif
  129          struct vnode ** vpp)
  130 {
  131     NNPFSDEB(XDEBVFOPS, ("xfs_vget\n"));
  132     return EOPNOTSUPP;
  133 }
  134 
  135 static int
  136 common_fhtovp(struct mount * mp,
  137            struct fid * fhp,
  138            struct vnode ** vpp)
  139 {
  140 #ifdef ARLA_KNFS
  141     struct netcred *np = NULL;
  142     struct xfs_node *xn;
  143     struct vnode *vp;
  144     xfs_handle handle;
  145     int error;
  146 
  147     NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp\n"));
  148 
  149     if (fhp->fid_len != 16) {
  150         printf("xfs_fhtovp: *PANIC* got a invalid length of a fid\n");
  151         return EINVAL;
  152     }
  153 
  154     memcpy(&handle, fhp->fid_data, sizeof(handle));
  155     NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp: fid: %d.%d.%d.%d\n", 
  156                        handle.a, handle.d, handle.c, handle.d));
  157 
  158     NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp: xfs_vnode_find\n"));
  159     xn = xfs_node_find(&xfs[0].nodehead, &handle);
  160 
  161     if (xn == NULL) {
  162         struct xfs_message_getattr msg;
  163 
  164         error = xfs_getnewvnode(xfs[0].mp, &vp, &handle);
  165         if (error)
  166             return error;
  167         
  168         xfs_do_vget(vp, 0, curproc);
  169 
  170     } else {
  171         /* XXX access ? */
  172         vp = XNODE_TO_VNODE(xn);
  173 
  174         /* XXX wrong ? (we tell arla below) */
  175         if (vp->v_usecount <= 0) 
  176             xfs_do_vget(vp, 0, curproc);
  177         else
  178             VREF(vp);
  179         error = 0;
  180     }
  181 
  182     *vpp = vp;
  183 
  184     if (error == 0) {
  185         NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp done\n"));
  186 
  187         /* 
  188          * XXX tell arla about this node is hold by nfsd.
  189          * There need to be code in xfs_write too.
  190          */
  191     } else
  192         NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp failed (%d)\n", error));
  193 
  194     return error;
  195 #else /* !ARLA_KNFS */
  196     return EOPNOTSUPP;
  197 #endif /* !ARLA_KNFS */
  198 }
  199 
  200 /* new style fhtovp */
  201 
  202 #ifdef HAVE_STRUCT_VFSOPS_VFS_CHECKEXP
  203 int
  204 xfs_fhtovp(struct mount * mp,
  205            struct fid * fhp,
  206            struct vnode ** vpp)
  207 {
  208     return common_fhtovp (mp, fhp, vpp);
  209 }
  210 
  211 #else /* !HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */
  212 
  213 /* old style fhtovp */
  214 
  215 int
  216 xfs_fhtovp(struct mount * mp,
  217            struct fid * fhp,
  218            struct mbuf * nam,
  219            struct vnode ** vpp,
  220            int *exflagsp,
  221            struct ucred ** credanonp)
  222 {
  223     static struct ucred fhtovpcred;
  224     int error;
  225 
  226     /* XXX: Should see if we is exported to this client */
  227 #if 0
  228     np = vfs_export_lookup(mp, &ump->um_export, nam);
  229     if (np == NULL)
  230        return EACCES;
  231 #endif
  232     error = common_fhtovp(mp, fhp, vpp);
  233     if (error == 0) {
  234        fhtovpcred.cr_uid = 0;
  235        fhtovpcred.cr_gid = 0;
  236        fhtovpcred.cr_ngroups = 0;
  237       
  238 #ifdef MNT_EXPUBLIC
  239        *exflagsp = MNT_EXPUBLIC;
  240 #else
  241        *exflagsp = 0;
  242 #endif
  243        *credanonp = &fhtovpcred;
  244     }
  245     return error;
  246 }
  247 #endif /* !HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */
  248 
  249 int
  250 xfs_checkexp (struct mount *mp,
  251 #ifdef __FreeBSD__
  252               struct sockaddr *nam,
  253 #else
  254               struct mbuf *nam,
  255 #endif
  256               int *exflagsp,
  257               struct ucred **credanonp)
  258 {
  259     NNPFSDEB(XDEBVFOPS, ("xfs_checkexp\n"));
  260 
  261 #if 0
  262     np = vfs_export_lookup(mp, &ump->um_export, nam);
  263     if (np == NULL)
  264         return EACCES;
  265 #endif
  266     return 0;
  267 }
  268 
  269 int
  270 xfs_vptofh(struct vnode * vp,
  271            struct fid * fhp)
  272 {
  273 #ifdef ARLA_KNFS
  274     struct xfs_node *xn;
  275     NNPFSDEB(XDEBVFOPS, ("xfs_vptofh\n"));
  276 
  277     if (MAXFIDSZ < 16)
  278         return EOPNOTSUPP;
  279 
  280     xn = VNODE_TO_XNODE(vp);
  281 
  282     if (xn == NULL)
  283         return EINVAL;
  284 
  285     fhp->fid_len = 16;
  286     memcpy(fhp->fid_data, &xn->handle,  16);
  287 
  288     return 0;
  289 #else
  290     NNPFSDEB(XDEBVFOPS, ("xfs_vptofh\n"));
  291     return EOPNOTSUPP;
  292 #endif
  293 }
  294 
  295 /* 
  296  * xfs complete dead vnodes implementation.
  297  *
  298  * this is because the dead_vnodeops_p is _not_ filesystem, but rather
  299  * a part of the vfs-layer.  
  300  */
  301 
  302 int
  303 xfs_dead_lookup(struct vop_lookup_args * ap)
  304      /* struct vop_lookup_args {
  305         struct vnodeop_desc *a_desc;
  306         struct vnode *a_dvp;
  307         struct vnode **a_vpp;
  308         struct componentname *a_cnp;
  309 }; */
  310 {
  311     *ap->a_vpp = NULL;
  312     return ENOTDIR;
  313 }
  314 
  315 /* 
  316  * Given `fsid', `fileid', and `gen', return in `vpp' a locked and
  317  * ref'ed vnode from that file system with that id and generation.
  318  * All is done in the context of `proc'.  Returns 0 if successful, and
  319  * error otherwise.  
  320  */
  321 
  322 int
  323 xfs_fhlookup (d_thread_t *proc,
  324               struct xfs_fhandle_t *fhp,
  325               struct vnode **vpp)
  326 {
  327     int error;
  328     struct mount *mp;
  329 #if !(defined(HAVE_GETFH) && defined(HAVE_FHOPEN))
  330     struct ucred *cred = proc->p_ucred;
  331     struct vattr vattr;
  332     fsid_t fsid;
  333     struct xfs_fh_args *fh_args = (struct xfs_fh_args *)fhp->fhdata;
  334 
  335     NNPFSDEB(XDEBVFOPS, ("xfs_fhlookup (xfs)\n"));
  336 
  337     error = xfs_suser (proc);
  338     if (error)
  339         return EPERM;
  340 
  341     if (fhp->len < sizeof(struct xfs_fh_args))
  342         return EINVAL;
  343     
  344     fsid = SCARG(fh_args, fsid);
  345 
  346     mp = xfs_vfs_getvfs (&fsid);
  347     if (mp == NULL)
  348         return ENXIO;
  349 
  350 #ifdef __APPLE__
  351     {
  352         uint32_t ino = SCARG(fh_args, fileid);
  353         error = VFS_VGET(mp, &ino, vpp);
  354     }
  355 #else
  356     error = VFS_VGET(mp, SCARG(fh_args, fileid), vpp);
  357 #endif
  358 
  359     if (error)
  360         return error;
  361 
  362     if (*vpp == NULL)
  363         return ENOENT;
  364 
  365     error = VOP_GETATTR(*vpp, &vattr, cred, proc);
  366     if (error) {
  367         vput(*vpp);
  368         return error;
  369     }
  370 
  371     if (vattr.va_gen != SCARG(fh_args, gen)) {
  372         vput(*vpp);
  373         return ENOENT;
  374     }
  375 #else /* HAVE_GETFH && HAVE_FHOPEN */
  376     {
  377         fhandle_t *fh = (fhandle_t *) fhp;
  378 
  379         NNPFSDEB(XDEBVFOPS, ("xfs_fhlookup (native)\n"));
  380 
  381         mp = xfs_vfs_getvfs (&fh->fh_fsid);
  382         if (mp == NULL)
  383             return ESTALE;
  384 
  385         if ((error = VFS_FHTOVP(mp, &fh->fh_fid, vpp)) != 0) {
  386             *vpp = NULL;
  387             return error;
  388         }
  389     }
  390 #endif  /* HAVE_GETFH && HAVE_FHOPEN */
  391 
  392 #ifdef HAVE_KERNEL_VFS_OBJECT_CREATE
  393     if ((*vpp)->v_type == VREG && (*vpp)->v_object == NULL)
  394 #ifdef HAVE_FREEBSD_THREAD
  395         xfs_vfs_object_create (*vpp, proc, proc->td_proc->p_ucred);
  396 #else
  397         xfs_vfs_object_create (*vpp, proc, proc->p_ucred);
  398 #endif
  399 #elif __APPLE__
  400     if ((*vpp)->v_type == VREG && (!UBCINFOEXISTS(*vpp))) {
  401         ubc_info_init(*vpp);
  402     }
  403     ubc_hold(*vpp);
  404 #endif
  405     return 0;
  406 }
  407 
  408 
  409 
  410 /*
  411  * Perform an open operation on the vnode identified by a `xfs_fhandle_t'
  412  * (see xfs_fhlookup) with flags `user_flags'.  Returns 0 or
  413  * error.  If successful, the file descriptor is returned in `retval'.
  414  */
  415 
  416 extern struct fileops vnops;    /* sometimes declared in <file.h> */
  417 
  418 int
  419 xfs_fhopen (d_thread_t *proc,
  420             struct xfs_fhandle_t *fhp,
  421             int user_flags,
  422             register_t *retval)
  423 {
  424     int error;
  425     struct vnode *vp;
  426 #ifdef HAVE_FREEBSD_THREAD
  427     struct ucred *cred = proc->td_proc->p_ucred;
  428 #else
  429     struct ucred *cred = proc->p_ucred;
  430 #endif
  431     int flags = FFLAGS(user_flags);
  432     int index;
  433     struct file *fp;
  434     int mode;
  435     struct xfs_fhandle_t fh;
  436 
  437     NNPFSDEB(XDEBVFOPS, ("xfs_fhopen: flags = %d\n", user_flags));
  438 
  439     error = copyin (fhp, &fh, sizeof(fh));
  440     if (error)
  441         return error;
  442 
  443     error = xfs_fhlookup (proc, &fh, &vp);
  444     NNPFSDEB(XDEBVFOPS, ("xfs_fhlookup returned %d\n", error));
  445     if (error)
  446         return error;
  447 
  448     switch (vp->v_type) {
  449     case VDIR :
  450     case VREG :
  451         break;
  452     case VLNK :
  453         error = EMLINK;
  454         goto out;
  455     default :
  456         error = EOPNOTSUPP;
  457         goto out;
  458     }
  459 
  460     mode = 0;
  461     if (flags & FWRITE) {
  462         switch (vp->v_type) {
  463         case VREG :
  464             break;
  465         case VDIR :
  466             error = EISDIR;
  467             goto out;
  468         default :
  469             error = EOPNOTSUPP;
  470             goto out;
  471         }
  472 
  473         error = vn_writechk (vp);
  474         if (error)
  475             goto out;
  476 
  477         mode |= VWRITE;
  478     }
  479     if (flags & FREAD)
  480         mode |= VREAD;
  481 
  482     if (mode) {
  483         error = VOP_ACCESS(vp, mode, cred, proc);
  484         if (error)
  485             goto out;
  486     }
  487 
  488     error = VOP_OPEN(vp, flags, cred, proc);
  489     if (error)
  490         goto out;
  491 
  492     error = falloc(proc, &fp, &index);
  493     if (error)
  494         goto out;
  495 
  496     if (flags & FWRITE)
  497         vp->v_writecount++;
  498 
  499 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300000
  500     if (vp->v_type == VREG) {
  501 #ifdef HAVE_FREEBSD_THREAD
  502         error = xfs_vfs_object_create(vp, proc, proc->td_proc->p_ucred);
  503 #else
  504         error = xfs_vfs_object_create(vp, proc, proc->p_ucred);
  505 #endif
  506         if (error)
  507             goto out;
  508     }
  509 #endif
  510 
  511     fp->f_flag = flags & FMASK;
  512     fp->f_type = DTYPE_VNODE;
  513     fp->f_ops  = &vnops;
  514     fp->f_data = (caddr_t)vp;
  515     xfs_vfs_unlock(vp, proc);
  516     *retval = index;
  517 #ifdef FILE_UNUSE
  518     FILE_UNUSE(fp, proc);
  519 #endif
  520 #ifdef __APPLE__
  521     *fdflags(proc, index) &= ~UF_RESERVED;
  522 #endif
  523     return 0;
  524 out:
  525     NNPFSDEB(XDEBVFOPS, ("xfs_fhopen: error = %d\n", error));
  526     vput(vp);
  527     return error;
  528 }

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