/* * Reclaim an fnode/ntnode so that it can be used for other purposes. */ int ntfs_reclaim(void *v) { struct vop_reclaim_args /* { struct vnode *a_vp; } */ *ap = v; struct vnode *vp = ap->a_vp; struct fnode *fp = VTOF(vp); struct ntnode *ip = FTONT(fp); int error; dprintf(("ntfs_reclaim: vnode: %p, ntnode: %llu\n", vp, (unsigned long long)ip->i_number)); if (prtactive && vp->v_usecount > 1) vprint("ntfs_reclaim: pushing active", vp); if ((error = ntfs_ntget(ip)) != 0) return (error); if (ip->i_devvp) { vrele(ip->i_devvp); ip->i_devvp = NULL; } genfs_node_destroy(vp); ntfs_frele(fp); ntfs_ntput(ip); vp->v_data = NULL; return (0); }
/* * Reclaim an fnode/ntnode so that it can be used for other purposes. */ int ntfs_reclaim(void *v) { struct vop_reclaim_args *ap = v; struct vnode *vp = ap->a_vp; struct fnode *fp = VTOF(vp); struct ntnode *ip = FTONT(fp); struct proc *p = ap->a_p; int error; dprintf(("ntfs_reclaim: vnode: %p, ntnode: %d\n", vp, ip->i_number)); #ifdef DIAGNOSTIC if (ntfs_prtactive && vp->v_usecount != 0) vprint("ntfs_reclaim: pushing active", vp); #endif if ((error = ntfs_ntget(ip, p)) != 0) return (error); /* Purge old data structures associated with the inode. */ cache_purge(vp); ntfs_frele(fp); ntfs_ntput(ip, p); vp->v_data = NULL; return (0); }
/* * Reclaim an fnode/ntnode so that it can be used for other purposes. */ int ntfs_reclaim(void *v) { struct vop_reclaim_args /* { struct vnode *a_vp; } */ *ap = v; struct vnode *vp = ap->a_vp; struct fnode *fp = VTOF(vp); struct ntnode *ip = FTONT(fp); const int attrlen = strlen(fp->f_attrname); int error; dprintf(("ntfs_reclaim: vnode: %p, ntnode: %llu\n", vp, (unsigned long long)ip->i_number)); if (prtactive && vp->v_usecount > 1) vprint("ntfs_reclaim: pushing active", vp); if ((error = ntfs_ntget(ip)) != 0) return (error); vcache_remove(vp->v_mount, fp->f_key, NTKEY_SIZE(attrlen)); if (ip->i_devvp) { vrele(ip->i_devvp); ip->i_devvp = NULL; } genfs_node_destroy(vp); vp->v_data = NULL; /* Destroy fnode. */ if (fp->f_key != &fp->f_smallkey) kmem_free(fp->f_key, NTKEY_SIZE(attrlen)); if (fp->f_dirblbuf) free(fp->f_dirblbuf, M_NTFSDIR); kmem_free(fp, sizeof(*fp)); ntfs_ntrele(ip); ntfs_ntput(ip); return (0); }
int ntfs_vgetex( struct mount *mp, ino_t ino, u_int32_t attrtype, char *attrname, u_long lkflags, u_long flags, struct vnode **vpp) { int error; struct ntfsmount *ntmp; struct ntnode *ip; struct fnode *fp; struct vnode *vp; enum vtype f_type = VBAD; dprintf(("ntfs_vgetex: ino: %llu, attr: 0x%x:%s, lkf: 0x%lx, f:" " 0x%lx\n", (unsigned long long)ino, attrtype, attrname ? attrname : "", (u_long)lkflags, (u_long)flags)); ntmp = VFSTONTFS(mp); *vpp = NULL; loop: /* Get ntnode */ error = ntfs_ntlookup(ntmp, ino, &ip); if (error) { printf("ntfs_vget: ntfs_ntget failed\n"); return (error); } /* It may be not initialized fully, so force load it */ if (!(flags & VG_DONTLOADIN) && !(ip->i_flag & IN_LOADED)) { error = ntfs_loadntnode(ntmp, ip); if(error) { printf("ntfs_vget: CAN'T LOAD ATTRIBUTES FOR INO:" " %llu\n", (unsigned long long)ip->i_number); ntfs_ntput(ip); return (error); } } error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp); if (error) { printf("ntfs_vget: ntfs_fget failed\n"); ntfs_ntput(ip); return (error); } if (!(flags & VG_DONTVALIDFN) && !(fp->f_flag & FN_VALID)) { if ((ip->i_frflag & NTFS_FRFLAG_DIR) && (fp->f_attrtype == NTFS_A_DATA && fp->f_attrname == NULL)) { f_type = VDIR; } else if (flags & VG_EXT) { f_type = VNON; fp->f_size = fp->f_allocated = 0; } else { f_type = VREG; error = ntfs_filesize(ntmp, fp, &fp->f_size, &fp->f_allocated); if (error) { ntfs_ntput(ip); return (error); } } fp->f_flag |= FN_VALID; } /* * We may be calling vget() now. To avoid potential deadlock, we need * to release ntnode lock, since due to locking order vnode * lock has to be acquired first. * ntfs_fget() bumped ntnode usecount, so ntnode won't be recycled * prematurely. * Take v_interlock before releasing ntnode lock to avoid races. */ vp = FTOV(fp); if (vp) { mutex_enter(vp->v_interlock); ntfs_ntput(ip); if (vget(vp, lkflags) != 0) goto loop; *vpp = vp; return 0; } ntfs_ntput(ip); error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, NULL, &vp); if(error) { ntfs_frele(fp); return (error); } ntfs_ntget(ip); error = ntfs_fget(ntmp, ip, attrtype, attrname, &fp); if (error) { printf("ntfs_vget: ntfs_fget failed\n"); ntfs_ntput(ip); return (error); } if (FTOV(fp)) { /* * Another thread beat us, put back freshly allocated * vnode and retry. */ ntfs_ntput(ip); ungetnewvnode(vp); goto loop; } dprintf(("ntfs_vget: vnode: %p for ntnode: %llu\n", vp, (unsigned long long)ino)); fp->f_vp = vp; vp->v_data = fp; if (f_type != VBAD) vp->v_type = f_type; genfs_node_init(vp, &ntfs_genfsops); if (ino == NTFS_ROOTINO) vp->v_vflag |= VV_ROOT; ntfs_ntput(ip); if (lkflags & (LK_EXCLUSIVE | LK_SHARED)) { error = vn_lock(vp, lkflags); if (error) { vput(vp); return (error); } } uvm_vnp_setsize(vp, fp->f_size); /* XXX: mess, cf. ntfs_lookupfile() */ vref(ip->i_devvp); *vpp = vp; return (0); }