+/*
+ * allocate a new directory
+ */
+allocdir(parent, request, mode)
+ ino_t parent, request;
+ int mode;
+{
+ ino_t ino;
+ char *cp;
+ struct dinode *dp;
+ register struct bufarea *bp;
+
+ ino = allocino(request, IFDIR|mode);
+ dirhead.dot_ino = ino;
+ dirhead.dotdot_ino = parent;
+ dp = ginode(ino);
+ bp = getdirblk(dp->di_db[0], sblock.fs_fsize);
+ if (bp->b_errs) {
+ freeino(ino);
+ return (0);
+ }
+ bcopy((char *)&dirhead, bp->b_un.b_buf, sizeof dirhead);
+ for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
+ cp < &bp->b_un.b_buf[sblock.fs_fsize];
+ cp += DIRBLKSIZ)
+ bcopy((char *)&emptydir, cp, sizeof emptydir);
+ dirty(bp);
+ dp->di_nlink = 2;
+ inodirty();
+ if (ino == ROOTINO) {
+ lncntp[ino] = dp->di_nlink;
+ return(ino);
+ }
+ if (statemap[parent] != DSTATE && statemap[parent] != DFOUND) {
+ freeino(ino);
+ return (0);
+ }
+ statemap[ino] = statemap[parent];
+ if (statemap[ino] == DSTATE) {
+ lncntp[ino] = dp->di_nlink;
+ lncntp[parent]++;
+ }
+ dp = ginode(parent);
+ dp->di_nlink++;
+ inodirty();
+ return (ino);
+}
+
+/*
+ * free a directory inode
+ */
+freedir(ino, parent)
+ ino_t ino, parent;
+{
+ struct dinode *dp;
+
+ if (ino != parent) {
+ dp = ginode(parent);
+ dp->di_nlink--;
+ inodirty();
+ }
+ freeino(ino);
+}
+