summaryrefslogtreecommitdiffstats
path: root/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c')
-rw-r--r--sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c1680
1 files changed, 0 insertions, 1680 deletions
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
deleted file mode 100644
index 01aa0e5..0000000
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
+++ /dev/null
@@ -1,1680 +0,0 @@
-/*
- * Copyright (c) 2001, Alexander Kabaev
- * Copyright (c) 2006, Russell Cattelan Digital Elves Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/namei.h>
-#include <sys/kernel.h>
-#include <sys/fcntl.h>
-#include <sys/mount.h>
-#include <sys/unistd.h>
-#include <sys/vnode.h>
-#include <sys/dirent.h>
-#include <sys/ioccom.h>
-#include <sys/malloc.h>
-#include <sys/extattr.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_object.h>
-#include <vm/vm_page.h>
-#include <vm/vm_pager.h>
-#include <vm/vnode_pager.h>
-
-#define NO_VFS_MACROS
-#include "xfs.h"
-#include "xfs_types.h"
-#include "xfs_bit.h"
-#include "xfs_inum.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_trans_priv.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_bmap_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_imap.h"
-#include "xfs_attr.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
-#include "xfs_ialloc.h"
-#include "xfs_alloc.h"
-#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_acl.h"
-#include "xfs_cap.h"
-#include "xfs_mac.h"
-#include "xfs_iomap.h"
-#include "xfs_clnt.h"
-#include "xfs_mountops.h"
-
-/*
- * Prototypes for XFS vnode operations.
- */
-static vop_access_t _xfs_access;
-static vop_advlock_t _xfs_advlock;
-static vop_bmap_t _xfs_bmap;
-static vop_cachedlookup_t _xfs_cachedlookup;
-static vop_close_t _xfs_close;
-static vop_create_t _xfs_create;
-static vop_deleteextattr_t _xfs_deleteextattr;
-static vop_fsync_t _xfs_fsync;
-static vop_getattr_t _xfs_getattr;
-static vop_getextattr_t _xfs_getextattr;
-static vop_inactive_t _xfs_inactive;
-static vop_ioctl_t _xfs_ioctl;
-static vop_link_t _xfs_link;
-static vop_listextattr_t _xfs_listextattr;
-static vop_mkdir_t _xfs_mkdir;
-static vop_mknod_t _xfs_mknod;
-static vop_open_t _xfs_open;
-static vop_read_t _xfs_read;
-static vop_readdir_t _xfs_readdir;
-static vop_readlink_t _xfs_readlink;
-static vop_reclaim_t _xfs_reclaim;
-static vop_remove_t _xfs_remove;
-static vop_rename_t _xfs_rename;
-static vop_rmdir_t _xfs_rmdir;
-static vop_setattr_t _xfs_setattr;
-static vop_setextattr_t _xfs_setextattr;
-static vop_strategy_t _xfs_strategy;
-static vop_symlink_t _xfs_symlink;
-static vop_write_t _xfs_write;
-static vop_vptofh_t _xfs_vptofh;
-
-struct vop_vector xfs_vnops = {
- .vop_default = &default_vnodeops,
- .vop_access = _xfs_access,
- .vop_advlock = _xfs_advlock,
- .vop_bmap = _xfs_bmap,
- .vop_cachedlookup = _xfs_cachedlookup,
- .vop_close = _xfs_close,
- .vop_create = _xfs_create,
- .vop_deleteextattr = _xfs_deleteextattr,
- .vop_fsync = _xfs_fsync,
- .vop_getattr = _xfs_getattr,
- .vop_getextattr = _xfs_getextattr,
- .vop_inactive = _xfs_inactive,
- .vop_ioctl = _xfs_ioctl,
- .vop_link = _xfs_link,
- .vop_listextattr = _xfs_listextattr,
- .vop_lookup = vfs_cache_lookup,
- .vop_mkdir = _xfs_mkdir,
- .vop_mknod = _xfs_mknod,
- .vop_open = _xfs_open,
- .vop_read = _xfs_read,
- .vop_readdir = _xfs_readdir,
- .vop_readlink = _xfs_readlink,
- .vop_reclaim = _xfs_reclaim,
- .vop_remove = _xfs_remove,
- .vop_rename = _xfs_rename,
- .vop_rmdir = _xfs_rmdir,
- .vop_setattr = _xfs_setattr,
- .vop_setextattr = _xfs_setextattr,
- .vop_strategy = _xfs_strategy,
- .vop_symlink = _xfs_symlink,
- .vop_write = _xfs_write,
- .vop_vptofh = _xfs_vptofh,
-};
-
-/*
- * FIFO's specific operations.
- */
-
-static vop_close_t _xfsfifo_close;
-static vop_read_t _xfsfifo_read;
-static vop_kqfilter_t _xfsfifo_kqfilter;
-static vop_write_t _xfsfifo_write;
-
-struct vop_vector xfs_fifoops = {
- .vop_default = &fifo_specops,
- .vop_access = _xfs_access,
- .vop_close = _xfsfifo_close,
- .vop_fsync = _xfs_fsync,
- .vop_getattr = _xfs_getattr,
- .vop_inactive = _xfs_inactive,
- .vop_kqfilter = _xfsfifo_kqfilter,
- .vop_read = _xfsfifo_read,
- .vop_reclaim = _xfs_reclaim,
- .vop_setattr = _xfs_setattr,
- .vop_write = _xfsfifo_write,
- .vop_vptofh = _xfs_vptofh,
-};
-
-static int
-_xfs_access(
- struct vop_access_args /* {
- struct vnode *a_vp;
- accmode_t a_accmode;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error;
-
- XVOP_ACCESS(VPTOXFSVP(ap->a_vp), ap->a_accmode, ap->a_cred, error);
- return (error);
-}
-
-static int
-_xfs_open(
- struct vop_open_args /* {
- struct vnode *a_vp;
- int a_mode;
- struct ucred *a_cred;
- struct thread *a_td;
- struct file *a_fp;
- } */ *ap)
-{
- int error;
-
- XVOP_OPEN(VPTOXFSVP(ap->a_vp), ap->a_cred, error);
- if (error == 0)
- vnode_create_vobject(ap->a_vp, 0, ap->a_td);
- return (error);
-}
-
-static int
-_xfs_close(
- struct vop_close_args /* {
- struct vnodeop_desc *a_desc;
- struct vnode *a_vp;
- int a_fflag;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error = 0;
- /* XVOP_CLOSE(VPTOXFSVP(ap->a_vp), NULL, error); */
- return (error);
-}
-
-static int
-_xfs_getattr(
- struct vop_getattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vattr *vap = ap->a_vap;
- struct mount *mp;
- xfs_vattr_t va;
- int error;
- /* extract the xfs vnode from the private data */
- //xfs_vnode_t *xvp = (xfs_vnode_t *)vp->v_data;
-
- memset(&va,0,sizeof(xfs_vattr_t));
- va.va_mask = XFS_AT_STAT|XFS_AT_GENCOUNT|XFS_AT_XFLAGS;
-
- XVOP_GETATTR(VPTOXFSVP(vp), &va, 0, ap->a_cred, error);
- if (error)
- return (error);
-
- mp = vp->v_mount;
-
- vap->va_type = IFTOVT(((xfs_vnode_t *)vp->v_data)->v_inode->i_d.di_mode);
- vap->va_mode = va.va_mode;
- vap->va_nlink = va.va_nlink;
- vap->va_uid = va.va_uid;
- vap->va_gid = va.va_gid;
- vap->va_fsid = mp->mnt_stat.f_fsid.val[0];
- vap->va_fileid = va.va_nodeid;
- vap->va_size = va.va_size;
- vap->va_blocksize = va.va_blocksize;
- vap->va_atime = va.va_atime;
- vap->va_mtime = va.va_mtime;
- vap->va_ctime = va.va_ctime;
- vap->va_gen = va.va_gen;
- vap->va_rdev = va.va_rdev;
- vap->va_bytes = (va.va_nblocks << BBSHIFT);
-
- /* XFS now supports devices that have block sizes
- * other than 512 so BBSHIFT will work for now
- * but need to get this value from the super block
- */
-
- /*
- * Fields with no direct equivalent in XFS
- */
- vap->va_filerev = 0;
- vap->va_flags = 0;
-
- return (0);
-}
-
-static int
-_xfs_setattr(
- struct vop_setattr_args /* {
- struct vnode *a_vp;
- struct vattr *a_vap;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vattr *vap = ap->a_vap;
- xfs_vattr_t va;
- int error;
-
- /*
- * Check for unsettable attributes.
- */
-#ifdef RMC
- if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
- (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
- (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
- ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL))
- return (EINVAL);
-#endif
-
- memset(&va, 0, sizeof(va));
-
- if (vap->va_uid != (uid_t)VNOVAL) {
- va.va_mask |= XFS_AT_UID;
- va.va_uid = vap->va_uid;
- }
- if (vap->va_gid != (gid_t)VNOVAL) {
- va.va_mask |= XFS_AT_GID;
- va.va_gid = vap->va_gid;
- }
- if (vap->va_size != VNOVAL) {
- va.va_mask |= XFS_AT_SIZE;
- va.va_size = vap->va_size;
- }
- if (vap->va_atime.tv_sec != VNOVAL) {
- va.va_mask |= XFS_AT_ATIME;
- va.va_atime = vap->va_atime;
- }
- if (vap->va_mtime.tv_sec != VNOVAL) {
- va.va_mask |= XFS_AT_MTIME;
- va.va_mtime = vap->va_mtime;
- }
- if (vap->va_ctime.tv_sec != VNOVAL) {
- va.va_mask |= XFS_AT_CTIME;
- va.va_ctime = vap->va_ctime;
- }
- if (vap->va_mode != (mode_t)VNOVAL) {
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = vap->va_mode;
- }
-
- XVOP_SETATTR(VPTOXFSVP(vp), &va, 0, ap->a_cred, error);
- return (error);
-}
-
-static int
-_xfs_inactive(
- struct vop_inactive_args /* {
- struct vnode *a_vp;
- struct thread *a_td;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct thread *td = ap->a_td;
- int error;
-
- XVOP_INACTIVE(VPTOXFSVP(vp), td->td_ucred, error);
- return (error);
-}
-
-static int
-_xfs_read(
- struct vop_read_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- int error;
-
- switch (vp->v_type) {
- case VREG:
- break;
- case VDIR:
- return (EISDIR);
- default:
- return (EPERM);
- };
-
- XVOP_READ(VPTOXFSVP(vp), uio, ap->a_ioflag, ap->a_cred, error);
- return error;
-}
-
-int
-xfs_read_file(xfs_mount_t *mp, xfs_inode_t *ip, struct uio *uio, int ioflag)
-{
- xfs_fileoff_t lbn, nextlbn;
- xfs_fsize_t bytesinfile;
- long size, xfersize, blkoffset;
- struct buf *bp;
- struct vnode *vp;
- int error, orig_resid;
- int seqcount;
-
- seqcount = ioflag >> IO_SEQSHIFT;
-
- orig_resid = uio->uio_resid;
- if (orig_resid <= 0)
- return (0);
-
- vp = XFS_ITOV(ip)->v_vnode;
-
- /*
- * Ok so we couldn't do it all in one vm trick...
- * so cycle around trying smaller bites..
- */
- for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
- if ((bytesinfile = ip->i_d.di_size - uio->uio_offset) <= 0)
- break;
-
- lbn = XFS_B_TO_FSBT(mp, uio->uio_offset);
- nextlbn = lbn + 1;
-
- /*
- * size of buffer. The buffer representing the
- * end of the file is rounded up to the size of
- * the block type ( fragment or full block,
- * depending ).
- */
- size = mp->m_sb.sb_blocksize;
- blkoffset = XFS_B_FSB_OFFSET(mp, uio->uio_offset);
-
- /*
- * The amount we want to transfer in this iteration is
- * one FS block less the amount of the data before
- * our startpoint (duh!)
- */
- xfersize = mp->m_sb.sb_blocksize - blkoffset;
-
- /*
- * But if we actually want less than the block,
- * or the file doesn't have a whole block more of data,
- * then use the lesser number.
- */
- if (uio->uio_resid < xfersize)
- xfersize = uio->uio_resid;
- if (bytesinfile < xfersize)
- xfersize = bytesinfile;
-
- if (XFS_FSB_TO_B(mp, nextlbn) >= ip->i_d.di_size ) {
- /*
- * Don't do readahead if this is the end of the file.
- */
- error = bread(vp, lbn, size, NOCRED, &bp);
- } else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
- /*
- * Otherwise if we are allowed to cluster,
- * grab as much as we can.
- *
- * XXX This may not be a win if we are not
- * doing sequential access.
- */
- error = cluster_read(vp, ip->i_d.di_size, lbn,
- size, NOCRED, uio->uio_resid, seqcount, &bp);
- } else if (seqcount > 1) {
- /*
- * If we are NOT allowed to cluster, then
- * if we appear to be acting sequentially,
- * fire off a request for a readahead
- * as well as a read. Note that the 4th and 5th
- * arguments point to arrays of the size specified in
- * the 6th argument.
- */
- int nextsize = mp->m_sb.sb_blocksize;
- error = breadn(vp, lbn,
- size, &nextlbn, &nextsize, 1, NOCRED, &bp);
- } else {
- /*
- * Failing all of the above, just read what the
- * user asked for. Interestingly, the same as
- * the first option above.
- */
- error = bread(vp, lbn, size, NOCRED, &bp);
- }
- if (error) {
- brelse(bp);
- bp = NULL;
- break;
- }
-
- /*
- * If IO_DIRECT then set B_DIRECT for the buffer. This
- * will cause us to attempt to release the buffer later on
- * and will cause the buffer cache to attempt to free the
- * underlying pages.
- */
- if (ioflag & IO_DIRECT)
- bp->b_flags |= B_DIRECT;
-
- /*
- * We should only get non-zero b_resid when an I/O error
- * has occurred, which should cause us to break above.
- * However, if the short read did not cause an error,
- * then we want to ensure that we do not uiomove bad
- * or uninitialized data.
- */
- size -= bp->b_resid;
- if (size < xfersize) {
- if (size == 0)
- break;
- xfersize = size;
- }
-
- /*
- * otherwise use the general form
- */
- error = uiomove((char *)bp->b_data + blkoffset,
- (int)xfersize, uio);
-
- if (error)
- break;
-
- if (ioflag & (IO_VMIO|IO_DIRECT) ) {
- /*
- * If there are no dependencies, and it's VMIO,
- * then we don't need the buf, mark it available
- * for freeing. The VM has the data.
- */
- bp->b_flags |= B_RELBUF;
- brelse(bp);
- } else {
- /*
- * Otherwise let whoever
- * made the request take care of
- * freeing it. We just queue
- * it onto another list.
- */
- bqrelse(bp);
- }
- }
-
- /*
- * This can only happen in the case of an error
- * because the loop above resets bp to NULL on each iteration
- * and on normal completion has not set a new value into it.
- * so it must have come from a 'break' statement
- */
- if (bp != NULL) {
- if (ioflag & (IO_VMIO|IO_DIRECT)) {
- bp->b_flags |= B_RELBUF;
- brelse(bp);
- } else
- bqrelse(bp);
- }
-
- return (error);
-}
-
-static int
-_xfs_write(struct vop_write_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- int ioflag = ap->a_ioflag;
- int error;
-
- xfs_vnode_t *xvp = (xfs_vnode_t *)vp->v_data;
-
- error = xfs_write(xvp->v_bh.bh_first, uio, ioflag, ap->a_cred);
-
- if (error < 0) {
- printf("Xfs_write got error %d\n",error);
- return -error;
- }
- return 0;
-}
-
-
-int
-xfs_write_file(xfs_inode_t *xip, struct uio *uio, int ioflag)
-{
- struct buf *bp;
- //struct thread *td;
- daddr_t lbn;
- off_t osize = 0;
- off_t offset= 0;
- int blkoffset, error, resid, xfersize;
- int fsblocksize;
- int seqcount;
- xfs_iomap_t iomap;
- int maps = 1;
-
- xfs_vnode_t *xvp = XFS_ITOV(xip);
- struct vnode *vp = xvp->v_vnode;
-
- xfs_mount_t *mp = (&xip->i_iocore)->io_mount;
-
- seqcount = ioflag >> IO_SEQSHIFT;
-
- memset(&iomap,0,sizeof(xfs_iomap_t));
-
- /*
- * Maybe this should be above the vnode op call, but so long as
- * file servers have no limits, I don't think it matters.
- */
-#if 0
- td = uio->uio_td;
- if (vn_rlimit_fsize(vp, uio, uio->uio_td))
- return (EFBIG);
-#endif
-
- resid = uio->uio_resid;
- offset = uio->uio_offset;
- osize = xip->i_d.di_size;
-
- /* xfs bmap wants bytes for both offset and size */
- XVOP_BMAP(xvp,
- uio->uio_offset,
- uio->uio_resid,
- BMAPI_WRITE|BMAPI_DIRECT,
- &iomap, &maps, error);
- if(error) {
- printf("XVOP_BMAP failed\n");
- goto error;
- }
-
- for (error = 0; uio->uio_resid > 0;) {
-
- lbn = XFS_B_TO_FSBT(mp, offset);
- blkoffset = XFS_B_FSB_OFFSET(mp, offset);
- xfersize = mp->m_sb.sb_blocksize - blkoffset;
- fsblocksize = mp->m_sb.sb_blocksize;
-
- if (uio->uio_resid < xfersize)
- xfersize = uio->uio_resid;
-
- /*
- * getblk sets buf by blkno * bo->bo_bsize
- * bo_bsize is set from the mnt point fsize
- * so we call getblk in the case using fsblocks
- * not basic blocks
- */
-
- bp = getblk(vp, lbn, fsblocksize, 0, 0, 0);
- if(!bp) {
- printf("getblk failed\n");
- error = EINVAL;
- break;
- }
-
- if (!(bp->b_flags & B_CACHE) && fsblocksize > xfersize)
- vfs_bio_clrbuf(bp);
-
- if (offset + xfersize > xip->i_d.di_size) {
- xip->i_d.di_size = offset + xfersize;
- vnode_pager_setsize(vp, offset + fsblocksize);
- }
-
- /* move the offset for the next itteration of the loop */
- offset += xfersize;
-
- error = uiomove((char *)bp->b_data + blkoffset, xfersize, uio);
-
- if ((ioflag & IO_VMIO) &&
- (LIST_FIRST(&bp->b_dep) == NULL)) /* in ext2fs? */
- bp->b_flags |= B_RELBUF;
-
- /* force to full direct for now */
- bp->b_flags |= B_DIRECT;
- /* and sync ... the delay path is not pushing data out */
- ioflag |= IO_SYNC;
-
- if (ioflag & IO_SYNC) {
- (void)bwrite(bp);
- } else if (0 /* RMC xfersize + blkoffset == fs->s_frag_size */) {
- if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0) {
- bp->b_flags |= B_CLUSTEROK;
- cluster_write(vp, bp, osize, seqcount);
- } else {
- bawrite(bp);
- }
- } else {
- bp->b_flags |= B_CLUSTEROK;
- bdwrite(bp);
- }
- if (error || xfersize == 0)
- break;
- }
- /*
- * If we successfully wrote any data, and we are not the superuser
- * we clear the setuid and setgid bits as a precaution against
- * tampering.
- */
-#if 0
- if (resid > uio->uio_resid && ap->a_cred && ap->a_cred->cr_uid != 0)
- ip->i_mode &= ~(ISUID | ISGID);
-#endif
- if (error) {
- if (ioflag & IO_UNIT) {
-#if 0
- (void)ext2_truncate(vp, osize,
- ioflag & IO_SYNC, ap->a_cred, uio->uio_td);
-#endif
- uio->uio_offset -= resid - uio->uio_resid;
- uio->uio_resid = resid;
- }
- } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) {
- /* Update the vnode here? */
- }
-
-error:
- return error;
-}
-
-static int
-_xfs_create(
- struct vop_create_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- struct componentname *cnp = ap->a_cnp;
- xfs_vnode_t *xvp;
- xfs_vattr_t va;
- int error;
-
- memset(&va, 0, sizeof (va));
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = vap->va_mode;
- va.va_mask |= XFS_AT_TYPE;
- va.va_mode |= VTTOIF(vap->va_type);
-
- xvp = NULL;
- XVOP_CREATE(VPTOXFSVP(dvp), cnp, &va, &xvp, credp, error);
-
- if (error == 0) {
- *ap->a_vpp = xvp->v_vnode;
- VOP_LOCK(xvp->v_vnode, LK_EXCLUSIVE);
- }
-
- return (error);
-}
-
-extern int xfs_remove(bhv_desc_t *, bhv_desc_t *, vname_t *, cred_t *);
-
-static int
-_xfs_remove(
- struct vop_remove_args /* {
- struct vnodeop_desc *a_desc;
- struct vnode * a_dvp;
- struct vnode * a_vp;
- struct componentname * a_cnp;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- /*
- struct vnode *dvp = ap->a_dvp;
- struct componentname *cnp = ap->a_cnp;
- */
- int error;
-
- if (vp->v_type == VDIR || vp->v_usecount != 1)
- return (EPERM);
-
- error = xfs_remove(VPTOXFSVP(ap->a_dvp)->v_bh.bh_first,
- VPTOXFSVP(ap->a_vp)->v_bh.bh_first,
- ap->a_cnp,credp);
-
- cache_purge(vp);
- return error;
-}
-
-static int
-_xfs_rename(
- struct vop_rename_args /* {
- struct vnode *a_fdvp;
- struct vnode *a_fvp;
- struct componentname *a_fcnp;
- struct vnode *a_tdvp;
- struct vnode *a_tvp;
- struct componentname *a_tcnp;
- } */ *ap)
-{
- struct vnode *fvp = ap->a_fvp;
- struct vnode *tvp = ap->a_tvp;
- struct vnode *fdvp = ap->a_fdvp;
- struct vnode *tdvp = ap->a_tdvp;
-/* struct componentname *tcnp = ap->a_tcnp; */
-/* struct componentname *fcnp = ap->a_fcnp;*/
- int error = EPERM;
-
- if (error)
- goto out;
-
- /* Check for cross-device rename */
- if ((fvp->v_mount != tdvp->v_mount) ||
- (tvp && (fvp->v_mount != tvp->v_mount))) {
- error = EXDEV;
- goto out;
- }
-
- if (tvp && tvp->v_usecount > 1) {
- error = EBUSY;
- goto out;
- }
-
- if (fvp->v_type == VDIR) {
- if (tvp != NULL && tvp->v_type == VDIR)
- cache_purge(tdvp);
- cache_purge(fdvp);
- }
-out:
- if (tdvp == tvp)
- vrele(tdvp);
- else
- vput(tdvp);
- if (tvp)
- vput(tvp);
- vrele(fdvp);
- vrele(fvp);
- vgone(fvp);
- if (tvp)
- vgone(tvp);
- return (error);
-}
-
-static int
-_xfs_link(
- struct vop_link_args /* {
- struct vnode *a_tdvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
- } */ *ap)
-{
- xfs_vnode_t *tdvp, *vp;
- int error;
-
- tdvp = VPTOXFSVP(ap->a_tdvp);
- vp = VPTOXFSVP(ap->a_vp);
- XVOP_LINK(tdvp, vp, ap->a_cnp, NULL, error);
- return (error);
-}
-
-static int
-_xfs_symlink(
- struct vop_symlink_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- char *a_target;
- } */ *ap)
-{
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- xfs_vnode_t *xvp;
- xfs_vattr_t va;
- int error;
-
- memset(&va, 0, sizeof (va));
-
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = ap->a_vap->va_mode | S_IFLNK;
- va.va_mask |= XFS_AT_TYPE;
-
- XVOP_SYMLINK(VPTOXFSVP(ap->a_dvp), ap->a_cnp, &va, ap->a_target,
- &xvp, credp, error);
-
- if (error == 0) {
- *ap->a_vpp = xvp->v_vnode;
- VOP_LOCK(xvp->v_vnode, LK_EXCLUSIVE);
- }
-
- return (error);
-}
-
-static int
-_xfs_mknod(
- struct vop_mknod_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- struct componentname *cnp = ap->a_cnp;
- xfs_vnode_t *xvp;
- xfs_vattr_t va;
- int error;
-
- memset(&va, 0, sizeof (va));
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = vap->va_mode | S_IFIFO;
- va.va_mask |= XFS_AT_TYPE;
- va.va_mask |= XFS_AT_RDEV;
- va.va_rdev = vap->va_rdev;
-
- xvp = NULL;
- XVOP_CREATE(VPTOXFSVP(dvp), cnp, &va, &xvp, credp, error);
-
- if (error == 0) {
- *ap->a_vpp = xvp->v_vnode;
- VOP_LOCK(xvp->v_vnode, LK_EXCLUSIVE);
- }
-
- return (error);
-}
-
-static int
-_xfs_mkdir(
- struct vop_mkdir_args /* {
- struct vnode *a_dvp;
- struct vnode **a_vpp;
- struct componentname *a_cnp;
- struct vattr *a_vap;
- } */ *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct thread *td = curthread;
- struct ucred *credp = td->td_ucred;
- struct componentname *cnp = ap->a_cnp;
- xfs_vnode_t *xvp;
- xfs_vattr_t va;
- int error;
-
- memset(&va, 0, sizeof (va));
- va.va_mask |= XFS_AT_MODE;
- va.va_mode = vap->va_mode | S_IFDIR;
- va.va_mask |= XFS_AT_TYPE;
-
- xvp = NULL;
- XVOP_MKDIR(VPTOXFSVP(dvp), cnp, &va, &xvp, credp, error);
-
- if (error == 0) {
- *ap->a_vpp = xvp->v_vnode;
- VOP_LOCK(xvp->v_vnode, LK_EXCLUSIVE);
- }
-
- return (error);
-}
-
-static int
-_xfs_rmdir(
- struct vop_rmdir_args /* {
- struct vnode *a_dvp;
- struct vnode *a_vp;
- struct componentname *a_cnp;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
-/* struct componentname *cnp = ap->a_cnp; */
- int error;
-
- if (dvp == vp)
- return (EINVAL);
-
- error = EPERM;
-
- return (error);
-}
-
-static int
-_xfs_readdir(
- struct vop_readdir_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- struct ucred *a_cred;
- int *a_eofflag;
- int *a_ncookies;
- u_long **a_cookies;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- int error;
- off_t off;
- int eof = 0;
-
- if (vp->v_type != VDIR)
- return (EPERM);
- if (ap->a_ncookies) {
- return (EOPNOTSUPP);
- }
-
- error = 0;
- while (!eof){
- off = (int)uio->uio_offset;
-
- XVOP_READDIR(VPTOXFSVP(vp), uio, NULL, &eof, error);
- if ((uio->uio_offset == off) || error) {
- break;
- }
- }
-
- if (ap->a_eofflag)
- *ap->a_eofflag = (eof != 0);
-
- return (error);
-}
-
-
-static int
-_xfs_readlink(
- struct vop_readlink_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- struct ucred *a_cred;
- } */ *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct uio *uio = ap->a_uio;
- struct ucred *cred = ap->a_cred;
- int error;
-
- XVOP_READLINK(VPTOXFSVP(vp), uio, 0, cred, error);
- return (error);
-}
-
-static int
-_xfs_fsync(
- struct vop_fsync_args /* {
- struct vnode * a_vp;
- int a_waitfor;
- struct thread * a_td;
- } */ *ap)
-{
- xfs_vnode_t *vp = VPTOXFSVP(ap->a_vp);
- int flags = FSYNC_DATA;
- int error;
-
- if (ap->a_waitfor == MNT_WAIT)
- flags |= FSYNC_WAIT;
- XVOP_FSYNC(vp, flags, ap->a_td->td_ucred, (xfs_off_t)0, (xfs_off_t)-1, error);
-
- return (error);
-}
-
-static int
-_xfs_bmap(
- struct vop_bmap_args /* {
- struct vnode *a_vp;
- daddr_t a_bn;
- struct bufobj **a_bop;
- daddr_t *a_bnp;
- int *a_runp;
- int *a_runb;
- } */ *ap)
-{
- xfs_iomap_t iomap;
- xfs_off_t offset;
- ssize_t size;
- struct mount *mp;
- struct xfs_mount *xmp;
- struct xfs_vnode *xvp;
- int error, maxrun, retbm;
-
- mp = ap->a_vp->v_mount;
- xmp = XFS_VFSTOM(MNTTOVFS(mp));
- if (ap->a_bop != NULL)
- *ap->a_bop = &xmp->m_ddev_targp->specvp->v_bufobj;
- if (ap->a_bnp == NULL)
- return (0);
-
- xvp = VPTOXFSVP(ap->a_vp);
- retbm = 1;
-
- offset = XFS_FSB_TO_B(xmp, ap->a_bn);
- size = XFS_FSB_TO_B(xmp, 1);
- XVOP_BMAP(xvp, offset, size, BMAPI_READ, &iomap, &retbm, error);
- if (error)
- return (error);
- if (retbm == 0 || iomap.iomap_bn == IOMAP_DADDR_NULL) {
- *ap->a_bnp = (daddr_t)-1;
- if (ap->a_runb)
- *ap->a_runb = 0;
- if (ap->a_runp)
- *ap->a_runp = 0;
- } else {
- *ap->a_bnp = iomap.iomap_bn + btodb(iomap.iomap_delta);
- maxrun = mp->mnt_iosize_max / mp->mnt_stat.f_iosize - 1;
- if (ap->a_runb) {
- *ap->a_runb = XFS_B_TO_FSB(xmp, iomap.iomap_delta);
- if (*ap->a_runb > maxrun)
- *ap->a_runb = maxrun;
- }
- if (ap->a_runp) {
- *ap->a_runp =
- XFS_B_TO_FSB(xmp, iomap.iomap_bsize
- - iomap.iomap_delta - size);
- if (*ap->a_runp > maxrun)
- *ap->a_runp = maxrun;
- }
- }
- return (0);
-}
-
-static int
-_xfs_strategy(
- struct vop_strategy_args /* {
- struct vnode *a_vp;
- struct buf *a_bp;
- } */ *ap)
-{
- daddr_t blkno;
- struct buf *bp;
- struct bufobj *bo;
- struct vnode *vp;
- struct xfs_mount *xmp;
- int error;
-
- bp = ap->a_bp;
- vp = ap->a_vp;
-
- KASSERT(ap->a_vp == ap->a_bp->b_vp, ("%s(%p != %p)",
- __func__, ap->a_vp, ap->a_bp->b_vp));
- if (bp->b_blkno == bp->b_lblkno) {
- error = VOP_BMAP(vp, bp->b_lblkno, NULL, &blkno, NULL, NULL);
- bp->b_blkno = blkno;
- bp->b_iooffset = (blkno << BBSHIFT);
- if (error) {
- bp->b_error = error;
- bp->b_ioflags |= BIO_ERROR;
- bufdone(bp);
- return (0);
- }
- if ((long)bp->b_blkno == -1)
- vfs_bio_clrbuf(bp);
- }
- if ((long)bp->b_blkno == -1) {
- bufdone(bp);
- return (0);
- }
-
- xmp = XFS_VFSTOM(MNTTOVFS(vp->v_mount));
- bo = &xmp->m_ddev_targp->specvp->v_bufobj;
- bo->bo_ops->bop_strategy(bo, bp);
- return (0);
-}
-
-int
-_xfs_ioctl(
- struct vop_ioctl_args /* {
- struct vnode *a_vp;
- u_long a_command;
- caddr_t a_data;
- int fflag;
- struct ucred *cred;
- struct thread *a_td;
- } */ *ap)
-{
-/* struct vnode *vp = ap->a_vp; */
-/* struct thread *p = ap->a_td; */
-/* struct file *fp; */
- int error;
-
- xfs_vnode_t *xvp = VPTOXFSVP(ap->a_vp);
-
- printf("_xfs_ioctl cmd 0x%lx data %p\n",ap->a_command,ap->a_data);
-
-// XVOP_IOCTL(xvp,(void *)NULL,(void *)NULL,ap->a_fflag,ap->a_command,ap->a_data,error);
- error = xfs_ioctl(xvp->v_bh.bh_first,NULL,NULL,ap->a_fflag,ap->a_command,ap->a_data);
-
- return error;
-}
-
-int
-_xfs_advlock(
- struct vop_advlock_args /* {
- struct vnode *a_vp;
- caddr_t a_id;
- int a_op;
- struct flock *a_fl;
- int a_flags;
- } */ *ap)
-{
-/* struct vnode *vp = ap->a_vp;*/
- struct flock *fl = ap->a_fl;
-/* caddr_t id = (caddr_t)1 */ /* ap->a_id */;
-/* int flags = ap->a_flags; */
- off_t start, end, size;
- int error/* , lkop */;
-
- /*KAN: temp */
- return (EOPNOTSUPP);
-
- size = 0;
- error = 0;
- switch (fl->l_whence) {
- case SEEK_SET:
- case SEEK_CUR:
- start = fl->l_start;
- break;
- case SEEK_END:
- start = fl->l_start + size;
- default:
- return (EINVAL);
- }
- if (start < 0)
- return (EINVAL);
- if (fl->l_len == 0)
- end = -1;
- else {
- end = start + fl->l_len - 1;
- if (end < start)
- return (EINVAL);
- }
-#ifdef notyet
- switch (ap->a_op) {
- case F_SETLK:
- error = lf_advlock(ap, &vp->v_lockf, size);
- break;
- case F_UNLCK:
- lf_advlock(ap, &vp->v_lockf, size);
- break;
- case F_GETLK:
- error = lf_advlock(ap, &vp->v_lockf, size);
- break;
- default:
- return (EINVAL);
- }
-#endif
- return (error);
-}
-
-static int
-_xfs_cachedlookup(
- struct vop_cachedlookup_args /* {
- struct vnode * a_dvp;
- struct vnode ** a_vpp;
- struct componentname * a_cnp;
- } */ *ap)
-{
- struct vnode *dvp, *tvp;
- struct xfs_vnode *cvp;
- int islastcn;
- int error;
- struct vnode **vpp = ap->a_vpp;
- struct componentname *cnp = ap->a_cnp;
- struct ucred *cred = cnp->cn_cred;
- int flags = cnp->cn_flags;
- int nameiop = cnp->cn_nameiop;
- struct thread *td = cnp->cn_thread;
-
- char *pname = cnp->cn_nameptr;
- int namelen = cnp->cn_namelen;
-
- *vpp = NULL;
- dvp = ap->a_dvp;
- islastcn = flags & ISLASTCN;
-
- XVOP_LOOKUP(VPTOXFSVP(dvp), cnp, &cvp, 0, NULL, cred, error);
-
- if (error == ENOENT) {
- if ((nameiop == CREATE || nameiop == RENAME ||
- nameiop == DELETE) && islastcn)
- {
- error = VOP_ACCESS(dvp, VWRITE, cred, td);
- if (error)
- return (error);
- cnp->cn_flags |= SAVENAME;
- return (EJUSTRETURN);
- }
- if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
- cache_enter(dvp, *vpp, cnp);
- return (error);
- }
- if (error)
- return (error);
-
- tvp = cvp->v_vnode;
-
- if (nameiop == DELETE && islastcn) {
- if ((error = vn_lock(tvp, LK_EXCLUSIVE))) {
- vrele(tvp);
- goto err_out;
- }
- *vpp = tvp;
-
- /* Directory should be writable for deletes. */
- error = VOP_ACCESS(dvp, VWRITE, cred, td);
- if (error)
- goto err_out;
-
- /* XXXKAN: Permission checks for sticky dirs? */
- return (0);
- }
-
- if (nameiop == RENAME && islastcn) {
- if ((error = vn_lock(tvp, LK_EXCLUSIVE))) {
- vrele(tvp);
- goto err_out;
- }
- *vpp = tvp;
-
- if ((error = VOP_ACCESS(dvp, VWRITE, cred, td)))
- goto err_out;
- return (0);
- }
-
- if (flags & ISDOTDOT) {
- VOP_UNLOCK(dvp, 0);
- error = vn_lock(tvp, cnp->cn_lkflags);
- if (error) {
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
- vrele(tvp);
- goto err_out;
- }
- *vpp = tvp;
- } else if (namelen == 1 && pname[0] == '.') {
- *vpp = tvp;
- KASSERT(tvp == dvp, ("not same directory"));
- } else {
- if ((error = vn_lock(tvp, cnp->cn_lkflags))) {
- vrele(tvp);
- goto err_out;
- }
- *vpp = tvp;
- }
-
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(dvp, *vpp, cnp);
- return (0);
-
-err_out:
- if (*vpp != 0)
- vput(*vpp);
- return (error);
-}
-
-static int
-_xfs_reclaim(
- struct vop_reclaim_args /* {
- struct vnode *a_vp;
- struct thread *a_td;
- } */ *ap)
-{
-
- struct vnode *vp = ap->a_vp;
- struct xfs_vnode *xfs_vp = VPTOXFSVP(vp);
- int error;
-
- XVOP_RECLAIM(xfs_vp, error);
- kmem_free(xfs_vp, sizeof(*xfs_vp));
- vp->v_data = NULL;
- return (error);
-}
-
-static int
-_xfs_kqfilter(
- struct vop_kqfilter_args /* {
- struct vnodeop_desc *a_desc;
- struct vnode *a_vp;
- struct knote *a_kn;
- } */ *ap)
-{
- return (0);
-}
-
-struct xfs_inode *
-xfs_vtoi(struct xfs_vnode *xvp)
-{
- return(XFS_BHVTOI(xvp->v_fbhv));
-}
-
-/*
- * Read wrapper for fifos.
- */
-static int
-_xfsfifo_read(
- struct vop_read_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap)
-{
- int error, resid;
- struct xfs_inode *ip;
- struct uio *uio;
-
- uio = ap->a_uio;
- resid = uio->uio_resid;
- error = fifo_specops.vop_read(ap);
- ip = xfs_vtoi(VPTOXFSVP(ap->a_vp));
- if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
- (uio->uio_resid != resid || (error == 0 && resid != 0)))
- xfs_ichgtime(ip, XFS_ICHGTIME_ACC);
- return (error);
-}
-
-/*
- * Write wrapper for fifos.
- */
-static int
-_xfsfifo_write(
- struct vop_write_args /* {
- struct vnode *a_vp;
- struct uio *a_uio;
- int a_ioflag;
- struct ucred *a_cred;
- } */ *ap)
-{
- int error, resid;
- struct uio *uio;
- struct xfs_inode *ip;
-
- uio = ap->a_uio;
- resid = uio->uio_resid;
- error = fifo_specops.vop_write(ap);
- ip = xfs_vtoi(VPTOXFSVP(ap->a_vp));
- if (ip != NULL && (uio->uio_resid != resid ||
- (error == 0 && resid != 0)))
- xfs_ichgtime(ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
- return (error);
-}
-
-/*
- * Close wrapper for fifos.
- *
- * Update the times on the inode then do device close.
- */
-static int
-_xfsfifo_close(
- struct vop_close_args /* {
- struct vnode *a_vp;
- int a_fflag;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
-
- return (fifo_specops.vop_close(ap));
-}
-
-/*
- * Kqfilter wrapper for fifos.
- *
- * Fall through to ufs kqfilter routines if needed
- */
-static int
-_xfsfifo_kqfilter(
- struct vop_kqfilter_args /* {
- struct vnodeop_desc *a_desc;
- struct vnode *a_vp;
- struct knote *a_kn;
- } */ *ap)
-{
- int error;
-
- error = fifo_specops.vop_kqfilter(ap);
- if (error)
- error = _xfs_kqfilter(ap);
- return (error);
-}
-
-static int
-_xfs_getextattr(
- struct vop_getextattr_args /* {
- struct vnode *a_vp;
- int a_attrnamespace;
- const char *a_name;
- struct uio *a_uio;
- size_t *a_size;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error;
- char *value;
- int size;
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VREAD);
- if (error)
- return (error);
-
- size = ATTR_MAX_VALUELEN;
- value = (char *)kmem_zalloc(size, KM_SLEEP);
- if (value == NULL)
- return (ENOMEM);
-
- XVOP_ATTR_GET(VPTOXFSVP(ap->a_vp), ap->a_name, value, &size, 1,
- ap->a_cred, error);
-
- if (ap->a_uio != NULL) {
- if (ap->a_uio->uio_iov->iov_len < size)
- error = ERANGE;
- else
- uiomove(value, size, ap->a_uio);
- }
-
- if (ap->a_size != NULL)
- *ap->a_size = size;
-
- kmem_free(value, ATTR_MAX_VALUELEN);
- return (error);
-}
-
-static int
-_xfs_listextattr(
- struct vop_listextattr_args /* {
- struct vnode *a_vp;
- int a_attrnamespace;
- struct uio *a_uio;
- size_t *a_size;
- struct ucred *a_cred;
- struct thread *a_td;
- } */ *ap)
-{
- int error;
- char *buf = NULL;
- int buf_len = 0;
- attrlist_cursor_kern_t cursor = { 0 };
- int i;
- char name_len;
- int attrnames_len = 0;
- int xfs_flags = ATTR_KERNAMELS;
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VREAD);
- if (error)
- return (error);
-
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_USER)
- xfs_flags |= ATTR_KERNORMALS;
-
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_SYSTEM)
- xfs_flags |= ATTR_KERNROOTLS;
-
- if (ap->a_uio == NULL || ap->a_uio->uio_iov[0].iov_base == NULL) {
- xfs_flags |= ATTR_KERNOVAL;
- buf_len = 0;
- } else {
- buf = ap->a_uio->uio_iov[0].iov_base;
- buf_len = ap->a_uio->uio_iov[0].iov_len;
- }
-
- XVOP_ATTR_LIST(VPTOXFSVP(ap->a_vp), buf, buf_len, xfs_flags,
- &cursor, ap->a_cred, error);
- if (error < 0) {
- attrnames_len = -error;
- error = 0;
- }
- if (buf == NULL)
- goto done;
-
- /*
- * extattr_list expects a list of names. Each list
- * entry consists of one byte for the name length, followed
- * by the name (not null terminated)
- */
- name_len=0;
- for(i=attrnames_len-1; i > 0 ; --i) {
- buf[i] = buf[i-1];
- if (buf[i])
- ++name_len;
- else {
- buf[i] = name_len;
- name_len = 0;
- }
- }
- buf[0] = name_len;
-
- if (ap->a_uio != NULL)
- ap->a_uio->uio_resid -= attrnames_len;
-
-done:
- if (ap->a_size != NULL)
- *ap->a_size = attrnames_len;
-
- return (error);
-}
-
-static int
-_xfs_setextattr(struct vop_setextattr_args *ap)
-/*
-vop_setextattr {
- IN struct vnode *a_vp;
- IN int a_attrnamespace;
- IN const char *a_name;
- INOUT struct uio *a_uio;
- IN struct ucred *a_cred;
- IN struct thread *a_td;
-};
-*/
-{
- char *val;
- size_t vallen;
- int error, xfs_flags;
-
- if (ap->a_vp->v_type == VCHR)
- return (EOPNOTSUPP);
-
- if (ap->a_uio == NULL)
- return (EINVAL);
- vallen = ap->a_uio->uio_resid;
- if (vallen > ATTR_MAX_VALUELEN)
- return (EOVERFLOW);
-
- if (ap->a_name[0] == '\0')
- return (EINVAL);
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VWRITE);
- if (error)
- return (error);
-
- xfs_flags = 0;
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_USER)
- xfs_flags |= ATTR_KERNORMALS;
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_SYSTEM)
- xfs_flags |= ATTR_KERNROOTLS;
-
- val = (char *)kmem_zalloc(vallen, KM_SLEEP);
- if (val == NULL)
- return (ENOMEM);
- error = uiomove(val, (int)vallen, ap->a_uio);
- if (error)
- goto err_out;
-
- XVOP_ATTR_SET(VPTOXFSVP(ap->a_vp), ap->a_name, val, vallen, xfs_flags,
- ap->a_cred, error);
-err_out:
- kmem_free(val, vallen);
- return(error);
-}
-
-static int
-_xfs_deleteextattr(struct vop_deleteextattr_args *ap)
-/*
-vop_deleteextattr {
- IN struct vnode *a_vp;
- IN int a_attrnamespace;
- IN const char *a_name;
- IN struct ucred *a_cred;
- IN struct thread *a_td;
-};
-*/
-{
- int error, xfs_flags;
-
- if (ap->a_vp->v_type == VCHR)
- return (EOPNOTSUPP);
-
- if (ap->a_name[0] == '\0')
- return (EINVAL);
-
- error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
- ap->a_cred, ap->a_td, VWRITE);
- if (error)
- return (error);
-
- xfs_flags = 0;
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_USER)
- xfs_flags |= ATTR_KERNORMALS;
- if (ap->a_attrnamespace & EXTATTR_NAMESPACE_SYSTEM)
- xfs_flags |= ATTR_KERNROOTLS;
-
- XVOP_ATTR_REMOVE(VPTOXFSVP(ap->a_vp), ap->a_name, xfs_flags,
- ap->a_cred, error);
- return (error);
-}
-
-static int
-_xfs_vptofh(struct vop_vptofh_args *ap)
-/*
-vop_vptofh {
- IN struct vnode *a_vp;
- IN struct fid *a_fhp;
-};
-*/
-{
- printf("xfs_vptofh");
- return ENOSYS;
-}
OpenPOWER on IntegriCloud