/* This function closes the session file, given its handle */ void blkclose (BLK *buf) /* buffer, holds superblock */ { blkread (buf, 0); buf->super.inuse = 0L; blkwrite (buf, 0); (void)DosClose (fd); fd = NULLHANDLE; if (o_tempsession) { (void)DosDelete (tochar8(o_session)); } /* if */ }
int ufs_dir_iterate(uufsd_t *ufs, ino_t dirino, int (*func)( struct direct *dirent, int n, char *buf, void *priv_data), void *priv_data) { int i, ret = 0; ufs2_daddr_t ndb; ufs2_daddr_t blkno; int blksize = ufs->d_fs.fs_bsize; u_int64_t dir_size; char *dirbuf = NULL; struct ufs_vnode *vnode; vnode = vnode_get(ufs, dirino); if (vnode == NULL) { ret = -ENOMEM; goto out; } dir_size = vnode2inode(vnode)->i_size; dirbuf = malloc(blksize); if (!dirbuf) { ret = -ENOMEM; goto out; } ndb = howmany(dir_size, ufs->d_fs.fs_bsize); int offset, pos = 0; for (i = 0; i < ndb ; i++) { ret = ufs_bmap(ufs, vnode, i, &blkno); if (ret) { ret = -EIO; goto out; } blksize = ufs_inode_io_size(vnode2inode(vnode), pos, 0); if (blkread(ufs, fsbtodb(&ufs->d_fs, blkno), dirbuf, blksize) == -1) { debugf("Unable to read block %d\n",blkno); ret = -EIO; goto out; } offset = 0; while (offset < blksize && pos + offset < dir_size) { struct direct *de = (struct direct *)(dirbuf + offset); /* HACK: Restrict frame for func() operations * to blocks of DIRBLKSIZ bytes */ int blockoff = offset % DIRBLKSIZ; char * dirblock = dirbuf + (offset-blockoff); ret = (*func)(de, blockoff, dirblock, priv_data); if (ret & DIRENT_CHANGED) { if (blkwrite(ufs, fsbtodb(&ufs->d_fs, blkno), dirbuf, blksize) == -1) { debugf("Unable to write block %d\n",blkno); ret = -EIO; goto out; } } if (ret & DIRENT_ABORT) { ret = 0; goto out; } offset += de->d_reclen; } pos += blksize; } out: if (vnode) { vnode_put(vnode, 0); } if (dirbuf) { free(dirbuf); } return ret; }
static int ufs_mkdir(uufsd_t *ufs, ino_t parent, ino_t inum, char *name) { int retval; struct ufs_vnode *parent_vnode = NULL, *vnode = NULL; struct inode *parent_inode, *inode; ino_t ino = inum; ino_t scratch_ino; ufs2_daddr_t blk; char *block = 0; struct fs *fs = &ufs->d_fs; int dirsize = DIRBLKSIZ; int blocksize = fragroundup(fs, dirsize); parent_vnode = vnode_get(ufs, parent); if (!parent_vnode) { return ENOENT; } parent_inode = vnode2inode(parent_vnode); /* * Allocate an inode, if necessary */ if (!ino) { retval = ufs_valloc(parent_vnode, DTTOIF(DT_DIR), &vnode); if (retval) goto cleanup; ino = vnode->inode.i_number; inode = vnode2inode(vnode); } /* * Allocate a data block for the directory */ retval = ufs_block_alloc(ufs, inode, fragroundup(fs, dirsize), &blk); if (retval) goto cleanup; /* * Create a scratch template for the directory */ retval = ufs_new_dir_block(ufs, vnode->inode.i_number, parent_vnode, &block); if (retval) goto cleanup; /* * Get the parent's inode, if necessary if (parent != ino) { parent_vnode = vnode_get(ufs, parent); if (retval) goto cleanup; } else memset(&parent_inode, 0, sizeof(parent_inode)); */ /* * Create the inode structure.... */ inode->i_mode = DT_DIR | (0777); inode->i_uid = inode->i_gid = 0; UFS_DINODE(inode)->di_db[0] = blk; inode->i_nlink = 1; inode->i_size = dirsize; /* * Write out the inode and inode data block */ retval = blkwrite(ufs, fsbtodb(fs, blk), block, blocksize); if (retval == -1) goto cleanup; /* * Link the directory into the filesystem hierarchy */ if (name) { retval = ufs_lookup(ufs, parent, name, strlen(name), &scratch_ino); if (!retval) { retval = EEXIST; name = 0; goto cleanup; } if (retval != ENOENT) goto cleanup; retval = ufs_link(ufs, parent, name, vnode, DTTOIF(DT_DIR)); if (retval) goto cleanup; } /* * Update parent inode's counts */ if (parent != ino) { parent_inode->i_nlink++; } cleanup: if (vnode) vnode_put(vnode, 1); if (parent_vnode) vnode_put(parent_vnode, 1); if (block) ufs_free_mem(&block); return retval; }