[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; |