Deleted Added
full compact
msdosfs_lookup.c (203827) msdosfs_lookup.c (204474)
1/* $FreeBSD: head/sys/fs/msdosfs/msdosfs_lookup.c 203827 2010-02-13 12:41:07Z kib $ */
1/* $FreeBSD: head/sys/fs/msdosfs/msdosfs_lookup.c 204474 2010-02-28 17:17:29Z kib $ */
2/* $NetBSD: msdosfs_lookup.c,v 1.37 1997/11/17 15:36:54 ws Exp $ */
3
4/*-
5 * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
6 * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
7 * All rights reserved.
8 * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
9 *

--- 46 unchanged lines hidden (view full) ---

56#include <sys/vnode.h>
57
58#include <fs/msdosfs/bpb.h>
59#include <fs/msdosfs/direntry.h>
60#include <fs/msdosfs/denode.h>
61#include <fs/msdosfs/fat.h>
62#include <fs/msdosfs/msdosfsmount.h>
63
2/* $NetBSD: msdosfs_lookup.c,v 1.37 1997/11/17 15:36:54 ws Exp $ */
3
4/*-
5 * Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
6 * Copyright (C) 1994, 1995, 1997 TooLs GmbH.
7 * All rights reserved.
8 * Original code by Paul Popelka (paulp@uts.amdahl.com) (see below).
9 *

--- 46 unchanged lines hidden (view full) ---

56#include <sys/vnode.h>
57
58#include <fs/msdosfs/bpb.h>
59#include <fs/msdosfs/direntry.h>
60#include <fs/msdosfs/denode.h>
61#include <fs/msdosfs/fat.h>
62#include <fs/msdosfs/msdosfsmount.h>
63
64static int msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
65 struct componentname *cnp, u_int64_t *inum);
66static int msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff,
67 struct vnode **rvp);
68
69int
70msdosfs_lookup(struct vop_cachedlookup_args *ap)
71{
72
73 return (msdosfs_lookup_(ap->a_dvp, ap->a_vpp, ap->a_cnp, NULL));
74}
75
64/*
65 * When we search a directory the blocks containing directory entries are
66 * read and examined. The directory entries contain information that would
67 * normally be in the inode of a unix filesystem. This means that some of
68 * a directory's contents may also be in memory resident denodes (sort of
69 * an inode). This can cause problems if we are searching while some other
70 * process is modifying a directory. To prevent one process from accessing
71 * incompletely modified directory information we depend upon being the
72 * sole owner of a directory block. bread/brelse provide this service.
73 * This being the case, when a process modifies a directory it must first
74 * acquire the disk block that contains the directory entry to be modified.
75 * Then update the disk block and the denode, and then write the disk block
76 * out to disk. This way disk blocks containing directory entries and in
77 * memory denode's will be in synch.
78 */
76/*
77 * When we search a directory the blocks containing directory entries are
78 * read and examined. The directory entries contain information that would
79 * normally be in the inode of a unix filesystem. This means that some of
80 * a directory's contents may also be in memory resident denodes (sort of
81 * an inode). This can cause problems if we are searching while some other
82 * process is modifying a directory. To prevent one process from accessing
83 * incompletely modified directory information we depend upon being the
84 * sole owner of a directory block. bread/brelse provide this service.
85 * This being the case, when a process modifies a directory it must first
86 * acquire the disk block that contains the directory entry to be modified.
87 * Then update the disk block and the denode, and then write the disk block
88 * out to disk. This way disk blocks containing directory entries and in
89 * memory denode's will be in synch.
90 */
79int
80msdosfs_lookup(ap)
81 struct vop_cachedlookup_args /* {
82 struct vnode *a_dvp;
83 struct vnode **a_vpp;
84 struct componentname *a_cnp;
85 } */ *ap;
91static int
92msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
93 struct componentname *cnp, u_int64_t *dd_inum)
86{
87 struct mbnambuf nb;
94{
95 struct mbnambuf nb;
88 struct vnode *vdp = ap->a_dvp;
89 struct vnode **vpp = ap->a_vpp;
90 struct componentname *cnp = ap->a_cnp;
91 daddr_t bn;
92 int error;
93 int slotcount;
94 int slotoffset = 0;
95 int frcn;
96 u_long cluster;
97 int blkoff;
98 int diroff;

--- 5 unchanged lines hidden (view full) ---

104 struct denode *tdp;
105 struct msdosfsmount *pmp;
106 struct buf *bp = 0;
107 struct direntry *dep = NULL;
108 u_char dosfilename[12];
109 int flags = cnp->cn_flags;
110 int nameiop = cnp->cn_nameiop;
111 int unlen;
96 daddr_t bn;
97 int error;
98 int slotcount;
99 int slotoffset = 0;
100 int frcn;
101 u_long cluster;
102 int blkoff;
103 int diroff;

--- 5 unchanged lines hidden (view full) ---

109 struct denode *tdp;
110 struct msdosfsmount *pmp;
111 struct buf *bp = 0;
112 struct direntry *dep = NULL;
113 u_char dosfilename[12];
114 int flags = cnp->cn_flags;
115 int nameiop = cnp->cn_nameiop;
116 int unlen;
117 u_int64_t inode1;
112
113 int wincnt = 1;
114 int chksum = -1, chksum_ok;
115 int olddos = 1;
116
117#ifdef MSDOSFS_DEBUG
118 printf("msdosfs_lookup(): looking for %s\n", cnp->cn_nameptr);
119#endif
120 dp = VTODE(vdp);
121 pmp = dp->de_pmp;
118
119 int wincnt = 1;
120 int chksum = -1, chksum_ok;
121 int olddos = 1;
122
123#ifdef MSDOSFS_DEBUG
124 printf("msdosfs_lookup(): looking for %s\n", cnp->cn_nameptr);
125#endif
126 dp = VTODE(vdp);
127 pmp = dp->de_pmp;
122 *vpp = NULL;
128 if (vpp != NULL)
129 *vpp = NULL;
123#ifdef MSDOSFS_DEBUG
124 printf("msdosfs_lookup(): vdp %p, dp %p, Attr %02x\n",
125 vdp, dp, dp->de_Attributes);
126#endif
127
130#ifdef MSDOSFS_DEBUG
131 printf("msdosfs_lookup(): vdp %p, dp %p, Attr %02x\n",
132 vdp, dp, dp->de_Attributes);
133#endif
134
135 restart:
128 /*
129 * If they are going after the . or .. entry in the root directory,
130 * they won't find it. DOS filesystems don't have them in the root
131 * directory. So, we fake it. deget() is in on this scam too.
132 */
133 if ((vdp->v_vflag & VV_ROOT) && cnp->cn_nameptr[0] == '.' &&
134 (cnp->cn_namelen == 1 ||
135 (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.'))) {

--- 295 unchanged lines hidden (view full) ---

431 /*
432 * If we entered at foundroot, then we are looking for the . or ..
433 * entry of the filesystems root directory. isadir and scn were
434 * setup before jumping here. And, bp is already null.
435 */
436 if (FAT32(pmp) && scn == MSDOSFSROOT)
437 scn = pmp->pm_rootdirblk;
438
136 /*
137 * If they are going after the . or .. entry in the root directory,
138 * they won't find it. DOS filesystems don't have them in the root
139 * directory. So, we fake it. deget() is in on this scam too.
140 */
141 if ((vdp->v_vflag & VV_ROOT) && cnp->cn_nameptr[0] == '.' &&
142 (cnp->cn_namelen == 1 ||
143 (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.'))) {

--- 295 unchanged lines hidden (view full) ---

439 /*
440 * If we entered at foundroot, then we are looking for the . or ..
441 * entry of the filesystems root directory. isadir and scn were
442 * setup before jumping here. And, bp is already null.
443 */
444 if (FAT32(pmp) && scn == MSDOSFSROOT)
445 scn = pmp->pm_rootdirblk;
446
447 if (dd_inum != NULL) {
448 *dd_inum = (uint64_t)pmp->pm_bpcluster * scn + blkoff;
449 return (0);
450 }
451
439 /*
440 * If deleting, and at end of pathname, return
441 * parameters which can be used to remove file.
442 */
443 if (nameiop == DELETE && (flags & ISLASTCN)) {
444 /*
445 * Don't allow deleting the root.
446 */

--- 56 unchanged lines hidden (view full) ---

503 * directory because we may need it again if a symbolic link
504 * is relative to the current directory. Instead we save it
505 * unlocked as "pdp". We must get the target inode before unlocking
506 * the directory to insure that the inode will not be removed
507 * before we get it. We prevent deadlock by always fetching
508 * inodes from the root, moving down the directory tree. Thus
509 * when following backward pointers ".." we must unlock the
510 * parent directory before getting the requested directory.
452 /*
453 * If deleting, and at end of pathname, return
454 * parameters which can be used to remove file.
455 */
456 if (nameiop == DELETE && (flags & ISLASTCN)) {
457 /*
458 * Don't allow deleting the root.
459 */

--- 56 unchanged lines hidden (view full) ---

516 * directory because we may need it again if a symbolic link
517 * is relative to the current directory. Instead we save it
518 * unlocked as "pdp". We must get the target inode before unlocking
519 * the directory to insure that the inode will not be removed
520 * before we get it. We prevent deadlock by always fetching
521 * inodes from the root, moving down the directory tree. Thus
522 * when following backward pointers ".." we must unlock the
523 * parent directory before getting the requested directory.
511 * There is a potential race condition here if both the current
512 * and parent directories are removed before the VFS_VGET for the
513 * inode associated with ".." returns. We hope that this occurs
514 * infrequently since we cannot avoid this race condition without
515 * implementing a sophisticated deadlock detection algorithm.
516 * Note also that this simple deadlock detection scheme will not
517 * work if the filesystem has any hard links other than ".."
518 * that point backwards in the directory structure.
519 */
520 pdp = vdp;
521 if (flags & ISDOTDOT) {
524 */
525 pdp = vdp;
526 if (flags & ISDOTDOT) {
522 VOP_UNLOCK(pdp, 0);
523 error = deget(pmp, cluster, blkoff, &tdp);
524 vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
527 error = msdosfs_deget_dotdot(pdp, cluster, blkoff, vpp);
525 if (error)
526 return (error);
528 if (error)
529 return (error);
527 *vpp = DETOV(tdp);
530 /*
531 * Recheck that ".." still points to the inode we
532 * looked up before pdp lock was dropped.
533 */
534 error = msdosfs_lookup_(pdp, NULL, cnp, &inode1);
535 if (error) {
536 vput(*vpp);
537 return (error);
538 }
539 if (VTODE(*vpp)->de_inode != inode1) {
540 vput(*vpp);
541 goto restart;
542 }
528 } else if (dp->de_StartCluster == scn && isadir) {
529 VREF(vdp); /* we want ourself, ie "." */
530 *vpp = vdp;
531 } else {
532 if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0)
533 return (error);
534 *vpp = DETOV(tdp);
535 }
536
537 /*
538 * Insert name into cache if appropriate.
539 */
540 if (cnp->cn_flags & MAKEENTRY)
541 cache_enter(vdp, *vpp, cnp);
542 return (0);
543}
544
543 } else if (dp->de_StartCluster == scn && isadir) {
544 VREF(vdp); /* we want ourself, ie "." */
545 *vpp = vdp;
546 } else {
547 if ((error = deget(pmp, cluster, blkoff, &tdp)) != 0)
548 return (error);
549 *vpp = DETOV(tdp);
550 }
551
552 /*
553 * Insert name into cache if appropriate.
554 */
555 if (cnp->cn_flags & MAKEENTRY)
556 cache_enter(vdp, *vpp, cnp);
557 return (0);
558}
559
560static int
561msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff,
562 struct vnode **rvp)
563{
564 struct mount *mp;
565 struct msdosfsmount *pmp;
566 struct denode *rdp;
567 int ltype, error;
568
569 mp = vp->v_mount;
570 pmp = VFSTOMSDOSFS(mp);
571 ltype = VOP_ISLOCKED(vp);
572 KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED,
573 ("msdosfs_deget_dotdot: vp not locked"));
574
575 error = vfs_busy(mp, MBF_NOWAIT);
576 if (error != 0) {
577 vfs_ref(mp);
578 VOP_UNLOCK(vp, 0);
579 error = vfs_busy(mp, 0);
580 vn_lock(vp, ltype | LK_RETRY);
581 vfs_rel(mp);
582 if (error != 0)
583 return (ENOENT);
584 if (vp->v_iflag & VI_DOOMED) {
585 vfs_unbusy(mp);
586 return (ENOENT);
587 }
588 }
589 VOP_UNLOCK(vp, 0);
590 error = deget(pmp, cluster, blkoff, &rdp);
591 vfs_unbusy(mp);
592 if (error == 0)
593 *rvp = DETOV(rdp);
594 vn_lock(vp, ltype | LK_RETRY);
595 if (vp->v_iflag & VI_DOOMED) {
596 if (error == 0)
597 vput(*rvp);
598 error = ENOENT;
599 }
600 return (error);
601}
602
545/*
546 * dep - directory entry to copy into the directory
547 * ddep - directory to add to
548 * depp - return the address of the denode for the created directory entry
549 * if depp != 0
550 * cnp - componentname needed for Win95 long filenames
551 */
552int

--- 535 unchanged lines hidden ---
603/*
604 * dep - directory entry to copy into the directory
605 * ddep - directory to add to
606 * depp - return the address of the denode for the created directory entry
607 * if depp != 0
608 * cnp - componentname needed for Win95 long filenames
609 */
610int

--- 535 unchanged lines hidden ---