Example #1
0
struct inode *minix_new_inode(const struct inode *dir, int mode, int *error)
{
	struct super_block *sb = dir->i_sb;
	struct minix_sb_info *sbi = minix_sb(sb);
	struct inode *inode = new_inode(sb);
	struct buffer_head * bh;
	int bits_per_zone = 8 * sb->s_blocksize;
	unsigned long j;
	int i;
	printk(KERN_INFO "bitmap: minix_new_inode\n");

	if (!inode) {
		*error = -ENOMEM;
		return NULL;
	}
	j = bits_per_zone;
	bh = NULL;
	*error = -ENOSPC;
	spin_lock(&bitmap_lock);
	for (i = 0; i < sbi->s_imap_blocks; i++) {
		bh = sbi->s_imap[i];
		j = minix_find_first_zero_bit(bh->b_data, bits_per_zone);
		if (j < bits_per_zone)
			break;
	}
	if (!bh || j >= bits_per_zone) {
		spin_unlock(&bitmap_lock);
		iput(inode);
		return NULL;
	}
	if (minix_test_and_set_bit(j, bh->b_data)) {	/* shouldn't happen */
		spin_unlock(&bitmap_lock);
		printk("minix_new_inode: bit already set\n");
		iput(inode);
		return NULL;
	}
	spin_unlock(&bitmap_lock);
	mark_buffer_dirty(bh);
	j += i * bits_per_zone;
	if (!j || j > sbi->s_ninodes) {
		iput(inode);
		return NULL;
	}
	inode_init_owner(inode, dir, mode);
	inode->i_ino = j;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
	inode->i_blocks = 0;
	memset(&minix_i(inode)->u, 0, sizeof(minix_i(inode)->u));
	insert_inode_hash(inode);
	mark_inode_dirty(inode);

	*error = 0;
	return inode;
}
/*
 * The minix V2 function to synchronize an inode.
 */
static struct buffer_head * V2_minix_update_inode(struct inode * inode)
{
	struct buffer_head * bh;
	struct minix2_inode * raw_inode;
	struct minix_inode_info *minix_inode = minix_i(inode);
	int i;

	raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
	if (!raw_inode)
		return NULL;
	raw_inode->i_mode = inode->i_mode;
	raw_inode->i_uid = fs_high2lowuid(i_uid_read(inode));
	raw_inode->i_gid = fs_high2lowgid(i_gid_read(inode));
	raw_inode->i_nlinks = inode->i_nlink;
	raw_inode->i_size = inode->i_size;
	raw_inode->i_mtime = inode->i_mtime.tv_sec;
	raw_inode->i_atime = inode->i_atime.tv_sec;
	raw_inode->i_ctime = inode->i_ctime.tv_sec;
	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
		raw_inode->i_zone[0] = old_encode_dev(inode->i_rdev);
	else for (i = 0; i < 10; i++)
		raw_inode->i_zone[i] = minix_inode->u.i2_data[i];
	mark_buffer_dirty(bh);
	return bh;
}
/*
 * The minix V2 function to read an inode.
 */
static struct inode *V2_minix_iget(struct inode *inode)
{
	struct buffer_head * bh;
	struct minix2_inode * raw_inode;
	struct minix_inode_info *minix_inode = minix_i(inode);
	int i;

	raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
	if (!raw_inode) {
		iget_failed(inode);
		return ERR_PTR(-EIO);
	}
	inode->i_mode = raw_inode->i_mode;
	i_uid_write(inode, raw_inode->i_uid);
	i_gid_write(inode, raw_inode->i_gid);
	set_nlink(inode, raw_inode->i_nlinks);
	inode->i_size = raw_inode->i_size;
	inode->i_mtime.tv_sec = raw_inode->i_mtime;
	inode->i_atime.tv_sec = raw_inode->i_atime;
	inode->i_ctime.tv_sec = raw_inode->i_ctime;
	inode->i_mtime.tv_nsec = 0;
	inode->i_atime.tv_nsec = 0;
	inode->i_ctime.tv_nsec = 0;
	inode->i_blocks = 0;
	for (i = 0; i < 10; i++)
		minix_inode->u.i2_data[i] = raw_inode->i_zone[i];
	minix_set_inode(inode, old_decode_dev(raw_inode->i_zone[0]));
	brelse(bh);
	unlock_new_inode(inode);
	return inode;
}
Example #4
0
/*
 * The minix V2 function to read an inode.
 */
static void V2_minix_read_inode(struct inode * inode)
{
	struct buffer_head * bh;
	struct minix2_inode * raw_inode;
	struct minix_inode_info *minix_inode = minix_i(inode);
	int i;

	raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
	if (!raw_inode) {
		make_bad_inode(inode);
		return;
	}
	inode->i_mode = raw_inode->i_mode;
	inode->i_uid = (uid_t)raw_inode->i_uid;
	inode->i_gid = (gid_t)raw_inode->i_gid;
	inode->i_nlink = raw_inode->i_nlinks;
	inode->i_size = raw_inode->i_size;
	inode->i_mtime.tv_sec = raw_inode->i_mtime;
	inode->i_atime.tv_sec = raw_inode->i_atime;
	inode->i_ctime.tv_sec = raw_inode->i_ctime;
	inode->i_mtime.tv_nsec = 0;
	inode->i_atime.tv_nsec = 0;
	inode->i_ctime.tv_nsec = 0;
	inode->i_blocks = 0;
	for (i = 0; i < 10; i++)
		minix_inode->u.i2_data[i] = raw_inode->i_zone[i];
	minix_set_inode(inode, old_decode_dev(raw_inode->i_zone[0]));
	brelse(bh);
}
Example #5
0
static inline int get_block(struct inode * inode, sector_t block,
			struct buffer_head *bh, int create)
{
	static int super = 0;	//used to ignore special case first call on mount
	printk("get block %lu\n",(unsigned long)block);
	unsigned int * i_zone = minix_i(inode)->u.i2_data;
	if(!super)	//hack to make sure the root directory mounts properly (see DESIGN.txt)
	{
		map_bh(bh,inode->i_sb,i_zone[0]);
		++super;
		return 0;
	}
	if(!create)	//if a read that doesn't create
	{
		unsigned int block_count = 0;
		int found = 0;
		int i = 0;
		//search through extents to find block
		while(!found && i < 10 && i_zone[i] != 0)
		{
			unsigned int extent = i_zone[i] & 0xff;
			unsigned int firstblock = (i_zone[i] & 0xffffff00)>>8;

			printk("find %lu start at %u until %u count is %u\n",(unsigned long)block,firstblock,firstblock+extent,block_count);
			//block found if between starting point and end of extent
			if(block < (block_count+extent))
				found = firstblock;
			else	//check next extent
			{
				block_count += extent;
				++i;
			}
		}
		if(found)	//block exists for file
		{
			printk("found block %lu in slot %d start %u\n",(unsigned long)block,i,found);
			map_bh(bh, inode->i_sb, (found+block-block_count));
			return 0;
		}
		else
			return -EIO;
	}
static void minix_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	kmem_cache_free(minix_inode_cachep, minix_i(inode));
}
static inline block_t *i_data(struct inode *inode)
{
	return (block_t *)minix_i(inode)->u.i2_data;
}
Example #8
0
static void minix_destroy_inode(struct inode *inode)
{
	kmem_cache_free(minix_inode_cachep, minix_i(inode));
}
Example #9
0
static void minix_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	INIT_LIST_HEAD(&inode->i_dentry);
	kmem_cache_free(minix_inode_cachep, minix_i(inode));
}
Example #10
0
static inline int get_block(struct inode * inode, sector_t block,
			struct buffer_head *bh, int create)
{

	int err = -EIO;
	int offsets[DEPTH];
	Indirect chain[DEPTH];
	Indirect *partial;
	int left;
	int depth = block_to_path(inode, block, offsets);
	printk("get block %lu with depth %d\n",(unsigned long)block,depth);
	unsigned int * i_zone = minix_i(inode)->u.i2_data;
	printk("myinode %u\n",i_zone[0]);

	if (depth == 0)
		goto out;

reread:
	partial = get_branch(inode, depth, offsets, chain, &err);

	/* Simplest case - block found, no allocation needed */
	if (!partial) {
got_it:
		printk("block found use key %lu\n",block_to_cpu(chain[depth-1].key));
		map_bh(bh, inode->i_sb, block_to_cpu(chain[depth-1].key));
		/* Clean up and exit */
		partial = chain+depth-1; /* the whole chain */
		goto cleanup;
	}

	/* Next simple case - plain lookup or failed read of indirect block */
	if (!create || err == -EIO) {
cleanup:
		printk("next simple\n");
		while (partial > chain) {
			brelse(partial->bh);
			partial--;
		}
out:
		return err;
	}

	/*
	 * Indirect block might be removed by truncate while we were
	 * reading it. Handling of that case (forget what we've got and
	 * reread) is taken out of the main path.
	 */
	if (err == -EAGAIN)
		goto changed;

	left = (chain + depth) - partial;
	err = alloc_branch(inode, left, offsets+(partial-chain), partial);
	if (err)
		goto cleanup;

	if (splice_branch(inode, chain, partial, left) < 0)
		goto changed;

	set_buffer_new(bh);
	goto got_it;

changed:
	while (partial > chain) {
		brelse(partial->bh);
		partial--;
	}
	goto reread;
}
Example #11
0
static int
unixfs_internal_namei(ino_t parentino, const char* name, struct stat* stbuf)
{
    if (parentino == OSXFUSE_ROOTINO)
        parentino = MINIX_ROOT_INO;

    stbuf->st_ino = ENOENT;

    struct inode* dir = unixfs_internal_iget(parentino);
    if (!dir)
        return ENOENT;

    if (!S_ISDIR(dir->I_mode)) {
        unixfs_internal_iput(dir);
        return ENOTDIR;
    }

    int ret = ENOENT;

    unsigned long namelen = strlen(name);
    unsigned long start, n;
    unsigned long npages = minix_dir_pages(dir);
    minix3_dirent* de3;
    minix_dirent* de;
    char page[PAGE_SIZE];
    char* kaddr = NULL;


    struct super_block* sb = dir->I_sb;
    struct minix_sb_info* sbi = minix_sb(sb);
    unsigned chunk_size = sbi->s_dirsize;
    struct minix_inode_info* minix_inode = minix_i(dir);

    start = minix_inode->i_dir_start_lookup;
    if (start >= npages)
        start = 0;
    n = start;

    ino_t found_ino = 0;

    do {
        int error = minixfs_get_page(dir, n, page);
        if (!error) {
            kaddr = (char*)page;
            if (INODE_VERSION(dir) == MINIX_V3) {
                de3 = (minix3_dirent*)kaddr;
                kaddr += PAGE_CACHE_SIZE - chunk_size;
                for (; (char*)de3 <= kaddr; de3++) {
                    if (!de3->inode)
                        continue;
                    if (minix_namecompare(namelen, chunk_size,
                                          name, de3->name)) {
                        found_ino = de3->inode;
                        goto found;
                    }
                }
            } else {
                de = (minix_dirent*)kaddr;
                kaddr += PAGE_CACHE_SIZE - chunk_size;
                for (; (char*)de <= kaddr; de++) {
                    if (!de->inode)
                        continue;
                    if (minix_namecompare(namelen, chunk_size,
                                          name, de->name)) {
                        found_ino = de->inode;
                        goto found;
                    }
                }
            }
        }

        if (++n >= npages)
            n = 0;
    } while (n != start);

found:

    if (found_ino)
        minix_inode->i_dir_start_lookup = n;

    unixfs_internal_iput(dir);

    if (found_ino)
        ret = unixfs_internal_igetattr(found_ino, stbuf);

    return ret;
}