+ /*
+ * If still looking for a slot, and at a DIRBLKSIZE
+ * boundary, have to start looking for free space
+ * again.
+ */
+ if (slotstatus == NONE &&
+ (entryoffsetinblock&(DIRBLKSIZ-1)) == 0) {
+ slotoffset = -1;
+ slotfreespace = 0;
+ }
+
+ /*
+ * Get pointer to next entry, and do consistency checking:
+ * record length must be multiple of 4
+ * record length must not be zero
+ * entry must fit in rest of this DIRBLKSIZ block
+ * record must be large enough to contain name
+ * When dirchk is set we also check:
+ * name is not longer than MAXNAMLEN
+ * name must be as long as advertised, and null terminated
+ * Checking last two conditions is done only when dirchk is
+ * set, to save time.
+ */
+ ep = (struct direct *)(bp->b_un.b_addr + entryoffsetinblock);
+ i = DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1));
+ if ((ep->d_reclen & 0x3) || ep->d_reclen == 0 ||
+ ep->d_reclen > i || DIRSIZ(ep) > ep->d_reclen ||
+ dirchk && (ep->d_namlen > MAXNAMLEN || dirbadname(ep))) {
+ dirbad(dp, "mangled entry");
+ u.u_offset += i;
+ entryoffsetinblock += i;
+ continue;
+ }
+
+ /*
+ * If an appropriate sized slot has not yet been found,
+ * check to see if one is available. Also accumulate space
+ * in the current block so that we can determine if
+ * compaction is viable.
+ */
+ if (slotstatus != FOUND) {
+ int size = ep->d_reclen;
+
+ if (ep->d_ino != 0)
+ size -= DIRSIZ(ep);
+ if (size > 0) {
+ if (size >= slotneeded) {
+ slotstatus = FOUND;
+ slotoffset = u.u_offset;
+ slotsize = ep->d_reclen;
+ } else if (slotstatus == NONE) {
+ slotfreespace += size;
+ if (slotoffset == -1)
+ slotoffset = u.u_offset;
+ if (slotfreespace >= slotneeded) {
+ slotstatus = COMPACT;
+ slotsize =
+ u.u_offset+ep->d_reclen -
+ slotoffset;
+ }
+ }
+ }
+ }
+
+ /*
+ * Check for a name match.
+ */
+ if (ep->d_ino) {
+ if (ep->d_namlen == u.u_dent.d_namlen &&
+ !bcmp(u.u_dent.d_name, ep->d_name, ep->d_namlen))
+ goto found;
+ }
+ prevoff = u.u_offset;
+ u.u_offset += ep->d_reclen;
+ entryoffsetinblock += ep->d_reclen;
+ }
+/* notfound: */