View | Details | Raw Unified | Return to bug 19331
Collapse All | Expand All

(-)vfs_cache.c (+94 lines)
Lines 587-589 Link Here
587
	return (error);
587
	return (error);
588
}
588
}
589
589
590
/*
591
 * Thus begins the fullpath magic.
592
 */
593
594
#undef STATNODE
595
#define STATNODE(name)							\
596
	static u_int name;						\
597
	SYSCTL_INT(_vfs_cache, OID_AUTO, name, CTLFLAG_RD, &name, 0, "")
598
599
static int disablefullpath;
600
SYSCTL_INT(_debug, OID_AUTO, disablefullpath, CTLFLAG_RW,
601
    &disablefullpath, 0, "");
602
603
STATNODE(numfullpathcalls);
604
STATNODE(numfullpathfail1);
605
STATNODE(numfullpathfail2);
606
STATNODE(numfullpathfail3);
607
STATNODE(numfullpathfail4);
608
STATNODE(numfullpathfound);
609
610
int
611
textvp_fullpath(struct proc *p, char **retbuf, char **retfreebuf) {
612
	char *bp, *buf;
613
	int i, slash_prefixed;
614
	struct filedesc *fdp;
615
	struct namecache *ncp;
616
	struct vnode *vp, *textvp;
617
618
	numfullpathcalls++;
619
	if (disablefullpath)
620
		return (ENODEV);
621
	textvp = p->p_textvp;
622
	if (textvp == NULL)
623
		return (EINVAL);
624
	buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
625
	bp = buf + MAXPATHLEN - 1;
626
	*bp = '\0';
627
	fdp = p->p_fd;
628
	slash_prefixed = 0;
629
	for (vp = textvp; vp != fdp->fd_rdir && vp != rootvnode;) {
630
		if (vp->v_flag & VROOT) {
631
			if (vp->v_mount == NULL) {	/* forced unmount */
632
				free(buf, M_TEMP);
633
				return (EBADF);
634
			}
635
			vp = vp->v_mount->mnt_vnodecovered;
636
			continue;
637
		}
638
		if (vp != textvp && vp->v_dd->v_id != vp->v_ddid) {
639
			numfullpathfail1++;
640
			free(buf, M_TEMP);
641
			return (ENOTDIR);
642
		}
643
		ncp = TAILQ_FIRST(&vp->v_cache_dst);
644
		if (!ncp) {
645
			numfullpathfail2++;
646
			free(buf, M_TEMP);
647
			return (ENOENT);
648
		}
649
		if (vp != textvp && ncp->nc_dvp != vp->v_dd) {
650
			numfullpathfail3++;
651
			free(buf, M_TEMP);
652
			return (EBADF);
653
		}
654
		for (i = ncp->nc_nlen - 1; i >= 0; i--) {
655
			if (bp == buf) {
656
				numfullpathfail4++;
657
				free(buf, M_TEMP);
658
				return (ENOMEM);
659
			}
660
			*--bp = ncp->nc_name[i];
661
		}
662
		if (bp == buf) {
663
			numfullpathfail4++;
664
			free(buf, M_TEMP);
665
			return (ENOMEM);
666
		}
667
		*--bp = '/';
668
		slash_prefixed = 1;
669
		vp = ncp->nc_dvp;
670
	}
671
	if (!slash_prefixed) {
672
		if (bp == buf) {
673
			numfullpathfail4++;
674
			free(buf, M_TEMP);
675
			return (ENOMEM);
676
		}
677
		*--bp = '/';
678
	}
679
	numfullpathfound++;
680
	*retbuf = bp; 
681
	*retfreebuf = buf;
682
	return (0);
683
}

Return to bug 19331