Module Name: src Committed By: hannken Date: Mon Apr 6 08:39:23 UTC 2015
Modified Files: src/sys/fs/udf: udf.h udf_subr.c udf_vfsops.c udf_vnops.c Log Message: Change udf to vcache, keyed on udf_node->loc.loc. To generate a diff of this commit: cvs rdiff -u -r1.47 -r1.48 src/sys/fs/udf/udf.h cvs rdiff -u -r1.128 -r1.129 src/sys/fs/udf/udf_subr.c cvs rdiff -u -r1.67 -r1.68 src/sys/fs/udf/udf_vfsops.c cvs rdiff -u -r1.99 -r1.100 src/sys/fs/udf/udf_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/fs/udf/udf.h diff -u src/sys/fs/udf/udf.h:1.47 src/sys/fs/udf/udf.h:1.48 --- src/sys/fs/udf/udf.h:1.47 Wed Sep 17 19:47:05 2014 +++ src/sys/fs/udf/udf.h Mon Apr 6 08:39:23 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: udf.h,v 1.47 2014/09/17 19:47:05 reinoud Exp $ */ +/* $NetBSD: udf.h,v 1.48 2015/04/06 08:39:23 hannken Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -94,6 +94,7 @@ extern int udf_verbose; #define DPRINTFIF(name, cond, arg) {} #endif +VFS_PROTOS(udf); /* constants to identify what kind of identifier we are dealing with */ #define UDF_REGID_DOMAIN 1 @@ -339,7 +340,6 @@ struct udf_mount { /* rb tree for lookup icb to udf_node and sorted list for sync */ kmutex_t ihash_lock; - kmutex_t get_node_lock; struct rb_tree udf_node_tree; /* syncing */ Index: src/sys/fs/udf/udf_subr.c diff -u src/sys/fs/udf/udf_subr.c:1.128 src/sys/fs/udf/udf_subr.c:1.129 --- src/sys/fs/udf/udf_subr.c:1.128 Sat Feb 7 04:18:03 2015 +++ src/sys/fs/udf/udf_subr.c Mon Apr 6 08:39:23 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_subr.c,v 1.128 2015/02/07 04:18:03 christos Exp $ */ +/* $NetBSD: udf_subr.c,v 1.129 2015/04/06 08:39:23 hannken Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -29,7 +29,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.128 2015/02/07 04:18:03 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.129 2015/04/06 08:39:23 hannken Exp $"); #endif /* not lint */ @@ -3444,31 +3444,6 @@ udf_init_nodes_tree(struct udf_mount *um } -static struct udf_node * -udf_node_lookup(struct udf_mount *ump, struct long_ad *icbptr) -{ - struct udf_node *udf_node; - struct vnode *vp; - -loop: - mutex_enter(&ump->ihash_lock); - - udf_node = rb_tree_find_node(&ump->udf_node_tree, icbptr); - if (udf_node) { - vp = udf_node->vnode; - assert(vp); - mutex_enter(vp->v_interlock); - mutex_exit(&ump->ihash_lock); - if (vget(vp, LK_EXCLUSIVE)) - goto loop; - return udf_node; - } - mutex_exit(&ump->ihash_lock); - - return NULL; -} - - static void udf_register_node(struct udf_node *udf_node) { @@ -5279,44 +5254,33 @@ error_out: */ int -udf_get_node(struct udf_mount *ump, struct long_ad *node_icb_loc, - struct udf_node **udf_noderes) +udf_loadvnode(struct mount *mp, struct vnode *vp, + const void *key, size_t key_len, const void **new_key) { union dscrptr *dscr; + struct udf_mount *ump; struct udf_node *udf_node; - struct vnode *nvp; - struct long_ad icb_loc, next_icb_loc, last_fe_icb_loc; + struct long_ad node_icb_loc, icb_loc, next_icb_loc, last_fe_icb_loc; uint64_t file_size; uint32_t lb_size, sector, dummy; int udf_file_type, dscr_type, strat, strat4096, needs_indirect; int slot, eof, error; int num_indir_followed = 0; - DPRINTF(NODE, ("udf_get_node called\n")); - *udf_noderes = udf_node = NULL; - - /* lock to disallow simultanious creation of same udf_node */ - mutex_enter(&ump->get_node_lock); - - DPRINTF(NODE, ("\tlookup in hash table\n")); - /* lookup in hash table */ - assert(ump); - assert(node_icb_loc); - udf_node = udf_node_lookup(ump, node_icb_loc); - if (udf_node) { - DPRINTF(NODE, ("\tgot it from the hash!\n")); - /* vnode is returned locked */ - *udf_noderes = udf_node; - mutex_exit(&ump->get_node_lock); - return 0; - } + DPRINTF(NODE, ("udf_loadvnode called\n")); + udf_node = NULL; + ump = VFSTOUDF(mp); + + KASSERT(key_len == sizeof(node_icb_loc.loc)); + memset(&node_icb_loc, 0, sizeof(node_icb_loc)); + node_icb_loc.len = ump->logical_vol->lb_size; + memcpy(&node_icb_loc.loc, key, key_len); /* garbage check: translate udf_node_icb_loc to sectornr */ - error = udf_translate_vtop(ump, node_icb_loc, §or, &dummy); + error = udf_translate_vtop(ump, &node_icb_loc, §or, &dummy); if (error) { DPRINTF(NODE, ("\tcan't translate icb address!\n")); /* no use, this will fail anyway */ - mutex_exit(&ump->get_node_lock); return EINVAL; } @@ -5324,33 +5288,18 @@ udf_get_node(struct udf_mount *ump, stru udf_node = pool_get(&udf_node_pool, PR_WAITOK); memset(udf_node, 0, sizeof(struct udf_node)); - DPRINTF(NODE, ("\tget new vnode\n")); - /* give it a vnode */ - error = getnewvnode(VT_UDF, ump->vfs_mountp, udf_vnodeop_p, NULL, &nvp); - if (error) { - pool_put(&udf_node_pool, udf_node); - mutex_exit(&ump->get_node_lock); - return error; - } - - /* always return locked vnode */ - if ((error = vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY))) { - /* recycle vnode and unlock; simultaneous will fail too */ - ungetnewvnode(nvp); - pool_put(&udf_node_pool, udf_node); - mutex_exit(&ump->get_node_lock); - return error; - } + vp->v_tag = VT_UDF; + vp->v_op = udf_vnodeop_p; + vp->v_data = udf_node; /* initialise crosslinks, note location of fe/efe for hashing */ udf_node->ump = ump; - udf_node->vnode = nvp; - nvp->v_data = udf_node; - udf_node->loc = *node_icb_loc; + udf_node->vnode = vp; + udf_node->loc = node_icb_loc; udf_node->lockf = 0; mutex_init(&udf_node->node_mutex, MUTEX_DEFAULT, IPL_NONE); cv_init(&udf_node->node_lock, "udf_nlk"); - genfs_node_init(nvp, &udf_genfsops); /* inititise genfs */ + genfs_node_init(vp, &udf_genfsops); /* inititise genfs */ udf_node->outstanding_bufs = 0; udf_node->outstanding_nodedscr = 0; udf_node->uncommitted_lbs = 0; @@ -5359,15 +5308,12 @@ udf_get_node(struct udf_mount *ump, stru if (ump->fileset_desc) if (memcmp(&udf_node->loc, &ump->fileset_desc->rootdir_icb, sizeof(struct long_ad)) == 0) - nvp->v_vflag |= VV_ROOT; + vp->v_vflag |= VV_ROOT; /* insert into the hash lookup */ udf_register_node(udf_node); - /* safe to unlock, the entry is in the hash table, vnode is locked */ - mutex_exit(&ump->get_node_lock); - - icb_loc = *node_icb_loc; + icb_loc = node_icb_loc; needs_indirect = 0; strat4096 = 0; udf_file_type = UDF_ICB_FILETYPE_UNKNOWN; @@ -5471,10 +5417,6 @@ udf_get_node(struct udf_mount *ump, stru /* recycle udf_node */ udf_dispose_node(udf_node); - VOP_UNLOCK(nvp); - nvp->v_data = NULL; - ungetnewvnode(nvp); - return EINVAL; /* error code ok? */ } DPRINTF(NODE, ("\tnode fe/efe read in fine\n")); @@ -5567,10 +5509,6 @@ udf_get_node(struct udf_mount *ump, stru /* recycle udf_node */ udf_dispose_node(udf_node); - VOP_UNLOCK(nvp); - nvp->v_data = NULL; - ungetnewvnode(nvp); - return EINVAL; /* error code ok? */ } @@ -5587,49 +5525,69 @@ udf_get_node(struct udf_mount *ump, stru switch (udf_file_type) { case UDF_ICB_FILETYPE_DIRECTORY : case UDF_ICB_FILETYPE_STREAMDIR : - nvp->v_type = VDIR; + vp->v_type = VDIR; break; case UDF_ICB_FILETYPE_BLOCKDEVICE : - nvp->v_type = VBLK; + vp->v_type = VBLK; break; case UDF_ICB_FILETYPE_CHARDEVICE : - nvp->v_type = VCHR; + vp->v_type = VCHR; break; case UDF_ICB_FILETYPE_SOCKET : - nvp->v_type = VSOCK; + vp->v_type = VSOCK; break; case UDF_ICB_FILETYPE_FIFO : - nvp->v_type = VFIFO; + vp->v_type = VFIFO; break; case UDF_ICB_FILETYPE_SYMLINK : - nvp->v_type = VLNK; + vp->v_type = VLNK; break; case UDF_ICB_FILETYPE_VAT : case UDF_ICB_FILETYPE_META_MAIN : case UDF_ICB_FILETYPE_META_MIRROR : - nvp->v_type = VNON; + vp->v_type = VNON; break; case UDF_ICB_FILETYPE_RANDOMACCESS : case UDF_ICB_FILETYPE_REALTIME : - nvp->v_type = VREG; + vp->v_type = VREG; break; default: /* YIKES, something else */ - nvp->v_type = VNON; + vp->v_type = VNON; } /* TODO specfs, fifofs etc etc. vnops setting */ /* don't forget to set vnode's v_size */ - uvm_vnp_setsize(nvp, file_size); + uvm_vnp_setsize(vp, file_size); /* TODO ext attr and streamdir udf_nodes */ - *udf_noderes = udf_node; + *new_key = &udf_node->loc.loc; return 0; } +int +udf_get_node(struct udf_mount *ump, struct long_ad *node_icb_loc, + struct udf_node **udf_noderes) +{ + int error; + struct vnode *vp; + + error = vcache_get(ump->vfs_mountp, &node_icb_loc->loc, + sizeof(node_icb_loc->loc), &vp); + if (error) + return error; + error = vn_lock(vp, LK_EXCLUSIVE); + if (error) { + vrele(vp); + return error; + } + *udf_noderes = VTOI(vp); + return 0; +} + /* --------------------------------------------------------------------- */ int @@ -5759,19 +5717,19 @@ udf_dispose_node(struct udf_node *udf_no /* - * create a new node using the specified vnodeops, vap and cnp but with the - * udf_file_type. This allows special files to be created. Use with care. + * create a new node using the specified dvp, vap and cnp. + * This allows special files to be created. Use with care. */ -static int -udf_create_node_raw(struct vnode *dvp, struct vnode **vpp, int udf_file_type, - int (**vnodeops)(void *), struct vattr *vap, struct componentname *cnp) +int +udf_newvnode(struct mount *mp, struct vnode *dvp, struct vnode *vp, + struct vattr *vap, kauth_cred_t cred, + size_t *key_len, const void **new_key) { union dscrptr *dscr; struct udf_node *dir_node = VTOI(dvp); struct udf_node *udf_node; struct udf_mount *ump = dir_node->ump; - struct vnode *nvp; struct long_ad node_icb_loc; uint64_t parent_unique_id; uint64_t lmapping; @@ -5779,28 +5737,65 @@ udf_create_node_raw(struct vnode *dvp, s uint16_t vpart_num; uid_t uid; gid_t gid, parent_gid; - int fid_size, error; + int (**vnodeops)(void *); + int udf_file_type, fid_size, error; - lb_size = udf_rw32(ump->logical_vol->lb_size); - *vpp = NULL; + vnodeops = udf_vnodeop_p; + udf_file_type = UDF_ICB_FILETYPE_RANDOMACCESS; - /* allocate vnode */ - error = getnewvnode(VT_UDF, ump->vfs_mountp, vnodeops, NULL, &nvp); - if (error) - return error; + switch (vap->va_type) { + case VREG : + udf_file_type = UDF_ICB_FILETYPE_RANDOMACCESS; + break; + case VDIR : + udf_file_type = UDF_ICB_FILETYPE_DIRECTORY; + break; + case VLNK : + udf_file_type = UDF_ICB_FILETYPE_SYMLINK; + break; + case VBLK : + udf_file_type = UDF_ICB_FILETYPE_BLOCKDEVICE; + /* specfs */ + return ENOTSUP; + break; + case VCHR : + udf_file_type = UDF_ICB_FILETYPE_CHARDEVICE; + /* specfs */ + return ENOTSUP; + break; + case VFIFO : + udf_file_type = UDF_ICB_FILETYPE_FIFO; + /* fifofs */ + return ENOTSUP; + break; + case VSOCK : + udf_file_type = UDF_ICB_FILETYPE_SOCKET; + return ENOTSUP; + break; + case VNON : + case VBAD : + default : + /* nothing; can we even create these? */ + return EINVAL; + } + + lb_size = udf_rw32(ump->logical_vol->lb_size); /* reserve space for one logical block */ vpart_num = ump->node_part; error = udf_reserve_space(ump, NULL, UDF_C_NODE, vpart_num, 1, /* can_fail */ true); if (error) - goto error_out_unget; + return error; /* allocate node */ error = udf_allocate_space(ump, NULL, UDF_C_NODE, vpart_num, 1, &lmapping); - if (error) - goto error_out_unreserve; + if (error) { + udf_do_unreserve_space(ump, NULL, vpart_num, 1); + return error; + } + lb_num = lmapping; /* initialise pointer to location */ @@ -5816,8 +5811,8 @@ udf_create_node_raw(struct vnode *dvp, s /* initialise crosslinks, note location of fe/efe for hashing */ /* bugalert: synchronise with udf_get_node() */ udf_node->ump = ump; - udf_node->vnode = nvp; - nvp->v_data = udf_node; + udf_node->vnode = vp; + vp->v_data = udf_node; udf_node->loc = node_icb_loc; udf_node->write_loc = node_icb_loc; udf_node->lockf = 0; @@ -5827,8 +5822,11 @@ udf_create_node_raw(struct vnode *dvp, s udf_node->outstanding_nodedscr = 0; udf_node->uncommitted_lbs = 0; + vp->v_tag = VT_UDF; + vp->v_op = vnodeops; + /* initialise genfs */ - genfs_node_init(nvp, &udf_genfsops); + genfs_node_init(vp, &udf_genfsops); /* insert into the hash lookup */ udf_register_node(udf_node); @@ -5861,25 +5859,49 @@ udf_create_node_raw(struct vnode *dvp, s KASSERT(dscr->tag.tag_loc == udf_node->loc.loc.lb_num); /* update vnode's size and type */ - nvp->v_type = vap->va_type; - uvm_vnp_setsize(nvp, fid_size); + vp->v_type = vap->va_type; + uvm_vnp_setsize(vp, fid_size); /* set access mode */ udf_setaccessmode(udf_node, vap->va_mode); /* set ownership */ - uid = kauth_cred_geteuid(cnp->cn_cred); + uid = kauth_cred_geteuid(cred); gid = parent_gid; udf_setownership(udf_node, uid, gid); + *key_len = sizeof(udf_node->loc.loc);; + *new_key = &udf_node->loc.loc; + + return 0; +} + + +int +udf_create_node(struct vnode *dvp, struct vnode **vpp, struct vattr *vap, + struct componentname *cnp) +{ + struct udf_node *udf_node, *dir_node = VTOI(dvp); + struct udf_mount *ump = dir_node->ump; + int error; + + error = vcache_new(dvp->v_mount, dvp, vap, cnp->cn_cred, vpp); + if (error) + return error; + + udf_node = VTOI(*vpp); error = udf_dir_attach(ump, dir_node, udf_node, vap, cnp); if (error) { + struct long_ad *node_icb_loc = &udf_node->loc; + uint32_t lb_num = udf_rw32(node_icb_loc->loc.lb_num); + uint16_t vpart_num = udf_rw16(node_icb_loc->loc.part_num); + /* free disc allocation for node */ udf_free_allocated_space(ump, lb_num, vpart_num, 1); /* recycle udf_node */ udf_dispose_node(udf_node); - vrele(nvp); + vrele(*vpp); *vpp = NULL; return error; @@ -5888,76 +5910,7 @@ udf_create_node_raw(struct vnode *dvp, s /* adjust file count */ udf_adjust_filecount(udf_node, 1); - /* return result */ - *vpp = nvp; - return 0; - -error_out_unreserve: - udf_do_unreserve_space(ump, NULL, vpart_num, 1); - -error_out_unget: - nvp->v_data = NULL; - ungetnewvnode(nvp); - - return error; -} - - -int -udf_create_node(struct vnode *dvp, struct vnode **vpp, struct vattr *vap, - struct componentname *cnp) -{ - int (**vnodeops)(void *); - int udf_file_type; - - DPRINTF(NODE, ("udf_create_node called\n")); - - /* what type are we creating ? */ - vnodeops = udf_vnodeop_p; - /* start with a default */ - udf_file_type = UDF_ICB_FILETYPE_RANDOMACCESS; - - *vpp = NULL; - - switch (vap->va_type) { - case VREG : - udf_file_type = UDF_ICB_FILETYPE_RANDOMACCESS; - break; - case VDIR : - udf_file_type = UDF_ICB_FILETYPE_DIRECTORY; - break; - case VLNK : - udf_file_type = UDF_ICB_FILETYPE_SYMLINK; - break; - case VBLK : - udf_file_type = UDF_ICB_FILETYPE_BLOCKDEVICE; - /* specfs */ - return ENOTSUP; - break; - case VCHR : - udf_file_type = UDF_ICB_FILETYPE_CHARDEVICE; - /* specfs */ - return ENOTSUP; - break; - case VFIFO : - udf_file_type = UDF_ICB_FILETYPE_FIFO; - /* specfs */ - return ENOTSUP; - break; - case VSOCK : - udf_file_type = UDF_ICB_FILETYPE_SOCKET; - /* specfs */ - return ENOTSUP; - break; - case VNON : - case VBAD : - default : - /* nothing; can we even create these? */ - return EINVAL; - } - - return udf_create_node_raw(dvp, vpp, udf_file_type, vnodeops, vap, cnp); } /* --------------------------------------------------------------------- */ Index: src/sys/fs/udf/udf_vfsops.c diff -u src/sys/fs/udf/udf_vfsops.c:1.67 src/sys/fs/udf/udf_vfsops.c:1.68 --- src/sys/fs/udf/udf_vfsops.c:1.67 Wed Apr 16 18:55:19 2014 +++ src/sys/fs/udf/udf_vfsops.c Mon Apr 6 08:39:23 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_vfsops.c,v 1.67 2014/04/16 18:55:19 maxv Exp $ */ +/* $NetBSD: udf_vfsops.c,v 1.68 2015/04/06 08:39:23 hannken Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -28,7 +28,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.67 2014/04/16 18:55:19 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_vfsops.c,v 1.68 2015/04/06 08:39:23 hannken Exp $"); #endif /* not lint */ @@ -79,9 +79,6 @@ MALLOC_JUSTDEFINE(M_UDFVOLD, "UDF volsp MALLOC_JUSTDEFINE(M_UDFTEMP, "UDF temp", "UDF scrap space"); struct pool udf_node_pool; -/* supported functions predefined */ -VFS_PROTOS(udf); - static struct sysctllog *udf_sysctl_log; /* internal functions */ @@ -111,6 +108,8 @@ struct vfsops udf_vfsops = { .vfs_statvfs = udf_statvfs, .vfs_sync = udf_sync, .vfs_vget = udf_vget, + .vfs_loadvnode = udf_loadvnode, + .vfs_newvnode = udf_newvnode, .vfs_fhtovp = udf_fhtovp, .vfs_vptofh = udf_vptofh, .vfs_init = udf_init, @@ -261,7 +260,6 @@ free_udf_mountinfo(struct mount *mp) MPFREE(ump->la_lmapping, M_TEMP); mutex_destroy(&ump->ihash_lock); - mutex_destroy(&ump->get_node_lock); mutex_destroy(&ump->logvol_mutex); mutex_destroy(&ump->allocate_mutex); cv_destroy(&ump->dirtynodes_cv); @@ -584,7 +582,6 @@ udf_mountfs(struct vnode *devvp, struct /* init locks */ mutex_init(&ump->logvol_mutex, MUTEX_DEFAULT, IPL_NONE); mutex_init(&ump->ihash_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&ump->get_node_lock, MUTEX_DEFAULT, IPL_NONE); mutex_init(&ump->allocate_mutex, MUTEX_DEFAULT, IPL_NONE); cv_init(&ump->dirtynodes_cv, "udfsync2"); Index: src/sys/fs/udf/udf_vnops.c diff -u src/sys/fs/udf/udf_vnops.c:1.99 src/sys/fs/udf/udf_vnops.c:1.100 --- src/sys/fs/udf/udf_vnops.c:1.99 Mon Apr 6 08:38:25 2015 +++ src/sys/fs/udf/udf_vnops.c Mon Apr 6 08:39:23 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_vnops.c,v 1.99 2015/04/06 08:38:25 hannken Exp $ */ +/* $NetBSD: udf_vnops.c,v 1.100 2015/04/06 08:39:23 hannken Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -32,7 +32,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.99 2015/04/06 08:38:25 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_vnops.c,v 1.100 2015/04/06 08:39:23 hannken Exp $"); #endif /* not lint */ @@ -129,8 +129,6 @@ udf_inactive(void *v) /* --------------------------------------------------------------------- */ -int udf_sync(struct mount *mp, int waitfor, kauth_cred_t cred, struct lwp *lwp); - int udf_reclaim(void *v) { @@ -176,6 +174,9 @@ udf_reclaim(void *v) tsleep(&udf_node->outstanding_nodedscr, PRIBIO, "recl wait", hz/8); } + vcache_remove(vp->v_mount, &udf_node->loc.loc, + sizeof(udf_node->loc.loc)); + /* dispose all node knowledge */ udf_dispose_node(udf_node);