From 7efd71c161dd5fd099ec65db51c4b6fe972ffe90 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 21 Jun 1994 17:44:54 +0000 Subject: Initial revision --- ufs/dir.c | 861 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 861 insertions(+) create mode 100644 ufs/dir.c (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c new file mode 100644 index 00000000..d088778e --- /dev/null +++ b/ufs/dir.c @@ -0,0 +1,861 @@ +/* Directory management routines + Copyright (C) 1994 Free Software Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "ufs.h" +#include "dir.h" + +#include +#include + +enum slot_status +{ + /* This means we haven't yet found room for a new entry. */ + LOOKING, + + /* This means that the specified entry is free and should be used. */ + TAKE, + + /* This means that the specified entry has enough room at the end + to hold the new entry. */ + SHRINK, + + /* This means that there is enough space in the block, but not in + any one single entry, so they all have to be shifted to make + room. */ + COMPRESS, + + /* This means that the directory will have to be grown to hold the + entry. */ + EXTEND, + + /* For removal and rename, this means that this is the location + of the entry found. */ + HERE_TIS, +}; + +struct dirstat +{ + /* Type of followp operation expected */ + enum lookup_type type; + + /* One of the statuses above */ + enum slot_status stat; + + /* Mapped address and length of directory */ + vm_address_t mapbuf; + vm_size_t mapextent; + + /* Index of this directory block. */ + int idx; + + /* For stat COMPRESS, this is the address (inside mapbuf) + of the first direct in the directory block to be compressed. */ + /* For stat HERE_TIS, SHRINK, and TAKE, this is the entry referenced. */ + struct direct *entry; + + /* For stat HERE_TIS, type REMOVE, this is the address of the immediately + previous direct in this directory block, or zero if this is the first. */ + struct direct *preventry; +}; + +size_t diskfs_dirstat_size = sizeof (struct dirstat); + +static error_t +dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, + int namelen, enum lookup_type type, struct dirstat *ds, + ino_t *inum); + +/* Implement the diskfs_lookup from the diskfs library. See + for the interface specification. */ +error_t +diskfs_lookup (struct node *dp, char *name, enum lookup_type type, + struct node **npp, struct dirstat *ds, struct protid *cred) +{ + error_t err; + ino_t inum; + int namelen; + int spec_dotdot; + struct node *np = 0; + int retry_dotdot = 0; + memory_object_t memobj; + vm_address_t buf; + vm_size_t buflen; + int blockaddr; + int idx; + + if (npp) + *npp = 0; + + spec_dotdot = type & SPEC_DOTDOT; + type &= ~SPEC_DOTDOT; + + namelen = strlen (name); + + if (!S_ISDIR (dp->dn_stat.st_mode)) + return ENOTDIR; + err = diskfs_access (dp, S_IEXEC, cred); + if (err) + return err; + + try_again: + if (ds) + { + ds->type = LOOKUP; + ds->mapbuf = 0; + ds->mapextent = 0; + } + if (ds && (type == CREATE || type == RENAME)) + ds->stat = LOOKING; + + /* Map in the directory contents. */ + memobj = diskfs_get_filemap (dp); + mach_port_insert_right (mach_task_self (), memobj, memobj, + MACH_MSG_TYPE_MAKE_SEND); + buf = 0; + /* We allow extra space in case we have to do an EXTEND. */ + buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); + if (type == LOOKUP) + /* Map read-only; we won't be writing */ + err = vm_map (mach_task_self (), &buf, buflen, 0, 1, memobj, 0, 0, + VM_PROT_READ, VM_PROT_READ, 0); + else + err = vm_map (mach_task_self (), &buf, buflen, 0, 1, memobj, 0, 0, + VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0); + mach_port_deallocate (mach_task_self (), memobj); + + inum = 0; + + for (blockaddr = buf, idx = 0; + blockaddr - buf < dp->dn_stat.st_size; + blockaddr += DIRBLKSIZ, idx++) + { + err = dirscanblock (blockaddr, dp, idx, name, namelen, type, ds, &inum); + if (!err) + break; + if (err != ENOENT) + { + vm_deallocate (mach_task_self (), buf, buflen); + return err; + } + } + + /* If err is set here, it's ENOENT, and we don't want to + think about that as an error yet. */ + err = 0; + + if (inum) + { + if (namelen != 2 || name[0] != '.' || name[1] != '.') + { + if (inum == dp->dn->number) + { + np = dp; + diskfs_nref (np); + } + else + { + err = iget (inum, &np); + if (err) + goto out; + } + } + + /* We are looking up .. */ + /* Check to see if this is the root of the filesystem. */ + else if (dp->dn->number == 2) + { + err = EAGAIN; + goto out; + } + + /* We can't just do iget, because we would then deadlock. + So we do this. Ick. */ + else if (retry_dotdot) + { + /* Check to see that we got the same answer as last time. */ + if (inum != retry_dotdot) + { + /* Drop what we *thought* was .. (but isn't any more) and + try *again*. */ + diskfs_nput (np); + mutex_unlock (&dp->lock); + err = iget (inum, &np); + mutex_lock (&dp->lock); + if (err) + goto out; + retry_dotdot = inum; + goto try_again; + } + /* Otherwise, we got it fine and np is already set properly. */ + } + else if (!spec_dotdot) + { + /* Lock them in the proper order, and then + repeat the directory scan to see if this is still + right. */ + mutex_unlock (&dp->lock); + err = iget (inum, &np); + mutex_lock (&dp->lock); + if (err) + goto out; + retry_dotdot = inum; + goto try_again; + } + + /* Here below are the spec dotdot cases. */ + else if (type == RENAME || type == REMOVE) + np = ifind (inum); + + else if (type == LOOKUP) + { + diskfs_nput (dp); + err = iget (inum, &np); + if (err) + goto out; + } + else + assert (0); + } + + /* If we will be modifying the directory, make sure it's allowed. */ + if (type == RENAME + || (type == REMOVE && np) + || (type == CREATE && !np)) + { + err = diskfs_checkdirmod (dp, np, cred); + if (err) + goto out; + } + + if ((type == CREATE || type == RENAME) && !np && ds && ds->type == LOOKING) + { + /* We didn't find any room, so mark ds to extend the dir */ + ds->type = CREATE; + ds->stat = EXTEND; + ds->idx = idx; + } + + /* Return to the user; if we can't, release the reference + (and lock) we acquired above. */ + out: + /* Deallocate or save the mapping. */ + if ((err && err != ENOENT) + || !ds + || ds->type == LOOKUP) + vm_deallocate (mach_task_self (), buf, buflen); + else + { + ds->mapbuf = buf; + ds->mapextent = buflen; + } + + if (np) + { + if (err || !npp) + { + if (!spec_dotdot) + { + /* Normal case */ + if (np == dp) + diskfs_nrele (np); + else + diskfs_nput (np); + } + else if (type == RENAME || type == REMOVE) + /* We just did ifind to get np; that allocates + no new references, so we don't have anything to do */ + ; + else if (type == LOOKUP) + /* We did iget */ + diskfs_nput (np); + } + else if (npp) + *npp = np; + } + + return err ? : np ? 0 : ENOENT; +} + +/* Scan block at address BLKADDR (of node DP; block index IDX), for + name NAME of length NAMELEN. Args TYPE, DS are as for + diskfs_lookup. If found, set *INUM to the inode number, else + return ENOENT. */ +static error_t +dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, + int namelen, enum lookup_type type, + struct dirstat *ds, ino_t *inum) +{ + int nfree = 0; + int needed = 0; + int countup = 0; + vm_address_t currentoff, prevoff; + struct direct *entry; + int nentries = 0; + + if (ds && ds->stat == LOOKING) + { + countup = 1; + needed = DIRSIZ (namelen); + } + + for (currentoff = blockaddr, prevoff = blockaddr; + currentoff < blockaddr + DIRBLKSIZ; + prevoff = currentoff, currentoff += entry->d_reclen) + { + entry = (struct direct *)currentoff; + + if (!entry->d_reclen + || entry->d_reclen % 4 + || entry->d_namlen > MAXNAMLEN + || currentoff + entry->d_reclen > blockaddr + DIRBLKSIZ + || entry->d_name[entry->d_namlen] + || DIRSIZ (entry->d_namlen) > entry->d_reclen + || memchr (entry->d_name, '\0', entry->d_namlen)) + { + fprintf (stderr, "Bad directory entry: inode: %ld offset: %d\n", + dp->dn->number, currentoff - blockaddr); + return ENOENT; + } + + if (countup) + { + int thisfree; + + if (entry->d_ino == 0) + thisfree = entry->d_reclen; + else + thisfree = entry->d_reclen - DIRSIZ (entry->d_namlen); + + if (thisfree >= needed) + { + ds->type = CREATE; + ds->stat = entry->d_ino == 0 ? TAKE : SHRINK; + ds->entry = entry; + ds->idx = idx; + countup = 0; + } + else + { + nfree += thisfree; + if (nfree >= needed) + { + ds->type = CREATE; + ds->stat = COMPRESS; + ds->entry = (struct direct *) blockaddr; + ds->idx = idx; + countup = 0; + } + } + } + + if (entry->d_ino) + nentries++; + + if (entry->d_namlen == namelen + && entry->d_name[0] == name[0] + && entry->d_ino + && !bcmp (entry->d_name, name, namelen)) + break; + } + + if (currentoff >= blockaddr + DIRBLKSIZ) + { + int i; + /* The name is not in this block. */ + + /* Because we scanned the entire block, we should write + down how many entries there were. */ + if (!dp->dn->dirents) + { + dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ + 1) + * sizeof (int)); + for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) + dp->dn->dirents[i] = -1; + } + /* Make sure the count is correct if there is one now. */ + assert (dp->dn->dirents[idx] == -1 + || dp->dn->dirents[idx] == nentries); + dp->dn->dirents[idx] = nentries; + + return ENOENT; + } + + /* We have found the required name. */ + + if (ds && type == CREATE) + ds->type = LOOKUP; /* it's invalid now */ + else if (ds && (type == REMOVE || type == RENAME)) + { + ds->type = type; + ds->stat = HERE_TIS; + ds->entry = entry; + ds->idx = idx; + ds->preventry = (struct direct *) prevoff; + } + + *inum = entry->d_ino; + return 0; +} + +/* Following a lookup call for CREATE, this adds a node to a directory. + DP is the directory to be modified; NAME is the name to be entered; + NP is the node being linked in; DS is the cached information returned + by lookup; CRED describes the user making the call. This call may + only be made if the directory has been held locked continuously since + the preceding lookup call, and only if that call returned ENOENT. */ +error_t +diskfs_direnter(struct node *dp, + char *name, + struct node *np, + struct dirstat *ds, + struct protid *cred) +{ + struct direct *new; + int namelen = strlen (name); + int needed = DIRSIZ (namelen); + int oldneeded; + vm_address_t fromoff, tooff; + int totfreed; + error_t err; + + assert (ds->type == CREATE); + + switch (ds->stat) + { + case TAKE: + /* We are supposed to consume this slot. */ + assert (ds->entry->d_ino == 0 && ds->entry->d_reclen >= needed); + + ds->entry->d_ino = np->dn->number; + ds->entry->d_namlen = namelen; + bcopy (name, ds->entry->d_name, namelen + 1); + + break; + + case SHRINK: + /* We are supposed to take the extra space at the end + of this slot. */ + oldneeded = DIRSIZ (ds->entry->d_namlen); + assert (ds->entry->d_reclen - oldneeded >= needed); + + new = (struct direct *) ((vm_address_t) ds->entry + oldneeded); + + new->d_ino = np->dn->number; + new->d_reclen = ds->entry->d_reclen - oldneeded; + new->d_namlen = namelen; + bcopy (name, new->d_name, namelen + 1); + + ds->entry->d_reclen = oldneeded; + + break; + + case COMPRESS: + /* We are supposed to move all the entries to the + front of the block, giving each the minimum + necessary room. This should free up enough space + for the new entry. */ + fromoff = tooff = (vm_address_t) ds->entry; + + while (fromoff < (vm_address_t) ds->entry + DIRBLKSIZ) + { + struct direct *from = (struct direct *)fromoff; + struct direct *to = (struct direct *) tooff; + int fromreclen = from->d_reclen; + + if (from->d_ino != 0) + { + assert (fromoff >= tooff); + + bcopy (from, to, fromreclen); + to->d_reclen = DIRSIZ (to->d_namlen); + + tooff += to->d_reclen; + } + fromoff += fromreclen; + } + + totfreed = (vm_address_t) ds->entry + DIRBLKSIZ - tooff; + assert (totfreed >= needed); + + new = (struct direct *) tooff; + new->d_ino = np->dn->number; + new->d_reclen = totfreed; + new->d_namlen = namelen; + bcopy (name, new->d_name, namelen + 1); + break; + + case EXTEND: + /* Extend the file. */ + while (dp->dn_stat.st_size + DIRBLKSIZ > dp->allocsize) + if (err = diskfs_grow (dp, dp->dn_stat.st_size + DIRBLKSIZ, cred)) + { + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + return err; + } + + new = (struct direct *) (ds->mapbuf + dp->dn_stat.st_size); + + dp->dn_stat.st_size += DIRBLKSIZ; + dp->dn_set_ctime = 1; + + new->d_ino = np->dn->number; + new->d_reclen = DIRBLKSIZ; + new->d_namlen = namelen; + bcopy (name, new->d_name, namelen + 1); + break; + + default: + assert (0); + } + + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + + if (ds->stat != EXTEND) + { + /* If we are keeping count of this block, then keep the count up + to date. */ + if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) + dp->dn->dirents[ds->idx]++; + } + else + { + /* 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->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[i] = -1; + dp->dn->dirents[ds->idx] = 1; + } + } + + diskfs_file_update (dp, 1); + + if (dp->dirmod_reqs) + diskfs_notice_dirchange (dp, DIR_CHANGED_NEW, name); + + return 0; +} + +/* Following a lookup call for REMOVE, this removes the link from the + directory. DP is the directory being changed and DS is the cached + information returned from lookup. This call is only valid if the + directory has been locked continously since the call to lookup, and + only if that call succeeded. */ +error_t +diskfs_dirremove(struct node *dp, + struct dirstat *ds) +{ + assert (ds->type == REMOVE); + assert (ds->stat == HERE_TIS); + + if (ds->preventry == 0) + ds->entry->d_ino = 0; + else + { + assert ((vm_address_t )ds->entry - (vm_address_t)ds->preventry + == ds->preventry->d_reclen); + ds->preventry->d_reclen += ds->entry->d_reclen; + } + + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + + /* If we are keeping count of this block, then keep the count up + to date. */ + if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) + dp->dn->dirents[ds->idx]--; + + diskfs_file_update (dp, 1); + + if (dp->dirmod_reqs) + diskfs_notice_dirchange (dp, DIR_CHANGED_UNLINK, ds->entry->d_name); + + return 0; +} + + +/* Following a lookup call for RENAME, this changes the inode number + on a directory entry. DP is the directory being changed; NP is + the new node being linked in; DP is the cached information returned + by lookup. This call is only valid if the directory has been locked + continuously since the call to lookup, and only if that call + succeeded. */ +error_t +diskfs_dirrewrite(struct node *dp, + struct node *np, + struct dirstat *ds) +{ + assert (ds->type == RENAME); + assert (ds->stat == HERE_TIS); + + ds->entry->d_ino = np->dn->number; + + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + + diskfs_file_update (dp, 1); + + if (dp->dirmod_reqs) + diskfs_notice_dirchange (dp, DIR_CHANGED_RENUMBER, ds->entry->d_name); + + return 0; +} + +/* Tell if DP is an empty directory (has only "." and ".." entries). */ +/* This routine must be called from inside a catch_exception (). */ +int +diskfs_dirempty(struct node *dp, + struct protid *cred) +{ + struct direct *entry; + int curoff; + vm_address_t buf; + memory_object_t memobj; + error_t err; + + memobj = diskfs_get_filemap (dp); + mach_port_insert_right (mach_task_self (), memobj, memobj, + MACH_MSG_TYPE_MAKE_SEND); + buf = 0; + + err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, + 1, memobj, 0, 0, VM_PROT_READ, VM_PROT_READ, 0); + mach_port_deallocate (mach_task_self (), memobj); + assert (!err); + + for (curoff = buf; + curoff < buf + dp->dn_stat.st_size; + curoff += entry->d_reclen) + { + entry = (struct direct *) curoff; + + if (entry->d_ino != 0 + && (entry->d_namlen > 2 + || entry->d_name[0] != '.' + || (entry->d_name[1] != '.' + && entry->d_name[1] != '\0'))) + { + vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + return 0; + } + } + vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + return 1; +} + +/* Make DS an invalid dirstat. */ +error_t +diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) +{ + if (ds->type != LOOKUP) + { + assert (ds->mapbuf); + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + ds->type = LOOKUP; + } + return 0; +} + + +/* Count the entries in directory block NB for directory DP and + write the answer down in its dirents array. As a side affect + fill BUF with the block. */ +static error_t +count_dirents (struct node *dp, int nb, char *buf) +{ + int amt; + char *offinblk; + struct direct *entry; + int count = 0; + error_t err; + + assert (dp->dn->dirents); + assert ((nb + 1) * DIRBLKSIZ <= dp->dn_stat.st_size); + + err = diskfs_node_rdwr (dp, buf, nb * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &amt); + if (err) + return err; + assert (amt == DIRBLKSIZ); + + for (offinblk = buf; + offinblk < buf + DIRBLKSIZ; + offinblk += entry->d_reclen) + { + entry = (struct direct *) offinblk; + if (entry->d_ino) + count++; + } + + assert (dp->dn->dirents[nb] == -1 || dp->dn->dirents[nb] == count); + dp->dn->dirents[nb] = count; + return 0; +} + +/* Implement the disikfs_get_directs callback as described in + . */ +error_t +diskfs_get_directs (struct node *dp, + int entry, + int nentries, + char **data, + u_int *datacnt, + vm_size_t bufsiz, + int *amt) +{ + int blkno; + int nblks; + int curentry; + char buf[DIRBLKSIZ]; + char *bufp; + int bufvalid; + error_t err; + int i; + char *datap; + struct direct *entryp; + int allocsize; + int checklen; + + nblks = dp->dn_stat.st_size/DIRBLKSIZ; + + if (!dp->dn->dirents) + { + dp->dn->dirents = malloc (nblks * sizeof (int)); + for (i = 0; i < nblks; i++) + dp->dn->dirents[i] = -1; + } + + /* Allocate enough space to hold the maximum we might return */ + if (!bufsiz || bufsiz > dp->dn_stat.st_size) + allocsize = round_page (dp->dn_stat.st_size); + else + allocsize = round_page (bufsiz); + + if (allocsize > *datacnt) + vm_allocate (mach_task_self (), (vm_address_t *) data, allocsize, 1); + + /* Scan through the entries to find ENTRY. If we encounter + a -1 in the process then stop to fill it. When we run + off the end, ENTRY is too big. */ + curentry = 0; + bufvalid = 0; + for (blkno = 0; blkno < nblks; blkno++) + { + if (dp->dn->dirents[blkno] == -1) + { + err = count_dirents (dp, blkno, buf); + if (err) + return err; + bufvalid = 1; + } + + if (curentry + dp->dn->dirents[blkno] > entry) + /* ENTRY starts in this block. */ + break; + + curentry += dp->dn->dirents[blkno]; + + bufvalid = 0; + } + + if (blkno == nblks) + { + *datacnt = 0; + *amt = 0; + return 0; + } + + /* Set bufp appropriately */ + bufp = buf; + if (curentry != entry) + { + /* Look through the block to find out where to start, + setting bufp appropriately. */ + if (!bufvalid) + { + err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, + 0, 0, &checklen); + if (err) + return err; + assert (checklen == DIRBLKSIZ); + bufvalid = 1; + } + for (i = 0, bufp = buf; + i < entry - curentry && bufp - buf < DIRBLKSIZ; + bufp += ((struct direct *)bufp)->d_reclen, i++) + ; + /* Make sure we didn't run off the end. */ + assert (bufp - buf < DIRBLKSIZ); + } + + i = 0; + datap = *data; + + /* Copy the entries, one at a time. */ + while (((nentries == -1) || (i < nentries)) + && (!bufsiz || (datap - *data < bufsiz) ) + && blkno < nblks) + { + if (!bufvalid) + { + err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, + 0, 0, &checklen); + if (err) + return err; + assert (checklen == DIRBLKSIZ); + bufvalid = 1; + bufp = buf; + } + + entryp = (struct direct *)bufp; + + if (entryp->d_ino) + { + bcopy (bufp, datap, DIRSIZ (entryp->d_namlen)); + i++; + datap += DIRSIZ (entryp->d_namlen); + } + + bufp += entryp->d_reclen; + if (bufp - buf == DIRBLKSIZ) + { + blkno++; + bufvalid = 0; + } + } + + /* We've copied all we can. If we allocated our own array + but didn't fill all of it, then free whatever memory we didn't use. */ + if (allocsize > *datacnt) + { + if (round_page (datap - *data) < allocsize) + vm_deallocate (mach_task_self (), + (vm_address_t) (*data + round_page (datap - *data)), + allocsize - round_page (datap - *data)); + } + + /* Set variables for return */ + *datacnt = datap - *data; + *amt = i; + return 0; +} -- cgit v1.2.3 From 0188170d4e1ab74f3f0d1bb439de263beed1df2e Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 6 Jul 1994 18:47:34 +0000 Subject: Formerly dir.c.~20~ --- ufs/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index d088778e..62bf3302 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -312,7 +312,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, needed = DIRSIZ (namelen); } - for (currentoff = blockaddr, prevoff = blockaddr; + for (currentoff = blockaddr, prevoff = 0; currentoff < blockaddr + DIRBLKSIZ; prevoff = currentoff, currentoff += entry->d_reclen) { @@ -575,7 +575,7 @@ diskfs_dirremove(struct node *dp, ds->entry->d_ino = 0; else { - assert ((vm_address_t )ds->entry - (vm_address_t)ds->preventry + assert ((vm_address_t) ds->entry - (vm_address_t) ds->preventry == ds->preventry->d_reclen); ds->preventry->d_reclen += ds->entry->d_reclen; } -- cgit v1.2.3 From b98b3ceaa0eb2636ae351c69eaafece9d51ac6fa Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 11 Jul 1994 22:14:23 +0000 Subject: Formerly dir.c.~21~ --- ufs/dir.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 62bf3302..c67d2ee1 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -832,6 +832,7 @@ diskfs_get_directs (struct node *dp, if (entryp->d_ino) { bcopy (bufp, datap, DIRSIZ (entryp->d_namlen)); + ((struct direct *)bufp)->d_reclen = DIRSIZ (entryp->d_namlen); i++; datap += DIRSIZ (entryp->d_namlen); } -- cgit v1.2.3 From 260c89b51118b7f7e8d0119bd86c38e5fb9462de Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Jul 1994 17:05:43 +0000 Subject: Formerly dir.c.~22~ --- ufs/dir.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index c67d2ee1..9cbb42d5 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -320,11 +320,11 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, if (!entry->d_reclen || entry->d_reclen % 4 - || entry->d_namlen > MAXNAMLEN + || DIRECT_NAMLEN (entry) > MAXNAMLEN || currentoff + entry->d_reclen > blockaddr + DIRBLKSIZ - || entry->d_name[entry->d_namlen] - || DIRSIZ (entry->d_namlen) > entry->d_reclen - || memchr (entry->d_name, '\0', entry->d_namlen)) + || entry->d_name[DIRECT_NAMLEN (entry)] + || DIRSIZ (DIRECT_NAMLEN (entry)) > entry->d_reclen + || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { fprintf (stderr, "Bad directory entry: inode: %ld offset: %d\n", dp->dn->number, currentoff - blockaddr); @@ -338,7 +338,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, if (entry->d_ino == 0) thisfree = entry->d_reclen; else - thisfree = entry->d_reclen - DIRSIZ (entry->d_namlen); + thisfree = entry->d_reclen - DIRSIZ (DIRECT_NAMLEN (entry)); if (thisfree >= needed) { @@ -365,7 +365,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, if (entry->d_ino) nentries++; - if (entry->d_namlen == namelen + if (DIRECT_NAMLEN (entry) == namelen && entry->d_name[0] == name[0] && entry->d_ino && !bcmp (entry->d_name, name, namelen)) @@ -441,7 +441,9 @@ diskfs_direnter(struct node *dp, assert (ds->entry->d_ino == 0 && ds->entry->d_reclen >= needed); ds->entry->d_ino = np->dn->number; - ds->entry->d_namlen = namelen; + DIRECT_NAMLEN (ds->entry) = namelen; + if (direct_symlink_extension) + ds->d_type = IFTODT (np->dn->dn_stat.st_mode); bcopy (name, ds->entry->d_name, namelen + 1); break; @@ -449,14 +451,16 @@ diskfs_direnter(struct node *dp, case SHRINK: /* We are supposed to take the extra space at the end of this slot. */ - oldneeded = DIRSIZ (ds->entry->d_namlen); + oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); assert (ds->entry->d_reclen - oldneeded >= needed); new = (struct direct *) ((vm_address_t) ds->entry + oldneeded); new->d_ino = np->dn->number; new->d_reclen = ds->entry->d_reclen - oldneeded; - new->d_namlen = namelen; + DIRECT_NAMLEN (new) = namelen; + if (direct_symlink_extension) + ds->d_type = IFTODT (np->dn->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); ds->entry->d_reclen = oldneeded; @@ -481,7 +485,7 @@ diskfs_direnter(struct node *dp, assert (fromoff >= tooff); bcopy (from, to, fromreclen); - to->d_reclen = DIRSIZ (to->d_namlen); + to->d_reclen = DIRSIZ (DIRECT_NAMLEN (to)); tooff += to->d_reclen; } @@ -494,7 +498,9 @@ diskfs_direnter(struct node *dp, new = (struct direct *) tooff; new->d_ino = np->dn->number; new->d_reclen = totfreed; - new->d_namlen = namelen; + DIRECT_NAMLEN (new) = namelen; + if (direct_symlink_extension) + new->d_type = IFTODT (np->dn->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; @@ -514,7 +520,9 @@ diskfs_direnter(struct node *dp, new->d_ino = np->dn->number; new->d_reclen = DIRBLKSIZ; - new->d_namlen = namelen; + DIRECT_NAMLEN (new) = namelen; + if (direct_symlink_extension) + new->d_type = IFTODT (np->dn->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; @@ -611,6 +619,8 @@ diskfs_dirrewrite(struct node *dp, assert (ds->stat == HERE_TIS); ds->entry->d_ino = np->dn->number; + if (direct_symlink_extension) + ds->entry->d_type = IFTODT (np->dn->dn_stat.st_mode); vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); @@ -651,7 +661,7 @@ diskfs_dirempty(struct node *dp, entry = (struct direct *) curoff; if (entry->d_ino != 0 - && (entry->d_namlen > 2 + && (DIRECT_NAMLEN (entry) > 2 || entry->d_name[0] != '.' || (entry->d_name[1] != '.' && entry->d_name[1] != '\0'))) @@ -831,10 +841,10 @@ diskfs_get_directs (struct node *dp, if (entryp->d_ino) { - bcopy (bufp, datap, DIRSIZ (entryp->d_namlen)); - ((struct direct *)bufp)->d_reclen = DIRSIZ (entryp->d_namlen); + bcopy (bufp, datap, DIRSIZ (DIRECT_NAMLEN (entryp))); + ((struct direct *)bufp)->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); i++; - datap += DIRSIZ (entryp->d_namlen); + datap += DIRSIZ (DIRECT_NAMLEN (entryp)); } bufp += entryp->d_reclen; -- cgit v1.2.3 From 7490c7f6549dd620ffc24f396b6fd36151ba0f58 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 15 Jul 1994 17:28:01 +0000 Subject: Formerly dir.c.~23~ --- ufs/dir.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 9cbb42d5..7c793d84 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -326,7 +326,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, || DIRSIZ (DIRECT_NAMLEN (entry)) > entry->d_reclen || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { - fprintf (stderr, "Bad directory entry: inode: %ld offset: %d\n", + fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", dp->dn->number, currentoff - blockaddr); return ENOENT; } @@ -443,7 +443,7 @@ diskfs_direnter(struct node *dp, ds->entry->d_ino = np->dn->number; DIRECT_NAMLEN (ds->entry) = namelen; if (direct_symlink_extension) - ds->d_type = IFTODT (np->dn->dn_stat.st_mode); + ds->entry->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, ds->entry->d_name, namelen + 1); break; @@ -460,7 +460,7 @@ diskfs_direnter(struct node *dp, new->d_reclen = ds->entry->d_reclen - oldneeded; DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) - ds->d_type = IFTODT (np->dn->dn_stat.st_mode); + new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); ds->entry->d_reclen = oldneeded; @@ -500,7 +500,7 @@ diskfs_direnter(struct node *dp, new->d_reclen = totfreed; DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) - new->d_type = IFTODT (np->dn->dn_stat.st_mode); + new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; @@ -522,7 +522,7 @@ diskfs_direnter(struct node *dp, new->d_reclen = DIRBLKSIZ; DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) - new->d_type = IFTODT (np->dn->dn_stat.st_mode); + new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; @@ -620,7 +620,7 @@ diskfs_dirrewrite(struct node *dp, ds->entry->d_ino = np->dn->number; if (direct_symlink_extension) - ds->entry->d_type = IFTODT (np->dn->dn_stat.st_mode); + ds->entry->d_type = IFTODT (np->dn_stat.st_mode); vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); -- cgit v1.2.3 From d9fc33c37a55ac8d84023ac0dd0ddd9e10cd3a4c Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 19 Jul 1994 02:35:07 +0000 Subject: Formerly dir.c.~24~ --- ufs/dir.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 7c793d84..f4bb4c63 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -722,6 +722,16 @@ count_dirents (struct node *dp, int nb, char *buf) return 0; } +/* XXX */ +struct olddirect +{ + u_long d_ino; + u_short d_reclen; + u_short d_namlen; + char d_name[MAXNAMLEN + 1]; +}; + + /* Implement the disikfs_get_directs callback as described in . */ error_t @@ -841,8 +851,22 @@ diskfs_get_directs (struct node *dp, if (entryp->d_ino) { +#ifdef notyet bcopy (bufp, datap, DIRSIZ (DIRECT_NAMLEN (entryp))); - ((struct direct *)bufp)->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); + if (!direct_symlink_extension) + { + /* Fix up fields into new format */ + ((struct direct *)datap)->d_namlen = DIRECT_NAMLEN (entryp); + ((struct direct *)datap)->d_type = DT_UNKNOWN; + } + ((struct direct *)datap)->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); +#else + struct olddirect *userd; + userd = (struct olddirect *)datap; + userd->d_ino = entryp->d_ino; + userd->d_reclen = userd->d_namlen = DIRECT_NAMLEN (entryp); + bcopy (entryp->d_name, userd->d_name, DIRECT_NAMLEN (entryp) + 1); +#endif i++; datap += DIRSIZ (DIRECT_NAMLEN (entryp)); } -- cgit v1.2.3 From 5a92483b8ff9718ef86ada672c7aa244641177f6 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 5 Aug 1994 19:54:21 +0000 Subject: Formerly dir.c.~25~ --- ufs/dir.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index f4bb4c63..a3b0b7f6 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -104,6 +104,9 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, type &= ~SPEC_DOTDOT; namelen = strlen (name); + + if (namelen > MAXNAMLEN) + return ENAMETOOLONG; if (!S_ISDIR (dp->dn_stat.st_mode)) return ENOTDIR; @@ -506,6 +509,8 @@ diskfs_direnter(struct node *dp, case EXTEND: /* Extend the file. */ + assert (needed <= DIRBLKSIZ); + while (dp->dn_stat.st_size + DIRBLKSIZ > dp->allocsize) if (err = diskfs_grow (dp, dp->dn_stat.st_size + DIRBLKSIZ, cred)) { @@ -864,7 +869,8 @@ diskfs_get_directs (struct node *dp, struct olddirect *userd; userd = (struct olddirect *)datap; userd->d_ino = entryp->d_ino; - userd->d_reclen = userd->d_namlen = DIRECT_NAMLEN (entryp); + userd->d_namlen = DIRECT_NAMLEN (entryp); + userd->d_reclen = DIRSIZ (userd->d_namlen); bcopy (entryp->d_name, userd->d_name, DIRECT_NAMLEN (entryp) + 1); #endif i++; -- cgit v1.2.3 From 7923c99c3fb6536f4c7d575ff47becfb63e63d2f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 16 Sep 1994 17:24:59 +0000 Subject: Formerly dir.c.~26~ --- ufs/dir.c | 79 ++++++++++++++++++++++++++------------------------------------- 1 file changed, 32 insertions(+), 47 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index a3b0b7f6..d0bf151d 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -65,11 +65,11 @@ struct dirstat /* For stat COMPRESS, this is the address (inside mapbuf) of the first direct in the directory block to be compressed. */ /* For stat HERE_TIS, SHRINK, and TAKE, this is the entry referenced. */ - struct direct *entry; + struct directory_entry *entry; /* For stat HERE_TIS, type REMOVE, this is the address of the immediately previous direct in this directory block, or zero if this is the first. */ - struct direct *preventry; + struct director_entry *preventry; }; size_t diskfs_dirstat_size = sizeof (struct dirstat); @@ -306,7 +306,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, int needed = 0; int countup = 0; vm_address_t currentoff, prevoff; - struct direct *entry; + struct directory_entry *entry; int nentries = 0; if (ds && ds->stat == LOOKING) @@ -319,7 +319,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, currentoff < blockaddr + DIRBLKSIZ; prevoff = currentoff, currentoff += entry->d_reclen) { - entry = (struct direct *)currentoff; + entry = (struct directory_entry *)currentoff; if (!entry->d_reclen || entry->d_reclen % 4 @@ -358,7 +358,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, { ds->type = CREATE; ds->stat = COMPRESS; - ds->entry = (struct direct *) blockaddr; + ds->entry = (struct directory_entry *) blockaddr; ds->idx = idx; countup = 0; } @@ -407,7 +407,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, ds->stat = HERE_TIS; ds->entry = entry; ds->idx = idx; - ds->preventry = (struct direct *) prevoff; + ds->preventry = (struct directory_entry *) prevoff; } *inum = entry->d_ino; @@ -427,13 +427,14 @@ diskfs_direnter(struct node *dp, struct dirstat *ds, struct protid *cred) { - struct direct *new; + struct directory_entry *new; int namelen = strlen (name); int needed = DIRSIZ (namelen); int oldneeded; vm_address_t fromoff, tooff; int totfreed; error_t err; + off_t newsize; assert (ds->type == CREATE); @@ -457,7 +458,7 @@ diskfs_direnter(struct node *dp, oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); assert (ds->entry->d_reclen - oldneeded >= needed); - new = (struct direct *) ((vm_address_t) ds->entry + oldneeded); + new = (struct directory_entry *) ((vm_address_t) ds->entry + oldneeded); new->d_ino = np->dn->number; new->d_reclen = ds->entry->d_reclen - oldneeded; @@ -479,8 +480,8 @@ diskfs_direnter(struct node *dp, while (fromoff < (vm_address_t) ds->entry + DIRBLKSIZ) { - struct direct *from = (struct direct *)fromoff; - struct direct *to = (struct direct *) tooff; + struct directory_entry *from = (struct directory_entry *)fromoff; + struct directory_entry *to = (struct directory_entry *) tooff; int fromreclen = from->d_reclen; if (from->d_ino != 0) @@ -498,7 +499,7 @@ diskfs_direnter(struct node *dp, totfreed = (vm_address_t) ds->entry + DIRBLKSIZ - tooff; assert (totfreed >= needed); - new = (struct direct *) tooff; + new = (struct directory_entry *) tooff; new->d_ino = np->dn->number; new->d_reclen = totfreed; DIRECT_NAMLEN (new) = namelen; @@ -511,14 +512,15 @@ diskfs_direnter(struct node *dp, /* Extend the file. */ assert (needed <= DIRBLKSIZ); - while (dp->dn_stat.st_size + DIRBLKSIZ > dp->allocsize) - if (err = diskfs_grow (dp, dp->dn_stat.st_size + DIRBLKSIZ, cred)) + newsize = dp->dn_stat.st_size + DIRBLKSIZ; + while (newsize > dp->allocsize) + if (err = diskfs_grow (dp, newsize, cred)) { vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); return err; } - new = (struct direct *) (ds->mapbuf + dp->dn_stat.st_size); + new = (struct directory_entry *) (ds->mapbuf + dp->dn_stat.st_size); dp->dn_stat.st_size += DIRBLKSIZ; dp->dn_set_ctime = 1; @@ -643,7 +645,7 @@ int diskfs_dirempty(struct node *dp, struct protid *cred) { - struct direct *entry; + struct directory_entry *entry; int curoff; vm_address_t buf; memory_object_t memobj; @@ -663,7 +665,7 @@ diskfs_dirempty(struct node *dp, curoff < buf + dp->dn_stat.st_size; curoff += entry->d_reclen) { - entry = (struct direct *) curoff; + entry = (struct directory_entry *) curoff; if (entry->d_ino != 0 && (DIRECT_NAMLEN (entry) > 2 @@ -701,7 +703,7 @@ count_dirents (struct node *dp, int nb, char *buf) { int amt; char *offinblk; - struct direct *entry; + struct directory_entry *entry; int count = 0; error_t err; @@ -717,7 +719,7 @@ count_dirents (struct node *dp, int nb, char *buf) offinblk < buf + DIRBLKSIZ; offinblk += entry->d_reclen) { - entry = (struct direct *) offinblk; + entry = (struct directory_entry *) offinblk; if (entry->d_ino) count++; } @@ -727,16 +729,6 @@ count_dirents (struct node *dp, int nb, char *buf) return 0; } -/* XXX */ -struct olddirect -{ - u_long d_ino; - u_short d_reclen; - u_short d_namlen; - char d_name[MAXNAMLEN + 1]; -}; - - /* Implement the disikfs_get_directs callback as described in . */ error_t @@ -757,10 +749,11 @@ diskfs_get_directs (struct node *dp, error_t err; int i; char *datap; - struct direct *entryp; + struct directory_entry *entryp; int allocsize; int checklen; - + struct dirent *userp; + nblks = dp->dn_stat.st_size/DIRBLKSIZ; if (!dp->dn->dirents) @@ -827,7 +820,7 @@ diskfs_get_directs (struct node *dp, } for (i = 0, bufp = buf; i < entry - curentry && bufp - buf < DIRBLKSIZ; - bufp += ((struct direct *)bufp)->d_reclen, i++) + bufp += ((struct directory_entry *)bufp)->d_reclen, i++) ; /* Make sure we didn't run off the end. */ assert (bufp - buf < DIRBLKSIZ); @@ -852,26 +845,18 @@ diskfs_get_directs (struct node *dp, bufp = buf; } - entryp = (struct direct *)bufp; + entryp = (struct directory_entry *)bufp; if (entryp->d_ino) { + userp = (struct dirent *) datap; + + userp->d_fileno = entryp->d_fileno; + userp->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); + userp->d_namlen = DIRECT_NAMLEN (entryp); + bcopy (entryp->d_name, userp->d_name, DIRECT_NAMLEN (entryp) + 1); #ifdef notyet - bcopy (bufp, datap, DIRSIZ (DIRECT_NAMLEN (entryp))); - if (!direct_symlink_extension) - { - /* Fix up fields into new format */ - ((struct direct *)datap)->d_namlen = DIRECT_NAMLEN (entryp); - ((struct direct *)datap)->d_type = DT_UNKNOWN; - } - ((struct direct *)datap)->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); -#else - struct olddirect *userd; - userd = (struct olddirect *)datap; - userd->d_ino = entryp->d_ino; - userd->d_namlen = DIRECT_NAMLEN (entryp); - userd->d_reclen = DIRSIZ (userd->d_namlen); - bcopy (entryp->d_name, userd->d_name, DIRECT_NAMLEN (entryp) + 1); + userp->d_type = entryp->d_type; #endif i++; datap += DIRSIZ (DIRECT_NAMLEN (entryp)); -- cgit v1.2.3 From 1ea101365f74d5df1372e0360d46cd16a13bc602 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 16 Sep 1994 18:48:26 +0000 Subject: Formerly dir.c.~27~ --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index d0bf151d..35760842 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -330,7 +330,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", - dp->dn->number, currentoff - blockaddr); + dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } -- cgit v1.2.3 From 8f5be4556fc63e831b3ebcf6de5d3515f5b311ed Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 19 Sep 1994 22:14:36 +0000 Subject: Formerly dir.c.~28~ --- ufs/dir.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 35760842..e4d54cdf 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -20,6 +20,9 @@ #include #include +#include + +#undef d_ino enum slot_status { @@ -69,7 +72,7 @@ struct dirstat /* For stat HERE_TIS, type REMOVE, this is the address of the immediately previous direct in this directory block, or zero if this is the first. */ - struct director_entry *preventry; + struct directory_entry *preventry; }; size_t diskfs_dirstat_size = sizeof (struct dirstat); @@ -434,7 +437,7 @@ diskfs_direnter(struct node *dp, vm_address_t fromoff, tooff; int totfreed; error_t err; - off_t newsize; + off_t oldsize; assert (ds->type == CREATE); @@ -512,17 +515,17 @@ diskfs_direnter(struct node *dp, /* Extend the file. */ assert (needed <= DIRBLKSIZ); - newsize = dp->dn_stat.st_size + DIRBLKSIZ; - while (newsize > dp->allocsize) - if (err = diskfs_grow (dp, newsize, cred)) + oldsize = dp->dn_stat.st_size; + while (oldsize + DIRBLKSIZ > dp->allocsize) + if (err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred)) { vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); return err; } - new = (struct directory_entry *) (ds->mapbuf + dp->dn_stat.st_size); + new = (struct directory_entry *) (ds->mapbuf + oldsize); - dp->dn_stat.st_size += DIRBLKSIZ; + dp->dn_stat.st_size = oldsize + DIRBLKSIZ; dp->dn_set_ctime = 1; new->d_ino = np->dn->number; @@ -851,7 +854,7 @@ diskfs_get_directs (struct node *dp, { userp = (struct dirent *) datap; - userp->d_fileno = entryp->d_fileno; + userp->d_fileno = entryp->d_ino; userp->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); userp->d_namlen = DIRECT_NAMLEN (entryp); bcopy (entryp->d_name, userp->d_name, DIRECT_NAMLEN (entryp) + 1); -- cgit v1.2.3 From 661267c4ad4f5724340d5167d2b25f3e26547fb3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 30 Sep 1994 15:25:32 +0000 Subject: Formerly dir.c.~29~ --- ufs/dir.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index e4d54cdf..2f215974 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -858,9 +858,7 @@ diskfs_get_directs (struct node *dp, userp->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); userp->d_namlen = DIRECT_NAMLEN (entryp); bcopy (entryp->d_name, userp->d_name, DIRECT_NAMLEN (entryp) + 1); -#ifdef notyet - userp->d_type = entryp->d_type; -#endif + userp->d_type = DT_UNKNOWN; /* until fixed */ i++; datap += DIRSIZ (DIRECT_NAMLEN (entryp)); } -- cgit v1.2.3 From 1e025ef8df752af1c26ababf60ff96ed38d599d1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Fri, 28 Oct 1994 01:15:47 +0000 Subject: entered into RCS --- ufs/dir.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 2f215974..83eae80d 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -129,8 +129,6 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, /* Map in the directory contents. */ memobj = diskfs_get_filemap (dp); - mach_port_insert_right (mach_task_self (), memobj, memobj, - MACH_MSG_TYPE_MAKE_SEND); buf = 0; /* We allow extra space in case we have to do an EXTEND. */ buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); @@ -655,8 +653,6 @@ diskfs_dirempty(struct node *dp, error_t err; memobj = diskfs_get_filemap (dp); - mach_port_insert_right (mach_task_self (), memobj, memobj, - MACH_MSG_TYPE_MAKE_SEND); buf = 0; err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, -- cgit v1.2.3 From 4c51401dcc09332dae33bc0de3dd9fb7c14627f1 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 8 May 1995 13:32:20 +0000 Subject: (diskfs_lookup): When looping back to try_again: because we're looking up "..", be sure and trash the mapping we made of the directory's pager -- otherwise the reference to the pager never gets dropped and we can never free the node. (diskfs_lookup): ds->type was being compared to LOOKING, which value it can never have. Compare ds->stat against LOOKING instead. --- ufs/dir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 83eae80d..aeaa5abc 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -95,7 +95,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, struct node *np = 0; int retry_dotdot = 0; memory_object_t memobj; - vm_address_t buf; + vm_address_t buf = 0; vm_size_t buflen; int blockaddr; int idx; @@ -124,6 +124,11 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, ds->mapbuf = 0; ds->mapextent = 0; } + if (buf) + { + vm_deallocate (mach_task_self (), buf, buflen); + buf = 0; + } if (ds && (type == CREATE || type == RENAME)) ds->stat = LOOKING; @@ -245,7 +250,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, goto out; } - if ((type == CREATE || type == RENAME) && !np && ds && ds->type == LOOKING) + if ((type == CREATE || type == RENAME) && !np && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ ds->type = CREATE; -- cgit v1.2.3 From 0c65f6707ccf315961f964c55f692e08dd894ac1 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 21 Jun 1995 16:19:57 +0000 Subject: (diskfs_lookup): Provide initialization for BUFLEN. (diskfs_direnter): Move assignment out of if test. --- ufs/dir.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index aeaa5abc..1d7004d8 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994 Free Software Foundation + Copyright (C) 1994, 1995 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -96,7 +96,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, int retry_dotdot = 0; memory_object_t memobj; vm_address_t buf = 0; - vm_size_t buflen; + vm_size_t buflen = 0; int blockaddr; int idx; @@ -520,11 +520,14 @@ diskfs_direnter(struct node *dp, oldsize = dp->dn_stat.st_size; while (oldsize + DIRBLKSIZ > dp->allocsize) - if (err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred)) - { - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - return err; - } + { + err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred); + if (err) + { + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + return err; + } + } new = (struct directory_entry *) (ds->mapbuf + oldsize); -- cgit v1.2.3 From b6d7707a397cec1abccdf558ba180112cd04a149 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 13 Sep 1995 16:30:20 +0000 Subject: (diskfs_lookup): Don't attempt to lock NP if NPP is not set. Don't even set NP if NPP is not set; use INUM as "lookup succeeded flag" instead. Lookups for REMOVE now *must* set NPP. --- ufs/dir.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 1d7004d8..ab98d4bb 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -100,6 +100,9 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, int blockaddr; int idx; + if (type == REMOVE) + assert (npp); + if (npp) *npp = 0; @@ -166,7 +169,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, think about that as an error yet. */ err = 0; - if (inum) + if (inum && npp) { if (namelen != 2 || name[0] != '.' || name[1] != '.') { @@ -242,15 +245,15 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, /* If we will be modifying the directory, make sure it's allowed. */ if (type == RENAME - || (type == REMOVE && np) - || (type == CREATE && !np)) + || (type == REMOVE && inum) + || (type == CREATE && !inum)) { err = diskfs_checkdirmod (dp, np, cred); if (err) goto out; } - if ((type == CREATE || type == RENAME) && !np && ds && ds->stat == LOOKING) + if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ ds->type = CREATE; @@ -274,7 +277,8 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, if (np) { - if (err || !npp) + assert (npp); + if (err) { if (!spec_dotdot) { @@ -292,11 +296,11 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, /* We did iget */ diskfs_nput (np); } - else if (npp) + else *npp = np; } - return err ? : np ? 0 : ENOENT; + return err ? : inum ? 0 : ENOENT; } /* Scan block at address BLKADDR (of node DP; block index IDX), for -- cgit v1.2.3 From 639d32ce79bfb66727ccefd136cfb5f3486d79ec Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 13 Sep 1995 16:38:40 +0000 Subject: (diskfs_lookup): Require NPP set for RENAME too. --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index ab98d4bb..ff79cc1e 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -100,7 +100,7 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, int blockaddr; int idx; - if (type == REMOVE) + if ((type == REMOVE) || (type == RENAME)) assert (npp); if (npp) -- cgit v1.2.3 From 99e1a1cbb3b4cb72e794d48735280a106c28f1c8 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Thu, 19 Oct 1995 20:23:12 +0000 Subject: (diskfs_lookup, diskfs_dirempty): Give diskfs_get_filemap a protection arg. --- ufs/dir.c | 15 ++++++--------- ufs/sizes.c | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index ff79cc1e..f8150d64 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -95,6 +95,8 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, struct node *np = 0; int retry_dotdot = 0; memory_object_t memobj; + vm_prot_t prot = + (type == LOOKUP) ? VM_PROT_READ : (VM_PROT_READ | VM_PROT_WRITE); vm_address_t buf = 0; vm_size_t buflen = 0; int blockaddr; @@ -136,17 +138,12 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, ds->stat = LOOKING; /* Map in the directory contents. */ - memobj = diskfs_get_filemap (dp); + memobj = diskfs_get_filemap (dp, prot); buf = 0; /* We allow extra space in case we have to do an EXTEND. */ buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); - if (type == LOOKUP) - /* Map read-only; we won't be writing */ - err = vm_map (mach_task_self (), &buf, buflen, 0, 1, memobj, 0, 0, - VM_PROT_READ, VM_PROT_READ, 0); - else - err = vm_map (mach_task_self (), &buf, buflen, 0, 1, memobj, 0, 0, - VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0); + err = vm_map (mach_task_self (), + &buf, buflen, 0, 1, memobj, 0, 0, prot, prot, 0); mach_port_deallocate (mach_task_self (), memobj); inum = 0; @@ -664,7 +661,7 @@ diskfs_dirempty(struct node *dp, memory_object_t memobj; error_t err; - memobj = diskfs_get_filemap (dp); + memobj = diskfs_get_filemap (dp, VM_PROT_READ); buf = 0; err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, diff --git a/ufs/sizes.c b/ufs/sizes.c index f4f81393..0dadac28 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -101,7 +101,7 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); - obj = diskfs_get_filemap (np); + obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); poke_pages (obj, round_page (length), round_page (np->allocsize)); mach_port_deallocate (mach_task_self (), obj); pager_flush_some (upi->p, round_page (length), @@ -588,7 +588,7 @@ diskfs_grow (struct node *np, { mach_port_t obj; - obj = diskfs_get_filemap (np); + obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); poke_pages (obj, trunc_page (poke_off), round_page (poke_off + poke_len)); mach_port_deallocate (mach_task_self (), obj); -- cgit v1.2.3 From 4c972b4fb48bdb7e8177bd56b6e4b412c01ebb73 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 9 Nov 1995 19:19:06 +0000 Subject: (struct dirstat): New member `nbytes'. (dirscanblock): If DS->type is COMPRESS, still look for TAKE/SHRINK possibilities. Also, if it's COMPRESS, still look to see if the current block can be compressed with fewer byte copies. --- ufs/dir.c | 58 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index f8150d64..5906cb01 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -73,6 +73,10 @@ struct dirstat /* For stat HERE_TIS, type REMOVE, this is the address of the immediately previous direct in this directory block, or zero if this is the first. */ struct directory_entry *preventry; + + /* For stat COMPRESS, this is the number of bytes needed to be copied + in order to undertake the compression. */ + size_t nbytes; }; size_t diskfs_dirstat_size = sizeof (struct dirstat); @@ -311,17 +315,22 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, { int nfree = 0; int needed = 0; - int countup = 0; vm_address_t currentoff, prevoff; - struct directory_entry *entry; + struct directory_entry *entry = 0; int nentries = 0; - - if (ds && ds->stat == LOOKING) + size_t nbytes = 0; + int looking = 0; + int countcopies = 0; + int consider_compress = 0; + + if (ds && (ds->stat == LOOKING + || ds->stat == COMPRESS)) { - countup = 1; + looking = 1; + countcopies = 1; needed = DIRSIZ (namelen); } - + for (currentoff = blockaddr, prevoff = 0; currentoff < blockaddr + DIRBLKSIZ; prevoff = currentoff, currentoff += entry->d_reclen) @@ -341,35 +350,41 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, return ENOENT; } - if (countup) + if (looking || countcopies) { int thisfree; + /* Count how much free space this entry has in it. */ if (entry->d_ino == 0) thisfree = entry->d_reclen; else thisfree = entry->d_reclen - DIRSIZ (DIRECT_NAMLEN (entry)); + + /* If this isn't at the front of the block, then it will + have to be copied if we do a compression; count the + number of bytes there too. */ + if (countcopies && currentoff != blockaddr) + nbytes += DIRSIZ (DIRECT_NAMLEN (entry)); + if (ds->stat == COMPRESS && nbytes > ds->nbytes) + /* The previously found compress is better than + this one, so don't bother counting any more. */ + countcopies = 0; + if (thisfree >= needed) { ds->type = CREATE; ds->stat = entry->d_ino == 0 ? TAKE : SHRINK; ds->entry = entry; ds->idx = idx; - countup = 0; + looking = countcopies = 0; } else { nfree += thisfree; if (nfree >= needed) - { - ds->type = CREATE; - ds->stat = COMPRESS; - ds->entry = (struct directory_entry *) blockaddr; - ds->idx = idx; - countup = 0; - } - } + consider_compress = 1; + } } if (entry->d_ino) @@ -382,6 +397,17 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, break; } + if (consider_compress + && (ds->type == LOOKING + || (ds->type == COMPRESS && ds->nbytes > nbytes))) + { + ds->type = CREATE; + ds->stat = COMPRESS; + ds->entry = (struct directory_entry *) blockaddr; + ds->idx = idx; + ds->nbytes = nbytes; + } + if (currentoff >= blockaddr + DIRBLKSIZ) { int i; -- cgit v1.2.3 From 748c574a54af4bbc87e548b6f6bb8cfddccb6ccf Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Thu, 14 Dec 1995 18:14:33 +0000 Subject: (diskfs_lookup): If we are returning an error, then set the dirstat to be ignored by drop_dirstat. --- ufs/dir.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 5906cb01..b2147007 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -269,7 +269,11 @@ diskfs_lookup (struct node *dp, char *name, enum lookup_type type, if ((err && err != ENOENT) || !ds || ds->type == LOOKUP) - vm_deallocate (mach_task_self (), buf, buflen); + { + vm_deallocate (mach_task_self (), buf, buflen); + if (ds) + ds->type = LOOKUP; /* set to be ignored by drop_dirstat */ + } else { ds->mapbuf = buf; -- cgit v1.2.3 From e802372ce7210fe006b9207f810bc274d3dd9ff3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 20 Mar 1996 19:36:27 +0000 Subject: (diskfs_dirrewrite_hard): Renamed from diskfs_dirrewrite. No longer call modification tracking routines. (diskfs_dirremove_hard): Renamed from diskfs_dirremove. No longer call modification tracking routines. (diskfs_direnter_hard): Renamed from diskfs_direnter. No longer call modification tracking routines. (diskfs_lookup_hard): Renamed from diskfs_lookup. --- ufs/dir.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index b2147007..16364071 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995 Free Software Foundation + Copyright (C) 1994, 1995, 1996 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -89,8 +89,8 @@ dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, /* Implement the diskfs_lookup from the diskfs library. See for the interface specification. */ error_t -diskfs_lookup (struct node *dp, char *name, enum lookup_type type, - struct node **npp, struct dirstat *ds, struct protid *cred) +diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, + struct node **npp, struct dirstat *ds, struct protid *cred) { error_t err; ino_t inum; @@ -458,11 +458,11 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, only be made if the directory has been held locked continuously since the preceding lookup call, and only if that call returned ENOENT. */ error_t -diskfs_direnter(struct node *dp, - char *name, - struct node *np, - struct dirstat *ds, - struct protid *cred) +diskfs_direnter_hard(struct node *dp, + char *name, + struct node *np, + struct dirstat *ds, + struct protid *cred) { struct directory_entry *new; int namelen = strlen (name); @@ -608,9 +608,6 @@ diskfs_direnter(struct node *dp, diskfs_file_update (dp, 1); - if (dp->dirmod_reqs) - diskfs_notice_dirchange (dp, DIR_CHANGED_NEW, name); - return 0; } @@ -620,8 +617,8 @@ diskfs_direnter(struct node *dp, directory has been locked continously since the call to lookup, and only if that call succeeded. */ error_t -diskfs_dirremove(struct node *dp, - struct dirstat *ds) +diskfs_dirremove_hard(struct node *dp, + struct dirstat *ds) { assert (ds->type == REMOVE); assert (ds->stat == HERE_TIS); @@ -644,9 +641,6 @@ diskfs_dirremove(struct node *dp, diskfs_file_update (dp, 1); - if (dp->dirmod_reqs) - diskfs_notice_dirchange (dp, DIR_CHANGED_UNLINK, ds->entry->d_name); - return 0; } @@ -658,9 +652,9 @@ diskfs_dirremove(struct node *dp, continuously since the call to lookup, and only if that call succeeded. */ error_t -diskfs_dirrewrite(struct node *dp, - struct node *np, - struct dirstat *ds) +diskfs_dirrewrite_hard(struct node *dp, + struct node *np, + struct dirstat *ds) { assert (ds->type == RENAME); assert (ds->stat == HERE_TIS); @@ -673,9 +667,6 @@ diskfs_dirrewrite(struct node *dp, diskfs_file_update (dp, 1); - if (dp->dirmod_reqs) - diskfs_notice_dirchange (dp, DIR_CHANGED_RENUMBER, ds->entry->d_name); - return 0; } -- cgit v1.2.3 From a14a84d7bfba8c138367a433cc6f562895ce5b54 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 20 Mar 1996 21:02:17 +0000 Subject: (diskfs_lookup_hard): Don't do initial permission checking here. --- ufs/dir.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 16364071..73ed5f02 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -120,12 +120,6 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, if (namelen > MAXNAMLEN) return ENAMETOOLONG; - if (!S_ISDIR (dp->dn_stat.st_mode)) - return ENOTDIR; - err = diskfs_access (dp, S_IEXEC, cred); - if (err) - return err; - try_again: if (ds) { -- cgit v1.2.3 From 4591952861c94f2ae928ac560753b14283aac365 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 20 Mar 1996 21:13:17 +0000 Subject: (diskfs_lookup_hard): Don't do final permission checking here. --- ufs/dir.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 73ed5f02..843735c2 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -238,16 +238,6 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, assert (0); } - /* If we will be modifying the directory, make sure it's allowed. */ - if (type == RENAME - || (type == REMOVE && inum) - || (type == CREATE && !inum)) - { - err = diskfs_checkdirmod (dp, np, cred); - if (err) - goto out; - } - if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ -- cgit v1.2.3 From 612d539a3edb9ab67412c0df900dd459da8525de Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 25 Mar 1996 18:08:16 +0000 Subject: (diskfs_null_dirstat): New function. --- ufs/dir.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 843735c2..8fb2b39b 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -81,6 +81,14 @@ struct dirstat size_t diskfs_dirstat_size = sizeof (struct dirstat); +/* The user must define this function. Initialize DS such that + diskfs_drop_dirstat will ignore it. */ +void +diskfs_null_dirstat (struct dirstat *ds) +{ + ds->type = LOOKUP; +} + static error_t dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, int namelen, enum lookup_type type, struct dirstat *ds, -- cgit v1.2.3 From 2eb9f242fcddff34edf23c1dac966da7d2dda419 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 25 Mar 1996 18:08:40 +0000 Subject: (diskfs_null_dirstat): doc fix --- ufs/dir.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 8fb2b39b..e5c2e6e2 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -81,8 +81,7 @@ struct dirstat size_t diskfs_dirstat_size = sizeof (struct dirstat); -/* The user must define this function. Initialize DS such that - diskfs_drop_dirstat will ignore it. */ +/* Initialize DS such that diskfs_drop_dirstat will ignore it. */ void diskfs_null_dirstat (struct dirstat *ds) { -- cgit v1.2.3 From 4cd22ece29676a8581764de37c9be07e4b68d87f Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 3 Apr 1996 21:07:50 +0000 Subject: (diskfs_lookup_hard): --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index e5c2e6e2..0a109c0c 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -182,7 +182,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } else { - err = iget (inum, &np); + err = diskfs_cached_lookup (inum, &np); if (err) goto out; } -- cgit v1.2.3 From 85ae67dbee7e957c859144a1e09cba5a38275568 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Wed, 3 Apr 1996 21:08:58 +0000 Subject: (diskfs_lookup_hard): --- ufs/dir.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 0a109c0c..136b470f 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -196,7 +196,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, goto out; } - /* We can't just do iget, because we would then deadlock. + /* We can't just do diskfs_cached_lookup, because we would then deadlock. So we do this. Ick. */ else if (retry_dotdot) { @@ -207,7 +207,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, try *again*. */ diskfs_nput (np); mutex_unlock (&dp->lock); - err = iget (inum, &np); + err = diskfs_cached_lookup (inum, &np); mutex_lock (&dp->lock); if (err) goto out; @@ -222,7 +222,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, repeat the directory scan to see if this is still right. */ mutex_unlock (&dp->lock); - err = iget (inum, &np); + err = diskfs_cached_lookup (inum, &np); mutex_lock (&dp->lock); if (err) goto out; @@ -237,7 +237,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, else if (type == LOOKUP) { diskfs_nput (dp); - err = iget (inum, &np); + err = diskfs_cached_lookup (inum, &np); if (err) goto out; } @@ -289,7 +289,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, no new references, so we don't have anything to do */ ; else if (type == LOOKUP) - /* We did iget */ + /* We did diskfs_cached_lookup */ diskfs_nput (np); } else -- cgit v1.2.3 From f8849fe3bc59296bee95db4a5b13a1275edaf2e5 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 16 Apr 1996 19:35:27 +0000 Subject: (diskfs_lookup_hard): Set atime appropriately, and sync the new atime if we are running synchronously (!). (diskfs_dirempty): Likewise. (diskfs_direnter_hard): Set mtime appropriately. (diskfs_dirremove_hard): Likewise. (diskfs_dirrewrite_hard): Likewise. --- ufs/dir.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 136b470f..67b3645e 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -153,6 +153,9 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, inum = 0; + if (!diskfs_readonly) + dp->dn_set_atime = 1; + for (blockaddr = buf, idx = 0; blockaddr - buf < dp->dn_stat.st_size; blockaddr += DIRBLKSIZ, idx++) @@ -167,6 +170,11 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } } + if (!diskfs_readonly) + dp->dn_set_atime = 1; + if (diskfs_synchronous) + diskfs_node_update (dp, 1); + /* If err is set here, it's ENOENT, and we don't want to think about that as an error yet. */ err = 0; @@ -466,6 +474,8 @@ diskfs_direnter_hard(struct node *dp, assert (ds->type == CREATE); + dp->dn_set_mtime = 1; + switch (ds->stat) { case TAKE: @@ -568,6 +578,8 @@ diskfs_direnter_hard(struct node *dp, assert (0); } + dp->dn_set_mtime = 1; + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); if (ds->stat != EXTEND) @@ -614,6 +626,8 @@ diskfs_dirremove_hard(struct node *dp, assert (ds->type == REMOVE); assert (ds->stat == HERE_TIS); + dp->dn_set_mtime = 1; + if (ds->preventry == 0) ds->entry->d_ino = 0; else @@ -623,6 +637,8 @@ diskfs_dirremove_hard(struct node *dp, ds->preventry->d_reclen += ds->entry->d_reclen; } + dp->dn_set_mtime = 1; + vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); /* If we are keeping count of this block, then keep the count up @@ -650,9 +666,11 @@ diskfs_dirrewrite_hard(struct node *dp, assert (ds->type == RENAME); assert (ds->stat == HERE_TIS); + dp->dn_set_mtime = 1; ds->entry->d_ino = np->dn->number; if (direct_symlink_extension) ds->entry->d_type = IFTODT (np->dn_stat.st_mode); + dp->dn_set_mtime = 1; vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); @@ -681,6 +699,9 @@ diskfs_dirempty(struct node *dp, mach_port_deallocate (mach_task_self (), memobj); assert (!err); + if (!diskfs_readonly) + dp->dn_set_atime = 1; + for (curoff = buf; curoff < buf + dp->dn_stat.st_size; curoff += entry->d_reclen) @@ -694,9 +715,17 @@ diskfs_dirempty(struct node *dp, && entry->d_name[1] != '\0'))) { vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + if (!diskfs_readonly) + dp->dn_set_atime = 1; + if (diskfs_synchronous) + node_update (dp, 1); return 0; } } + if (!diskfs_readonly) + dp->dn_set_atime = 1; + if (diskfs_synchronous) + node_update (dp, 1); vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); return 1; } -- cgit v1.2.3 From 1f5db073a1c103fc54f9568c53d3d0c17fd32767 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 23 Apr 1996 18:35:14 +0000 Subject: (diskfs_dirempty): node_update -> diskfs_node_update. --- ufs/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 67b3645e..ed7ac212 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -718,14 +718,14 @@ diskfs_dirempty(struct node *dp, if (!diskfs_readonly) dp->dn_set_atime = 1; if (diskfs_synchronous) - node_update (dp, 1); + diskfs_node_update (dp, 1); return 0; } } if (!diskfs_readonly) dp->dn_set_atime = 1; if (diskfs_synchronous) - node_update (dp, 1); + diskfs_node_update (dp, 1); vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); return 1; } -- cgit v1.2.3 From d233bdfd39e968e4cffc9af6b21ba2f4ce24df22 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Tue, 14 May 1996 12:57:14 +0000 Subject: foo. --- devio/MAKEDEV | 18 ++++++++++++---- ufs/dir.c | 66 +++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 51 insertions(+), 33 deletions(-) (limited to 'ufs/dir.c') diff --git a/devio/MAKEDEV b/devio/MAKEDEV index bf5217dc..d992d06a 100644 --- a/devio/MAKEDEV +++ b/devio/MAKEDEV @@ -18,19 +18,28 @@ for I; do console|tty[0-9]?|tty[0-9a-f]) $ST $I /hurd/term $_CWD/$I device $I;; null) - $ST $I /hurd/null ;; + $ST $I /hurd/null + chmod 666 $I + ;; zero) - $ST $I /hurd/null -z ;; + $ST $I /hurd/null -z + chmod 666 $I + ;; tty) - $ST $I /hurd/magic tty ;; + $ST $I /hurd/magic tty + chmod 666 $I + ;; fd) $ST $I /hurd/magic fd + chmod 666 $I ln -f -s fd/0 stdin ln -f -s fd/1 stdout ln -f -s fd/2 stderr ;; time) - $ST $I /hurd/devport time ;; + $ST $I /hurd/devport time + chmod 666 $I + ;; # ptys [pt]ty[pqPQ]?) @@ -38,6 +47,7 @@ for I; do ID="`expr substr $I 4 99`" $ST pty$ID /hurd/term $_CWD/pty$ID pty-master $_CWD/tty$ID $ST tty$ID /hurd/term $_CWD/tty$ID pty-slave $_CWD/pty$ID + chmod 666 pty$ID tty$ID ;; [pt]ty[pqPQ]) # Make a bunch of ptys diff --git a/ufs/dir.c b/ufs/dir.c index ed7ac212..9abcdbea 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -336,16 +336,17 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, for (currentoff = blockaddr, prevoff = 0; currentoff < blockaddr + DIRBLKSIZ; - prevoff = currentoff, currentoff += entry->d_reclen) + prevoff = currentoff, currentoff += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *)currentoff; if (!entry->d_reclen - || entry->d_reclen % 4 + || read_disk_entry (entry->d_reclen) % 4 || DIRECT_NAMLEN (entry) > MAXNAMLEN - || currentoff + entry->d_reclen > blockaddr + DIRBLKSIZ + || (currentoff + read_disk_entry (entry->d_reclen) + > blockaddr + DIRBLKSIZ) || entry->d_name[DIRECT_NAMLEN (entry)] - || DIRSIZ (DIRECT_NAMLEN (entry)) > entry->d_reclen + || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", @@ -359,9 +360,10 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, /* Count how much free space this entry has in it. */ if (entry->d_ino == 0) - thisfree = entry->d_reclen; + thisfree = read_disk_entry (entry->d_reclen); else - thisfree = entry->d_reclen - DIRSIZ (DIRECT_NAMLEN (entry)); + thisfree = (read_disk_entry (entry->d_reclen) + - DIRSIZ (DIRECT_NAMLEN (entry))); /* If this isn't at the front of the block, then it will have to be copied if we do a compression; count the @@ -377,7 +379,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, if (thisfree >= needed) { ds->type = CREATE; - ds->stat = entry->d_ino == 0 ? TAKE : SHRINK; + ds->stat = read_disk_entry (entry->d_ino) == 0 ? TAKE : SHRINK; ds->entry = entry; ds->idx = idx; looking = countcopies = 0; @@ -446,7 +448,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, ds->preventry = (struct directory_entry *) prevoff; } - *inum = entry->d_ino; + *inum = read_disk_entry (entry->d_ino); return 0; } @@ -480,9 +482,10 @@ diskfs_direnter_hard(struct node *dp, { case TAKE: /* We are supposed to consume this slot. */ - assert (ds->entry->d_ino == 0 && ds->entry->d_reclen >= needed); + assert (ds->entry->d_ino == 0 + && read_disk_entry (ds->entry->d_reclen) >= needed); - ds->entry->d_ino = np->dn->number; + write_disk_entry (ds->entry->d_ino, np->dn->number); DIRECT_NAMLEN (ds->entry) = namelen; if (direct_symlink_extension) ds->entry->d_type = IFTODT (np->dn_stat.st_mode); @@ -494,18 +497,19 @@ diskfs_direnter_hard(struct node *dp, /* We are supposed to take the extra space at the end of this slot. */ oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); - assert (ds->entry->d_reclen - oldneeded >= needed); + assert (read_disk_entry (ds->entry->d_reclen) - oldneeded >= needed); new = (struct directory_entry *) ((vm_address_t) ds->entry + oldneeded); - new->d_ino = np->dn->number; - new->d_reclen = ds->entry->d_reclen - oldneeded; + write_disk_entry (new->d_ino, np->dn->number); + write_disk_entry (new->d_reclen, + read_disk_entry (ds->entry->d_reclen) - oldneeded); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); - ds->entry->d_reclen = oldneeded; + write_disk_entry (ds->entry->d_reclen, oldneeded); break; @@ -520,16 +524,16 @@ diskfs_direnter_hard(struct node *dp, { struct directory_entry *from = (struct directory_entry *)fromoff; struct directory_entry *to = (struct directory_entry *) tooff; - int fromreclen = from->d_reclen; + int fromreclen = read_disk_entry (from->d_reclen); if (from->d_ino != 0) { assert (fromoff >= tooff); bcopy (from, to, fromreclen); - to->d_reclen = DIRSIZ (DIRECT_NAMLEN (to)); + write_disk_entry (to->d_reclen, DIRSIZ (DIRECT_NAMLEN (to))); - tooff += to->d_reclen; + tooff += read_disk_entry (to->d_reclen); } fromoff += fromreclen; } @@ -538,8 +542,8 @@ diskfs_direnter_hard(struct node *dp, assert (totfreed >= needed); new = (struct directory_entry *) tooff; - new->d_ino = np->dn->number; - new->d_reclen = totfreed; + write_disk_entry (new->d_ino, np->dn->number); + write_disk_entry (new->d_reclen, totfreed); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); @@ -566,8 +570,8 @@ diskfs_direnter_hard(struct node *dp, dp->dn_stat.st_size = oldsize + DIRBLKSIZ; dp->dn_set_ctime = 1; - new->d_ino = np->dn->number; - new->d_reclen = DIRBLKSIZ; + write_disk_entry (new->d_ino, np->dn->number); + write_disk_entry (new->d_reclen, DIRBLKSIZ); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); @@ -633,8 +637,10 @@ diskfs_dirremove_hard(struct node *dp, else { assert ((vm_address_t) ds->entry - (vm_address_t) ds->preventry - == ds->preventry->d_reclen); - ds->preventry->d_reclen += ds->entry->d_reclen; + == read_disk_entry (ds->preventry->d_reclen)); + write_disk_entry (ds->preventry->d_reclen, + (read_disk_entry (ds->preventry->d_reclen) + + read_disk_entry (ds->entry->d_reclen))); } dp->dn_set_mtime = 1; @@ -667,7 +673,7 @@ diskfs_dirrewrite_hard(struct node *dp, assert (ds->stat == HERE_TIS); dp->dn_set_mtime = 1; - ds->entry->d_ino = np->dn->number; + write_disk_entry (ds->entry->d_ino, np->dn->number); if (direct_symlink_extension) ds->entry->d_type = IFTODT (np->dn_stat.st_mode); dp->dn_set_mtime = 1; @@ -704,7 +710,7 @@ diskfs_dirempty(struct node *dp, for (curoff = buf; curoff < buf + dp->dn_stat.st_size; - curoff += entry->d_reclen) + curoff += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *) curoff; @@ -766,7 +772,7 @@ count_dirents (struct node *dp, int nb, char *buf) for (offinblk = buf; offinblk < buf + DIRBLKSIZ; - offinblk += entry->d_reclen) + offinblk += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *) offinblk; if (entry->d_ino) @@ -869,7 +875,9 @@ diskfs_get_directs (struct node *dp, } for (i = 0, bufp = buf; i < entry - curentry && bufp - buf < DIRBLKSIZ; - bufp += ((struct directory_entry *)bufp)->d_reclen, i++) + (bufp + += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), + i++) ; /* Make sure we didn't run off the end. */ assert (bufp - buf < DIRBLKSIZ); @@ -900,7 +908,7 @@ diskfs_get_directs (struct node *dp, { userp = (struct dirent *) datap; - userp->d_fileno = entryp->d_ino; + userp->d_fileno = read_disk_entry (entryp->d_ino); userp->d_reclen = DIRSIZ (DIRECT_NAMLEN (entryp)); userp->d_namlen = DIRECT_NAMLEN (entryp); bcopy (entryp->d_name, userp->d_name, DIRECT_NAMLEN (entryp) + 1); @@ -909,7 +917,7 @@ diskfs_get_directs (struct node *dp, datap += DIRSIZ (DIRECT_NAMLEN (entryp)); } - bufp += entryp->d_reclen; + bufp += read_disk_entry (entryp->d_reclen); if (bufp - buf == DIRBLKSIZ) { blkno++; -- cgit v1.2.3 From f99f473d18563d7167793f9391e73f9c6d802cc3 Mon Sep 17 00:00:00 2001 From: "Michael I. Bushnell" Date: Mon, 24 Jun 1996 21:25:22 +0000 Subject: (diskfs_lookup_hard): Use diskfs_check_readonly instead of diskfs_readonly. (diskfs_dirempty): Likewise. --- ufs/dir.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 9abcdbea..d015a6c6 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -153,7 +153,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, inum = 0; - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; for (blockaddr = buf, idx = 0; @@ -170,7 +170,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, } } - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); @@ -705,7 +705,7 @@ diskfs_dirempty(struct node *dp, mach_port_deallocate (mach_task_self (), memobj); assert (!err); - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; for (curoff = buf; @@ -721,14 +721,14 @@ diskfs_dirempty(struct node *dp, && entry->d_name[1] != '\0'))) { vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); return 0; } } - if (!diskfs_readonly) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); -- cgit v1.2.3 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(-) (limited to 'ufs/dir.c') 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 From 39eaa6a47b81c641181528a1c31e9e01cfffecca Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Mon, 23 Sep 1996 17:24:57 +0000 Subject: (diskfs_direnter_hard): Initialize OLDSIZE to shut up gcc. --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 397481d0..6c44932d 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -494,7 +494,7 @@ diskfs_direnter_hard(struct node *dp, vm_address_t fromoff, tooff; int totfreed; error_t err; - off_t oldsize; + off_t oldsize = 0; assert (ds->type == CREATE); -- cgit v1.2.3 From c6358909aa9e73d34a5da39e3ea945c9c07b9e1a Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Wed, 20 Aug 1997 19:06:42 +0000 Subject: Wed Aug 20 14:34:24 1997 Thomas Bushnell, n/BSG * dir.c (diskfs_lookup_hard): Cope with error return from diskfs_get_filemap. * sizes.c (diskfs_grow): Likewise. * dir.c (diskfs_dirempty): Cope (poorly) with error return from diskfs_get_filemap. * sizes.c (diskfs_truncate): Likewise. (block_extended): Likewise. * pager.c (diskfs_get_filemap): If pager_create fails, return error to caller. --- ufs/ChangeLog | 13 +++++++++++++ ufs/dir.c | 11 ++++++++++- ufs/pager.c | 7 +++++++ ufs/sizes.c | 22 +++++++++++++++++----- 4 files changed, 47 insertions(+), 6 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index ca832c8e..3a225552 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,16 @@ +Wed Aug 20 14:34:24 1997 Thomas Bushnell, n/BSG + + * dir.c (diskfs_lookup_hard): Cope with error return from + diskfs_get_filemap. + * sizes.c (diskfs_grow): Likewise. + * dir.c (diskfs_dirempty): Cope (poorly) with error return from + diskfs_get_filemap. + * sizes.c (diskfs_truncate): Likewise. + (block_extended): Likewise. + + * pager.c (diskfs_get_filemap): If pager_create fails, return + error to caller. + Mon Jun 30 17:38:57 1997 Thomas Bushnell, n/BSG * main.c (main): If the store cannot be made writable, then set diff --git a/ufs/dir.c b/ufs/dir.c index 6c44932d..bdf84be6 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -145,6 +145,10 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, /* Map in the directory contents. */ memobj = diskfs_get_filemap (dp, prot); + + if (memobj == MACH_PORT_NULL) + return errno; + buf = 0; /* We allow extra space in case we have to do an EXTEND. */ buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); @@ -727,6 +731,11 @@ diskfs_dirempty(struct node *dp, error_t err; memobj = diskfs_get_filemap (dp, VM_PROT_READ); + + if (memobj == MACH_PORT_NULL) + /* XXX should reflect error properly */ + return 0; + buf = 0; err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, diff --git a/ufs/pager.c b/ufs/pager.c index afb34839..61695db6 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -569,6 +569,13 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot) diskfs_nref_light (np); upi->p = pager_create (upi, pager_bucket, MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); + if (upi->p == 0) + { + diskfs_nrele_light (np); + free (upi); + spin_unlock (&node2pagelock); + return MACH_PORT_NULL; + } np->dn->fileinfo = upi; right = pager_get_port (np->dn->fileinfo->p); ports_port_deref (np->dn->fileinfo->p); diff --git a/ufs/sizes.c b/ufs/sizes.c index 84c2493d..5c3d12f0 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -1,5 +1,5 @@ /* File growth and truncation - Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation + Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation This file is part of the GNU Hurd. @@ -104,10 +104,14 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); - poke_pages (obj, round_page (length), round_page (np->allocsize)); - mach_port_deallocate (mach_task_self (), obj); - pager_flush_some (upi->p, round_page (length), - np->allocsize - length, 1); + if (obj != MACH_PORT_NULL) + { + /* XXX should cope with errors from diskfs_get_filemap */ + poke_pages (obj, round_page (length), round_page (np->allocsize)); + mach_port_deallocate (mach_task_self (), obj); + pager_flush_some (upi->p, round_page (length), + np->allocsize - length, 1); + } ports_port_deref (upi->p); } @@ -400,6 +404,11 @@ block_extended (struct node *np, /* Map in this part of the file */ mapobj = diskfs_get_filemap (np, VM_PROT_WRITE | VM_PROT_READ); + + /* XXX Should cope with errors from diskfs_get_filemap and back + out the operation here. */ + assert (mapobj); + err = vm_map (mach_task_self (), &mapaddr, round_page (old_size), 0, 1, mapobj, lbn * sblock->fs_bsize, 0, VM_PROT_READ|VM_PROT_WRITE, VM_PROT_READ|VM_PROT_WRITE, 0); @@ -477,6 +486,9 @@ diskfs_grow (struct node *np, /* This reference will ensure that NP->dn->fileinfo stays allocated. */ pagerpt = diskfs_get_filemap (np, VM_PROT_WRITE|VM_PROT_READ); + if (pagerpt == MACH_PORT_NULL) + return errno; + /* The new last block of the file. */ lbn = lblkno (sblock, end - 1); -- cgit v1.2.3 From 0d3ef933e246eb5279b84b2dff6615698428f4c3 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 20 Oct 1998 19:20:07 +0000 Subject: 1998-09-04 Roland McGrath * dir.c (diskfs_lookup_hard): Fix defn with `const'. (diskfs_direnter_hard): Likewise. (dirscanblock): Likewise. * inode.c (diskfs_create_symlink_hook, create_symlink_hook): Likewise. (diskfs_set_translator): Likewise. --- ufs/dir.c | 172 ++++++++++++++++++++++++++++++------------------------------ ufs/inode.c | 98 +++++++++++++++++----------------- 2 files changed, 135 insertions(+), 135 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index bdf84be6..01432829 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -64,8 +64,8 @@ struct dirstat /* Index of this directory block. */ int idx; - - /* For stat COMPRESS, this is the address (inside mapbuf) + + /* For stat COMPRESS, this is the address (inside mapbuf) of the first direct in the directory block to be compressed. */ /* For stat HERE_TIS, SHRINK, and TAKE, this is the entry referenced. */ struct directory_entry *entry; @@ -82,21 +82,21 @@ struct dirstat size_t diskfs_dirstat_size = sizeof (struct dirstat); /* Initialize DS such that diskfs_drop_dirstat will ignore it. */ -void +void diskfs_null_dirstat (struct dirstat *ds) { ds->type = LOOKUP; } -static error_t -dirscanblock (vm_address_t blockoff, struct node *dp, int idx, char *name, - int namelen, enum lookup_type type, struct dirstat *ds, - ino_t *inum); +static error_t +dirscanblock (vm_address_t blockoff, struct node *dp, int idx, + const char *name, int namelen, enum lookup_type type, + struct dirstat *ds, ino_t *inum); /* Implement the diskfs_lookup from the diskfs library. See for the interface specification. */ error_t -diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, +diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, struct node **npp, struct dirstat *ds, struct protid *cred) { error_t err; @@ -113,7 +113,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, int blockaddr; int idx, lastidx; int looped; - + if ((type == REMOVE) || (type == RENAME)) assert (npp); @@ -122,12 +122,12 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, spec_dotdot = type & SPEC_DOTDOT; type &= ~SPEC_DOTDOT; - + namelen = strlen (name); if (namelen > MAXNAMLEN) return ENAMETOOLONG; - + try_again: if (ds) { @@ -157,10 +157,10 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, mach_port_deallocate (mach_task_self (), memobj); inum = 0; - + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; - + /* Start the lookup at DP->dn->dir_idx. */ idx = dp->dn->dir_idx; if (idx * DIRBLKSIZ > dp->dn_stat.st_size) @@ -221,7 +221,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, goto out; } } - + /* We are looking up .. */ /* Check to see if this is the root of the filesystem. */ else if (dp->dn->number == 2) @@ -229,7 +229,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, err = EAGAIN; goto out; } - + /* We can't just do diskfs_cached_lookup, because we would then deadlock. So we do this. Ick. */ else if (retry_dotdot) @@ -263,11 +263,11 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, retry_dotdot = inum; goto try_again; } - + /* Here below are the spec dotdot cases. */ else if (type == RENAME || type == REMOVE) np = ifind (inum); - + else if (type == LOOKUP) { diskfs_nput (dp); @@ -278,7 +278,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, else assert (0); } - + if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir */ @@ -304,7 +304,7 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, ds->mapbuf = buf; ds->mapextent = buflen; } - + if (np) { assert (npp); @@ -338,8 +338,8 @@ diskfs_lookup_hard (struct node *dp, char *name, enum lookup_type type, diskfs_lookup. If found, set *INUM to the inode number, else return ENOENT. */ static error_t -dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, - int namelen, enum lookup_type type, +dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, + const char *name, int namelen, enum lookup_type type, struct dirstat *ds, ino_t *inum) { int nfree = 0; @@ -351,7 +351,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, int looking = 0; int countcopies = 0; int consider_compress = 0; - + if (ds && (ds->stat == LOOKING || ds->stat == COMPRESS)) { @@ -365,11 +365,11 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, prevoff = currentoff, currentoff += read_disk_entry (entry->d_reclen)) { entry = (struct directory_entry *)currentoff; - + if (!entry->d_reclen || read_disk_entry (entry->d_reclen) % 4 || DIRECT_NAMLEN (entry) > MAXNAMLEN - || (currentoff + read_disk_entry (entry->d_reclen) + || (currentoff + read_disk_entry (entry->d_reclen) > blockaddr + DIRBLKSIZ) || entry->d_name[DIRECT_NAMLEN (entry)] || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) @@ -379,16 +379,16 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } - + if (looking || countcopies) { int thisfree; - + /* Count how much free space this entry has in it. */ if (entry->d_ino == 0) thisfree = read_disk_entry (entry->d_reclen); else - thisfree = (read_disk_entry (entry->d_reclen) + thisfree = (read_disk_entry (entry->d_reclen) - DIRSIZ (DIRECT_NAMLEN (entry))); /* If this isn't at the front of the block, then it will @@ -396,9 +396,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, number of bytes there too. */ if (countcopies && currentoff != blockaddr) nbytes += DIRSIZ (DIRECT_NAMLEN (entry)); - + if (ds->stat == COMPRESS && nbytes > ds->nbytes) - /* The previously found compress is better than + /* The previously found compress is better than this one, so don't bother counting any more. */ countcopies = 0; @@ -415,9 +415,9 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, nfree += thisfree; if (nfree >= needed) consider_compress = 1; - } + } } - + if (entry->d_ino) nentries++; @@ -428,7 +428,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, break; } - if (consider_compress + if (consider_compress && (ds->type == LOOKING || (ds->type == COMPRESS && ds->nbytes > nbytes))) { @@ -438,7 +438,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, ds->idx = idx; ds->nbytes = nbytes; } - + if (currentoff >= blockaddr + DIRBLKSIZ) { int i; @@ -448,9 +448,9 @@ 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) + dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) * sizeof (int)); - for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) + for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; } /* Make sure the count is correct if there is one now. */ @@ -460,7 +460,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, return ENOENT; } - + /* We have found the required name. */ if (ds && type == CREATE) @@ -486,7 +486,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, char *name, the preceding lookup call, and only if that call returned ENOENT. */ error_t diskfs_direnter_hard(struct node *dp, - char *name, + const char *name, struct node *np, struct dirstat *ds, struct protid *cred) @@ -496,21 +496,21 @@ diskfs_direnter_hard(struct node *dp, int needed = DIRSIZ (namelen); int oldneeded; vm_address_t fromoff, tooff; - int totfreed; + int totfreed; error_t err; off_t oldsize = 0; assert (ds->type == CREATE); - + dp->dn_set_mtime = 1; switch (ds->stat) { case TAKE: /* We are supposed to consume this slot. */ - assert (ds->entry->d_ino == 0 + assert (ds->entry->d_ino == 0 && read_disk_entry (ds->entry->d_reclen) >= needed); - + write_disk_entry (ds->entry->d_ino, np->dn->number); DIRECT_NAMLEN (ds->entry) = namelen; if (direct_symlink_extension) @@ -518,27 +518,27 @@ diskfs_direnter_hard(struct node *dp, bcopy (name, ds->entry->d_name, namelen + 1); break; - + case SHRINK: /* We are supposed to take the extra space at the end of this slot. */ oldneeded = DIRSIZ (DIRECT_NAMLEN (ds->entry)); assert (read_disk_entry (ds->entry->d_reclen) - oldneeded >= needed); - + new = (struct directory_entry *) ((vm_address_t) ds->entry + oldneeded); write_disk_entry (new->d_ino, np->dn->number); - write_disk_entry (new->d_reclen, + write_disk_entry (new->d_reclen, read_disk_entry (ds->entry->d_reclen) - oldneeded); DIRECT_NAMLEN (new) = namelen; if (direct_symlink_extension) new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); - + write_disk_entry (ds->entry->d_reclen, oldneeded); - + break; - + case COMPRESS: /* We are supposed to move all the entries to the front of the block, giving each the minimum @@ -566,7 +566,7 @@ diskfs_direnter_hard(struct node *dp, totfreed = (vm_address_t) ds->entry + DIRBLKSIZ - tooff; assert (totfreed >= needed); - + new = (struct directory_entry *) tooff; write_disk_entry (new->d_ino, np->dn->number); write_disk_entry (new->d_reclen, totfreed); @@ -579,7 +579,7 @@ diskfs_direnter_hard(struct node *dp, case EXTEND: /* Extend the file. */ assert (needed <= DIRBLKSIZ); - + oldsize = dp->dn_stat.st_size; while (oldsize + DIRBLKSIZ > dp->allocsize) { @@ -603,7 +603,7 @@ diskfs_direnter_hard(struct node *dp, new->d_type = IFTODT (np->dn_stat.st_mode); bcopy (name, new->d_name, namelen + 1); break; - + default: assert (0); } @@ -611,10 +611,10 @@ diskfs_direnter_hard(struct node *dp, dp->dn_set_mtime = 1; vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - + if (ds->stat != EXTEND) { - /* If we are keeping count of this block, then keep the count up + /* If we are keeping count of this block, then keep the count up to date. */ if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) dp->dn->dirents[ds->idx]++; @@ -626,10 +626,10 @@ diskfs_direnter_hard(struct node *dp, anything at all. */ if (dp->dn->dirents) { - dp->dn->dirents = realloc (dp->dn->dirents, + dp->dn->dirents = realloc (dp->dn->dirents, (dp->dn_stat.st_size / DIRBLKSIZ * sizeof (int))); - for (i = oldsize / DIRBLKSIZ; + for (i = oldsize / DIRBLKSIZ; i < dp->dn_stat.st_size / DIRBLKSIZ; i++) dp->dn->dirents[i] = -1; @@ -638,14 +638,14 @@ diskfs_direnter_hard(struct node *dp, } else { - dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ + 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; } } - + diskfs_file_update (dp, 1); return 0; @@ -662,7 +662,7 @@ diskfs_dirremove_hard(struct node *dp, { assert (ds->type == REMOVE); assert (ds->stat == HERE_TIS); - + dp->dn_set_mtime = 1; if (ds->preventry == 0) @@ -671,7 +671,7 @@ diskfs_dirremove_hard(struct node *dp, { assert ((vm_address_t) ds->entry - (vm_address_t) ds->preventry == read_disk_entry (ds->preventry->d_reclen)); - write_disk_entry (ds->preventry->d_reclen, + write_disk_entry (ds->preventry->d_reclen, (read_disk_entry (ds->preventry->d_reclen) + read_disk_entry (ds->entry->d_reclen))); } @@ -684,27 +684,27 @@ diskfs_dirremove_hard(struct node *dp, to date. */ if (dp->dn->dirents && dp->dn->dirents[ds->idx] != -1) dp->dn->dirents[ds->idx]--; - + diskfs_file_update (dp, 1); return 0; } - + /* Following a lookup call for RENAME, this changes the inode number - on a directory entry. DP is the directory being changed; NP is - the new node being linked in; DP is the cached information returned + on a directory entry. DP is the directory being changed; NP is + the new node being linked in; DP is the cached information returned by lookup. This call is only valid if the directory has been locked continuously since the call to lookup, and only if that call succeeded. */ error_t -diskfs_dirrewrite_hard(struct node *dp, +diskfs_dirrewrite_hard(struct node *dp, struct node *np, struct dirstat *ds) { assert (ds->type == RENAME); assert (ds->stat == HERE_TIS); - + dp->dn_set_mtime = 1; write_disk_entry (ds->entry->d_ino, np->dn->number); if (direct_symlink_extension) @@ -712,7 +712,7 @@ diskfs_dirrewrite_hard(struct node *dp, dp->dn_set_mtime = 1; vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); - + diskfs_file_update (dp, 1); return 0; @@ -737,7 +737,7 @@ diskfs_dirempty(struct node *dp, return 0; buf = 0; - + err = vm_map (mach_task_self (), &buf, dp->dn_stat.st_size, 0, 1, memobj, 0, 0, VM_PROT_READ, VM_PROT_READ, 0); mach_port_deallocate (mach_task_self (), memobj); @@ -746,7 +746,7 @@ diskfs_dirempty(struct node *dp, if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; - for (curoff = buf; + for (curoff = buf; curoff < buf + dp->dn_stat.st_size; curoff += read_disk_entry (entry->d_reclen)) { @@ -766,7 +766,7 @@ diskfs_dirempty(struct node *dp, return 0; } } - if (!diskfs_check_readonly ()) + if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); @@ -802,12 +802,12 @@ count_dirents (struct node *dp, int nb, char *buf) assert (dp->dn->dirents); assert ((nb + 1) * DIRBLKSIZ <= dp->dn_stat.st_size); - + err = diskfs_node_rdwr (dp, buf, nb * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &amt); if (err) return err; assert (amt == DIRBLKSIZ); - + for (offinblk = buf; offinblk < buf + DIRBLKSIZ; offinblk += read_disk_entry (entry->d_reclen)) @@ -816,7 +816,7 @@ count_dirents (struct node *dp, int nb, char *buf) if (entry->d_ino) count++; } - + assert (dp->dn->dirents[nb] == -1 || dp->dn->dirents[nb] == count); dp->dn->dirents[nb] = count; return 0; @@ -825,8 +825,8 @@ count_dirents (struct node *dp, int nb, char *buf) /* Implement the disikfs_get_directs callback as described in . */ error_t -diskfs_get_directs (struct node *dp, - int entry, +diskfs_get_directs (struct node *dp, + int entry, int nentries, char **data, u_int *datacnt, @@ -846,7 +846,7 @@ diskfs_get_directs (struct node *dp, int allocsize; int checklen; struct dirent *userp; - + nblks = dp->dn_stat.st_size/DIRBLKSIZ; if (!dp->dn->dirents) @@ -864,7 +864,7 @@ diskfs_get_directs (struct node *dp, if (allocsize > *datacnt) vm_allocate (mach_task_self (), (vm_address_t *) data, allocsize, 1); - + /* Scan through the entries to find ENTRY. If we encounter a -1 in the process then stop to fill it. When we run off the end, ENTRY is too big. */ @@ -885,10 +885,10 @@ diskfs_get_directs (struct node *dp, break; curentry += dp->dn->dirents[blkno]; - + bufvalid = 0; } - + if (blkno == nblks) { *datacnt = 0; @@ -911,15 +911,15 @@ diskfs_get_directs (struct node *dp, assert (checklen == DIRBLKSIZ); bufvalid = 1; } - for (i = 0, bufp = buf; - i < entry - curentry && bufp - buf < DIRBLKSIZ; + for (i = 0, bufp = buf; + i < entry - curentry && bufp - buf < DIRBLKSIZ; (bufp - += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), + += read_disk_entry (((struct directory_entry *)bufp)->d_reclen)), i++) ; /* Make sure we didn't run off the end. */ assert (bufp - buf < DIRBLKSIZ); - } + } i = 0; datap = *data; @@ -931,7 +931,7 @@ diskfs_get_directs (struct node *dp, { if (!bufvalid) { - err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, + err = diskfs_node_rdwr (dp, buf, blkno * DIRBLKSIZ, DIRBLKSIZ, 0, 0, &checklen); if (err) return err; @@ -962,17 +962,17 @@ diskfs_get_directs (struct node *dp, bufvalid = 0; } } - + /* We've copied all we can. If we allocated our own array but didn't fill all of it, then free whatever memory we didn't use. */ if (allocsize > *datacnt) { if (round_page (datap - *data) < allocsize) - vm_deallocate (mach_task_self (), + vm_deallocate (mach_task_self (), (vm_address_t) (*data + round_page (datap - *data)), allocsize - round_page (datap - *data)); } - + /* Set variables for return */ *datacnt = datap - *data; *amt = i; diff --git a/ufs/inode.c b/ufs/inode.c index fe5abbb9..658d6187 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,5 @@ /* Inode management routines - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -44,9 +44,9 @@ inode_init () nodehash[n] = 0; } -/* Fetch inode INUM, set *NPP to the node structure; +/* Fetch inode INUM, set *NPP to the node structure; gain one user reference and lock the node. */ -error_t +error_t diskfs_cached_lookup (int inum, struct node **npp) { struct disknode *dn; @@ -88,7 +88,7 @@ diskfs_cached_lookup (int inum, struct node **npp) spin_unlock (&diskfs_node_refcnt_lock); err = read_disknode (np); - + if (!diskfs_check_readonly () && !np->dn_stat.st_gen) { spin_lock (&gennumberlock); @@ -98,7 +98,7 @@ diskfs_cached_lookup (int inum, struct node **npp) spin_unlock (&gennumberlock); np->dn_set_ctime = 1; } - + if (err) return err; else @@ -114,13 +114,13 @@ struct node * ifind (ino_t inum) { struct node *np; - + spin_lock (&diskfs_node_refcnt_lock); for (np = nodehash[INOHASH(inum)]; np; np = np->dn->hnext) { if (np->dn->number != inum) continue; - + assert (np->references); spin_unlock (&diskfs_node_refcnt_lock); return np; @@ -130,7 +130,7 @@ ifind (ino_t inum) /* The last reference to a node has gone away; drop it from the hash table and clean all state in the dn structure. */ -void +void diskfs_node_norefs (struct node *np) { *np->dn->hprevp = np->dn->hnext; @@ -158,7 +158,7 @@ diskfs_lost_hardrefs (struct node *np) #ifdef notanymore struct port_info *pi; struct pager *p; - + /* Check and see if there is a pager which has only one reference (ours). If so, then drop that reference, breaking the cycle. The complexity in this routine @@ -170,17 +170,17 @@ diskfs_lost_hardrefs (struct node *np) pi = (struct port_info *) np->dn->fileinfo->p; if (pi->refcnt == 1) { - + /* The only way to get a new reference to the pager in this state is to call diskfs_get_filemap; this can't happen as long as we hold NP locked. So we can safely unlock _libports_portrefcntlock for the following call. */ spin_unlock (&_libports_portrefcntlock); - + /* Right now the node is locked with no hard refs; this is an anomolous situation. Before messing with - the reference count on the file pager, we have to + the reference count on the file pager, we have to give ourselves a reference back so that we are really allowed to hold the lock. Then we can do the unreference. */ @@ -216,7 +216,7 @@ read_disknode (struct node *np) struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; - + err = diskfs_catch_exception (); if (err) return err; @@ -232,7 +232,7 @@ read_disknode (struct node *np) st->st_ino = np->dn->number; st->st_gen = read_disk_entry (di->di_gen); st->st_rdev = read_disk_entry(di->di_rdev); - st->st_mode = (((read_disk_entry (di->di_model) + st->st_mode = (((read_disk_entry (di->di_model) | (read_disk_entry (di->di_modeh) << 16)) & ~S_ITRANS) | (di->di_trans ? S_IPTRANS : 0)); @@ -249,11 +249,11 @@ read_disknode (struct node *np) st->st_mtime_usec = read_disk_entry (di->di_mtime.tv_nsec) / 1000; st->st_ctime = read_disk_entry (di->di_ctime.tv_sec); st->st_ctime_usec = read_disk_entry (di->di_ctime.tv_nsec) / 1000; -#endif +#endif st->st_blksize = sblock->fs_bsize; st->st_blocks = read_disk_entry (di->di_blocks); st->st_flags = read_disk_entry (di->di_flags); - + if (sblock->fs_inodefmt < FS_44INODEFMT) { st->st_uid = read_disk_entry (di->di_ouid); @@ -274,8 +274,8 @@ read_disknode (struct node *np) if (!S_ISBLK (st->st_mode) && !S_ISCHR (st->st_mode)) st->st_rdev = 0; - if (S_ISLNK (st->st_mode) - && direct_symlink_extension + if (S_ISLNK (st->st_mode) + && direct_symlink_extension && st->st_size < sblock->fs_maxsymlinklen) np->allocsize = 0; else @@ -319,7 +319,7 @@ write_node (struct node *np) struct stat *st = &np->dn_stat; struct dinode *di = dino (np->dn->number); error_t err; - + assert (!np->dn_set_ctime && !np->dn_set_atime && !np->dn_set_mtime); if (np->dn_stat_dirty) { @@ -328,9 +328,9 @@ write_node (struct node *np) err = diskfs_catch_exception (); if (err) return; - + write_disk_entry (di->di_gen, st->st_gen); - + if (S_ISBLK (st->st_mode) || S_ISCHR (st->st_mode)) write_disk_entry (di->di_rdev, st->st_rdev); @@ -343,7 +343,7 @@ write_node (struct node *np) write_disk_entry (di->di_model, mode & 0xffff); write_disk_entry (di->di_modeh, (mode >> 16) & 0xffff); } - else + else { write_disk_entry (di->di_model, st->st_mode & 0xffff & ~S_ITRANS); di->di_modeh = 0; @@ -354,7 +354,7 @@ write_node (struct node *np) write_disk_entry (di->di_uid, st->st_uid); write_disk_entry (di->di_gid, st->st_gid); } - + if (sblock->fs_inodefmt < FS_44INODEFMT) { write_disk_entry (di->di_ouid, st->st_uid & 0xffff); @@ -376,38 +376,38 @@ write_node (struct node *np) write_disk_entry (di->di_mtime.tv_nsec, st->st_mtime_usec * 1000); write_disk_entry (di->di_ctime.tv_sec, st->st_ctime); write_disk_entry (di->di_ctime.tv_nsec, st->st_ctime_usec * 1000); -#endif +#endif write_disk_entry (di->di_blocks, st->st_blocks); write_disk_entry (di->di_flags, st->st_flags); - + diskfs_end_catch_exception (); np->dn_stat_dirty = 0; record_poke (di, sizeof (struct dinode)); } -} +} /* See if we should create a symlink by writing it directly into the block pointer array. Returning EINVAL tells diskfs to do it the usual way. */ static error_t -create_symlink_hook (struct node *np, char *target) +create_symlink_hook (struct node *np, const char *target) { int len = strlen (target); error_t err; struct dinode *di; - + if (!direct_symlink_extension) return EINVAL; - + assert (compat_mode != COMPAT_BSD42); if (len >= sblock->fs_maxsymlinklen) return EINVAL; - + err = diskfs_catch_exception (); if (err) return err; - + di = dino (np->dn->number); bcopy (target, di->di_shortlink, len); np->dn_stat.st_size = len; @@ -418,25 +418,25 @@ create_symlink_hook (struct node *np, char *target) diskfs_end_catch_exception (); return 0; } -error_t (*diskfs_create_symlink_hook)(struct node *, char *) +error_t (*diskfs_create_symlink_hook)(struct node *, const char *) = create_symlink_hook; /* Check if this symlink is stored directly in the block pointer array. Returning EINVAL tells diskfs to do it the usual way. */ -static error_t +static error_t read_symlink_hook (struct node *np, char *buf) { error_t err; - - if (!direct_symlink_extension + + if (!direct_symlink_extension || np->dn_stat.st_size >= sblock->fs_maxsymlinklen) return EINVAL; err = diskfs_catch_exception (); if (err) return err; - + bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); if (! diskfs_check_readonly ()) @@ -456,7 +456,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *)) struct item *i; error_t err; int n; - + /* Acquire a reference on all the nodes in the hash table and enter them into a list on the stack. */ spin_lock (&diskfs_node_refcnt_lock); @@ -496,10 +496,10 @@ write_all_disknodes () write_node (np); return 0; } - + diskfs_node_iterate (helper); } - + void diskfs_write_disknode (struct node *np, int wait) { @@ -530,7 +530,7 @@ diskfs_set_statfs (struct statfs *st) /* Implement the diskfs_set_translator callback from the diskfs library; see for the interface description. */ error_t -diskfs_set_translator (struct node *np, char *name, u_int namelen, +diskfs_set_translator (struct node *np, const char *name, u_int namelen, struct protid *cred) { daddr_t blkno; @@ -547,10 +547,10 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, err = diskfs_catch_exception (); if (err) return err; - + di = dino (np->dn->number); blkno = read_disk_entry (di->di_trans); - + if (namelen && !blkno) { /* Allocate block for translator */ @@ -574,7 +574,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, np->dn_stat.st_mode &= ~S_IPTRANS; np->dn_set_ctime = 1; } - + if (namelen) { bcopy (&namelen, buf, sizeof (u_int)); @@ -586,7 +586,7 @@ diskfs_set_translator (struct node *np, char *name, u_int namelen, np->dn_stat.st_mode |= S_IPTRANS; np->dn_set_ctime = 1; } - + diskfs_end_catch_exception (); return err; } @@ -608,7 +608,7 @@ diskfs_get_translator (struct node *np, char **namep, u_int *namelen) blkno = read_disk_entry ((dino (np->dn->number))->di_trans); assert (blkno); transloc = disk_image + fsaddr (sblock, blkno); - + datalen = *(u_int *)transloc; *namep = malloc (datalen); bcopy (transloc + sizeof (u_int), *namep, datalen); @@ -649,13 +649,13 @@ diskfs_S_file_get_storage_info (struct protid *cred, struct store *file_store; struct store_run runs[NDADDR]; size_t num_runs = 0; - + if (! cred) return EOPNOTSUPP; np = cred->po->np; mutex_lock (&np->lock); - + /* See if this file fits in the direct block pointers. If not, punt for now. (Reading indir blocks is a pain, and I'm postponing pain.) XXX */ @@ -679,7 +679,7 @@ diskfs_S_file_get_storage_info (struct protid *cred, for (i = 0; i < NDADDR; i++) { off_t start = fsbtodb (sblock, read_disk_entry (di->di_db[i])); - off_t length = + off_t length = (((i + 1) * sblock->fs_bsize > np->allocsize) ? np->allocsize - i * sblock->fs_bsize : sblock->fs_bsize); @@ -694,7 +694,7 @@ diskfs_S_file_get_storage_info (struct protid *cred, diskfs_end_catch_exception (); mutex_unlock (&np->lock); - + if (! err) err = store_clone (store, &file_store); if (! err) -- cgit v1.2.3 From 022849d0b80dcb7b46f4f9dcb7c3af7bba95cf39 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Sat, 3 Jul 1999 23:55:45 +0000 Subject: 1999-07-03 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Use munmap instead of vm_deallocate. (diskfs_direnter_hard): Likewise. (diskfs_dirremove_hard): Likewise. (diskfs_dirrewrite_hard): Likewise. (diskfs_dirempty): Likewise. (diskfs_drop_dirstat): Likewise. (diskfs_get_directs): Likewise. * sizes.c (block_extended): Likewise. (poke_pages): Likewise. * hyper.c (get_hypermetadata): Likewise. (diskfs_set_hypermetadata): Likewise. --- ufs/ChangeLog | 15 +++++++++++++++ ufs/dir.c | 27 +++++++++++++-------------- ufs/hyper.c | 5 ++--- ufs/sizes.c | 6 +++--- 4 files changed, 33 insertions(+), 20 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 7b0fee70..8791b327 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,18 @@ +1999-07-03 Thomas Bushnell, BSG + + * dir.c (diskfs_lookup_hard): Use munmap instead of + vm_deallocate. + (diskfs_direnter_hard): Likewise. + (diskfs_dirremove_hard): Likewise. + (diskfs_dirrewrite_hard): Likewise. + (diskfs_dirempty): Likewise. + (diskfs_drop_dirstat): Likewise. + (diskfs_get_directs): Likewise. + * sizes.c (block_extended): Likewise. + (poke_pages): Likewise. + * hyper.c (get_hypermetadata): Likewise. + (diskfs_set_hypermetadata): Likewise. + 1999-06-29 Thomas Bushnell, BSG * hyper.c (diskfs_readonly_changed): Adjust whether the store diff --git a/ufs/dir.c b/ufs/dir.c index 01432829..c17549c2 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -137,7 +137,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, } if (buf) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); buf = 0; } if (ds && (type == CREATE || type == RENAME)) @@ -181,7 +181,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, } if (err != ENOENT) { - vm_deallocate (mach_task_self (), buf, buflen); + munmap ((caddr_t) buf, buflen); return err; } @@ -295,7 +295,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, || !ds || ds->type == LOOKUP) { - vm_deallocate (mach_task_self (), buf, buflen); + vm_deallocate ((caddr_t) buf, buflen); if (ds) ds->type = LOOKUP; /* set to be ignored by drop_dirstat */ } @@ -586,7 +586,7 @@ diskfs_direnter_hard(struct node *dp, err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred); if (err) { - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); return err; } } @@ -610,7 +610,7 @@ diskfs_direnter_hard(struct node *dp, dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); if (ds->stat != EXTEND) { @@ -678,7 +678,7 @@ diskfs_dirremove_hard(struct node *dp, dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); /* If we are keeping count of this block, then keep the count up to date. */ @@ -711,7 +711,7 @@ diskfs_dirrewrite_hard(struct node *dp, ds->entry->d_type = IFTODT (np->dn_stat.st_mode); dp->dn_set_mtime = 1; - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); diskfs_file_update (dp, 1); @@ -758,7 +758,7 @@ diskfs_dirempty(struct node *dp, || (entry->d_name[1] != '.' && entry->d_name[1] != '\0'))) { - vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + munmap ((caddr_t) buf, dp->dn_stat.st_size); if (!diskfs_check_readonly ()) dp->dn_set_atime = 1; if (diskfs_synchronous) @@ -770,7 +770,7 @@ diskfs_dirempty(struct node *dp, dp->dn_set_atime = 1; if (diskfs_synchronous) diskfs_node_update (dp, 1); - vm_deallocate (mach_task_self (), buf, dp->dn_stat.st_size); + munmap ((caddr_t) buf, dp->dn_stat.st_size); return 1; } @@ -781,7 +781,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) if (ds->type != LOOKUP) { assert (ds->mapbuf); - vm_deallocate (mach_task_self (), ds->mapbuf, ds->mapextent); + munmap ((caddr_t) ds->mapbuf, ds->mapextent); ds->type = LOOKUP; } return 0; @@ -968,9 +968,8 @@ diskfs_get_directs (struct node *dp, if (allocsize > *datacnt) { if (round_page (datap - *data) < allocsize) - vm_deallocate (mach_task_self (), - (vm_address_t) (*data + round_page (datap - *data)), - allocsize - round_page (datap - *data)); + munmap (*data + round_page (datap - *data), + allocsize - round_page (datap - *data)); } /* Set variables for return */ diff --git a/ufs/hyper.c b/ufs/hyper.c index c5101141..deb4a5df 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -138,8 +138,7 @@ get_hypermetadata (void) /* Free previous values. */ if (zeroblock) - vm_deallocate (mach_task_self(), - (vm_address_t)zeroblock, sblock->fs_bsize); + munmap ((caddr_t) zeroblock, sblock->fs_bsize); if (csum) free (csum); @@ -314,7 +313,7 @@ diskfs_set_hypermetadata (int wait, int clean) err = EIO; } - vm_deallocate (mach_task_self (), (vm_address_t)buf, read); + munmap (buf, read); if (err) { diff --git a/ufs/sizes.c b/ufs/sizes.c index 5c3d12f0..58cbfc98 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -1,5 +1,5 @@ /* File growth and truncation - Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1993, 1994, 1995, 1996, 1997, 1999 Free Software Foundation This file is part of the GNU Hurd. @@ -439,7 +439,7 @@ block_extended (struct node *np, /* Undo mapping */ mach_port_deallocate (mach_task_self (), mapobj); - vm_deallocate (mach_task_self (), mapaddr, round_page (old_size)); + munmap ((caddr_t) mapaddr, round_page (old_size)); /* Now it's OK to free the old block */ ffs_blkfree (np, old_pbn, old_size); @@ -711,7 +711,7 @@ poke_pages (memory_object_t obj, { for (poke = addr; poke < addr + len; poke += vm_page_size) *(volatile int *)poke = *(volatile int *)poke; - vm_deallocate (mach_task_self (), addr, len); + munmap ((caddr_t) addr, len); } start += len; } -- cgit v1.2.3 From 490d27a97e87769f04becd62bdfe3a783ee66c97 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Tue, 6 Jul 1999 00:09:18 +0000 Subject: Mon Jul 5 20:04:58 1999 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Repair typo. Reported by Yamashita TAKAO . --- ufs/ChangeLog | 5 +++++ ufs/dir.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 8791b327..4a983183 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +Mon Jul 5 20:04:58 1999 Thomas Bushnell, BSG + + * dir.c (diskfs_lookup_hard): Repair typo. Reported by Yamashita + TAKAO . + 1999-07-03 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Use munmap instead of diff --git a/ufs/dir.c b/ufs/dir.c index c17549c2..c0352d03 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -295,7 +295,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, || !ds || ds->type == LOOKUP) { - vm_deallocate ((caddr_t) buf, buflen); + munmap ((caddr_t) buf, buflen); if (ds) ds->type = LOOKUP; /* set to be ignored by drop_dirstat */ } -- cgit v1.2.3 From e529ce98486b413cca7b16e7f7a51642b60f0a6f Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Sun, 11 Jul 1999 05:32:44 +0000 Subject: 1999-07-09 Thomas Bushnell, BSG * dir.c (diskfs_get_directs): Use mmap instead of vm_allocate. * hyper.c (get_hypermetadata): Likewise. * pager.c (pager_read_page): Likewise. --- ufs/ChangeLog | 11 +++++++++++ ufs/dir.c | 2 +- ufs/hyper.c | 7 ++----- ufs/pager.c | 5 +++-- 4 files changed, 17 insertions(+), 8 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 209d39df..869840b8 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -2,6 +2,17 @@ * ufs.h: Add #include for munmap decl. +1999-07-09 Thomas Bushnell, BSG + + * dir.c (diskfs_get_directs): Use mmap instead of vm_allocate. + * hyper.c (get_hypermetadata): Likewise. + * pager.c (pager_read_page): Likewise. + +1999-07-06 Thomas Bushnell, BSG + + * hyper.c (diskfs_readonly_changed): Use mprotect instead of + vm_protect. + Mon Jul 5 20:04:58 1999 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Repair typo. Reported by Yamashita diff --git a/ufs/dir.c b/ufs/dir.c index c0352d03..304c8a44 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -863,7 +863,7 @@ diskfs_get_directs (struct node *dp, allocsize = round_page (bufsiz); if (allocsize > *datacnt) - vm_allocate (mach_task_self (), (vm_address_t *) data, allocsize, 1); + *data = mmap (0, allocsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); /* Scan through the entries to find ENTRY. If we encounter a -1 in the process then stop to fill it. When we run diff --git a/ufs/hyper.c b/ufs/hyper.c index deb4a5df..c907d274 100644 --- a/ufs/hyper.c +++ b/ufs/hyper.c @@ -257,8 +257,7 @@ get_hypermetadata (void) exit (1); } - vm_allocate (mach_task_self (), - (vm_address_t *)&zeroblock, sblock->fs_bsize, 1); + zeroblock = mmap (0, sblock->fs_bsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); /* If the filesystem has new features in it, don't pay attention to the user's request not to use them. */ @@ -397,9 +396,7 @@ diskfs_readonly_changed (int readonly) { (*(readonly ? store_set_flags : store_clear_flags)) (store, STORE_READONLY); - vm_protect (mach_task_self (), - (vm_address_t)disk_image, store->size, - 0, VM_PROT_READ | (readonly ? 0 : VM_PROT_WRITE)); + mprotect (disk_image, store->size, PROT_READ | (readonly ? 0 : PROT_WRITE)); if (readonly) { diff --git a/ufs/pager.c b/ufs/pager.c index 61695db6..e703bfd2 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -1,5 +1,5 @@ /* Pager for ufs - Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation + Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -180,7 +180,8 @@ pager_read_page (struct user_pager_info *pager, printf ("Write-locked pagein Object %#x\tOffset %#x\n", pager, page); fflush (stdout); #endif - vm_allocate (mach_task_self (), buf, __vm_page_size, 1); + *buf = (vm_address_t) mmap (0, vm_page_size, PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); *writelock = 1; } -- cgit v1.2.3 From 637f6a0aa9cec92581381a8a19a66d2f9b66216b Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Wed, 8 Sep 1999 08:41:59 +0000 Subject: 1999-09-08 Thomas Bushnell, BSG * dir.c (diskfs_get_directs): Initialize `err' to shut gcc up. 1999-09-07 Thomas Bushnell, BSG * dir.c (diskfs_lookup_hard): Pass additional parameter to diskfs_get_filemap. (diskfs_dirempty): Likewise. * sizes.c (diskfs_truncate): Likewise. (block_extended): Likewise. (diskfs_grow): Likewise. * pager.c (diskfs_get_filemap): Accept additional parameter. --- ufs/ChangeLog | 14 ++++++++++++++ ufs/dir.c | 6 +++--- ufs/pager.c | 4 +++- ufs/sizes.c | 6 +++--- 4 files changed, 23 insertions(+), 7 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 1375fede..4bebe284 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,17 @@ +1999-09-08 Thomas Bushnell, BSG + + * dir.c (diskfs_get_directs): Initialize `err' to shut gcc up. + +1999-09-07 Thomas Bushnell, BSG + + * dir.c (diskfs_lookup_hard): Pass additional parameter to + diskfs_get_filemap. + (diskfs_dirempty): Likewise. + * sizes.c (diskfs_truncate): Likewise. + (block_extended): Likewise. + (diskfs_grow): Likewise. + * pager.c (diskfs_get_filemap): Accept additional parameter. + 1999-09-04 Thomas Bushnell, BSG * pager.c (find_address): If !ISREAD, then don't return errors for diff --git a/ufs/dir.c b/ufs/dir.c index 304c8a44..aee08bb0 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -144,7 +144,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, ds->stat = LOOKING; /* Map in the directory contents. */ - memobj = diskfs_get_filemap (dp, prot); + memobj = diskfs_get_filemap (dp, 0, prot); if (memobj == MACH_PORT_NULL) return errno; @@ -730,7 +730,7 @@ diskfs_dirempty(struct node *dp, memory_object_t memobj; error_t err; - memobj = diskfs_get_filemap (dp, VM_PROT_READ); + memobj = diskfs_get_filemap (dp, 0, VM_PROT_READ); if (memobj == MACH_PORT_NULL) /* XXX should reflect error properly */ @@ -839,7 +839,7 @@ diskfs_get_directs (struct node *dp, char buf[DIRBLKSIZ]; char *bufp; int bufvalid; - error_t err; + error_t err = 0; int i; char *datap; struct directory_entry *entryp; diff --git a/ufs/pager.c b/ufs/pager.c index 3038932d..3cba748e 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -547,11 +547,13 @@ flush_node_pager (struct node *node) /* Call this to create a FILE_DATA pager and return a send right. NP must be locked. PROT is the max protection desired. */ mach_port_t -diskfs_get_filemap (struct node *np, vm_prot_t prot) +diskfs_get_filemap (struct node *np, int index, vm_prot_t prot) { struct user_pager_info *upi; mach_port_t right; + assert (index == 0); /* XXX */ + assert (S_ISDIR (np->dn_stat.st_mode) || S_ISREG (np->dn_stat.st_mode) || (S_ISLNK (np->dn_stat.st_mode) diff --git a/ufs/sizes.c b/ufs/sizes.c index 58cbfc98..cffce158 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -103,7 +103,7 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); - obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); + obj = diskfs_get_filemap (np, 0, VM_PROT_READ | VM_PROT_WRITE); if (obj != MACH_PORT_NULL) { /* XXX should cope with errors from diskfs_get_filemap */ @@ -403,7 +403,7 @@ block_extended (struct node *np, volatile int *pokeaddr; /* Map in this part of the file */ - mapobj = diskfs_get_filemap (np, VM_PROT_WRITE | VM_PROT_READ); + mapobj = diskfs_get_filemap (np, 0, VM_PROT_WRITE | VM_PROT_READ); /* XXX Should cope with errors from diskfs_get_filemap and back out the operation here. */ @@ -484,7 +484,7 @@ diskfs_grow (struct node *np, assert (!diskfs_readonly); /* This reference will ensure that NP->dn->fileinfo stays allocated. */ - pagerpt = diskfs_get_filemap (np, VM_PROT_WRITE|VM_PROT_READ); + pagerpt = diskfs_get_filemap (np, 0, VM_PROT_WRITE|VM_PROT_READ); if (pagerpt == MACH_PORT_NULL) return errno; -- cgit v1.2.3 From ddbe575459786c3530c2d092b4193b6d41f1e80a Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 13 Sep 1999 06:35:11 +0000 Subject: Reverted changes related to io_map_segment. --- ufs/ChangeLog | 4 ++++ ufs/dir.c | 6 +++--- ufs/pager.c | 4 +--- ufs/sizes.c | 6 +++--- 4 files changed, 11 insertions(+), 9 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 0ab45a3d..09d4b17a 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +1999-09-13 Roland McGrath + + * dir.c, sizes.c, pager.c: Reverted changes related to io_map_segment. + 1999-09-09 Roland McGrath * Makefile (makemode): servers -> server. diff --git a/ufs/dir.c b/ufs/dir.c index aee08bb0..304c8a44 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -144,7 +144,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, ds->stat = LOOKING; /* Map in the directory contents. */ - memobj = diskfs_get_filemap (dp, 0, prot); + memobj = diskfs_get_filemap (dp, prot); if (memobj == MACH_PORT_NULL) return errno; @@ -730,7 +730,7 @@ diskfs_dirempty(struct node *dp, memory_object_t memobj; error_t err; - memobj = diskfs_get_filemap (dp, 0, VM_PROT_READ); + memobj = diskfs_get_filemap (dp, VM_PROT_READ); if (memobj == MACH_PORT_NULL) /* XXX should reflect error properly */ @@ -839,7 +839,7 @@ diskfs_get_directs (struct node *dp, char buf[DIRBLKSIZ]; char *bufp; int bufvalid; - error_t err = 0; + error_t err; int i; char *datap; struct directory_entry *entryp; diff --git a/ufs/pager.c b/ufs/pager.c index 3cba748e..3038932d 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -547,13 +547,11 @@ flush_node_pager (struct node *node) /* Call this to create a FILE_DATA pager and return a send right. NP must be locked. PROT is the max protection desired. */ mach_port_t -diskfs_get_filemap (struct node *np, int index, vm_prot_t prot) +diskfs_get_filemap (struct node *np, vm_prot_t prot) { struct user_pager_info *upi; mach_port_t right; - assert (index == 0); /* XXX */ - assert (S_ISDIR (np->dn_stat.st_mode) || S_ISREG (np->dn_stat.st_mode) || (S_ISLNK (np->dn_stat.st_mode) diff --git a/ufs/sizes.c b/ufs/sizes.c index cffce158..58cbfc98 100644 --- a/ufs/sizes.c +++ b/ufs/sizes.c @@ -103,7 +103,7 @@ diskfs_truncate (struct node *np, pager_change_attributes (upi->p, MAY_CACHE, MEMORY_OBJECT_COPY_NONE, 1); - obj = diskfs_get_filemap (np, 0, VM_PROT_READ | VM_PROT_WRITE); + obj = diskfs_get_filemap (np, VM_PROT_READ | VM_PROT_WRITE); if (obj != MACH_PORT_NULL) { /* XXX should cope with errors from diskfs_get_filemap */ @@ -403,7 +403,7 @@ block_extended (struct node *np, volatile int *pokeaddr; /* Map in this part of the file */ - mapobj = diskfs_get_filemap (np, 0, VM_PROT_WRITE | VM_PROT_READ); + mapobj = diskfs_get_filemap (np, VM_PROT_WRITE | VM_PROT_READ); /* XXX Should cope with errors from diskfs_get_filemap and back out the operation here. */ @@ -484,7 +484,7 @@ diskfs_grow (struct node *np, assert (!diskfs_readonly); /* This reference will ensure that NP->dn->fileinfo stays allocated. */ - pagerpt = diskfs_get_filemap (np, 0, VM_PROT_WRITE|VM_PROT_READ); + pagerpt = diskfs_get_filemap (np, VM_PROT_WRITE|VM_PROT_READ); if (pagerpt == MACH_PORT_NULL) return errno; -- cgit v1.2.3 From 4ab9fb88b5ba408e9282a345ddbbdba80a1c47fd Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 3 Mar 2000 21:48:33 +0000 Subject: 2000-03-03 Roland McGrath * dir.c (diskfs_get_directs): Don't allocate buffer for *DATA until after scanning for ENTRY and possibly returning EOF. --- ufs/dir.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 304c8a44..8077234c 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation + Copyright (C) 1994,95,96,97,98,99,2000 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -856,15 +856,6 @@ diskfs_get_directs (struct node *dp, dp->dn->dirents[i] = -1; } - /* Allocate enough space to hold the maximum we might return */ - if (!bufsiz || bufsiz > dp->dn_stat.st_size) - allocsize = round_page (dp->dn_stat.st_size); - else - allocsize = round_page (bufsiz); - - if (allocsize > *datacnt) - *data = mmap (0, allocsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); - /* Scan through the entries to find ENTRY. If we encounter a -1 in the process then stop to fill it. When we run off the end, ENTRY is too big. */ @@ -891,11 +882,23 @@ diskfs_get_directs (struct node *dp, if (blkno == nblks) { + /* We reached the end of the directory without seeing ENTRY. + This is treated as an EOF condition, meaning we return + success with empty results. */ *datacnt = 0; *amt = 0; return 0; } + /* Allocate enough space to hold the maximum we might return */ + if (!bufsiz || bufsiz > dp->dn_stat.st_size) + allocsize = round_page (dp->dn_stat.st_size); + else + allocsize = round_page (bufsiz); + + if (allocsize > *datacnt) + *data = mmap (0, allocsize, PROT_READ|PROT_WRITE, MAP_ANON, 0, 0); + /* Set bufp appropriately */ bufp = buf; if (curentry != entry) -- cgit v1.2.3 From 6541698d7d102f16295bb8240d02dd112197b163 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 30 Nov 2000 19:10:04 +0000 Subject: ext2fs, ufs: 2000-11-30 Marcus Brinkmann * dir.c (diskfs_lookup_hard): If name is too long, clear DS before returning ENAMETOOLONG. pfinet: 2000-11-02 Marcus Brinkmann * tunnel.c (trivfs_S_io_get_owner): Add return type to silence compiler warning. --- ufs/ChangeLog | 5 +++++ ufs/dir.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index a83d02b8..82ada32f 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,8 @@ +2000-11-30 Marcus Brinkmann + + * dir.c (diskfs_lookup_hard): If name is too long, clear + DS before returning ENAMETOOLONG. + 2000-07-26 Mark Kettenis * Makefile (HURDLIBS): Reorder libs such that the threads lib diff --git a/ufs/dir.c b/ufs/dir.c index 8077234c..2cc77398 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -126,7 +126,11 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, namelen = strlen (name); if (namelen > MAXNAMLEN) - return ENAMETOOLONG; + { + if (ds) + diskfs_null_dirstat (ds); + return ENAMETOOLONG; + } try_again: if (ds) -- cgit v1.2.3 From 3bc8c9e3eed213b6326c607bfb368f695a4752e7 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sun, 7 Jan 2001 19:31:50 +0000 Subject: doc/ 2001-01-07 Marcus Brinkmann * hurd.texi (Diskfs Callbacks): Make diskfs_dirstat_size const. ext2fs/ 2001-01-07 Marcus Brinkmann * dir.c: Make diskfs_dirstat_size const. isofs/ 2001-01-07 Marcus Brinkmann * lookup.c: Make diskfs_dirstat_size const. ufs/ 2001-01-07 Marcus Brinkmann * dir.c: Make diskfs_dirstat_size const. libdiskfs/ 2001-01-07 Marcus Brinkmann * diskfs.h: Make diskfs_dirstat_size const. libdiskfs/ 2001-01-07 Marcus Brinkmann * file-statfs.c: Include . ftpfs/ 2001-01-07 Marcus Brinkmann * dir.c (ftpfs_dir_create): Fix last change (calloc invocation). 2001-01-07 Marcus Brinkmann * copy.c: Include . New macro page_aligned. (copy_write): Cast buf to vm_address_t in call to vm_write. Dereference amount for memcpy. (copy_read): Add len parameter to vm_read, remove redundant following len assignment. --- ufs/ChangeLog | 4 ++++ ufs/dir.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 6927195b..14aed9dd 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,7 @@ +2001-01-07 Marcus Brinkmann + + * dir.c: Make diskfs_dirstat_size const. + 2000-12-02 Roland McGrath * inode.c (write_node): Remove assert that dn_set_mtime et al are diff --git a/ufs/dir.c b/ufs/dir.c index 2cc77398..7880ca21 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -79,7 +79,7 @@ struct dirstat size_t nbytes; }; -size_t diskfs_dirstat_size = sizeof (struct dirstat); +const size_t diskfs_dirstat_size = sizeof (struct dirstat); /* Initialize DS such that diskfs_drop_dirstat will ignore it. */ void -- cgit v1.2.3 From ec432c9be247ee138cfce70b1d4aa3ada5090aad Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 8 May 2002 09:59:52 +0000 Subject: 2002-05-08 Roland McGrath * main.c (diskfs_append_args): Fix argument type. (main): Use %z format modifier for size_t arg. * dir.c (dirscanblock): Use %z format modifier for vm_address_t arg. (diskfs_dirempty): int -> vm_address_t (count_dirents): int -> size_t (diskfs_get_directs): u_int -> size_t --- ufs/dir.c | 13 ++++++------- ufs/main.c | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 7880ca21..3256bc42 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,5 @@ /* Directory management routines - Copyright (C) 1994,95,96,97,98,99,2000 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,98,99,2000,02 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -379,7 +379,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { - fprintf (stderr, "Bad directory entry: inode: %d offset: %d\n", + fprintf (stderr, "Bad directory entry: inode: %d offset: %zd\n", dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } @@ -729,8 +729,7 @@ diskfs_dirempty(struct node *dp, struct protid *cred) { struct directory_entry *entry; - int curoff; - vm_address_t buf; + vm_address_t buf, curoff; memory_object_t memobj; error_t err; @@ -798,7 +797,7 @@ diskfs_drop_dirstat (struct node *dp, struct dirstat *ds) static error_t count_dirents (struct node *dp, int nb, char *buf) { - int amt; + size_t amt; char *offinblk; struct directory_entry *entry; int count = 0; @@ -833,7 +832,7 @@ diskfs_get_directs (struct node *dp, int entry, int nentries, char **data, - u_int *datacnt, + size_t *datacnt, vm_size_t bufsiz, int *amt) { @@ -848,7 +847,7 @@ diskfs_get_directs (struct node *dp, char *datap; struct directory_entry *entryp; int allocsize; - int checklen; + size_t checklen; struct dirent *userp; nblks = dp->dn_stat.st_size/DIRBLKSIZ; diff --git a/ufs/main.c b/ufs/main.c index 8c79d707..242107f4 100644 --- a/ufs/main.c +++ b/ufs/main.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1994,95,96,97,98,99 Free Software Foundation, Inc. + Copyright (C) 1994,95,96,97,98,99,2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -136,7 +136,7 @@ struct argp *diskfs_runtime_argp = (struct argp *)&runtime_argp; /* Override the standard diskfs routine so we can add our own output. */ error_t -diskfs_append_args (char **argz, unsigned *argz_len) +diskfs_append_args (char **argz, size_t *argz_len) { error_t err; @@ -166,7 +166,7 @@ main (int argc, char **argv) &store_parsed, &bootstrap); if (store->block_size > DEV_BSIZE) - error (4, 0, "%s: Bad device block size %d (should be <= %d)", + error (4, 0, "%s: Bad device block size %zd (should be <= %d)", diskfs_disk_name, store->block_size, DEV_BSIZE); if (store->size < SBSIZE + SBOFF) error (5, 0, "%s: Disk too small (%Ld bytes)", diskfs_disk_name, -- cgit v1.2.3 From 155165974f8fbe5d448345e939792c5b30a20882 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 11 Jun 2002 21:40:58 +0000 Subject: 2002-06-08 Roland McGrath * dir.c (diskfs_direnter_hard): Use size_t for OLDSIZE. Fail with EOVERFLOW when it would exceed that width. * alloc.c, dir.c: Use %Ld format for ino_t values. * alloc.c (diskfs_alloc_node): Use %Ld format for blkcnt_t values. --- ufs/dir.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 3256bc42..b67e45f6 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -379,7 +379,7 @@ dirscanblock (vm_address_t blockaddr, struct node *dp, int idx, || DIRSIZ (DIRECT_NAMLEN (entry)) > read_disk_entry (entry->d_reclen) || memchr (entry->d_name, '\0', DIRECT_NAMLEN (entry))) { - fprintf (stderr, "Bad directory entry: inode: %d offset: %zd\n", + fprintf (stderr, "Bad directory entry: inode: %Ld offset: %zd\n", dp->dn->number, currentoff - blockaddr + idx * DIRBLKSIZ); return ENOENT; } @@ -502,7 +502,7 @@ diskfs_direnter_hard(struct node *dp, vm_address_t fromoff, tooff; int totfreed; error_t err; - off_t oldsize = 0; + size_t oldsize = 0; assert (ds->type == CREATE); @@ -585,6 +585,12 @@ diskfs_direnter_hard(struct node *dp, assert (needed <= DIRBLKSIZ); oldsize = dp->dn_stat.st_size; + if ((off_t)(oldsize + DIRBLKSIZ) != dp->dn_stat.st_size) + { + /* We can't possibly map the whole directory in. */ + munmap ((caddr_t) ds->mapbuf, ds->mapextent); + return EOVERFLOW; + } while (oldsize + DIRBLKSIZ > dp->allocsize) { err = diskfs_grow (dp, oldsize + DIRBLKSIZ, cred); -- cgit v1.2.3 From 25a921e6e16dfad15b5cdb37f0b6e81eacb8afe1 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 1 Aug 2002 00:59:34 +0000 Subject: 2002-07-31 Roland McGrath * dir.c (diskfs_direnter_hard): Fix test in last change. --- ufs/dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index b67e45f6..83b30e72 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -585,7 +585,7 @@ diskfs_direnter_hard(struct node *dp, assert (needed <= DIRBLKSIZ); oldsize = dp->dn_stat.st_size; - if ((off_t)(oldsize + DIRBLKSIZ) != dp->dn_stat.st_size) + if ((off_t)(oldsize + DIRBLKSIZ) != dp->dn_stat.st_size + DIRBLKSIZ) { /* We can't possibly map the whole directory in. */ munmap ((caddr_t) ds->mapbuf, ds->mapextent); -- cgit v1.2.3 From 8c1ea85c28a7a8f0f1dd963ad22fce4bcc97f9bf Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Mon, 20 Aug 2007 15:51:49 +0000 Subject: [doc/ChangeLog] 2007-08-16 Samuel Thibault * hurd.texi: Document diskfs_set_node_atime. [ext2fs/ChangeLog] 2007-08-16 Samuel Thibault * dir.c (diskfs_lookup_hard, diskfs_dirempty): Call diskfs_set_node_atime instead of setting dp->dn_set_atime. [fatfs/ChangeLog] 2007-08-16 Samuel Thibault * dir.c (diskfs_lookup_hard, diskfs_dirempty): Call diskfs_set_node_atime instead of setting dp->dn_set_atime. [libdiskfs/ChangeLog] 2007-08-16 Samuel Thibault * diskfs.h (diskfs_set_node_atime): New declaration. * node-times.c (diskfs_set_node_atime): New function. [ufs/ChangeLog] 2007-08-16 Samuel Thibault * dir.c (diskfs_lookup_hard, diskfs_dirempty): Call diskfs_set_node_atime instead of setting dp->dn_set_atime. * inode.c (read_symlink_hook): Likewise. --- ufs/ChangeLog | 6 ++++++ ufs/dir.c | 15 +++++---------- ufs/inode.c | 3 +-- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/ChangeLog b/ufs/ChangeLog index aa30e784..c7f01b7a 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,9 @@ +2007-08-16 Samuel Thibault + + * dir.c (diskfs_lookup_hard, diskfs_dirempty): Call + diskfs_set_node_atime instead of setting dp->dn_set_atime. + * inode.c (read_symlink_hook): Likewise. + 2006-03-15 Thomas Schwinge * dir.h (DIRECT_NAMELEN): Don't use ?: as a lvalue. diff --git a/ufs/dir.c b/ufs/dir.c index 83b30e72..7d9b0f55 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -162,8 +162,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, inum = 0; - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); /* Start the lookup at DP->dn->dir_idx. */ idx = dp->dn->dir_idx; @@ -200,8 +199,7 @@ diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, } } - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); @@ -752,8 +750,7 @@ diskfs_dirempty(struct node *dp, mach_port_deallocate (mach_task_self (), memobj); assert (!err); - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); for (curoff = buf; curoff < buf + dp->dn_stat.st_size; @@ -768,15 +765,13 @@ diskfs_dirempty(struct node *dp, && entry->d_name[1] != '\0'))) { munmap ((caddr_t) buf, dp->dn_stat.st_size); - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); return 0; } } - if (!diskfs_check_readonly ()) - dp->dn_set_atime = 1; + diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); munmap ((caddr_t) buf, dp->dn_stat.st_size); diff --git a/ufs/inode.c b/ufs/inode.c index a8bb661f..228429b1 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -431,8 +431,7 @@ read_symlink_hook (struct node *np, bcopy ((dino (np->dn->number))->di_shortlink, buf, np->dn_stat.st_size); - if (! diskfs_check_readonly ()) - np->dn_set_atime = 1; + diskfs_set_node_atime (dp); diskfs_end_catch_exception (); return 0; -- cgit v1.2.3 From 52ea733b99cb7de4794b0a8b3fa19dec57ec0ee9 Mon Sep 17 00:00:00 2001 From: Thomas Schwinge Date: Fri, 5 Oct 2007 10:00:44 +0000 Subject: Update copyright years. --- ufs/dir.c | 4 +++- ufs/inode.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'ufs/dir.c') diff --git a/ufs/dir.c b/ufs/dir.c index 7d9b0f55..7a8cfa55 100644 --- a/ufs/dir.c +++ b/ufs/dir.c @@ -1,5 +1,7 @@ /* Directory management routines - Copyright (C) 1994,95,96,97,98,99,2000,02 Free Software Foundation, Inc. + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2007 + Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/ufs/inode.c b/ufs/inode.c index 221a78f7..8223fe7f 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -1,5 +1,7 @@ /* Inode management routines - Copyright (C) 1994,95,96,97,98,2000,01,02 Free Software Foundation, Inc. + + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2007 + Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as -- cgit v1.2.3