summaryrefslogtreecommitdiff
path: root/sys/xfs/xfs_vnodeops-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/xfs/xfs_vnodeops-common.c')
-rw-r--r--sys/xfs/xfs_vnodeops-common.c314
1 files changed, 198 insertions, 116 deletions
diff --git a/sys/xfs/xfs_vnodeops-common.c b/sys/xfs/xfs_vnodeops-common.c
index 0fae847867d..ed102ad1205 100644
--- a/sys/xfs/xfs_vnodeops-common.c
+++ b/sys/xfs/xfs_vnodeops-common.c
@@ -1,7 +1,5 @@
-/* $OpenBSD: xfs_vnodeops-common.c,v 1.3 2000/03/03 00:54:59 todd Exp $ */
-
/*
- * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -51,10 +49,11 @@
#include <xfs/xfs_syscalls.h>
#include <xfs/xfs_vnodeops.h>
-RCSID("$OpenBSD: xfs_vnodeops-common.c,v 1.3 2000/03/03 00:54:59 todd Exp $");
+RCSID("$Id: xfs_vnodeops-common.c,v 1.4 2000/09/11 14:26:54 art Exp $");
int
-xfs_open_valid(struct vnode * vp, struct ucred * cred, u_int tok)
+xfs_open_valid(struct vnode *vp, struct ucred *cred, struct proc *p,
+ u_int tok)
{
struct xfs *xfsp = XFS_FROM_VNODE(vp);
struct xfs_node *xn = VNODE_TO_XNODE(vp);
@@ -71,7 +70,9 @@ xfs_open_valid(struct vnode * vp, struct ucred * cred, u_int tok)
msg.cred.pag = xfs_get_pag(cred);
msg.handle = xn->handle;
msg.tokens = tok;
+
error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+
if (error == 0)
error = ((struct xfs_message_wakeup *) & msg)->error;
} else {
@@ -86,12 +87,13 @@ done:
}
int
-xfs_attr_valid(struct vnode * vp, struct ucred * cred, u_int tok)
+xfs_attr_valid(struct vnode *vp, struct ucred *cred, struct proc *p,
+ u_int tok)
{
struct xfs *xfsp = XFS_FROM_VNODE(vp);
struct xfs_node *xn = VNODE_TO_XNODE(vp);
int error = 0;
- pag_t pag = xfs_get_pag(cred);
+ xfs_pag_t pag = xfs_get_pag(cred);
do {
if (!XFS_TOKEN_GOT(xn, tok)) {
@@ -114,13 +116,13 @@ done:
}
int
-xfs_fetch_rights(struct vnode * vp, struct ucred * cred)
+xfs_fetch_rights(struct vnode *vp, struct ucred *cred, struct proc *p)
{
struct xfs *xfsp = XFS_FROM_VNODE(vp);
struct xfs_node *xn = VNODE_TO_XNODE(vp);
int error = 0;
- pag_t pag = xfs_get_pag(cred);
+ xfs_pag_t pag = xfs_get_pag(cred);
do {
if (!xfs_has_pag(xn, pag)) {
@@ -144,7 +146,8 @@ done:
}
int
-xfs_data_valid(struct vnode * vp, struct ucred * cred, u_int tok)
+xfs_data_valid(struct vnode *vp, struct ucred *cred, struct proc *p,
+ u_int tok)
{
struct xfs *xfsp = XFS_FROM_VNODE(vp);
struct xfs_node *xn = VNODE_TO_XNODE(vp);
@@ -159,7 +162,9 @@ xfs_data_valid(struct vnode * vp, struct ucred * cred, u_int tok)
msg.cred.pag = xfs_get_pag(cred);
msg.handle = xn->handle;
msg.tokens = tok;
+
error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+
if (error == 0)
error = ((struct xfs_message_wakeup *) & msg)->error;
} else {
@@ -171,14 +176,46 @@ done:
return error;
}
+int
+xfs_open_common(struct vnode *vp,
+ int mode,
+ struct ucred *cred,
+ struct proc *p)
+{
+ struct xfs_node *xn = VNODE_TO_XNODE(vp);
+
+ XFSDEB(XDEBVNOPS, ("xfs_open\n"));
+
+ if (mode & FWRITE) {
+ if (xn->cred)
+ crfree (xn->cred);
+ crhold (cred);
+ xn->cred = cred;
+ return xfs_open_valid(vp, cred, p, XFS_OPEN_NW);
+ } else {
+ return xfs_open_valid(vp, cred, p, XFS_OPEN_NR);
+ }
+}
+
static int
-do_fsync(struct xfs * xfsp,
- struct xfs_node * xn,
- struct ucred * cred,
+do_fsync(struct xfs *xfsp,
+ struct xfs_node *xn,
+ struct ucred *cred,
+ struct proc *p,
u_int flag)
{
int error;
struct xfs_message_putdata msg;
+#if 0
+ struct vnode *vp = XNODE_TO_VNODE(xn);
+ struct vnode *t = DATA_FROM_XNODE(xn);
+
+ vinvalbuf (vp, V_SAVE, cred, p, 0, 0);
+
+ xfs_vfs_writelock(t, p);
+ vinvalbuf(t, V_SAVE, cred, p, 0, 0);
+ xfs_vfs_unlock(t, p);
+#endif
msg.header.opcode = XFS_MSG_PUTDATA;
if (cred != NOCRED) {
@@ -193,6 +230,7 @@ do_fsync(struct xfs * xfsp,
msg.flag = flag;
error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+
if (error == 0)
error = ((struct xfs_message_wakeup *) & msg)->error;
@@ -210,7 +248,7 @@ xfs_fsync_common(struct vnode *vp, struct ucred *cred,
struct xfs_node *xn = VNODE_TO_XNODE(vp);
int error = 0;
- XFSDEB(XDEBVNOPS, ("xfs_fsync: %p\n", vp));
+ XFSDEB(XDEBVNOPS, ("xfs_fsync: %lx\n", (unsigned long)vp));
/*
* It seems that fsync is sometimes called after reclaiming a node.
@@ -222,8 +260,17 @@ xfs_fsync_common(struct vnode *vp, struct ucred *cred,
return 0;
}
- if (xn->flags & XFS_DATA_DIRTY)
- error = do_fsync(xfsp, xn, cred, XFS_WRITE);
+ if (xn->flags & XFS_DATA_DIRTY) {
+#ifdef FSYNC_RECLAIM
+ /* writing back the data from this vnode failed */
+ if (waitfor & FSYNC_RECLAIM) {
+ printf("xfs_fsync: data lost, failed to write back\n");
+ xn->flags &= ~XFS_DATA_DIRTY;
+ return 0;
+ }
+#endif
+ error = do_fsync(xfsp, xn, cred, proc, XFS_WRITE | XFS_FSYNC);
+ }
return error;
}
@@ -236,45 +283,62 @@ xfs_close_common(struct vnode *vp, int fflag,
struct xfs_node *xn = VNODE_TO_XNODE(vp);
int error = 0;
- XFSDEB(XDEBVNOPS, ("xfs_close cred = %p\n", cred));
+ XFSDEB(XDEBVNOPS,
+ ("xfs_close cred = %lx, fflag = %x, xn->flags = %x\n",
+ (unsigned long)cred, fflag, xn->flags));
if (fflag & FWRITE && xn->flags & XFS_DATA_DIRTY)
- error = do_fsync(xfsp, xn, cred, XFS_WRITE);
+ error = do_fsync(xfsp, xn, cred, proc, XFS_WRITE);
return error;
}
int
-xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
+xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag,
+ struct ucred *cred)
{
int error = 0;
+ int i;
XFSDEB(XDEBVNOPS, ("xfs_read\n"));
- error = xfs_data_valid(vp, cred, XFS_DATA_R);
+ error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uio), XFS_DATA_R);
+
+ XFSDEB(XDEBVNOPS, ("xfs_read: iovcnt: %d\n", uio->uio_iovcnt));
+ for (i = 0; i < uio->uio_iovcnt; i++)
+ XFSDEB(XDEBVNOPS, (" base: %lx len: %d\n",
+ (unsigned long)uio->uio_iov[i].iov_base,
+ uio->uio_iov[i].iov_len));
if (error == 0) {
struct vnode *t = DATA_FROM_VNODE(vp);
xfs_vfs_readlock(t, xfs_uio_to_proc(uio));
-#ifdef __osf__
- VOP_READ(t, uio, ioflag, cred, error);
-#else /* __osf__ */
- error = VOP_READ(t, uio, ioflag, cred);
-#endif /* __osf__ */
+ xfs_vop_read(t, uio, ioflag, cred, error);
xfs_vfs_unlock(t, xfs_uio_to_proc(uio));
+
+ if (uio->uio_iovcnt && uio->uio_iov[0].iov_len > 0)
+ XFSDEB(XDEBVNOPS, ("xfs_read: byte: %d\n",
+ ((char*)uio->uio_iov[0].iov_base)[0]));
}
+
+ XFSDEB(XDEBVNOPS, ("xfs_read offset: %lu resid: %d\n",
+ (unsigned long)uio->uio_offset,
+ uio->uio_resid));
+ XFSDEB(XDEBVNOPS, ("xfs_read error: %d\n", error));
+
return error;
}
int
-xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *cred)
+xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag,
+ struct ucred *cred)
{
int error = 0;
XFSDEB(XDEBVNOPS, ("xfs_write\n"));
- error = xfs_data_valid(vp, cred, XFS_DATA_W);
+ error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), XFS_DATA_W);
if (error == 0) {
struct xfs_node *xn = VNODE_TO_XNODE(vp);
@@ -283,26 +347,14 @@ xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *c
int error2 = 0;
xfs_vfs_writelock(t, xfs_uio_to_proc(uiop));
-#ifdef __osf__
- VOP_WRITE(t, uiop, ioflag, cred, error);
- VNODE_TO_XNODE(vp)->flags |= XFS_DATA_DIRTY;
- VOP_GETATTR(t, &sub_attr, cred, error2);
-#else /* __osf__ */
- error = VOP_WRITE(t, uiop, ioflag, cred);
+ xfs_vop_write(t, uiop, ioflag, cred, error);
VNODE_TO_XNODE(vp)->flags |= XFS_DATA_DIRTY;
- error2 = VOP_GETATTR(t, &sub_attr, cred, uiop->uio_procp);
-#endif /* __osf__ */
+ xfs_vop_getattr(t, &sub_attr, cred, xfs_uio_to_proc(uiop), error2);
if (error2 == 0) {
xn->attr.va_size = sub_attr.va_size;
xn->attr.va_mtime = sub_attr.va_mtime;
-#ifdef UVM
- uvm_vnp_setsize(vp, sub_attr.va_size);
-#else
-#ifdef HAVE_KERNEL_VNODE_PAGER_SETSIZE
- vnode_pager_setsize(vp, sub_attr.va_size);
-#endif
-#endif
+ xfs_set_vp_size(vp, sub_attr.va_size);
}
xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
}
@@ -311,7 +363,8 @@ xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *c
}
int
-xfs_getattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred)
+xfs_getattr_common(struct vnode *vp, struct vattr *vap,
+ struct ucred *cred, struct proc *p)
{
int error = 0;
@@ -319,14 +372,15 @@ xfs_getattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred)
XFSDEB(XDEBVNOPS, ("xfs_getattr\n"));
- error = xfs_attr_valid(vp, cred, XFS_ATTR_R);
+ error = xfs_attr_valid(vp, cred, p, XFS_ATTR_R);
if (error == 0)
*vap = xn->attr;
return error;
}
int
-xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred)
+xfs_setattr_common(struct vnode *vp, struct vattr *vap,
+ struct ucred *cred, struct proc *p)
{
struct xfs *xfsp = XFS_FROM_VNODE(vp);
struct xfs_node *xn = VNODE_TO_XNODE(vp);
@@ -336,13 +390,13 @@ xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred)
#define CHECK_XFSATTR(A, cast) (vap->A == cast VNOVAL || vap->A == xn->attr.A)
if (CHECK_XFSATTR(va_mode,(mode_t)) &&
- CHECK_XFSATTR(va_nlink,) &&
- CHECK_XFSATTR(va_size,) &&
- CHECK_XFSATTR(va_uid,) &&
- CHECK_XFSATTR(va_gid,) &&
- CHECK_XFSATTR(va_mtime.tv_sec,) &&
- CHECK_XFSATTR(va_fileid,) &&
- CHECK_XFSATTR(va_type,))
+ CHECK_XFSATTR(va_nlink,(short)) &&
+ CHECK_XFSATTR(va_size,(u_quad_t)) &&
+ CHECK_XFSATTR(va_uid,(uid_t)) &&
+ CHECK_XFSATTR(va_gid,(gid_t)) &&
+ CHECK_XFSATTR(va_mtime.tv_sec,(unsigned int)) &&
+ CHECK_XFSATTR(va_fileid,(long)) &&
+ CHECK_XFSATTR(va_type,(enum vtype)))
return 0; /* Nothing to do */
#undef CHECK_XFSATTR
@@ -364,6 +418,18 @@ xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred)
}
msg.handle = xn->handle;
vattr2xfs_attr(vap, &msg.attr);
+ if (XFS_TOKEN_GOT(xn, XFS_DATA_R)) {
+ if (vp->v_type == VREG) {
+ if (vap->va_size != (u_quad_t)VNOVAL)
+ XA_SET_SIZE(&msg.attr, vap->va_size);
+ else
+ XA_SET_SIZE(&msg.attr, xn->attr.va_size);
+ }
+ if (vap->va_mtime.tv_sec != (unsigned int)VNOVAL)
+ XA_SET_MTIME(&msg.attr, vap->va_mtime.tv_sec);
+ else
+ XA_SET_MTIME(&msg.attr, xn->attr.va_mtime.tv_sec);
+ }
XFS_TOKEN_CLEAR(xn, XFS_ATTR_VALID, XFS_ATTR_MASK);
error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
@@ -393,14 +459,15 @@ check_rights (u_char rights, int mode)
}
int
-xfs_access_common(struct vnode *vp, int mode, struct ucred *cred)
+xfs_access_common(struct vnode *vp, int mode, struct ucred *cred,
+ struct proc *p)
{
int error = 0;
- pag_t pag = xfs_get_pag(cred);
+ xfs_pag_t pag = xfs_get_pag(cred);
XFSDEB(XDEBVNOPS, ("xfs_access mode = 0%o\n", mode));
- error = xfs_attr_valid(vp, cred, XFS_ATTR_R);
+ error = xfs_attr_valid(vp, cred, p, XFS_ATTR_R);
if (error == 0) {
struct xfs_node *xn = VNODE_TO_XNODE(vp);
int i;
@@ -412,7 +479,7 @@ xfs_access_common(struct vnode *vp, int mode, struct ucred *cred)
XFSDEB(XDEBVNOPS, ("xfs_access anonaccess failed\n"));
- xfs_fetch_rights(vp, cred); /* ignore error */
+ xfs_fetch_rights(vp, cred, p); /* ignore error */
error = EACCES; /* default to EACCES if pag isn't in xn->id */
@@ -445,15 +512,15 @@ xfs_lookup_common(struct vnode *dvp,
if (dvp->v_type != VDIR)
return ENOTDIR;
-
- again:
+ if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
+ *vpp = dvp;
+ VREF(*vpp);
+ return 0;
+ }
+
do {
-#ifdef __osf__
- VOP_ACCESS(dvp, VEXEC, cred, error);
-#else
- error = VOP_ACCESS(dvp, VEXEC, cred, xfs_cnp_to_proc(cnp));
-#endif
+ xfs_vop_access(dvp, VEXEC, cred, proc, error);
if (error != 0)
goto done;
@@ -490,14 +557,12 @@ xfs_lookup_common(struct vnode *dvp,
if (error == 0)
error = ((struct xfs_message_wakeup *) & msg)->error;
if(error == ENOENT && cnp->cn_nameiop != CREATE) {
- XFSDEB(XDEBVNOPS, ("xfs_lookup: neg cache %p (%s, %ld)\n",
- dvp,
+ XFSDEB(XDEBVNOPS, ("xfs_lookup: neg cache %lx (%s, %ld)\n",
+ (unsigned long)dvp,
cnp->cn_nameptr, cnp->cn_namelen));
xfs_dnlc_enter (dvp, cnp, NULL);
}
} else if (error == -1) {
- if (xfs_do_vget(*vpp, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp)))
- goto again;
error = 0;
goto done;
}
@@ -508,29 +573,18 @@ done:
}
int
-xfs_lookup_name(struct vnode *dvp,
- const char *name,
- struct proc *proc,
- struct ucred *cred,
- struct vnode **vpp)
-{
- xfs_componentname cn;
-
- xfs_cnp_init (&cn, name, NULL, dvp, proc, cred, CREATE);
- return xfs_lookup_common (dvp, &cn, vpp);
-}
-
-int
xfs_create_common(struct vnode *dvp,
const char *name,
struct vattr *vap,
- struct ucred *cred)
+ struct ucred *cred,
+ struct proc *p)
{
struct xfs *xfsp = XFS_FROM_VNODE(dvp);
struct xfs_node *xn = VNODE_TO_XNODE(dvp);
int error = 0;
- XFSDEB(XDEBVNOPS, ("xfs_create: (%s)\n", name));
+ XFSDEB(XDEBVNOPS, ("xfs_create: (%lx, %s)\n",
+ (unsigned long)dvp, name));
{
struct xfs_message_create msg;
@@ -548,7 +602,9 @@ xfs_create_common(struct vnode *dvp,
msg.cred.pag = XFS_ANONYMOUSID;
}
+
error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
+
if (error == 0)
error = ((struct xfs_message_wakeup *) & msg)->error;
}
@@ -565,7 +621,8 @@ int
xfs_remove_common(struct vnode *dvp,
struct vnode *vp,
const char *name,
- struct ucred *cred)
+ struct ucred *cred,
+ struct proc *p)
{
struct xfs *xfsp = XFS_FROM_VNODE(dvp);
struct xfs_node *xn = VNODE_TO_XNODE(dvp);
@@ -579,6 +636,7 @@ xfs_remove_common(struct vnode *dvp,
strncpy(msg.name, name, 256);
msg.cred.uid = cred->cr_uid;
msg.cred.pag = xfs_get_pag(cred);
+
error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg));
if (error == 0)
error = ((struct xfs_message_wakeup *) &msg)->error;
@@ -604,7 +662,8 @@ xfs_rename_common(struct vnode *fdvp,
struct vnode *tdvp,
struct vnode *tvp,
const char *tname,
- struct ucred *cred)
+ struct ucred *cred,
+ struct proc *p)
{
struct xfs *xfsp = XFS_FROM_VNODE(fdvp);
int error;
@@ -641,7 +700,8 @@ int
xfs_mkdir_common(struct vnode *dvp,
const char *name,
struct vattr *vap,
- struct ucred *cred)
+ struct ucred *cred,
+ struct proc *p)
{
struct xfs *xfsp = XFS_FROM_VNODE(dvp);
struct xfs_node *xn = VNODE_TO_XNODE(dvp);
@@ -674,7 +734,8 @@ int
xfs_rmdir_common(struct vnode *dvp,
struct vnode *vp,
const char *name,
- struct ucred *cred)
+ struct ucred *cred,
+ struct proc *p)
{
struct xfs *xfsp = XFS_FROM_VNODE(dvp);
struct xfs_node *xn = VNODE_TO_XNODE(dvp);
@@ -703,6 +764,8 @@ xfs_rmdir_common(struct vnode *dvp,
vput(dvp);
#endif
+ XFSDEB(XDEBVNOPS, ("xfs_rmdir error: %d\n", error));
+
return error;
}
@@ -710,6 +773,7 @@ int
xfs_readdir_common(struct vnode *vp,
struct uio *uiop,
struct ucred *cred,
+ struct proc *p,
int *eofflag)
{
int error = 0;
@@ -718,18 +782,20 @@ xfs_readdir_common(struct vnode *vp,
if(eofflag)
*eofflag = 0;
- error = xfs_data_valid(vp, cred, XFS_DATA_R);
+ error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), XFS_DATA_R);
if (error == 0) {
struct vnode *t = DATA_FROM_VNODE(vp);
xfs_vfs_readlock(t, xfs_uio_to_proc(uiop));
-#ifdef __osf__
- VOP_READ(t, uiop, 0, cred, error);
-#else
- error = VOP_READ(t, uiop, 0, cred);
-#endif
- if(eofflag)
- *eofflag = VNODE_TO_XNODE(vp)->attr.va_size <= uiop->uio_offset;
+ xfs_vop_read(t, uiop, 0, cred, error);
+ if (eofflag) {
+ struct vattr t_attr;
+ int error2;
+
+ xfs_vop_getattr(t, &t_attr, cred, xfs_uio_to_proc(uiop), error2);
+ if (error2 == 0)
+ *eofflag = t_attr.va_size <= uiop->uio_offset;
+ }
xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
}
return error;
@@ -739,7 +805,8 @@ int
xfs_link_common(struct vnode *dvp,
struct vnode *vp,
const char *name,
- struct ucred *cred)
+ struct ucred *cred,
+ struct proc *p)
{
struct xfs *xfsp = XFS_FROM_VNODE(dvp);
struct xfs_node *xn = VNODE_TO_XNODE(dvp);
@@ -766,15 +833,16 @@ xfs_link_common(struct vnode *dvp,
int
xfs_symlink_common(struct vnode *dvp,
struct vnode **vpp,
- const char *name,
- struct proc *proc,
- struct ucred *cred,
+ xfs_componentname *cnp,
struct vattr *vap,
char *target)
{
struct xfs *xfsp = XFS_FROM_VNODE(dvp);
struct xfs_node *xn = VNODE_TO_XNODE(dvp);
+ struct proc *proc = xfs_cnp_to_proc(cnp);
+ struct ucred *cred = xfs_proc_to_cred(proc);
struct xfs_message_symlink msg;
+ const char *name = cnp->cn_nameptr;
int error = 0;
XFSDEB(XDEBVNOPS, ("xfs_symlink: %s\n", name));
@@ -794,12 +862,14 @@ xfs_symlink_common(struct vnode *dvp,
error = ((struct xfs_message_wakeup *) & msg)->error;
if (error == 0) {
- error = xfs_lookup_name(dvp, name, proc, cred, vpp);
+ error = xfs_lookup_common(dvp, cnp, vpp);
+#if !defined(__FreeBSD__) || __FreeBSD_version < 400012
if (error == 0)
vput (*vpp);
+#endif
}
-#if !defined(__FreeBSD__) || __FreeBSD_version < 300000
+#if !defined(__FreeBSD__)
vput(dvp);
#endif
@@ -813,16 +883,12 @@ xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred)
XFSDEB(XDEBVNOPS, ("xfs_readlink\n"));
- error = xfs_data_valid(vp, cred, XFS_DATA_R);
+ error = xfs_data_valid(vp, cred, xfs_uio_to_proc(uiop), XFS_DATA_R);
if (error == 0) {
struct vnode *t = DATA_FROM_VNODE(vp);
xfs_vfs_readlock(t, xfs_uio_to_proc(uiop));
-#ifdef __osf__
- VOP_READ(t, uiop, 0, cred, error);
-#else
- error = VOP_READ(t, uiop, 0, cred);
-#endif
+ xfs_vop_read(t, uiop, 0, cred, error);
xfs_vfs_unlock(t, xfs_uio_to_proc(uiop));
}
return error;
@@ -831,11 +897,11 @@ xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred)
int
xfs_inactive_common(struct vnode *vp, struct proc *p)
{
- struct xfs_message_inactivenode msg;
- struct xfs *xfsp = XFS_FROM_VNODE(vp);
+ int error;
struct xfs_node *xn = VNODE_TO_XNODE(vp);
- XFSDEB(XDEBVNOPS, ("xfs_inactive, %p\n", vp));
+ XFSDEB(XDEBVNOPS, ("xfs_inactive, %lx\n",
+ (unsigned long)vp));
/*
* This seems rather bogus, but sometimes we get an already
@@ -847,14 +913,20 @@ xfs_inactive_common(struct vnode *vp, struct proc *p)
return 0;
}
- xn->tokens = 0;
- msg.header.opcode = XFS_MSG_INACTIVENODE;
- msg.handle = xn->handle;
- msg.flag = XFS_NOREFS;
- xfs_message_send(xfsp->fd, &msg.header, sizeof(msg));
+ /* xn->cred not set -> NOCRED */
+
+ error = xfs_fsync_common(vp, xn->cred, /* XXX */ 0, p);
+ if (error) {
+ printf ("xfs_inactive: failed writing back data: %d\n", error);
+ }
#ifndef __osf__
xfs_vfs_unlock(vp, p);
+ /* If this node is no longer valid, recycle immediately. */
+ if (!XFS_TOKEN_GOT(xn, XFS_ATTR_R | XFS_ATTR_W)) {
+ XFSDEB(XDEBVNOPS, ("xfs_inactive: vrecycle\n"));
+ vrecycle(vp, 0, p);
+ }
#else
/* XXX ? */
#endif
@@ -871,7 +943,18 @@ xfs_reclaim_common(struct vnode *vp)
struct xfs *xfsp = XFS_FROM_VNODE(vp);
struct xfs_node *xn = VNODE_TO_XNODE(vp);
- XFSDEB(XDEBVNOPS, ("xfs_reclaim: %p\n", vp));
+ XFSDEB(XDEBVNOPS, ("xfs_reclaim: %lx",
+ (unsigned long)vp));
+
+ XFS_TOKEN_CLEAR(xn,
+ ~0,
+ XFS_OPEN_MASK | XFS_ATTR_MASK |
+ XFS_DATA_MASK | XFS_LOCK_MASK);
+ /* Release, data if we still have it. */
+ if (DATA_FROM_XNODE(xn) != 0) {
+ vrele(DATA_FROM_XNODE(xn));
+ DATA_FROM_XNODE(xn) = 0;
+ }
msg.header.opcode = XFS_MSG_INACTIVENODE;
msg.handle = xn->handle;
@@ -880,7 +963,6 @@ xfs_reclaim_common(struct vnode *vp)
xfs_dnlc_purge(vp);
free_xfs_node(xn);
-
return 0;
}