[Libsysio-commit] cplant: libsysio/drivers/yod fs_yod.c
Brought to you by:
lward
|
From: Ruth K. <rk...@us...> - 2003-07-24 22:53:00
|
Update of /cvsroot/libsysio/libsysio/drivers/yod
In directory sc8-pr-cvs1:/tmp/cvs-serv19555/drivers/yod
Modified Files:
Tag: cplant
fs_yod.c
Log Message:
Add capability of checking inode generation numbers,
if a field for it exists in the stat struct.
Bug fix for unlink/creat failure:
Changes allow re-use of an inode which is no longer in use, but
still exists in the inode cache. If the stat info for the new use
matches cached info, the inode is re-used. If not, the old inode is
marked 'zombie' and removed from the inode cache to make way for
the new inode.
Index: fs_yod.c
===================================================================
RCS file: /cvsroot/libsysio/libsysio/drivers/yod/Attic/fs_yod.c,v
retrieving revision 1.1.2.5
retrieving revision 1.1.2.6
diff -u -w -b -B -p -r1.1.2.5 -r1.1.2.6
--- fs_yod.c 12 Jun 2003 19:48:37 -0000 1.1.2.5
+++ fs_yod.c 24 Jul 2003 22:52:57 -0000 1.1.2.6
@@ -126,6 +126,9 @@ do {
struct yod_inode_identifier {
dev_t dev; /* device number */
ino_t ino; /* i-number */
+#ifdef HAVE_GENERATION
+ unsigned int gen; /* generation number */
+#endif
};
/*
@@ -281,8 +284,12 @@ yod_i_new(struct filesys *fs, struct int
nino = malloc(sizeof(struct yod_inode));
if (!nino)
return NULL;
+ bzero(&nino->ni_ident, sizeof(nino->ni_ident));
nino->ni_ident.dev = buf->st_dev;
nino->ni_ident.ino = buf->st_ino;
+#ifdef HAVE_GENERATION
+ nino->ni_ident.gen = buf->st_gen;
+#endif
nino->ni_fileid.fid_data = &nino->ni_ident;
nino->ni_fileid.fid_len = sizeof(nino->ni_ident);
nino->ni_fd = -1;
@@ -468,6 +475,27 @@ yod_fsswop_mount(const char *source,
}
/*
+ * Validate passed in inode against stat struct info
+ */
+static int
+yod_i_validate(struct inode *inop, struct intnl_stat stbuf)
+{
+ struct yod_inode *nino = I2NI(inop);
+
+ if ((nino->ni_ident.dev == stbuf.st_dev &&
+ nino->ni_ident.ino == stbuf.st_ino &&
+#ifdef HAVE_GENERATION
+ nino->ni_ident.gen == stbuf.st_gen &&
+#endif
+ ((inop)->i_mode & stbuf.st_mode) == (inop)->i_mode) &&
+ (!(S_ISCHR((inop)->i_mode) || S_ISBLK((inop)->i_mode)) ||
+ (inop)->i_rdev == stbuf.st_rdev))
+ return 0;
+
+ return 1;
+}
+
+/*
* Find, and validate, or create i-node by host-relative path. Returned i-node
* is referenced.
*/
@@ -496,11 +524,7 @@ yod_iget(struct filesys *fs,
* Validate?
*/
if (*inop) {
- struct yod_inode *nino = I2NI(*inop);
-
- if (nino->ni_ident.dev == stbuf.st_dev &&
- nino->ni_ident.ino == stbuf.st_ino &&
- ((*inop)->i_mode & stbuf.st_mode) == (*inop)->i_mode)
+ if (!yod_i_validate(*inop, stbuf))
return 0;
/*
* Invalidate.
@@ -511,24 +535,40 @@ yod_iget(struct filesys *fs,
/*
* I-node is not already known. Find or create it.
*/
+ bzero(&ident, sizeof(ident));
ident.dev = stbuf.st_dev;
ident.ino = stbuf.st_ino;
+#ifdef HAVE_GENERATION
+ ident.gen = stbuf.st_gen;
+#endif
fileid.fid_data = &ident;
fileid.fid_len = sizeof(ident);
ino = _sysio_i_find(fs, stbuf.st_ino, &fileid);
-
- if (!ino) {
- ino = yod_i_new(fs, &stbuf);
- if (!ino)
- err = -ENOMEM;
- } else if (forced) {
+ if (ino && forced) {
/*
* Insertion was forced but it's already present!
*/
+ if (yod_i_validate(ino, stbuf)) {
+ /*
+ * Cached inode has stale attrs
+ * make way for the new one
+ */
I_RELE(ino);
- err = -EEXIST;
+ _sysio_i_undead(ino);
+ ino = NULL;
+ } else
+ /*
+ * OK to reuse cached inode
+ */
+ goto out;
}
+ if (!ino) {
+ ino = yod_i_new(fs, &stbuf);
+ if (!ino)
+ err = -ENOMEM;
+ }
+out:
if (!err)
*inop = ino;
return err;
|