int ufs_check_dir_entry (const char * function, struct inode * dir, struct ufs_dir_entry * de, struct buffer_head * bh, unsigned long offset) { struct super_block * sb; const char * error_msg; unsigned flags, swab; sb = dir->i_sb; flags = sb->u.ufs_sb.s_flags; swab = sb->u.ufs_sb.s_swab; error_msg = NULL; if (SWAB16(de->d_reclen) < UFS_DIR_REC_LEN(1)) error_msg = "reclen is smaller than minimal"; else if (SWAB16(de->d_reclen) % 4 != 0) error_msg = "reclen % 4 != 0"; else if (SWAB16(de->d_reclen) < UFS_DIR_REC_LEN(ufs_get_de_namlen(de))) error_msg = "reclen is too small for namlen"; else if (dir && ((char *) de - bh->b_data) + SWAB16(de->d_reclen) > dir->i_sb->s_blocksize) error_msg = "directory entry across blocks"; else if (dir && SWAB32(de->d_ino) > (sb->u.ufs_sb.s_uspi->s_ipg * sb->u.ufs_sb.s_uspi->s_ncg)) error_msg = "inode out of bounds"; if (error_msg != NULL) ufs_error (sb, function, "bad entry in directory #%lu, size %lu: %s - " "offset=%lu, inode=%lu, reclen=%d, namlen=%d", dir->i_ino, dir->i_size, error_msg, offset, (unsigned long) SWAB32(de->d_ino), SWAB16(de->d_reclen), ufs_get_de_namlen(de)); return (error_msg == NULL ? 1 : 0); }
static int ufs_new_dir_block(uufsd_t *ufs, ino_t dir_ino, struct ufs_vnode *parent, char **block) { struct direct *dir = NULL; int retval; char *buf; int rec_len; struct fs *fs = &ufs->d_fs; int dirsize = DIRBLKSIZ; int blocksize = fragroundup(fs, dirsize); retval = ufs_get_mem(blocksize, &buf); if (retval) return retval; memset(buf, 0, blocksize); dir = (struct direct *) buf; //retval = ufs_set_rec_len(ufs, dirsize, dir); //if (retval) //return retval; if (dir_ino) { /* * Set up entry for '.' */ dir->d_ino = dir_ino; dir->d_namlen = 1; dir->d_name[0] = '.'; dir->d_type = DT_DIR; rec_len = dirsize - UFS_DIR_REC_LEN(1); dir->d_reclen = UFS_DIR_REC_LEN(1); /* * Set up entry for '..' */ dir = (struct direct *) (buf + dir->d_reclen); //retval = ufs_set_rec_len(ufs, rec_len, dir); //if (retval) //return retval; dir->d_ino = vnode2inode(parent)->i_number; dir->d_namlen = 2; dir->d_name[0] = '.'; dir->d_name[1] = '.'; dir->d_type = DT_DIR; dir->d_reclen = rec_len; } *block = buf; return 0; }