. and .. may be placed in the cache
SCCS-vsn: sys/ufs/ffs/ffs_inode.c 6.5
SCCS-vsn: sys/ufs/ffs/ufs_inode.c 6.5
SCCS-vsn: sys/ufs/lfs/lfs_inode.c 6.5
SCCS-vsn: sys/ufs/ufs/ufs_inode.c 6.5
SCCS-vsn: sys/kern/vfs_lookup.c 6.7
SCCS-vsn: sys/ufs/ffs/ufs_lookup.c 6.7
SCCS-vsn: sys/ufs/ufs/ufs_lookup.c 6.7
SCCS-vsn: sys/kern/vfs_syscalls.c 6.7
SCCS-vsn: sys/ufs/ffs/ffs_vnops.c 6.7
SCCS-vsn: sys/ufs/ffs/ufs_vnops.c 6.7
SCCS-vsn: sys/ufs/lfs/lfs_vnops.c 6.7
SCCS-vsn: sys/ufs/ufs/ufs_vnops.c 6.7
12 files changed:
-/* vfs_lookup.c 6.6 84/02/15 */
+/* vfs_lookup.c 6.7 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
*/
nbp = geteblk(MAXPATHLEN);
for (cp = nbp->b_un.b_addr; *cp = (*func)(); ) {
*/
nbp = geteblk(MAXPATHLEN);
for (cp = nbp->b_un.b_addr; *cp = (*func)(); ) {
- if ((*cp&0377) == ('/'|0200) || (*cp&0200) && flag != LOOKUP) {
+ if ((*cp&0377) == ('/'|0200) || (*cp&0200) && flag != DELETE) {
u.u_error = EPERM;
goto bad;
}
u.u_error = EPERM;
goto bad;
}
nchstats.ncs_miss++;
ncp = NULL;
} else {
nchstats.ncs_miss++;
ncp = NULL;
} else {
- if (*cp == '/' || docache) {
+ if (ncp->nc_id != ncp->nc_ip->i_id)
+ nchstats.ncs_falsehits++;
+ else if (*cp == '/' || docache) {
dp = ncp->nc_ip;
if (dp == NULL)
panic("nami: null cache ino");
dp = ncp->nc_ip;
if (dp == NULL)
panic("nami: null cache ino");
- if (pdp != dp) {
- ilock(dp);
+ else if (dp->i_count) {
+ ilock(dp);
+ iunlock(pdp);
+ } else {
+ igrab(dp);
+ iunlock(pdp);
+ }
u.u_dent.d_ino = dp->i_number;
/* u_dent.d_reclen is garbage ... */
goto haveino;
u.u_dent.d_ino = dp->i_number;
/* u_dent.d_reclen is garbage ... */
goto haveino;
+ } else
+ nchstats.ncs_badhits++;
- * last segment and we are renaming or deleting
- * or otherwise don't want cache entry to exist
+ * Last component and we are renaming or deleting,
+ * the cache entry is invalid, or otherwise don't
+ * want cache entry to exist.
- nchstats.ncs_badhits++;
-
/* remove from LRU chain */
*ncp->nc_prev = ncp->nc_nxt;
if (ncp->nc_nxt)
/* remove from LRU chain */
*ncp->nc_prev = ncp->nc_nxt;
if (ncp->nc_nxt)
/* remove from hash chain */
remque(ncp);
/* remove from hash chain */
remque(ncp);
- /* release ref on the inode */
- irele(ncp->nc_ip);
- ncp->nc_ip = NULL;
-
/* insert at head of LRU list (first to grab) */
ncp->nc_nxt = nchhead;
ncp->nc_prev = &nchhead;
/* insert at head of LRU list (first to grab) */
ncp->nc_nxt = nchhead;
ncp->nc_prev = &nchhead;
* all other cases where making a cache entry would be wrong
* have already departed from the code sequence somewhere above.
*/
* all other cases where making a cache entry would be wrong
* have already departed from the code sequence somewhere above.
*/
- if (bcmp(u.u_dent.d_name, ".", 2) != 0 && !isdotdot && docache) {
if (ncp != NULL)
panic("nami: duplicating cache");
if (ncp != NULL)
panic("nami: duplicating cache");
/* remove from old hash chain */
remque(ncp);
/* remove from old hash chain */
remque(ncp);
- /* drop hold on inode (if we had one) */
- if (ncp->nc_ip)
- irele(ncp->nc_ip);
-
/* grab the inode we just found */
ncp->nc_ip = dp;
/* grab the inode we just found */
ncp->nc_ip = dp;
/* fill in cache info */
ncp->nc_ino = pdp->i_number; /* parents inum */
ncp->nc_dev = pdp->i_dev; /* & device */
ncp->nc_idev = dp->i_dev; /* our device */
/* fill in cache info */
ncp->nc_ino = pdp->i_number; /* parents inum */
ncp->nc_dev = pdp->i_dev; /* & device */
ncp->nc_idev = dp->i_dev; /* our device */
+ ncp->nc_id = dp->i_id; /* identifier */
ncp->nc_nlen = u.u_dent.d_namlen;
bcopy(u.u_dent.d_name, ncp->nc_name, ncp->nc_nlen);
ncp->nc_nlen = u.u_dent.d_namlen;
bcopy(u.u_dent.d_name, ncp->nc_name, ncp->nc_nlen);
-/* vfs_syscalls.c 6.6 84/05/24 */
+/* vfs_syscalls.c 6.7 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
+ dp->i_id = ++nextinodeid;
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}
-/* ffs_inode.c 6.4 84/05/22 */
+/* ffs_inode.c 6.5 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
ih = &ihead[INOHASH(dev, ino)];
for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
if (ino == ip->i_number && dev == ip->i_dev) {
ih = &ihead[INOHASH(dev, ino)];
for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
if (ino == ip->i_number && dev == ip->i_dev) {
+ /*
+ * Following is essentially an inline expanded
+ * copy of igrab(), expanded inline for speed,
+ * and so that the test for a mounted on inode
+ * can be deferred until after we are sure that
+ * the inode isn't busy.
+ */
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
ip->i_dev = dev;
ip->i_fs = fs;
ip->i_number = ino;
ip->i_dev = dev;
ip->i_fs = fs;
ip->i_number = ino;
+ ip->i_id = ++nextinodeid; /* also used in rename */
+ /*
+ * At an absurd rate of 100 calls/second,
+ * this should occur once every 16 months.
+ */
+ if (nextinodeid == 0)
+ panic("iget: wrap");
ip->i_flag = ILOCKED;
ip->i_count++;
ip->i_lastr = 0;
ip->i_flag = ILOCKED;
ip->i_count++;
ip->i_lastr = 0;
+/*
+ * Convert a pointer to an inode into a reference to an inode.
+ *
+ * This is basically the internal piece of iget (after the
+ * inode pointer is located) but without the test for mounted
+ * filesystems. It is caller's responsibility to check that
+ * the inode pointer is valid.
+ */
+igrab(ip)
+ register struct inode *ip;
+{
+ while ((ip->i_flag&ILOCKED) != 0) {
+ ip->i_flag |= IWANT;
+ sleep((caddr_t)ip, PINOD);
+ }
+ if (ip->i_count == 0) { /* ino on free list */
+ register struct inode *iq;
+
+ if (iq = ip->i_freef)
+ iq->i_freeb = ip->i_freeb;
+ else
+ ifreet = ip->i_freeb;
+ *ip->i_freeb = iq;
+ ip->i_freef = NULL;
+ ip->i_freeb = NULL;
+ }
+ ip->i_count++;
+ ip->i_flag |= ILOCKED;
+}
+
/*
* Decrement reference count of
* an inode structure.
/*
* Decrement reference count of
* an inode structure.
-/* ffs_vnops.c 6.6 84/05/24 */
+/* ffs_vnops.c 6.7 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
+ dp->i_id = ++nextinodeid;
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}
-/* ufs_inode.c 6.4 84/05/22 */
+/* ufs_inode.c 6.5 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
ih = &ihead[INOHASH(dev, ino)];
for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
if (ino == ip->i_number && dev == ip->i_dev) {
ih = &ihead[INOHASH(dev, ino)];
for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
if (ino == ip->i_number && dev == ip->i_dev) {
+ /*
+ * Following is essentially an inline expanded
+ * copy of igrab(), expanded inline for speed,
+ * and so that the test for a mounted on inode
+ * can be deferred until after we are sure that
+ * the inode isn't busy.
+ */
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
ip->i_dev = dev;
ip->i_fs = fs;
ip->i_number = ino;
ip->i_dev = dev;
ip->i_fs = fs;
ip->i_number = ino;
+ ip->i_id = ++nextinodeid; /* also used in rename */
+ /*
+ * At an absurd rate of 100 calls/second,
+ * this should occur once every 16 months.
+ */
+ if (nextinodeid == 0)
+ panic("iget: wrap");
ip->i_flag = ILOCKED;
ip->i_count++;
ip->i_lastr = 0;
ip->i_flag = ILOCKED;
ip->i_count++;
ip->i_lastr = 0;
+/*
+ * Convert a pointer to an inode into a reference to an inode.
+ *
+ * This is basically the internal piece of iget (after the
+ * inode pointer is located) but without the test for mounted
+ * filesystems. It is caller's responsibility to check that
+ * the inode pointer is valid.
+ */
+igrab(ip)
+ register struct inode *ip;
+{
+ while ((ip->i_flag&ILOCKED) != 0) {
+ ip->i_flag |= IWANT;
+ sleep((caddr_t)ip, PINOD);
+ }
+ if (ip->i_count == 0) { /* ino on free list */
+ register struct inode *iq;
+
+ if (iq = ip->i_freef)
+ iq->i_freeb = ip->i_freeb;
+ else
+ ifreet = ip->i_freeb;
+ *ip->i_freeb = iq;
+ ip->i_freef = NULL;
+ ip->i_freeb = NULL;
+ }
+ ip->i_count++;
+ ip->i_flag |= ILOCKED;
+}
+
/*
* Decrement reference count of
* an inode structure.
/*
* Decrement reference count of
* an inode structure.
-/* ufs_lookup.c 6.6 84/02/15 */
+/* ufs_lookup.c 6.7 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
*/
nbp = geteblk(MAXPATHLEN);
for (cp = nbp->b_un.b_addr; *cp = (*func)(); ) {
*/
nbp = geteblk(MAXPATHLEN);
for (cp = nbp->b_un.b_addr; *cp = (*func)(); ) {
- if ((*cp&0377) == ('/'|0200) || (*cp&0200) && flag != LOOKUP) {
+ if ((*cp&0377) == ('/'|0200) || (*cp&0200) && flag != DELETE) {
u.u_error = EPERM;
goto bad;
}
u.u_error = EPERM;
goto bad;
}
nchstats.ncs_miss++;
ncp = NULL;
} else {
nchstats.ncs_miss++;
ncp = NULL;
} else {
- if (*cp == '/' || docache) {
+ if (ncp->nc_id != ncp->nc_ip->i_id)
+ nchstats.ncs_falsehits++;
+ else if (*cp == '/' || docache) {
dp = ncp->nc_ip;
if (dp == NULL)
panic("nami: null cache ino");
dp = ncp->nc_ip;
if (dp == NULL)
panic("nami: null cache ino");
- if (pdp != dp) {
- ilock(dp);
+ else if (dp->i_count) {
+ ilock(dp);
+ iunlock(pdp);
+ } else {
+ igrab(dp);
+ iunlock(pdp);
+ }
u.u_dent.d_ino = dp->i_number;
/* u_dent.d_reclen is garbage ... */
goto haveino;
u.u_dent.d_ino = dp->i_number;
/* u_dent.d_reclen is garbage ... */
goto haveino;
+ } else
+ nchstats.ncs_badhits++;
- * last segment and we are renaming or deleting
- * or otherwise don't want cache entry to exist
+ * Last component and we are renaming or deleting,
+ * the cache entry is invalid, or otherwise don't
+ * want cache entry to exist.
- nchstats.ncs_badhits++;
-
/* remove from LRU chain */
*ncp->nc_prev = ncp->nc_nxt;
if (ncp->nc_nxt)
/* remove from LRU chain */
*ncp->nc_prev = ncp->nc_nxt;
if (ncp->nc_nxt)
/* remove from hash chain */
remque(ncp);
/* remove from hash chain */
remque(ncp);
- /* release ref on the inode */
- irele(ncp->nc_ip);
- ncp->nc_ip = NULL;
-
/* insert at head of LRU list (first to grab) */
ncp->nc_nxt = nchhead;
ncp->nc_prev = &nchhead;
/* insert at head of LRU list (first to grab) */
ncp->nc_nxt = nchhead;
ncp->nc_prev = &nchhead;
* all other cases where making a cache entry would be wrong
* have already departed from the code sequence somewhere above.
*/
* all other cases where making a cache entry would be wrong
* have already departed from the code sequence somewhere above.
*/
- if (bcmp(u.u_dent.d_name, ".", 2) != 0 && !isdotdot && docache) {
if (ncp != NULL)
panic("nami: duplicating cache");
if (ncp != NULL)
panic("nami: duplicating cache");
/* remove from old hash chain */
remque(ncp);
/* remove from old hash chain */
remque(ncp);
- /* drop hold on inode (if we had one) */
- if (ncp->nc_ip)
- irele(ncp->nc_ip);
-
/* grab the inode we just found */
ncp->nc_ip = dp;
/* grab the inode we just found */
ncp->nc_ip = dp;
/* fill in cache info */
ncp->nc_ino = pdp->i_number; /* parents inum */
ncp->nc_dev = pdp->i_dev; /* & device */
ncp->nc_idev = dp->i_dev; /* our device */
/* fill in cache info */
ncp->nc_ino = pdp->i_number; /* parents inum */
ncp->nc_dev = pdp->i_dev; /* & device */
ncp->nc_idev = dp->i_dev; /* our device */
+ ncp->nc_id = dp->i_id; /* identifier */
ncp->nc_nlen = u.u_dent.d_namlen;
bcopy(u.u_dent.d_name, ncp->nc_name, ncp->nc_nlen);
ncp->nc_nlen = u.u_dent.d_namlen;
bcopy(u.u_dent.d_name, ncp->nc_name, ncp->nc_nlen);
-/* ufs_vnops.c 6.6 84/05/24 */
+/* ufs_vnops.c 6.7 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
+ dp->i_id = ++nextinodeid;
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}
-/* lfs_inode.c 6.4 84/05/22 */
+/* lfs_inode.c 6.5 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
ih = &ihead[INOHASH(dev, ino)];
for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
if (ino == ip->i_number && dev == ip->i_dev) {
ih = &ihead[INOHASH(dev, ino)];
for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
if (ino == ip->i_number && dev == ip->i_dev) {
+ /*
+ * Following is essentially an inline expanded
+ * copy of igrab(), expanded inline for speed,
+ * and so that the test for a mounted on inode
+ * can be deferred until after we are sure that
+ * the inode isn't busy.
+ */
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
ip->i_dev = dev;
ip->i_fs = fs;
ip->i_number = ino;
ip->i_dev = dev;
ip->i_fs = fs;
ip->i_number = ino;
+ ip->i_id = ++nextinodeid; /* also used in rename */
+ /*
+ * At an absurd rate of 100 calls/second,
+ * this should occur once every 16 months.
+ */
+ if (nextinodeid == 0)
+ panic("iget: wrap");
ip->i_flag = ILOCKED;
ip->i_count++;
ip->i_lastr = 0;
ip->i_flag = ILOCKED;
ip->i_count++;
ip->i_lastr = 0;
+/*
+ * Convert a pointer to an inode into a reference to an inode.
+ *
+ * This is basically the internal piece of iget (after the
+ * inode pointer is located) but without the test for mounted
+ * filesystems. It is caller's responsibility to check that
+ * the inode pointer is valid.
+ */
+igrab(ip)
+ register struct inode *ip;
+{
+ while ((ip->i_flag&ILOCKED) != 0) {
+ ip->i_flag |= IWANT;
+ sleep((caddr_t)ip, PINOD);
+ }
+ if (ip->i_count == 0) { /* ino on free list */
+ register struct inode *iq;
+
+ if (iq = ip->i_freef)
+ iq->i_freeb = ip->i_freeb;
+ else
+ ifreet = ip->i_freeb;
+ *ip->i_freeb = iq;
+ ip->i_freef = NULL;
+ ip->i_freeb = NULL;
+ }
+ ip->i_count++;
+ ip->i_flag |= ILOCKED;
+}
+
/*
* Decrement reference count of
* an inode structure.
/*
* Decrement reference count of
* an inode structure.
-/* lfs_vnops.c 6.6 84/05/24 */
+/* lfs_vnops.c 6.7 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
+ dp->i_id = ++nextinodeid;
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}
-/* ufs_inode.c 6.4 84/05/22 */
+/* ufs_inode.c 6.5 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
ih = &ihead[INOHASH(dev, ino)];
for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
if (ino == ip->i_number && dev == ip->i_dev) {
ih = &ihead[INOHASH(dev, ino)];
for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
if (ino == ip->i_number && dev == ip->i_dev) {
+ /*
+ * Following is essentially an inline expanded
+ * copy of igrab(), expanded inline for speed,
+ * and so that the test for a mounted on inode
+ * can be deferred until after we are sure that
+ * the inode isn't busy.
+ */
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
ip->i_dev = dev;
ip->i_fs = fs;
ip->i_number = ino;
ip->i_dev = dev;
ip->i_fs = fs;
ip->i_number = ino;
+ ip->i_id = ++nextinodeid; /* also used in rename */
+ /*
+ * At an absurd rate of 100 calls/second,
+ * this should occur once every 16 months.
+ */
+ if (nextinodeid == 0)
+ panic("iget: wrap");
ip->i_flag = ILOCKED;
ip->i_count++;
ip->i_lastr = 0;
ip->i_flag = ILOCKED;
ip->i_count++;
ip->i_lastr = 0;
+/*
+ * Convert a pointer to an inode into a reference to an inode.
+ *
+ * This is basically the internal piece of iget (after the
+ * inode pointer is located) but without the test for mounted
+ * filesystems. It is caller's responsibility to check that
+ * the inode pointer is valid.
+ */
+igrab(ip)
+ register struct inode *ip;
+{
+ while ((ip->i_flag&ILOCKED) != 0) {
+ ip->i_flag |= IWANT;
+ sleep((caddr_t)ip, PINOD);
+ }
+ if (ip->i_count == 0) { /* ino on free list */
+ register struct inode *iq;
+
+ if (iq = ip->i_freef)
+ iq->i_freeb = ip->i_freeb;
+ else
+ ifreet = ip->i_freeb;
+ *ip->i_freeb = iq;
+ ip->i_freef = NULL;
+ ip->i_freeb = NULL;
+ }
+ ip->i_count++;
+ ip->i_flag |= ILOCKED;
+}
+
/*
* Decrement reference count of
* an inode structure.
/*
* Decrement reference count of
* an inode structure.
-/* ufs_lookup.c 6.6 84/02/15 */
+/* ufs_lookup.c 6.7 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
*/
nbp = geteblk(MAXPATHLEN);
for (cp = nbp->b_un.b_addr; *cp = (*func)(); ) {
*/
nbp = geteblk(MAXPATHLEN);
for (cp = nbp->b_un.b_addr; *cp = (*func)(); ) {
- if ((*cp&0377) == ('/'|0200) || (*cp&0200) && flag != LOOKUP) {
+ if ((*cp&0377) == ('/'|0200) || (*cp&0200) && flag != DELETE) {
u.u_error = EPERM;
goto bad;
}
u.u_error = EPERM;
goto bad;
}
nchstats.ncs_miss++;
ncp = NULL;
} else {
nchstats.ncs_miss++;
ncp = NULL;
} else {
- if (*cp == '/' || docache) {
+ if (ncp->nc_id != ncp->nc_ip->i_id)
+ nchstats.ncs_falsehits++;
+ else if (*cp == '/' || docache) {
dp = ncp->nc_ip;
if (dp == NULL)
panic("nami: null cache ino");
dp = ncp->nc_ip;
if (dp == NULL)
panic("nami: null cache ino");
- if (pdp != dp) {
- ilock(dp);
+ else if (dp->i_count) {
+ ilock(dp);
+ iunlock(pdp);
+ } else {
+ igrab(dp);
+ iunlock(pdp);
+ }
u.u_dent.d_ino = dp->i_number;
/* u_dent.d_reclen is garbage ... */
goto haveino;
u.u_dent.d_ino = dp->i_number;
/* u_dent.d_reclen is garbage ... */
goto haveino;
+ } else
+ nchstats.ncs_badhits++;
- * last segment and we are renaming or deleting
- * or otherwise don't want cache entry to exist
+ * Last component and we are renaming or deleting,
+ * the cache entry is invalid, or otherwise don't
+ * want cache entry to exist.
- nchstats.ncs_badhits++;
-
/* remove from LRU chain */
*ncp->nc_prev = ncp->nc_nxt;
if (ncp->nc_nxt)
/* remove from LRU chain */
*ncp->nc_prev = ncp->nc_nxt;
if (ncp->nc_nxt)
/* remove from hash chain */
remque(ncp);
/* remove from hash chain */
remque(ncp);
- /* release ref on the inode */
- irele(ncp->nc_ip);
- ncp->nc_ip = NULL;
-
/* insert at head of LRU list (first to grab) */
ncp->nc_nxt = nchhead;
ncp->nc_prev = &nchhead;
/* insert at head of LRU list (first to grab) */
ncp->nc_nxt = nchhead;
ncp->nc_prev = &nchhead;
* all other cases where making a cache entry would be wrong
* have already departed from the code sequence somewhere above.
*/
* all other cases where making a cache entry would be wrong
* have already departed from the code sequence somewhere above.
*/
- if (bcmp(u.u_dent.d_name, ".", 2) != 0 && !isdotdot && docache) {
if (ncp != NULL)
panic("nami: duplicating cache");
if (ncp != NULL)
panic("nami: duplicating cache");
/* remove from old hash chain */
remque(ncp);
/* remove from old hash chain */
remque(ncp);
- /* drop hold on inode (if we had one) */
- if (ncp->nc_ip)
- irele(ncp->nc_ip);
-
/* grab the inode we just found */
ncp->nc_ip = dp;
/* grab the inode we just found */
ncp->nc_ip = dp;
/* fill in cache info */
ncp->nc_ino = pdp->i_number; /* parents inum */
ncp->nc_dev = pdp->i_dev; /* & device */
ncp->nc_idev = dp->i_dev; /* our device */
/* fill in cache info */
ncp->nc_ino = pdp->i_number; /* parents inum */
ncp->nc_dev = pdp->i_dev; /* & device */
ncp->nc_idev = dp->i_dev; /* our device */
+ ncp->nc_id = dp->i_id; /* identifier */
ncp->nc_nlen = u.u_dent.d_namlen;
bcopy(u.u_dent.d_name, ncp->nc_name, ncp->nc_nlen);
ncp->nc_nlen = u.u_dent.d_namlen;
bcopy(u.u_dent.d_name, ncp->nc_name, ncp->nc_nlen);
-/* ufs_vnops.c 6.6 84/05/24 */
+/* ufs_vnops.c 6.7 84/06/27 */
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/param.h"
#include "../h/systm.h"
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
if (error == 0) {
dirbuf.dotdot_ino = dp->i_number;
+ dp->i_id = ++nextinodeid;
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}
(void) rdwri(UIO_WRITE, ip, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, 1, (int *)0);
}