diff options
Diffstat (limited to 'sys/xfs/xfs_node.c')
-rw-r--r-- | sys/xfs/xfs_node.c | 571 |
1 files changed, 284 insertions, 287 deletions
diff --git a/sys/xfs/xfs_node.c b/sys/xfs/xfs_node.c index 3c063d0db33..a0ad87b616d 100644 --- a/sys/xfs/xfs_node.c +++ b/sys/xfs/xfs_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xfs_node.c,v 1.1 1998/08/30 16:47:21 art Exp $ */ +/* $OpenBSD: xfs_node.c,v 1.2 1998/08/31 05:13:16 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -66,285 +66,283 @@ extern vop_t **xfs_vnodeop_p; */ int -new_xfs_node(struct xfs *xfsp, - struct xfs_msg_node *node, - struct xfs_node **xpp, - struct proc *p) +new_xfs_node(struct xfs *xfsp, struct xfs_msg_node *node, + struct xfs_node **xpp, struct proc *p) { - int do_vget = 0; - struct xfs_node *result; + int do_vget = 0; + struct xfs_node *result; - XFSDEB(XDEBNODE, ("new_xfs_node %d.%d.%d.%d\n", - node->handle.a, - node->handle.b, - node->handle.c, - node->handle.d)); + XFSDEB(XDEBNODE, ("new_xfs_node %d.%d.%d.%d\n", + node->handle.a, + node->handle.b, + node->handle.c, + node->handle.d)); - /* Does not allow duplicates */ - result = xfs_node_find(xfsp, &node->handle); - - if (result == 0) { - int error; - struct vnode *v; - - result = xfs_alloc(sizeof(*result)); + /* Does not allow duplicates */ + result = xfs_node_find(xfsp, &node->handle); if (result == 0) { - printf("xfs_alloc(%d) failed\n", (int) sizeof(*result)); - panic("new_xfs_node: You Loose!"); + int error; + struct vnode *v; + + result = xfs_alloc(sizeof(*result)); + if (result == 0) { + printf("xfs_alloc(%d) failed\n", + (int) sizeof(*result)); + panic("new_xfs_node: You Loose!"); + } + + bzero(result, sizeof(*result)); + + error = getnewvnode(VT_AFS, XFS_TO_VFS(xfsp), xfs_vnodeop_p, + &v); + if (error) { + xfs_free(result, sizeof(*result)); + return error; + } + + v->v_data = result; + result->vn = v; + + result->anonrights = node->anonrights; + result->handle = node->handle; + result->flags = 0; + result->tokens = 0; + + xfsp->nnodes++; + } else { + /* Node is already cached */ + do_vget = 1; } - bzero(result, sizeof(*result)); - error = getnewvnode(VT_AFS, XFS_TO_VFS(xfsp), xfs_vnodeop_p, &v); - if (error) { - XFSDEB(XDEBVNOPS, - ("XFS PANIC! new_xfs_node: could not allocate node")); - return error; - } - v->v_data = result; - result->vn = v; - - result->anonrights = node->anonrights; - - result->handle = node->handle; - result->flags = 0; - result->tokens = 0; - - xfsp->nnodes++; - } else { - /* Node is already cached */ - do_vget = 1; - } - - /* Init other fields */ - xfs_attr2vattr(&node->attr, &result->attr); - result->vn->v_type = result->attr.va_type; - XFS_TOKEN_SET(result, XFS_ATTR_R, XFS_ATTR_MASK); - bcopy(node->id, result->id, sizeof(result->id)); - bcopy(node->rights, result->rights, sizeof(result->rights)); - - /* - * We need to postpone this until here because (on FreeBSD) vget - * tries to install a pager on the vnode and for that it wants to - * retrieve the size with getattr. - */ - - if(do_vget) - vget(XNODE_TO_VNODE(result), 0, p); - - *xpp = result; - XFSDEB(XDEBNODE, ("return: new_xfs_node\n")); - return 0; + /* Init other fields */ + xfs_attr2vattr(&node->attr, &result->attr); + result->vn->v_type = result->attr.va_type; + XFS_TOKEN_SET(result, XFS_ATTR_R, XFS_ATTR_MASK); + bcopy(node->id, result->id, sizeof(result->id)); + bcopy(node->rights, result->rights, sizeof(result->rights)); + + /* + * We need to postpone this until here because (on FreeBSD) vget + * tries to install a pager on the vnode and for that it wants to + * retrieve the size with getattr. + */ + + if(do_vget) + vget(XNODE_TO_VNODE(result), 0, p); + + *xpp = result; + XFSDEB(XDEBNODE, ("return: new_xfs_node\n")); + return 0; } void free_xfs_node(struct xfs_node *node) { - struct xfs *xfsp = XFS_FROM_XNODE(node); + struct xfs *xfsp = XFS_FROM_XNODE(node); - XFSDEB(XDEBNODE, ("free_xfs_node starting\n")); + XFSDEB(XDEBNODE, ("free_xfs_node starting\n")); - /* XXX Really need to put back dirty data first. */ + /* XXX Really need to put back dirty data first. */ - if (DATA_FROM_XNODE(node)) { - vrele(DATA_FROM_XNODE(node)); - DATA_FROM_XNODE(node) = NULL; - } - xfsp->nnodes--; - XNODE_TO_VNODE(node)->v_data = NULL; - xfs_free(node, sizeof(*node)); + if (DATA_FROM_XNODE(node)) { + vrele(DATA_FROM_XNODE(node)); + DATA_FROM_XNODE(node) = NULL; + } + xfsp->nnodes--; + XNODE_TO_VNODE(node)->v_data = NULL; + xfs_free(node, sizeof(*node)); - XFSDEB(XDEBNODE, ("free_xfs_node done\n")); + XFSDEB(XDEBNODE, ("free_xfs_node done\n")); } int free_all_xfs_nodes(struct xfs *xfsp, int flags) { - int error = 0; - struct mount *mp = XFS_TO_VFS(xfsp); + int error = 0; + struct mount *mp = XFS_TO_VFS(xfsp); - if (mp == NULL) { - XFSDEB(XDEBNODE, ("free_all_xfs_nodes already freed\n")); - return 0; - } + if (mp == NULL) { + XFSDEB(XDEBNODE, ("free_all_xfs_nodes already freed\n")); + return 0; + } - XFSDEB(XDEBNODE, ("free_all_xfs_nodes starting\n")); + XFSDEB(XDEBNODE, ("free_all_xfs_nodes starting\n")); - xfs_dnlc_purge(mp); + xfs_dnlc_purge(mp); - XFSDEB(XDEBNODE, ("free_all_xfs_nodes now removing root\n")); + XFSDEB(XDEBNODE, ("free_all_xfs_nodes now removing root\n")); - if (xfsp->root) { - vgone(XNODE_TO_VNODE(xfsp->root)); - xfsp->root = 0; - } + if (xfsp->root) { + vgone(XNODE_TO_VNODE(xfsp->root)); + xfsp->root = 0; + } - XFSDEB(XDEBNODE, ("free_all_xfs_nodes root removed\n")); - XFSDEB(XDEBNODE, ("free_all_xfs_nodes now killing all remaining nodes\n")); + XFSDEB(XDEBNODE, ("free_all_xfs_nodes root removed\n")); + XFSDEB(XDEBNODE, ("free_all_xfs_nodes killing all remaining nodes\n")); - error = vflush(mp, NULL, flags); + error = vflush(mp, NULL, flags); + if (error) { + XFSDEB(XDEBNODE, ("xfree_all_xfs_nodes: vflush error == %d\n", + error)); + return error; + } - if (error) { - XFSDEB(XDEBNODE, ("xfree_all_xfs_nodes: vflush() error == %d\n", - error)); + XFSDEB(XDEBNODE, ("free_all_xfs_nodes done\n")); return error; - } - - XFSDEB(XDEBNODE, ("free_all_xfs_nodes done\n")); - return error; } struct xfs_node * xfs_node_find(struct xfs *xfsp, xfs_handle *handlep) { - struct vnode *t; - struct xfs_node *xn = NULL; + struct vnode *t; + struct xfs_node *xn = NULL; - XFSDEB(XDEBNODE, ("xfs_node_find: xfsp = %p handlep = %p\n", - xfsp, handlep)); + XFSDEB(XDEBNODE, ("xfs_node_find: xfsp = %p handlep = %p\n", + xfsp, handlep)); - for (t = XFS_TO_VFS(xfsp)->mnt_vnodelist.lh_first; - t != NULL; - t = t->v_mntvnodes.le_next) { - xn = VNODE_TO_XNODE(t); + for (t = XFS_TO_VFS(xfsp)->mnt_vnodelist.lh_first; + t != NULL; + t = t->v_mntvnodes.le_next) { + xn = VNODE_TO_XNODE(t); - if (xn && xfs_handle_eq(&xn->handle, handlep)) - break; - } + if (xn && xfs_handle_eq(&xn->handle, handlep)) + break; + } - if (t != NULL) - return xn; - else - return NULL; + if (t != NULL) + return xn; + else + return NULL; } void vattr2xfs_attr(const struct vattr *va, struct xfs_attr *xa) { - bzero(xa, sizeof(*xa)); - if (va->va_mode != (mode_t) VNOVAL) - XA_SET_MODE(xa, va->va_mode); - if (va->va_nlink != VNOVAL) - XA_SET_NLINK(xa, va->va_nlink); - if (va->va_size != (u_quad_t) VNOVAL) - XA_SET_SIZE(xa, va->va_size); - if (va->va_uid != VNOVAL) - XA_SET_UID(xa, va->va_uid); - if (va->va_gid != VNOVAL) - XA_SET_GID(xa, va->va_gid); - if (va->va_atime.tv_sec != VNOVAL) - XA_SET_ATIME(xa, va->va_atime.tv_sec); - if (va->va_mtime.tv_sec != VNOVAL) - XA_SET_MTIME(xa, va->va_mtime.tv_sec); - if (va->va_ctime.tv_sec != VNOVAL) - XA_SET_CTIME(xa, va->va_ctime.tv_sec); - if (va->va_fileid != VNOVAL) - XA_SET_FILEID(xa, va->va_fileid); - switch (va->va_type) { - case VNON: - xa->xa_type = XFS_FILE_NON; - break; - case VREG: - xa->xa_type = XFS_FILE_REG; - break; - case VDIR: - xa->xa_type = XFS_FILE_DIR; - break; - case VBLK: - xa->xa_type = XFS_FILE_BLK; - break; - case VCHR: - xa->xa_type = XFS_FILE_CHR; - break; - case VLNK: - xa->xa_type = XFS_FILE_LNK; - break; - case VSOCK: - xa->xa_type = XFS_FILE_SOCK; - break; - case VFIFO: - xa->xa_type = XFS_FILE_FIFO; - break; - case VBAD: - xa->xa_type = XFS_FILE_BAD; - break; - default: - panic("xfs_attr2attr: bad value"); - } + bzero(xa, sizeof(*xa)); + if (va->va_mode != (mode_t) VNOVAL) + XA_SET_MODE(xa, va->va_mode); + if (va->va_nlink != VNOVAL) + XA_SET_NLINK(xa, va->va_nlink); + if (va->va_size != (u_quad_t) VNOVAL) + XA_SET_SIZE(xa, va->va_size); + if (va->va_uid != VNOVAL) + XA_SET_UID(xa, va->va_uid); + if (va->va_gid != VNOVAL) + XA_SET_GID(xa, va->va_gid); + if (va->va_atime.tv_sec != VNOVAL) + XA_SET_ATIME(xa, va->va_atime.tv_sec); + if (va->va_mtime.tv_sec != VNOVAL) + XA_SET_MTIME(xa, va->va_mtime.tv_sec); + if (va->va_ctime.tv_sec != VNOVAL) + XA_SET_CTIME(xa, va->va_ctime.tv_sec); + if (va->va_fileid != VNOVAL) + XA_SET_FILEID(xa, va->va_fileid); + switch (va->va_type) { + case VNON: + xa->xa_type = XFS_FILE_NON; + break; + case VREG: + xa->xa_type = XFS_FILE_REG; + break; + case VDIR: + xa->xa_type = XFS_FILE_DIR; + break; + case VBLK: + xa->xa_type = XFS_FILE_BLK; + break; + case VCHR: + xa->xa_type = XFS_FILE_CHR; + break; + case VLNK: + xa->xa_type = XFS_FILE_LNK; + break; + case VSOCK: + xa->xa_type = XFS_FILE_SOCK; + break; + case VFIFO: + xa->xa_type = XFS_FILE_FIFO; + break; + case VBAD: + xa->xa_type = XFS_FILE_BAD; + break; + default: + panic("xfs_attr2attr: bad value"); + } } void xfs_attr2vattr(const struct xfs_attr *xa, struct vattr *va) { - VATTR_NULL(va); - if (XA_VALID_MODE(xa)) - va->va_mode = xa->xa_mode; - if (XA_VALID_NLINK(xa)) - va->va_nlink = xa->xa_nlink; - if (XA_VALID_SIZE(xa)) - va->va_size = xa->xa_size; - if (XA_VALID_UID(xa)) - va->va_uid = xa->xa_uid; - if (XA_VALID_GID(xa)) - va->va_gid = xa->xa_gid; - if (XA_VALID_ATIME(xa)) { - va->va_atime.tv_sec = xa->xa_atime; - va->va_atime.tv_nsec = 0; - } - if (XA_VALID_MTIME(xa)) { - va->va_mtime.tv_sec = xa->xa_mtime; - va->va_mtime.tv_nsec = 0; - } - if (XA_VALID_CTIME(xa)) { - va->va_ctime.tv_sec = xa->xa_ctime; - va->va_ctime.tv_nsec = 0; - } - if (XA_VALID_FILEID(xa)) { - va->va_fileid = xa->xa_fileid; - } - if (XA_VALID_TYPE(xa)) { - switch (xa->xa_type) { - case XFS_FILE_NON: - va->va_type = VNON; - break; - case XFS_FILE_REG: - va->va_type = VREG; - break; - case XFS_FILE_DIR: - va->va_type = VDIR; - break; - case XFS_FILE_BLK: - va->va_type = VBLK; - break; - case XFS_FILE_CHR: - va->va_type = VCHR; - break; - case XFS_FILE_LNK: - va->va_type = VLNK; - break; - case XFS_FILE_SOCK: - va->va_type = VSOCK; - break; - case XFS_FILE_FIFO: - va->va_type = VFIFO; - break; - case XFS_FILE_BAD: - va->va_type = VBAD; - break; - default: - panic("xfs_attr2vattr: bad value"); + VATTR_NULL(va); + if (XA_VALID_MODE(xa)) + va->va_mode = xa->xa_mode; + if (XA_VALID_NLINK(xa)) + va->va_nlink = xa->xa_nlink; + if (XA_VALID_SIZE(xa)) + va->va_size = xa->xa_size; + if (XA_VALID_UID(xa)) + va->va_uid = xa->xa_uid; + if (XA_VALID_GID(xa)) + va->va_gid = xa->xa_gid; + if (XA_VALID_ATIME(xa)) { + va->va_atime.tv_sec = xa->xa_atime; + va->va_atime.tv_nsec = 0; + } + if (XA_VALID_MTIME(xa)) { + va->va_mtime.tv_sec = xa->xa_mtime; + va->va_mtime.tv_nsec = 0; + } + if (XA_VALID_CTIME(xa)) { + va->va_ctime.tv_sec = xa->xa_ctime; + va->va_ctime.tv_nsec = 0; + } + if (XA_VALID_FILEID(xa)) { + va->va_fileid = xa->xa_fileid; } - } - va->va_flags = 0; - va->va_blocksize = 8192; - va->va_bytes = va->va_size; + if (XA_VALID_TYPE(xa)) { + switch (xa->xa_type) { + case XFS_FILE_NON: + va->va_type = VNON; + break; + case XFS_FILE_REG: + va->va_type = VREG; + break; + case XFS_FILE_DIR: + va->va_type = VDIR; + break; + case XFS_FILE_BLK: + va->va_type = VBLK; + break; + case XFS_FILE_CHR: + va->va_type = VCHR; + break; + case XFS_FILE_LNK: + va->va_type = VLNK; + break; + case XFS_FILE_SOCK: + va->va_type = VSOCK; + break; + case XFS_FILE_FIFO: + va->va_type = VFIFO; + break; + case XFS_FILE_BAD: + va->va_type = VBAD; + break; + default: + panic("xfs_attr2vattr: bad value"); + } + } + va->va_flags = 0; + va->va_blocksize = 8192; + va->va_bytes = va->va_size; } struct long_entry { - struct vnode *dvp, *vp; - char name[MAXNAMLEN + 1]; - size_t len; - u_long dvpid, vpid; + struct vnode *dvp, *vp; + char name[MAXNAMLEN + 1]; + size_t len; + u_long dvpid, vpid; }; static struct long_entry tbl; @@ -352,89 +350,88 @@ static struct long_entry tbl; int xfs_dnlc_enter(struct vnode *dvp, char *name, struct vnode *vp) { - struct componentname cn; - char *p; + struct componentname cn; + char *p; - XFSDEB(XDEBDNLC, ("xfs_dnlc_enter(0x%x, \"%s\", 0x%x)\n", - (int) dvp, name, (int) vp)); + XFSDEB(XDEBDNLC, ("xfs_dnlc_enter(0x%x, \"%s\", 0x%x)\n", + (int) dvp, name, (int) vp)); - XFSDEB(XDEBDNLC, ("xfs_dnlc_enter: v_id = %ld\n", - dvp->v_id)); + XFSDEB(XDEBDNLC, ("xfs_dnlc_enter: v_id = %ld\n", + dvp->v_id)); - cn.cn_namelen = strlen(name); - cn.cn_nameptr = name; - cn.cn_hash = 0; - for (p = name; *p; ++p) - cn.cn_hash += *p; + cn.cn_namelen = strlen(name); + cn.cn_nameptr = name; + cn.cn_hash = 0; + for (p = name; *p; ++p) + cn.cn_hash += *p; - XFSDEB(XDEBDNLC, ("xfs_dnlc_enter: calling cache_enter:" - "dvp = %p, vp = %p, cnp = (%s, %ld, %lu)\n", - dvp, vp, cn.cn_nameptr, cn.cn_namelen, cn.cn_hash)); + XFSDEB(XDEBDNLC, ("xfs_dnlc_enter: calling cache_enter:" + "dvp = %p, vp = %p, cnp = (%s, %ld, %lu)\n", + dvp, vp, cn.cn_nameptr, cn.cn_namelen, cn.cn_hash)); - if (cn.cn_namelen <= NCHNAMLEN) - cache_enter(dvp, vp, &cn); + if (cn.cn_namelen <= NCHNAMLEN) + cache_enter(dvp, vp, &cn); - tbl.len = cn.cn_namelen; - bcopy(name, tbl.name, tbl.len); - tbl.dvp = dvp; - tbl.vp = vp; - tbl.dvpid = dvp->v_id; - tbl.vpid = vp->v_id; + tbl.len = cn.cn_namelen; + bcopy(name, tbl.name, tbl.len); + tbl.dvp = dvp; + tbl.vp = vp; + tbl.dvpid = dvp->v_id; + tbl.vpid = vp->v_id; - return 0; + return 0; } int -xfs_dnlc_lookup(struct vnode *dvp, - struct componentname *cnp, +xfs_dnlc_lookup(struct vnode *dvp, struct componentname *cnp, struct vnode **res) { - int error; + int error; - XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup(0x%x, \"%s\")\n", - (int) dvp, cnp->cn_nameptr)); + XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup(0x%x, \"%s\")\n", + (int) dvp, cnp->cn_nameptr)); - XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: v_id = %ld\n", - dvp->v_id)); + XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: v_id = %ld\n", + dvp->v_id)); - XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: calling cache_lookup:" - "dvp = %p, cnp = (%s, %ld, %lu), flags = %lx\n", - dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_hash, - cnp->cn_flags)); + XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: calling cache_lookup:" + "dvp = %p, cnp = (%s, %ld, %lu), flags = %lx\n", + dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_hash, + cnp->cn_flags)); - cnp->cn_flags |= MAKEENTRY; + cnp->cn_flags |= MAKEENTRY; - error = cache_lookup(dvp, res, cnp); + error = cache_lookup(dvp, res, cnp); - XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: cache_lookup returned. " - "error == %d, *res == %p\n", error, *res)); + XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: cache_lookup returned. " + "error == %d, *res == %p\n", error, *res)); - if (error == -1 || error == ENOENT) - return error; + if (error == -1 || error == ENOENT) + return error; - if (tbl.dvp == dvp - && tbl.len == cnp->cn_namelen - && strncmp(tbl.name, cnp->cn_nameptr, cnp->cn_namelen) == 0 - && tbl.dvpid == tbl.dvp->v_id - && tbl.vpid == tbl.vp->v_id) { - *res = tbl.vp; - return -1; - } + if (tbl.dvp == dvp + && tbl.len == cnp->cn_namelen + && strncmp(tbl.name, cnp->cn_nameptr, cnp->cn_namelen) == 0 + && tbl.dvpid == tbl.dvp->v_id + && tbl.vpid == tbl.vp->v_id) { + *res = tbl.vp; + return -1; + } - return 0; + return 0; } void xfs_dnlc_purge(struct mount *mp) { - XFSDEB(XDEBDNLC, ("xfs_dnlc_purge()\n")); + XFSDEB(XDEBDNLC, ("xfs_dnlc_purge()\n")); - tbl.dvp = tbl.vp = NULL; - tbl.name[0] = '\0'; - tbl.len = 0; - tbl.dvpid = tbl.vpid = 0; + tbl.dvp = tbl.vp = NULL; + tbl.name[0] = '\0'; + tbl.len = 0; + tbl.dvpid = tbl.vpid = 0; - cache_purgevfs(mp); + cache_purgevfs(mp); } /* @@ -443,11 +440,11 @@ xfs_dnlc_purge(struct mount *mp) int xfs_has_pag(const struct xfs_node *xn, pag_t pag) { - int i; + int i; - for (i = 0; i < MAXRIGHTS; i++) - if (xn->id[i] == pag) - return 1; + for (i = 0; i < MAXRIGHTS; i++) + if (xn->id[i] == pag) + return 1; - return 0; + return 0; } |