[Libsysio-commit] HEAD: libsysio/drivers/native fs_native.c
Brought to you by:
lward
From: Ruth K. <rk...@us...> - 2003-07-26 05:21:22
|
Update of /cvsroot/libsysio/libsysio/drivers/native In directory sc8-pr-cvs1:/tmp/cvs-serv25000/drivers/native Modified Files: fs_native.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_native.c =================================================================== RCS file: /cvsroot/libsysio/libsysio/drivers/native/fs_native.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -w -b -B -p -r1.11 -r1.12 --- fs_native.c 23 Apr 2003 18:18:38 -0000 1.11 +++ fs_native.c 25 Jul 2003 14:45:34 -0000 1.12 @@ -151,6 +151,9 @@ do { struct native_inode_identifier { dev_t dev; /* device number */ ino_t ino; /* i-number */ +#ifdef HAVE_GENERATION + unsigned int gen; /* generation number */ +#endif }; /* @@ -310,8 +313,12 @@ native_i_new(struct filesys *fs, struct nino = malloc(sizeof(struct native_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; @@ -496,6 +503,27 @@ native_fsswop_mount(const char *source, return err; } +static int +native_i_validate(struct inode *inop, struct intnl_stat stbuf) +{ + /* + * Validate passed in inode against stat struct info + */ + struct native_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. @@ -525,11 +553,7 @@ native_iget(struct filesys *fs, * Validate? */ if (*inop) { - struct native_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 (!native_i_validate(*inop, stbuf)) return 0; /* * Invalidate. @@ -540,23 +564,40 @@ native_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 = native_i_new(fs, &stbuf); - if (!ino) - err = -ENOMEM; - } else if (forced) { + if (ino && forced) { /* * Insertion was forced but it's already present! */ + if (native_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 = native_i_new(fs, &stbuf); + if (!ino) + err = -ENOMEM; + } +out: if (!err) *inop = ino; return err; |