From 2729a2406f00c668611d0151b142d97d3607e599 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Thu, 29 Aug 1996 20:14:18 +0000 Subject: *** empty log message *** --- ufs/ChangeLog | 21 +++++++++++++++++++++ ufs/dir.c | 53 +++++++++++++++++++++++++++++++++++++++++------------ ufs/inode.c | 1 + ufs/ufs.h | 2 ++ 4 files changed, 65 insertions(+), 12 deletions(-) diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 2b964cf9..934c9856 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,24 @@ +Thu Aug 29 16:07:07 1996 Thomas Bushnell, n/BSG + + * dir.c (diskfs_lookup_hard): When setting ds->stat to EXTEND, set + ds->idx by looking at the size of the file. (IDX itself is no + longer at the end because of the change on Aug 16 1996.) + +Wed Aug 28 12:15:15 1996 Thomas Bushnell, n/BSG + + * dir.c (dirscanblock): Size dirents correctly when mallocing it. + (diskfs_direnter_hard): Be more careful when sizing or resizing + dirents. Correctly set to -1 all the new entries we create after + realloc call. + +Fri Aug 16 18:51:31 1996 Thomas Bushnell, n/BSG + + * ufs.h (struct disknode): New member `dir_idx'. + * inode.c (diskfs_cached_lookup): Initialize DN->dir_idx. + * dir.c (diskfs_lookup_hard): After successful dirscanblock, + record index where we finished in DP->dn->dir_idx. Start searches + at that index. + Mon Aug 12 13:43:46 1996 Thomas Bushnell, n/BSG * hyper.c (diskfs_set_hypermetadata): Bother to return 0 at end of diff --git a/ufs/dir.c b/ufs/dir.c index d015a6c6..397481d0 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -111,7 +111,8 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, vm_address_t buf = 0; vm_size_t buflen = 0; int blockaddr; - int idx; + int idx, lastidx; + int looped; if ((type == REMOVE) || (type == RENAME)) assert (npp); @@ -156,18 +157,39 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; - for (blockaddr = buf, idx = 0; - blockaddr - buf < dp->dn_stat.st_size; - blockaddr += DIRBLKSIZ, idx++) + /* Start the lookup at DP->dn->dir_idx. */ + idx = dp->dn->dir_idx; + if (idx * DIRBLKSIZ > dp->dn_stat.st_size) + idx = 0; /* just in case */ + blockaddr = buf + idx * DIRBLKSIZ; + looped = (idx == 0); + lastidx = idx; + if (lastidx == 0) + lastidx = dp->dn_stat.st_size / DIRBLKSIZ; + + while (!looped || idx < lastidx) { err = dirscanblock (blockaddr, dp, idx, name, namelen, type, ds, &inum); if (!err) - break; + { + dp->dn->dir_idx = idx; + break; + } if (err != ENOENT) { vm_deallocate (mach_task_self (), buf, buflen); return err; } + + blockaddr += DIRBLKSIZ; + idx++; + if (blockaddr - buf >= dp->dn_stat.st_size && !looped) + { + /* We've gotten to the end; start back at the beginning */ + looped = 1; + blockaddr = buf; + idx = 0; + } } if (!diskfs_check_readonly ()) @@ -258,7 +280,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, /* We didn't find any room, so mark ds to extend the dir */ ds->type = CREATE; ds->stat = EXTEND; - ds->idx = idx; + ds->idx = dp->dn_stat.st_size / DIRBLKSIZ; } /* Return to the user; if we can't, release the reference @@ -422,8 +444,8 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, down how many entries there were. */ if (!dp->dn->dirents) { - dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ + 1) - * sizeof (int)); + dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) + * sizeof (int)); for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; } @@ -595,19 +617,26 @@ diskfs_direnter_hard(struct node *dp, } else { + int i; /* It's cheap, so start a count here even if we aren't counting anything at all. */ if (dp->dn->dirents) { dp->dn->dirents = realloc (dp->dn->dirents, - (ds->idx + 1) * sizeof (int)); + (dp->dn_stat.st_size / DIRBLKSIZ + * sizeof (int))); + for (i = oldsize / DIRBLKSIZ; + i < dp->dn_stat.st_size / DIRBLKSIZ; + i++) + dp->dn->dirents[i] = -1; + dp->dn->dirents[ds->idx] = 1; } else { - int i; - dp->dn->dirents = malloc ((ds->idx + 1) * sizeof (int)); - for (i = 0; i < ds->idx; i++) + dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ + * sizeof (int)); + for (i = 0; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; dp->dn->dirents[ds->idx] = 1; } diff --git a/ufs/inode.c b/ufs/inode.c index ae323a8c..b06cb8d4 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -69,6 +69,7 @@ diskfs_cached_lookup (int inum, struct node **npp) dn->number = inum; dn->dirents = 0; + dn->dir_idx = 0; rwlock_init (&dn->allocptrlock); dn->dirty = 0; diff --git a/ufs/ufs.h b/ufs/ufs.h index ea13475e..f4b36ea5 100644 --- a/ufs/ufs.h +++ b/ufs/ufs.h @@ -36,6 +36,8 @@ struct disknode { ino_t number; + int dir_idx; + /* For a directory, this array holds the number of directory entries in each DIRBLKSIZE piece of the directory. */ int *dirents; -- cgit v1.2.3