no longer `irele' when clearing cache after a `umount'.
SCCS-vsn: sys/kern/vfs_lookup.c 6.9
SCCS-vsn: sys/ufs/ffs/ufs_lookup.c 6.9
SCCS-vsn: sys/ufs/ufs/ufs_lookup.c 6.9
-/* vfs_lookup.c 6.8 84/07/02 */
+/* vfs_lookup.c 6.9 84/07/02 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
}
u.u_dent.d_namlen = i;
u.u_dent.d_name[i] = 0;
}
u.u_dent.d_namlen = i;
u.u_dent.d_name[i] = 0;
+ isdotdot = (i == 2 &&
+ u.u_dent.d_name[0] == '.' && u.u_dent.d_name[1] == '.');
/*
* Check for degenerate name (e.g. / or "")
/*
* Check for degenerate name (e.g. / or "")
nchstats.ncs_miss++;
ncp = NULL;
} else {
nchstats.ncs_miss++;
ncp = NULL;
} else {
- if (ncp->nc_id != ncp->nc_ip->i_id)
+ if (ncp->nc_id != ncp->nc_ip->i_id) {
nchstats.ncs_falsehits++;
nchstats.ncs_falsehits++;
- else if (*cp == '/' || docache) {
-
- nchstats.ncs_goodhits++;
+ } else if (*cp == '\0' && !docache) {
+ nchstats.ncs_badhits++;
+ } else {
/*
* move this slot to end of LRU
/*
* move this slot to end of LRU
nchtail = &ncp->nc_nxt;
}
nchtail = &ncp->nc_nxt;
}
+ /*
+ * Get the next inode in the path.
+ * See comment above other `iunlock' code for
+ * an explaination of the locking protocol.
+ */
pdp = dp;
dp = ncp->nc_ip;
if (dp == NULL)
pdp = dp;
dp = ncp->nc_ip;
if (dp == NULL)
dp->i_count++;
else if (dp->i_count) {
dp->i_count++;
dp->i_count++;
else if (dp->i_count) {
dp->i_count++;
- ilock(dp);
- iunlock(pdp);
+ if (isdotdot) {
+ iunlock(pdp);
+ ilock(dp);
+ } else {
+ ilock(dp);
+ iunlock(pdp);
+ }
- igrab(dp);
- iunlock(pdp);
+ if (isdotdot) {
+ iunlock(pdp);
+ igrab(dp);
+ } else {
+ igrab(dp);
+ iunlock(pdp);
+ }
- u.u_dent.d_ino = dp->i_number;
- /* u_dent.d_reclen is garbage ... */
-
- goto haveino;
- } else
- nchstats.ncs_badhits++;
+ /*
+ * Verify that the inode that we got
+ * did not change while we were waiting
+ * for it to be locked.
+ */
+ if (ncp->nc_id != ncp->nc_ip->i_id) {
+ iput(dp);
+ ilock(pdp);
+ dp = pdp;
+ nchstats.ncs_falsehits++;
+ } else {
+ u.u_dent.d_ino = dp->i_number;
+ /* u_dent.d_reclen is garbage ... */
+ nchstats.ncs_goodhits++;
+ goto haveino;
+ }
+ }
/*
* Last component and we are renaming or deleting,
/*
* Last component and we are renaming or deleting,
* file system: indirect .. in root inode to reevaluate
* in directory file system was mounted on.
*/
* file system: indirect .. in root inode to reevaluate
* in directory file system was mounted on.
*/
- isdotdot = 0;
- if (bcmp(u.u_dent.d_name, "..", 3) == 0) {
- isdotdot++;
if (dp == u.u_rdir)
u.u_dent.d_ino = dp->i_number;
else if (u.u_dent.d_ino == ROOTINO &&
if (dp == u.u_rdir)
u.u_dent.d_ino = dp->i_number;
else if (u.u_dent.d_ino == ROOTINO &&
if (error != 0)
break;
if (dirbuf.dotdot_namlen != 2 ||
if (error != 0)
break;
if (dirbuf.dotdot_namlen != 2 ||
- bcmp(dirbuf.dotdot_name, "..", 3) != 0) {
+ dirbuf.dotdot_name[0] != '.' ||
+ dirbuf.dotdot_name[1] != '.') {
error = ENOTDIR;
break;
}
error = ENOTDIR;
break;
}
(ncp->nc_idev != dev && ncp->nc_dev != dev))
continue;
(ncp->nc_idev != dev && ncp->nc_dev != dev))
continue;
+ /* free the resources we had */
ncp->nc_idev = NODEV;
ncp->nc_dev = NODEV;
ncp->nc_idev = NODEV;
ncp->nc_dev = NODEV;
/* remove the entry from its hash chain */
remque(ncp);
/* remove the entry from its hash chain */
remque(ncp);
else
nchtail = ncp->nc_prev;
else
nchtail = ncp->nc_prev;
- /* free the inode we had */
- irele(ncp->nc_ip);
- ncp->nc_ip = NULL;
-
/* cause rescan of list, it may have altered */
nxtcp = nchhead;
/* put the now-free entry at head of LRU */
/* cause rescan of list, it may have altered */
nxtcp = nchhead;
/* put the now-free entry at head of LRU */
-/* ufs_lookup.c 6.8 84/07/02 */
+/* ufs_lookup.c 6.9 84/07/02 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
}
u.u_dent.d_namlen = i;
u.u_dent.d_name[i] = 0;
}
u.u_dent.d_namlen = i;
u.u_dent.d_name[i] = 0;
+ isdotdot = (i == 2 &&
+ u.u_dent.d_name[0] == '.' && u.u_dent.d_name[1] == '.');
/*
* Check for degenerate name (e.g. / or "")
/*
* Check for degenerate name (e.g. / or "")
nchstats.ncs_miss++;
ncp = NULL;
} else {
nchstats.ncs_miss++;
ncp = NULL;
} else {
- if (ncp->nc_id != ncp->nc_ip->i_id)
+ if (ncp->nc_id != ncp->nc_ip->i_id) {
nchstats.ncs_falsehits++;
nchstats.ncs_falsehits++;
- else if (*cp == '/' || docache) {
-
- nchstats.ncs_goodhits++;
+ } else if (*cp == '\0' && !docache) {
+ nchstats.ncs_badhits++;
+ } else {
/*
* move this slot to end of LRU
/*
* move this slot to end of LRU
nchtail = &ncp->nc_nxt;
}
nchtail = &ncp->nc_nxt;
}
+ /*
+ * Get the next inode in the path.
+ * See comment above other `iunlock' code for
+ * an explaination of the locking protocol.
+ */
pdp = dp;
dp = ncp->nc_ip;
if (dp == NULL)
pdp = dp;
dp = ncp->nc_ip;
if (dp == NULL)
dp->i_count++;
else if (dp->i_count) {
dp->i_count++;
dp->i_count++;
else if (dp->i_count) {
dp->i_count++;
- ilock(dp);
- iunlock(pdp);
+ if (isdotdot) {
+ iunlock(pdp);
+ ilock(dp);
+ } else {
+ ilock(dp);
+ iunlock(pdp);
+ }
- igrab(dp);
- iunlock(pdp);
+ if (isdotdot) {
+ iunlock(pdp);
+ igrab(dp);
+ } else {
+ igrab(dp);
+ iunlock(pdp);
+ }
- u.u_dent.d_ino = dp->i_number;
- /* u_dent.d_reclen is garbage ... */
-
- goto haveino;
- } else
- nchstats.ncs_badhits++;
+ /*
+ * Verify that the inode that we got
+ * did not change while we were waiting
+ * for it to be locked.
+ */
+ if (ncp->nc_id != ncp->nc_ip->i_id) {
+ iput(dp);
+ ilock(pdp);
+ dp = pdp;
+ nchstats.ncs_falsehits++;
+ } else {
+ u.u_dent.d_ino = dp->i_number;
+ /* u_dent.d_reclen is garbage ... */
+ nchstats.ncs_goodhits++;
+ goto haveino;
+ }
+ }
/*
* Last component and we are renaming or deleting,
/*
* Last component and we are renaming or deleting,
* file system: indirect .. in root inode to reevaluate
* in directory file system was mounted on.
*/
* file system: indirect .. in root inode to reevaluate
* in directory file system was mounted on.
*/
- isdotdot = 0;
- if (bcmp(u.u_dent.d_name, "..", 3) == 0) {
- isdotdot++;
if (dp == u.u_rdir)
u.u_dent.d_ino = dp->i_number;
else if (u.u_dent.d_ino == ROOTINO &&
if (dp == u.u_rdir)
u.u_dent.d_ino = dp->i_number;
else if (u.u_dent.d_ino == ROOTINO &&
if (error != 0)
break;
if (dirbuf.dotdot_namlen != 2 ||
if (error != 0)
break;
if (dirbuf.dotdot_namlen != 2 ||
- bcmp(dirbuf.dotdot_name, "..", 3) != 0) {
+ dirbuf.dotdot_name[0] != '.' ||
+ dirbuf.dotdot_name[1] != '.') {
error = ENOTDIR;
break;
}
error = ENOTDIR;
break;
}
(ncp->nc_idev != dev && ncp->nc_dev != dev))
continue;
(ncp->nc_idev != dev && ncp->nc_dev != dev))
continue;
+ /* free the resources we had */
ncp->nc_idev = NODEV;
ncp->nc_dev = NODEV;
ncp->nc_idev = NODEV;
ncp->nc_dev = NODEV;
/* remove the entry from its hash chain */
remque(ncp);
/* remove the entry from its hash chain */
remque(ncp);
else
nchtail = ncp->nc_prev;
else
nchtail = ncp->nc_prev;
- /* free the inode we had */
- irele(ncp->nc_ip);
- ncp->nc_ip = NULL;
-
/* cause rescan of list, it may have altered */
nxtcp = nchhead;
/* put the now-free entry at head of LRU */
/* cause rescan of list, it may have altered */
nxtcp = nchhead;
/* put the now-free entry at head of LRU */
-/* ufs_lookup.c 6.8 84/07/02 */
+/* ufs_lookup.c 6.9 84/07/02 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
}
u.u_dent.d_namlen = i;
u.u_dent.d_name[i] = 0;
}
u.u_dent.d_namlen = i;
u.u_dent.d_name[i] = 0;
+ isdotdot = (i == 2 &&
+ u.u_dent.d_name[0] == '.' && u.u_dent.d_name[1] == '.');
/*
* Check for degenerate name (e.g. / or "")
/*
* Check for degenerate name (e.g. / or "")
nchstats.ncs_miss++;
ncp = NULL;
} else {
nchstats.ncs_miss++;
ncp = NULL;
} else {
- if (ncp->nc_id != ncp->nc_ip->i_id)
+ if (ncp->nc_id != ncp->nc_ip->i_id) {
nchstats.ncs_falsehits++;
nchstats.ncs_falsehits++;
- else if (*cp == '/' || docache) {
-
- nchstats.ncs_goodhits++;
+ } else if (*cp == '\0' && !docache) {
+ nchstats.ncs_badhits++;
+ } else {
/*
* move this slot to end of LRU
/*
* move this slot to end of LRU
nchtail = &ncp->nc_nxt;
}
nchtail = &ncp->nc_nxt;
}
+ /*
+ * Get the next inode in the path.
+ * See comment above other `iunlock' code for
+ * an explaination of the locking protocol.
+ */
pdp = dp;
dp = ncp->nc_ip;
if (dp == NULL)
pdp = dp;
dp = ncp->nc_ip;
if (dp == NULL)
dp->i_count++;
else if (dp->i_count) {
dp->i_count++;
dp->i_count++;
else if (dp->i_count) {
dp->i_count++;
- ilock(dp);
- iunlock(pdp);
+ if (isdotdot) {
+ iunlock(pdp);
+ ilock(dp);
+ } else {
+ ilock(dp);
+ iunlock(pdp);
+ }
- igrab(dp);
- iunlock(pdp);
+ if (isdotdot) {
+ iunlock(pdp);
+ igrab(dp);
+ } else {
+ igrab(dp);
+ iunlock(pdp);
+ }
- u.u_dent.d_ino = dp->i_number;
- /* u_dent.d_reclen is garbage ... */
-
- goto haveino;
- } else
- nchstats.ncs_badhits++;
+ /*
+ * Verify that the inode that we got
+ * did not change while we were waiting
+ * for it to be locked.
+ */
+ if (ncp->nc_id != ncp->nc_ip->i_id) {
+ iput(dp);
+ ilock(pdp);
+ dp = pdp;
+ nchstats.ncs_falsehits++;
+ } else {
+ u.u_dent.d_ino = dp->i_number;
+ /* u_dent.d_reclen is garbage ... */
+ nchstats.ncs_goodhits++;
+ goto haveino;
+ }
+ }
/*
* Last component and we are renaming or deleting,
/*
* Last component and we are renaming or deleting,
* file system: indirect .. in root inode to reevaluate
* in directory file system was mounted on.
*/
* file system: indirect .. in root inode to reevaluate
* in directory file system was mounted on.
*/
- isdotdot = 0;
- if (bcmp(u.u_dent.d_name, "..", 3) == 0) {
- isdotdot++;
if (dp == u.u_rdir)
u.u_dent.d_ino = dp->i_number;
else if (u.u_dent.d_ino == ROOTINO &&
if (dp == u.u_rdir)
u.u_dent.d_ino = dp->i_number;
else if (u.u_dent.d_ino == ROOTINO &&
if (error != 0)
break;
if (dirbuf.dotdot_namlen != 2 ||
if (error != 0)
break;
if (dirbuf.dotdot_namlen != 2 ||
- bcmp(dirbuf.dotdot_name, "..", 3) != 0) {
+ dirbuf.dotdot_name[0] != '.' ||
+ dirbuf.dotdot_name[1] != '.') {
error = ENOTDIR;
break;
}
error = ENOTDIR;
break;
}
(ncp->nc_idev != dev && ncp->nc_dev != dev))
continue;
(ncp->nc_idev != dev && ncp->nc_dev != dev))
continue;
+ /* free the resources we had */
ncp->nc_idev = NODEV;
ncp->nc_dev = NODEV;
ncp->nc_idev = NODEV;
ncp->nc_dev = NODEV;
/* remove the entry from its hash chain */
remque(ncp);
/* remove the entry from its hash chain */
remque(ncp);
else
nchtail = ncp->nc_prev;
else
nchtail = ncp->nc_prev;
- /* free the inode we had */
- irele(ncp->nc_ip);
- ncp->nc_ip = NULL;
-
/* cause rescan of list, it may have altered */
nxtcp = nchhead;
/* put the now-free entry at head of LRU */
/* cause rescan of list, it may have altered */
nxtcp = nchhead;
/* put the now-free entry at head of LRU */