summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bushnell <thomas@gnu.org>1996-08-29 20:14:18 +0000
committerThomas Bushnell <thomas@gnu.org>1996-08-29 20:14:18 +0000
commit2729a2406f00c668611d0151b142d97d3607e599 (patch)
treef37a13c8423c948aca7d1fb8a01ad62e43daa2b4
parente2b96cec147bc4258e019bb3f16d6ca9d03234ab (diff)
*** empty log message ***
-rw-r--r--ufs/ChangeLog21
-rw-r--r--ufs/dir.c53
-rw-r--r--ufs/inode.c1
-rw-r--r--ufs/ufs.h2
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 <thomas@gnu.ai.mit.edu>
+
+ * 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 <thomas@gnu.ai.mit.edu>
+
+ * 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 <thomas@gnu.ai.mit.edu>
+
+ * 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 <thomas@gnu.ai.mit.edu>
* 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;