Ejemplo n.º 1
0
void minix_free_inode(struct inode * inode)
{
	struct super_block *sb = inode->i_sb;
	struct minix_sb_info *sbi = minix_sb(inode->i_sb);
	struct buffer_head *bh;
	int k = sb->s_blocksize_bits + 3;
	unsigned long ino, bit;

	ino = inode->i_ino;
	if (ino < 1 || ino > sbi->s_ninodes) {
;
		return;
	}
	bit = ino & ((1<<k) - 1);
	ino >>= k;
	if (ino >= sbi->s_imap_blocks) {
;
		return;
	}

	minix_clear_inode(inode);	/* clear on-disk copy */

	bh = sbi->s_imap[ino];
	spin_lock(&bitmap_lock);
	if (!minix_test_and_clear_bit(bit, bh->b_data))
;
	spin_unlock(&bitmap_lock);
	mark_buffer_dirty(bh);
}
Ejemplo n.º 2
0
int minix_new_block(struct inode * inode)
{
	struct minix_sb_info *sbi = minix_sb(inode->i_sb);
	int bits_per_zone = 8 * inode->i_sb->s_blocksize;
	int i;

	for (i = 0; i < sbi->s_zmap_blocks; i++) {
		struct buffer_head *bh = sbi->s_zmap[i];
		int j;

		spin_lock(&bitmap_lock);
		j = minix_find_first_zero_bit(bh->b_data, bits_per_zone);
		if (j < bits_per_zone) {
			minix_set_bit(j, bh->b_data);
			spin_unlock(&bitmap_lock);
			mark_buffer_dirty(bh);
			j += i * bits_per_zone + sbi->s_firstdatazone-1;
			if (j < sbi->s_firstdatazone || j >= sbi->s_nzones)
				break;
			return j;
		}
		spin_unlock(&bitmap_lock);
	}
	return 0;
}
Ejemplo n.º 3
0
unsigned long minix_count_free_inodes(struct super_block *sb)
{
	struct minix_sb_info *sbi = minix_sb(sb);
	u32 bits = sbi->s_ninodes + 1;

	return count_free(sbi->s_imap, sb->s_blocksize, bits);
}
Ejemplo n.º 4
0
void minix_free_block(struct inode *inode, unsigned long block)
{
	struct super_block *sb = inode->i_sb;
	struct minix_sb_info *sbi = minix_sb(sb);
	struct buffer_head *bh;
	int k = sb->s_blocksize_bits + 3;
	unsigned long bit, zone;

	if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) {
		printk("Trying to free block not in datazone\n");
		return;
	}
	zone = block - sbi->s_firstdatazone + 1;
	bit = zone & ((1<<k) - 1);
	zone >>= k;
	if (zone >= sbi->s_zmap_blocks) {
		printk("minix_free_block: nonexistent bitmap buffer\n");
		return;
	}
	bh = sbi->s_zmap[zone];
	spin_lock(&bitmap_lock);
	if (!minix_test_and_clear_bit(bit, bh->b_data))
		printk("minix_free_block (%s:%lu): bit already cleared\n",
		       sb->s_id, block);
	spin_unlock(&bitmap_lock);
	mark_buffer_dirty(bh);
	return;
}
Ejemplo n.º 5
0
void minix_free_inode(struct inode * inode)
{
	struct super_block *sb = inode->i_sb;
	struct minix_sb_info *sbi = minix_sb(inode->i_sb);
	struct buffer_head *bh;
	int k = sb->s_blocksize_bits + 3;
	unsigned long ino, bit;

	ino = inode->i_ino;
	if (ino < 1 || ino > sbi->s_ninodes) {
		printk("minix_free_inode: inode 0 or nonexistent inode\n");
		return;
	}
	bit = ino & ((1<<k) - 1);
	ino >>= k;
	if (ino >= sbi->s_imap_blocks) {
		printk("minix_free_inode: nonexistent imap in superblock\n");
		return;
	}

	minix_clear_inode(inode);	/*                    */

	bh = sbi->s_imap[ino];
	spin_lock(&bitmap_lock);
	if (!minix_test_and_clear_bit(bit, bh->b_data))
		printk("minix_free_inode: bit %lu already cleared\n", bit);
	spin_unlock(&bitmap_lock);
	mark_buffer_dirty(bh);
}
Ejemplo n.º 6
0
static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
{
	int n = 0;
	char b[BDEVNAME_SIZE];

	if (block < 0) {
//		printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
;
	} else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) {
		if (printk_ratelimit())
//			printk("MINIX-fs: block_to_path: "
//			       "block %ld too big on dev %s\n",
;
	} else if (block < 7) {
		offsets[n++] = block;
	} else if ((block -= 7) < 512) {
		offsets[n++] = 7;
		offsets[n++] = block;
	} else {
		block -= 512;
		offsets[n++] = 8;
		offsets[n++] = block>>9;
		offsets[n++] = block & 511;
	}
	return n;
}
Ejemplo n.º 7
0
static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
{
	int n = 0;
	char b[BDEVNAME_SIZE];
	struct super_block *sb = inode->i_sb;

	if (block < 0) {
		printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
			block, bdevname(sb->s_bdev, b));
	} else if (block >= (minix_sb(inode->i_sb)->s_max_size/sb->s_blocksize)) {
		if (printk_ratelimit())
			printk("MINIX-fs: block_to_path: "
			       "block %ld too big on dev %s\n",
				block, bdevname(sb->s_bdev, b));
	} else if (block < DIRCOUNT) {
		offsets[n++] = block;
	} else if ((block -= DIRCOUNT) < INDIRCOUNT(sb)) {
		offsets[n++] = DIRCOUNT;
		offsets[n++] = block;
	} else if ((block -= INDIRCOUNT(sb)) < INDIRCOUNT(sb) * INDIRCOUNT(sb)) {
		offsets[n++] = DIRCOUNT + 1;
		offsets[n++] = block / INDIRCOUNT(sb);
		offsets[n++] = block % INDIRCOUNT(sb);
	} else {
		block -= INDIRCOUNT(sb) * INDIRCOUNT(sb);
		offsets[n++] = DIRCOUNT + 2;
		offsets[n++] = (block / INDIRCOUNT(sb)) / INDIRCOUNT(sb);
		offsets[n++] = (block / INDIRCOUNT(sb)) % INDIRCOUNT(sb);
		offsets[n++] = block % INDIRCOUNT(sb);
	}
	return n;
}
Ejemplo n.º 8
0
struct minix2_inode *
minix_V2_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
{
	int block;
	struct minix_sb_info *sbi = minix_sb(sb);
	struct minix2_inode *p;
	int minix2_inodes_per_block = sb->s_blocksize / sizeof(struct minix2_inode);

	*bh = NULL;
	if (!ino || ino > sbi->s_ninodes) {
		printk("Bad inode number on dev %s: %ld is out of range\n",
		       sb->s_id, (long)ino);
		return NULL;
	}
	ino--;
	block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks +
		 ino / minix2_inodes_per_block;
	*bh = sb_bread(sb, block);
	if (!*bh) {
		printk("Unable to read inode block\n");
		return NULL;
	}
	p = (void *)(*bh)->b_data;
	return p + ino % minix2_inodes_per_block;
}
Ejemplo n.º 9
0
/*return the disk address of an inode (pointer to an inode)*/
struct minix2_inode *
minix_V2_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)	/*read an inode from disk, put the block data into buffer_head*/
{
	int block;
	struct minix_sb_info *sbi = minix_sb(sb);
	struct minix2_inode *p;
	int minix2_inodes_per_block = sb->s_blocksize / sizeof(struct minix2_inode);
	printk(KERN_INFO "bitmap: minix_V2_raw_inode\n");	

	*bh = NULL;
	if (!ino || ino > sbi->s_ninodes) {
		printk("Bad inode number on dev %s: %ld is out of range\n",
		       sb->s_id, (long)ino);
		return NULL;
	}
	ino--;
	block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks +
		 ino / minix2_inodes_per_block;	/*get the block number (on disk) that contains the inode*/
	*bh = sb_bread(sb, block); /*read the block by sb_read(), value is put into bh buffer_head*/
	if (!*bh) {
		printk("Unable to read inode block\n");
		return NULL;
	}
	p = (void *)(*bh)->b_data;/*address of block contain the seeking inode*/
	return p + ino % minix2_inodes_per_block;
}
Ejemplo n.º 10
0
static int minix_remount (struct super_block * sb, int * flags, char * data)
{
	struct minix_sb_info * sbi = minix_sb(sb);
	struct minix_super_block * ms;

	ms = sbi->s_ms;
	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
		return 0;
	if (*flags & MS_RDONLY) {
		if (ms->s_state & MINIX_VALID_FS ||
		    !(sbi->s_mount_state & MINIX_VALID_FS))
			return 0;
		/* Mounting a rw partition read-only. */
		if (sbi->s_version != MINIX_V3)
			ms->s_state = sbi->s_mount_state;
		mark_buffer_dirty(sbi->s_sbh);
	} else {
	  	/* Mount a partition which is read-only, read-write. */
		if (sbi->s_version != MINIX_V3) {
			sbi->s_mount_state = ms->s_state;
			ms->s_state &= ~MINIX_VALID_FS;
		} else {
			sbi->s_mount_state = MINIX_VALID_FS;
		}
		mark_buffer_dirty(sbi->s_sbh);

		if (!(sbi->s_mount_state & MINIX_VALID_FS))
			printk("MINIX-fs warning: remounting unchecked fs, "
				"running fsck is recommended\n");
		else if ((sbi->s_mount_state & MINIX_ERROR_FS))
			printk("MINIX-fs warning: remounting fs with errors, "
				"running fsck is recommended\n");
	}
	return 0;
}
Ejemplo n.º 11
0
unsigned long minix_count_free_blocks(struct super_block *sb)
{
	struct minix_sb_info *sbi = minix_sb(sb);
	u32 bits = sbi->s_nzones - (sbi->s_firstdatazone + 1);

	return (count_free(sbi->s_zmap, sb->s_blocksize, bits)
		<< sbi->s_log_zone_size);
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags)
{
	struct inode * inode = NULL;
	ino_t ino;

	if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen)
		return ERR_PTR(-ENAMETOOLONG);

	ino = minix_inode_by_name(dentry);
	if (ino)
		inode = minix_iget(dir->i_sb, ino);
	return d_splice_alias(inode, dentry);
}
Ejemplo n.º 14
0
static int minix_link(struct dentry * old_dentry, struct inode * dir,
	struct dentry *dentry)
{
	struct inode *inode = old_dentry->d_inode;

	if (inode->i_nlink >= minix_sb(inode->i_sb)->s_link_max)
		return -EMLINK;

	inode->i_ctime = CURRENT_TIME_SEC;
	inc_count(inode);
	atomic_inc(&inode->i_count);
	return add_nondir(dentry, inode);
}
Ejemplo n.º 15
0
static int minix_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	struct minix_sb_info *sbi = minix_sb(dentry->d_sb);
	buf->f_type = dentry->d_sb->s_magic;
	buf->f_bsize = dentry->d_sb->s_blocksize;
	buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size;
	buf->f_bfree = minix_count_free_blocks(sbi);
	buf->f_bavail = buf->f_bfree;
	buf->f_files = sbi->s_ninodes;
	buf->f_ffree = minix_count_free_inodes(sbi);
	buf->f_namelen = sbi->s_namelen;
	return 0;
}
Ejemplo n.º 16
0
static void
unixfs_internal_fini(void* filsys)
{
    unixfs_inodelayer_fini();

    struct super_block* sb = (struct super_block*)filsys;
    if (sb) {
        struct minix_sb_info* sbi = minix_sb(sb);
        if (sbi)
            free(sbi);
        free(sb);
    }
}
Ejemplo n.º 17
0
static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
{
	struct inode * inode = NULL;
	ino_t ino;

	if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen)
		return ERR_PTR(-ENAMETOOLONG);

	ino = minix_inode_by_name(dentry);
	if (ino) {
		inode = minix_iget(dir->i_sb, ino);
		if (IS_ERR(inode))
			return ERR_CAST(inode);
	}
	d_add(dentry, inode);
	return NULL;
}
Ejemplo n.º 18
0
static int minix_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	struct super_block *sb = dentry->d_sb;
	struct minix_sb_info *sbi = minix_sb(sb);
	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
	buf->f_type = sb->s_magic;
	buf->f_bsize = sb->s_blocksize;
	buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size;
	buf->f_bfree = minix_count_free_blocks(sb);
	buf->f_bavail = buf->f_bfree;
	buf->f_files = sbi->s_ninodes;
	buf->f_ffree = minix_count_free_inodes(sb);
	buf->f_namelen = sbi->s_namelen;
	buf->f_fsid.val[0] = (u32)id;
	buf->f_fsid.val[1] = (u32)(id >> 32);

	return 0;
}
Ejemplo n.º 19
0
static void minix_put_super(struct super_block *sb)
{
	int i;
	struct minix_sb_info *sbi = minix_sb(sb);

	if (!(sb->s_flags & MS_RDONLY)) {
		if (sbi->s_version != MINIX_V3)	 /* s_state is now out from V3 sb */
			sbi->s_ms->s_state = sbi->s_mount_state;
		mark_buffer_dirty(sbi->s_sbh);
	}
	for (i = 0; i < sbi->s_imap_blocks; i++)
		brelse(sbi->s_imap[i]);
	for (i = 0; i < sbi->s_zmap_blocks; i++)
		brelse(sbi->s_zmap[i]);
	brelse (sbi->s_sbh);
	kfree(sbi->s_imap);
	sb->s_fs_info = NULL;
	kfree(sbi);
}
Ejemplo n.º 20
0
static int minix_hash(struct dentry *dentry, struct qstr *qstr)
{
	unsigned long hash;
	int i;
	const unsigned char *name;

	i = minix_sb(dentry->d_inode->i_sb)->s_namelen;
	if (i >= qstr->len)
		return 0;
	/* Truncate the name in place, avoids having to define a compare
	   function. */
	qstr->len = i;
	name = qstr->name;
	hash = init_name_hash();
	while (i--)
		hash = partial_name_hash(*name++, hash);
	qstr->hash = end_name_hash(hash);
	return 0;
}
Ejemplo n.º 21
0
static void minix_put_super(struct super_block *sb)
{
	int i;
	struct minix_sb_info *sbi = minix_sb(sb);

	if (!(sb->s_flags & MS_RDONLY)) {
		sbi->s_ms->s_state = sbi->s_mount_state;
		mark_buffer_dirty(sbi->s_sbh);
	}
	for (i = 0; i < sbi->s_imap_blocks; i++)
		brelse(sbi->s_imap[i]);
	for (i = 0; i < sbi->s_zmap_blocks; i++)
		brelse(sbi->s_zmap[i]);
	brelse (sbi->s_sbh);
	kfree(sbi->s_imap);
	sb->s_fs_info = NULL;
	kfree(sbi);

	return;
}
Ejemplo n.º 22
0
static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
{
	struct inode * inode = NULL;
	ino_t ino;

	dentry->d_op = dir->i_sb->s_root->d_op;

	if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen)
		return ERR_PTR(-ENAMETOOLONG);

	ino = minix_inode_by_name(dentry);
	if (ino) {
		inode = iget(dir->i_sb, ino);
 
		if (!inode)
			return ERR_PTR(-EACCES);
	}
	d_add(dentry, inode);
	return NULL;
}
Ejemplo n.º 23
0
static int block_to_path(struct inode* inode, long block, int offsets[DEPTH])
{
    int n = 0;
    struct super_block* sb = inode->I_sb;

    if (block < 0) {
        printk("MINIX-fs: block_to_path: block %ld < 0\n", block);
    } else if (block >= (minix_sb(inode->I_sb)->s_max_size/sb->s_blocksize)) {
        if (0)
            printk("MINIX-fs: block_to_path: block %ld too big\n", block);
    } else if (block < 7) {
        offsets[n++] = block;
    } else if ((block -= 7) < 256) {
        offsets[n++] = 7;
        offsets[n++] = block;
    } else if ((block -= 256) < 256 * 256) {
        offsets[n++] = 8;
        offsets[n++] = block >> 8;
        offsets[n++] = block & 255;
    } else {
Ejemplo n.º 24
0
static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
{
	struct inode * inode;
	int err = -EMLINK;

	if (dir->i_nlink >= minix_sb(dir->i_sb)->s_link_max)
		goto out;

	inc_count(dir);

	inode = minix_new_inode(dir, &err);
	if (!inode)
		goto out_dir;

	inode->i_mode = S_IFDIR | mode;
	if (dir->i_mode & S_ISGID)
		inode->i_mode |= S_ISGID;
	minix_set_inode(inode, 0);

	inc_count(inode);

	err = minix_make_empty(inode, dir);
	if (err)
		goto out_fail;

	err = minix_add_link(dentry, inode);
	if (err)
		goto out_fail;

	d_instantiate(dentry, inode);
out:
	return err;

out_fail:
	dec_count(inode);
	dec_count(inode);
	iput(inode);
out_dir:
	dec_count(dir);
	goto out;
}
Ejemplo n.º 25
0
static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
{
	int n = 0;

	if (block < 0) {
		printk("minix_bmap: block<0\n");
	} else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) {
		printk("minix_bmap: block>big\n");
	} else if (block < 7) {
		offsets[n++] = block;
	} else if ((block -= 7) < 512) {
		offsets[n++] = 7;
		offsets[n++] = block;
	} else {
		block -= 512;
		offsets[n++] = 8;
		offsets[n++] = block>>9;
		offsets[n++] = block & 511;
	}
	return n;
}
Ejemplo n.º 26
0
struct minix_inode *
minix_V1_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
{
	int block;
	struct minix_sb_info *sbi = minix_sb(sb);
	struct minix_inode *p;

	if (!ino || ino > sbi->s_ninodes) {
//		printk("Bad inode number on dev %s: %ld is out of range\n",
;
		return NULL;
	}
	ino--;
	block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks +
		 ino / MINIX_INODES_PER_BLOCK;
	*bh = sb_bread(sb, block);
	if (!*bh) {
;
		return NULL;
	}
	p = (void *)(*bh)->b_data;
	return p + ino % MINIX_INODES_PER_BLOCK;
}
Ejemplo n.º 27
0
static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
{
    int n = 0;
    char b[BDEVNAME_SIZE];
    struct super_block *sb = inode->i_sb;

    if (block < 0) {
        printk("MINIX-fs: block_to_path: block %ld < 0 on dev %s\n",
            block, bdevname(sb->s_bdev, b));
    } else if (block >= (minix_sb(inode->i_sb)->s_max_size/sb->s_blocksize)) {
        if (printk_ratelimit())
            printk("MINIX-fs: block_to_path: "
                   "block %ld too big on dev %s\n",
                block, bdevname(sb->s_bdev, b));
    } else if (block < 7) {
        offsets[n++] = block;
    } else if ((block -= 7) < 256) {
        offsets[n++] = 7;
        offsets[n++] = block;
    } else if ((block -= 256) < 256*256) {
        offsets[n++] = 8;
        offsets[n++] = block>>8;
        offsets[n++] = block & 255;
    } else {
Ejemplo n.º 28
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;
}
Ejemplo n.º 29
0
static void*
unixfs_internal_init(const char* dmg, uint32_t flags, __unused fs_endian_t fse,
                     char** fsname, char** volname)
{
    int fd = -1;

    if ((fd = open(dmg, O_RDONLY)) < 0) {
        perror("open");
        return NULL;
    }

    int err;
    struct stat stbuf;
    struct super_block* sb = (struct super_block*)0;

    if ((err = fstat(fd, &stbuf)) != 0) {
        perror("fstat");
        goto out;
    }

    if (!S_ISREG(stbuf.st_mode) && !(flags & UNIXFS_FORCE)) {
        err = EINVAL;
        fprintf(stderr, "%s is not a disk image file\n", dmg);
        goto out;
    }

    if ((err = unixfs_inodelayer_init(sizeof(struct minix_inode_info))) != 0)
        goto out;

    sb = minixfs_fill_super(fd, (void*)0, 1 /* silent */);
    if (!sb) {
        err = EINVAL;
        goto out;
    }

    struct minix_sb_info* sbi = minix_sb(sb);

    unixfs = sb;
    unixfs->s_flags = flags;

    (void)minixfs_statvfs(sb, &(unixfs->s_statvfs));

    unixfs->s_dentsize = 0;

    snprintf(unixfs->s_fsname, UNIXFS_MNAMELEN, "%s %s",
             unixfs_fstype, (sbi->s_version == MINIX_V3) ? "V3" :
             (sbi->s_version == MINIX_V2) ? "V2" :
             (sbi->s_version == MINIX_V1) ? "V1" : "??");
    snprintf(unixfs->s_volname, UNIXFS_MAXNAMLEN, "%s (%s)",
             unixfs_fstype, (sbi->s_version == MINIX_V3) ? "V3" :
             (sbi->s_version == MINIX_V2) ? "V2" :
             (sbi->s_version == MINIX_V1) ? "V1" : "??");

    *fsname = unixfs->s_fsname;
    *volname = unixfs->s_volname;

out:
    if (err) {
        if (fd > 0)
            close(fd);
        if (sb) {
            free(sb);
            sb = NULL;
        }
    }

    return sb;
}
Ejemplo n.º 30
0
static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
			   struct inode * new_dir, struct dentry *new_dentry)
{
	struct minix_sb_info * info = minix_sb(old_dir->i_sb);
	struct inode * old_inode = old_dentry->d_inode;
	struct inode * new_inode = new_dentry->d_inode;
	struct page * dir_page = NULL;
	struct minix_dir_entry * dir_de = NULL;
	struct page * old_page;
	struct minix_dir_entry * old_de;
	int err = -ENOENT;

	old_de = minix_find_entry(old_dentry, &old_page);
	if (!old_de)
		goto out;

	if (S_ISDIR(old_inode->i_mode)) {
		err = -EIO;
		dir_de = minix_dotdot(old_inode, &dir_page);
		if (!dir_de)
			goto out_old;
	}

	if (new_inode) {
		struct page * new_page;
		struct minix_dir_entry * new_de;

		err = -ENOTEMPTY;
		if (dir_de && !minix_empty_dir(new_inode))
			goto out_dir;

		err = -ENOENT;
		new_de = minix_find_entry(new_dentry, &new_page);
		if (!new_de)
			goto out_dir;
		inc_count(old_inode);
		minix_set_link(new_de, new_page, old_inode);
		new_inode->i_ctime = CURRENT_TIME_SEC;
		if (dir_de)
			new_inode->i_nlink--;
		dec_count(new_inode);
	} else {
		if (dir_de) {
			err = -EMLINK;
			if (new_dir->i_nlink >= info->s_link_max)
				goto out_dir;
		}
		inc_count(old_inode);
		err = minix_add_link(new_dentry, old_inode);
		if (err) {
			dec_count(old_inode);
			goto out_dir;
		}
		if (dir_de)
			inc_count(new_dir);
	}

	minix_delete_entry(old_de, old_page);
	dec_count(old_inode);

	if (dir_de) {
		minix_set_link(dir_de, dir_page, new_dir);
		dec_count(old_dir);
	}
	return 0;

out_dir:
	if (dir_de) {
		kunmap(dir_page);
		page_cache_release(dir_page);
	}
out_old:
	kunmap(old_page);
	page_cache_release(old_page);
out:
	return err;
}