int ux_diradd(struct inode *dip, const char *name, int inum) { struct ux_inode *uip = (struct ux_inode *) &dip->i_private; struct buffer_head *bh; struct super_block *sb = dip->i_sb; struct ux_dirent *dirent; __u32 blk = 0; int i, pos; for (blk=0 ; blk < uip->i_blocks ; blk++) { bh = sb_bread(sb, uip->i_addr[blk]); dirent = (struct ux_dirent *)bh->b_data; for (i=0 ; i < UX_DIRS_PER_BLOCK ; i++) { if (dirent->d_ino != 0) { dirent++; continue; } else { dirent->d_ino = inum; strcpy(dirent->d_name, name); mark_buffer_dirty(bh); mark_inode_dirty(dip); brelse(bh); return 0; } } brelse(bh); } /* * We didn't find an empty slot so need to allocate * a new block if there's space in the inode. */ if (uip->i_blocks < UX_DIRECT_BLOCKS) { pos = uip->i_blocks; blk = ux_block_alloc(sb); uip->i_blocks++; uip->i_size += UX_BSIZE; dip->i_size += UX_BSIZE; dip->i_blocks++; uip->i_addr[pos] = blk; bh = sb_bread(sb, blk); memset(bh->b_data, 0, UX_BSIZE); mark_inode_dirty(dip); dirent = (struct ux_dirent *)bh->b_data; dirent->d_ino = inum; strcpy(dirent->d_name, name); mark_buffer_dirty(bh); brelse(bh); } return 0; }
int ux_get_block(struct inode *inode, long block, struct buffer_head *bh_result, int create) { struct super_block *sb = inode->i_sb; struct ux_fs *fs = (struct ux_fs *) sb->s_private; struct ux_inode *uip = (struct ux_inode *) &inode->i_private; __u32 blk; /* * First check to see is the file can be extended. */ if (block >= UX_DIRECT_BLOCKS) { return -EFBIG; } /* * If we're creating, we must allocate a new block. */ if (create) { blk = ux_block_alloc(sb); if (blk == 0) { printk("uxfs: ux_get_block - " "Out of space\n"); return -ENOSPC; } uip->i_addr[block] = blk; uip->i_blocks++; uip->i_size = inode->i_size; mark_inode_dirty(inode); } bh_result->b_dev = inode->i_dev; bh_result->b_blocknr = uip->i_addr[block]; bh_result->b_state |= (1UL << BH_Mapped); return 0; }
int ux_mkdir(struct inode *dip, struct dentry *dentry, int mode) { struct ux_inode *nip; struct buffer_head *bh; struct super_block *sb = dip->i_sb; struct ux_dirent *dirent; struct inode *inode; ino_t inum = 0; int blk; /* * Make sure there isn't already an entry. If not, * allocate one, a new inode and new incore inode. */ inum = ux_find_entry(dip, (char *)dentry->d_name.name); if (inum) { return -EEXIST; } inode = new_inode(sb); if (!inode) { return -ENOSPC; } inum = ux_ialloc(sb); if (!inum) { iput(inode); return -ENOSPC; } ux_diradd(dip, (char *)dentry->d_name.name, inum); inode->i_uid = current->cred->fsuid; inode->i_gid = (dip->i_mode & S_ISGID) ? dip->i_gid : current->cred->fsgid; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_blocks = 1; inode->i_op = &ux_dir_inops; inode->i_fop = &ux_dir_operations; inode->i_mapping->a_ops = &ux_aops; inode->i_mode = mode | S_IFDIR; inode->i_ino = inum; inode->i_size = UX_BSIZE; inode->i_nlink = 2; nip = (struct ux_inode *)&inode->i_private; nip->i_mode = mode | S_IFDIR; nip->i_nlink = 2; nip->i_atime = nip->i_ctime = nip->i_mtime = CURRENT_TIME; nip->i_uid = current->cred->fsuid; nip->i_gid = (dip->i_mode & S_ISGID) ? dip->i_gid : current->cred->fsgid; nip->i_size = 512; nip->i_blocks = 1; memset(nip->i_addr, 0, 16); blk = ux_block_alloc(sb); nip->i_addr[0] = blk; bh = sb_bread(sb, blk); memset(bh->b_data, 0, UX_BSIZE); dirent = (struct ux_dirent *)bh->b_data; dirent->d_ino = inum; strcpy(dirent->d_name, "."); dirent++; dirent->d_ino = inode->i_ino; strcpy(dirent->d_name, ".."); mark_buffer_dirty(bh); brelse(bh); insert_inode_hash(inode); d_instantiate(dentry, inode); mark_inode_dirty(inode); /* * Increment the link count of the parent directory. */ dip->i_nlink++; mark_inode_dirty(dip); return 0; }