Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}