Exemplo n.º 1
0
static int hfsplus_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
	struct inode *inode;
	hfsplus_handle_t hfsplus_handle;
	int res;

	if ((res = hfsplus_journal_start(__FUNCTION__, dir->i_sb, &hfsplus_handle)))
		return res;

	inode = hfsplus_new_inode(&hfsplus_handle, dir->i_sb, S_IFDIR | mode);
	if (!inode) {
		hfsplus_journal_stop(&hfsplus_handle);
		return -ENOSPC;
	}

	res = hfsplus_create_cat(&hfsplus_handle, inode->i_ino, dir, &dentry->d_name, inode);
	if (res) {
		inode->i_nlink = 0;
		hfsplus_delete_inode(&hfsplus_handle, inode);
		iput(inode);
		hfsplus_journal_stop(&hfsplus_handle);
		return res;
	}
	hfsplus_instantiate(dentry, inode, inode->i_ino);
	res = hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode);
	hfsplus_journal_stop(&hfsplus_handle);
	return res;
}
Exemplo n.º 2
0
static int hfsplus_mknod(struct inode *dir, struct dentry *dentry,
			 int mode, dev_t rdev)
{
	struct super_block *sb;
	struct inode *inode;
	hfsplus_handle_t hfsplus_handle;
	int res;

	if ((res = hfsplus_journal_start(__FUNCTION__, dir->i_sb, &hfsplus_handle)))
		return res;

	sb = dir->i_sb;
	inode = hfsplus_new_inode(&hfsplus_handle, sb, mode);
	if (!inode) {
		hfsplus_journal_stop(&hfsplus_handle);
		return -ENOSPC;
	}

	res = hfsplus_create_cat(&hfsplus_handle, inode->i_ino, dir, &dentry->d_name, inode);
	if (res) {
		inode->i_nlink = 0;
		hfsplus_delete_inode(&hfsplus_handle, inode);
		iput(inode);
		hfsplus_journal_stop(&hfsplus_handle);
		return res;
	}
	init_special_inode(inode, mode, rdev);
	hfsplus_instantiate(dentry, inode, inode->i_ino);
	res = hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode);

	hfsplus_journal_stop(&hfsplus_handle);
	return 0;
}
Exemplo n.º 3
0
static int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
{
	struct super_block *sb = dir->i_sb;
	struct inode *inode = dentry->d_inode;
	struct qstr str;
	char name[32];
	u32 cnid;
	int res;
	hfsplus_handle_t hfsplus_handle;

	if (HFSPLUS_IS_RSRC(inode))
		return -EPERM;

	if ((res = hfsplus_journal_start(__FUNCTION__, dir->i_sb, &hfsplus_handle)))
		return res;

	cnid = (u32)(unsigned long)dentry->d_fsdata;
	if (inode->i_ino == cnid &&
	    atomic_read(&HFSPLUS_I(inode).opencnt)) {
		str.name = name;
		str.len = sprintf(name, "temp%lu", inode->i_ino);
		res = hfsplus_rename_cat(&hfsplus_handle, inode->i_ino,
					 dir, &dentry->d_name,
					 HFSPLUS_SB(sb).hidden_dir, &str);
		if (!res)
			inode->i_flags |= S_DEAD;
		hfsplus_journal_stop(&hfsplus_handle);
		return res;
	}
	res = hfsplus_delete_cat(&hfsplus_handle, cnid, dir, &dentry->d_name);
	if (res) {
		hfsplus_journal_stop(&hfsplus_handle);
		return res;
	}
	if (inode->i_nlink > 0)
		drop_nlink(inode);
	if (inode->i_ino == cnid)
		clear_nlink(inode);
	if (!inode->i_nlink) {
		if (inode->i_ino != cnid) {
			HFSPLUS_SB(sb).file_count--;
			if (!atomic_read(&HFSPLUS_I(inode).opencnt)) {
			res = hfsplus_delete_cat(&hfsplus_handle, inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
				if (!res)
				hfsplus_delete_inode(&hfsplus_handle, inode);
			} else
				inode->i_flags |= S_DEAD;
		} else
			hfsplus_delete_inode(&hfsplus_handle,inode);
	} else
		HFSPLUS_SB(sb).file_count--;
	inode->i_ctime = CURRENT_TIME_SEC;
	res = hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode);

	hfsplus_journal_stop(&hfsplus_handle);
	return res;
}
Exemplo n.º 4
0
int hfs_brec_remove(hfsplus_handle_t *hfsplus_handle, struct hfs_find_data *fd)
{
	struct hfs_btree *tree;
	struct hfs_bnode *node, *parent;
	int end_off, rec_off, data_off, size;

	tree = fd->tree;
	node = fd->bnode;
again:
	rec_off = tree->node_size - (fd->record + 2) * 2;
	end_off = tree->node_size - (node->num_recs + 1) * 2;

	if (node->type == HFS_NODE_LEAF) {
		tree->leaf_count--;
		if (hfsplus_journalled_mark_inode_dirty(__FUNCTION__, hfsplus_handle, tree->inode))
			return -1;
	}
	hfs_bnode_dump(node);
	dprint(DBG_BNODE_MOD, "remove_rec: %d, %d\n", fd->record, fd->keylength + fd->entrylength);
	if (!--node->num_recs) {
		hfs_bnode_unlink(hfsplus_handle, node);
		if (!node->parent)
			return 0;
		parent = hfs_bnode_find(hfsplus_handle, tree, node->parent);
		if (IS_ERR(parent))
			return PTR_ERR(parent);
		hfs_bnode_put(hfsplus_handle, node);
		node = fd->bnode = parent;

		__hfs_brec_find(node, fd);
		goto again;
	}
	hfs_bnode_write_u16(hfsplus_handle, node, offsetof(struct hfs_bnode_desc, num_recs), node->num_recs);

	if (rec_off == end_off)
		goto skip;
	size = fd->keylength + fd->entrylength;

	do {
		data_off = hfs_bnode_read_u16(node, rec_off);
		hfs_bnode_write_u16(hfsplus_handle, node, rec_off + 2, data_off - size);
		rec_off -= 2;
	} while (rec_off >= end_off);

	/* fill hole */
	hfs_bnode_move(hfsplus_handle, node, fd->keyoffset, fd->keyoffset + size,
		       data_off - fd->keyoffset - size);
skip:
	hfs_bnode_dump(node);
	if (!fd->record)
		hfs_brec_update_parent(hfsplus_handle, fd);
	return 0;
}
Exemplo n.º 5
0
static int hfsplus_symlink(struct inode *dir, struct dentry *dentry,
			   const char *symname)
{
	struct super_block *sb;
	struct inode *inode;
	hfsplus_handle_t hfsplus_handle;
	int res;

	if ((res = hfsplus_journal_start(__FUNCTION__, dir->i_sb, &hfsplus_handle)))
		return res;

	sb = dir->i_sb;
	inode = hfsplus_new_inode(&hfsplus_handle, sb, S_IFLNK | S_IRWXUGO);
	if (!inode) {
		hfsplus_journal_stop(&hfsplus_handle);
		return -ENOSPC;
	}

	res = page_symlink(inode, symname, strlen(symname) + 1);
	if (res) {
		inode->i_nlink = 0;
		hfsplus_delete_inode(&hfsplus_handle, inode);
		iput(inode);
		hfsplus_journal_stop(&hfsplus_handle);
		return res;
	}

	if ((res = hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode)))
		goto symlink_out;
	res = hfsplus_create_cat(&hfsplus_handle, inode->i_ino, dir, &dentry->d_name, inode);

	if (!res) {
		hfsplus_instantiate(dentry, inode, inode->i_ino);
		res = hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode);
	}

symlink_out:
	hfsplus_journal_stop(&hfsplus_handle);
	return res;
}
Exemplo n.º 6
0
void hfsplus_file_truncate(struct inode *inode)
{
	struct super_block *sb = inode->i_sb;
	struct hfs_find_data fd;
	u32 alloc_cnt, blk_cnt, start;
	int res;
	hfsplus_handle_t hfsplus_handle;

	dprint(DBG_INODE, "truncate: %lu, %Lu -> %Lu\n", inode->i_ino,
	       (long long)HFSPLUS_I(inode).phys_size, inode->i_size);
	
	if (inode->i_size > HFSPLUS_I(inode).phys_size) {
		struct address_space *mapping = inode->i_mapping;
		struct page *page;
		void *fsdata;
		u32 size = inode->i_size - 1;
		int res;

		page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT);
		if (!page)
			return;
		size &= PAGE_CACHE_SIZE - 1;
		size++;
		res = mapping->a_ops->write_begin(NULL, mapping, size, 0,
						AOP_FLAG_UNINTERRUPTIBLE,
						&page, &fsdata);
		if (!res)
			res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
		if (res)
			inode->i_size = HFSPLUS_I(inode).phys_size;
		unlock_page(page);
		page_cache_release(page);
		if (hfsplus_journal_start(__FUNCTION__, sb, &hfsplus_handle))
			return;

		hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode);
		hfsplus_journal_stop(&hfsplus_handle);
		return;
	} else if (inode->i_size == HFSPLUS_I(inode).phys_size)
Exemplo n.º 7
0
static int hfsplus_rmdir(struct inode *dir, struct dentry *dentry)
{
	struct inode *inode;
	hfsplus_handle_t hfsplus_handle;
	int res;

	inode = dentry->d_inode;
	if (inode->i_size != 2)
		return -ENOTEMPTY;
	if ((res = hfsplus_journal_start(__FUNCTION__, dir->i_sb, &hfsplus_handle)))
		return res;

	res = hfsplus_delete_cat(&hfsplus_handle, inode->i_ino, dir, &dentry->d_name);
	if (res) {
		hfsplus_journal_stop(&hfsplus_handle);
		return res;
	}
	clear_nlink(inode);
	inode->i_ctime = CURRENT_TIME_SEC;
	hfsplus_delete_inode(&hfsplus_handle, inode);
	res = hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode);
	hfsplus_journal_stop(&hfsplus_handle);
	return res;
}
Exemplo n.º 8
0
int hfs_brec_insert(hfsplus_handle_t *hfsplus_handle, struct hfs_find_data *fd, void *entry, int entry_len)
{
	struct hfs_btree *tree;
	struct hfs_bnode *node, *new_node;
	int size, key_len, rec;
	int data_off, end_off;
	int idx_rec_off, data_rec_off, end_rec_off;
	__be32 cnid;

	tree = fd->tree;
	if (!fd->bnode) {
		if (!tree->root)
			hfs_btree_inc_height(hfsplus_handle, tree);
		fd->bnode = hfs_bnode_find(hfsplus_handle, tree, tree->leaf_head);
		if (IS_ERR(fd->bnode))
			return PTR_ERR(fd->bnode);
		fd->record = -1;
	}
	new_node = NULL;
	key_len = be16_to_cpu(fd->search_key->key_len) + 2;
again:
	/* new record idx and complete record size */
	rec = fd->record + 1;
	size = key_len + entry_len;

	node = fd->bnode;
	hfs_bnode_dump(node);
	/* get last offset */
	end_rec_off = tree->node_size - (node->num_recs + 1) * 2;
	end_off = hfs_bnode_read_u16(node, end_rec_off);
	end_rec_off -= 2;
	dprint(DBG_BNODE_MOD, "insert_rec: %d, %d, %d, %d\n", rec, size, end_off, end_rec_off);
	if (size > end_rec_off - end_off) {
		if (new_node)
			panic("not enough room!\n");
		new_node = hfs_bnode_split(hfsplus_handle, fd);
		if (IS_ERR(new_node))
			return PTR_ERR(new_node);
		goto again;
	}
	if (node->type == HFS_NODE_LEAF) {
		tree->leaf_count++;
		if (hfsplus_journalled_mark_inode_dirty(__FUNCTION__, hfsplus_handle, tree->inode))
			return -1;
	}
	node->num_recs++;
	/* write new last offset */
	hfs_bnode_write_u16(hfsplus_handle, node, offsetof(struct hfs_bnode_desc, num_recs), node->num_recs);
	hfs_bnode_write_u16(hfsplus_handle, node, end_rec_off, end_off + size);
	data_off = end_off;
	data_rec_off = end_rec_off + 2;
	idx_rec_off = tree->node_size - (rec + 1) * 2;
	if (idx_rec_off == data_rec_off)
		goto skip;
	/* move all following entries */
	do {
		data_off = hfs_bnode_read_u16(node, data_rec_off + 2);
		hfs_bnode_write_u16(hfsplus_handle, node, data_rec_off, data_off + size);
		data_rec_off += 2;
	} while (data_rec_off < idx_rec_off);

	/* move data away */
	hfs_bnode_move(hfsplus_handle, node, data_off + size, data_off,
		       end_off - data_off);

skip:
	hfs_bnode_write(hfsplus_handle, node, fd->search_key, data_off, key_len);
	hfs_bnode_write(hfsplus_handle, node, entry, data_off + key_len, entry_len);
	hfs_bnode_dump(node);

	if (new_node) {
		/* update parent key if we inserted a key
		 * at the start of the first node
		 */
		if (!rec && new_node != node)
			hfs_brec_update_parent(hfsplus_handle, fd);

		hfs_bnode_put(hfsplus_handle, fd->bnode);
		if (!new_node->parent) {
			hfs_btree_inc_height(hfsplus_handle, tree);
			new_node->parent = tree->root;
		}
		fd->bnode = hfs_bnode_find(hfsplus_handle, tree, new_node->parent);

		/* create index data entry */
		cnid = cpu_to_be32(new_node->this);
		entry = &cnid;
		entry_len = sizeof(cnid);

		/* get index key */
		hfs_bnode_read_key(new_node, fd->search_key, 14);
		__hfs_brec_find(fd->bnode, fd);

		hfs_bnode_put(hfsplus_handle, new_node);
		new_node = NULL;

		if (tree->attributes & HFS_TREE_VARIDXKEYS)
			key_len = be16_to_cpu(fd->search_key->key_len) + 2;
		else {
			fd->search_key->key_len = cpu_to_be16(tree->max_key_len);
			key_len = tree->max_key_len + 2;
		}
		goto again;
	}

	if (!rec)
		hfs_brec_update_parent(hfsplus_handle, fd);

	return 0;
}
Exemplo n.º 9
0
static int hfsplus_link(struct dentry *src_dentry, struct inode *dst_dir,
			struct dentry *dst_dentry)
{
	struct super_block *sb = dst_dir->i_sb;
	struct inode *inode = src_dentry->d_inode;
	struct inode *src_dir = src_dentry->d_parent->d_inode;
	hfsplus_handle_t hfsplus_handle;
	struct qstr str;
	char name[32];
	u32 cnid, id;
	int res;

	if (HFSPLUS_IS_RSRC(inode))
		return -EPERM;

	if ((res = hfsplus_journal_start(__FUNCTION__, dst_dir->i_sb, &hfsplus_handle)))
		return res;

	if (inode->i_ino == (u32)(unsigned long)src_dentry->d_fsdata) {
		for (;;) {
			get_random_bytes(&id, sizeof(cnid));
			id &= 0x3fffffff;
			str.name = name;
			str.len = sprintf(name, "iNode%d", id);
			res = hfsplus_rename_cat(&hfsplus_handle, inode->i_ino,
						 src_dir, &src_dentry->d_name,
						 HFSPLUS_SB(sb).hidden_dir, &str);
			if (!res)
				break;
			if (res != -EEXIST) {
				hfsplus_journal_stop(&hfsplus_handle);
				return res;
			}
		}
		HFSPLUS_I(inode).dev = id;
		cnid = HFSPLUS_SB(sb).next_cnid++;
		src_dentry->d_fsdata = (void *)(unsigned long)cnid;
		res = hfsplus_create_cat(&hfsplus_handle, cnid, src_dir, &src_dentry->d_name, inode);
		if (res) {
			/* panic? */
			hfsplus_journal_stop(&hfsplus_handle);
			return res;
		}
		HFSPLUS_SB(sb).file_count++;
	}
	cnid = HFSPLUS_SB(sb).next_cnid++;
	res = hfsplus_create_cat(&hfsplus_handle, cnid, dst_dir, &dst_dentry->d_name, inode);
	if (res) {
		hfsplus_journal_stop(&hfsplus_handle);
		return res;
	}

	inc_nlink(inode);
	hfsplus_instantiate(dst_dentry, inode, cnid);
	atomic_inc(&inode->i_count);
	inode->i_ctime = CURRENT_TIME_SEC;
	res = hfsplus_journalled_mark_inode_dirty(__FUNCTION__, &hfsplus_handle, inode);
	HFSPLUS_SB(sb).file_count++;
	sb->s_dirt = 1;

	hfsplus_journal_stop(&hfsplus_handle);
	return res;
}
Exemplo n.º 10
0
int hfsplus_file_extend(hfsplus_handle_t *hfsplus_handle, struct inode *inode)
{
	struct super_block *sb = inode->i_sb;
	u32 start, len, goal;
	int res;

	if (HFSPLUS_SB(sb).alloc_file->i_size * 8 < HFSPLUS_SB(sb).total_blocks - HFSPLUS_SB(sb).free_blocks + 8) {
		// extend alloc file
		printk("extend alloc file! (%Lu,%u,%u)\n", HFSPLUS_SB(sb).alloc_file->i_size * 8,
			HFSPLUS_SB(sb).total_blocks, HFSPLUS_SB(sb).free_blocks);
		return -ENOSPC;
		//BUG();
	}

	mutex_lock(&HFSPLUS_I(inode).extents_lock);
	if (HFSPLUS_I(inode).alloc_blocks == HFSPLUS_I(inode).first_blocks)
		goal = hfsplus_ext_lastblock(HFSPLUS_I(inode).first_extents);
	else {
		res = hfsplus_ext_read_extent(hfsplus_handle, inode, HFSPLUS_I(inode).alloc_blocks);
		if (res)
			goto out;
		goal = hfsplus_ext_lastblock(HFSPLUS_I(inode).cached_extents);
	}

	len = HFSPLUS_I(inode).clump_blocks;
	start = hfsplus_block_allocate(hfsplus_handle, sb, HFSPLUS_SB(sb).total_blocks, goal, &len);
	if (start >= HFSPLUS_SB(sb).total_blocks) {
		start = hfsplus_block_allocate(hfsplus_handle, sb, goal, 0, &len);
		if (start >= goal) {
			res = -ENOSPC;
			goto out;
		}
	}

	dprint(DBG_EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len);
	if (HFSPLUS_I(inode).alloc_blocks <= HFSPLUS_I(inode).first_blocks) {
		if (!HFSPLUS_I(inode).first_blocks) {
			dprint(DBG_EXTENT, "first extents\n");
			/* no extents yet */
			HFSPLUS_I(inode).first_extents[0].start_block = cpu_to_be32(start);
			HFSPLUS_I(inode).first_extents[0].block_count = cpu_to_be32(len);
			res = 0;
		} else {
			/* try to append to extents in inode */
			res = hfsplus_add_extent(HFSPLUS_I(inode).first_extents,
						 HFSPLUS_I(inode).alloc_blocks,
						 start, len);
			if (res == -ENOSPC)
				goto insert_extent;
		}
		if (!res) {
			hfsplus_dump_extent(HFSPLUS_I(inode).first_extents);
			HFSPLUS_I(inode).first_blocks += len;
		}
	} else {
		res = hfsplus_add_extent(HFSPLUS_I(inode).cached_extents,
					 HFSPLUS_I(inode).alloc_blocks -
					 HFSPLUS_I(inode).cached_start,
					 start, len);
		if (!res) {
			hfsplus_dump_extent(HFSPLUS_I(inode).cached_extents);
			HFSPLUS_I(inode).flags |= HFSPLUS_FLG_EXT_DIRTY;
			HFSPLUS_I(inode).cached_blocks += len;
		} else if (res == -ENOSPC)
			goto insert_extent;
	}
out:
	mutex_unlock(&HFSPLUS_I(inode).extents_lock);
	if (!res) {
		HFSPLUS_I(inode).alloc_blocks += len;
		res = hfsplus_journalled_mark_inode_dirty(__FUNCTION__, hfsplus_handle, inode);
	}
	return res;

insert_extent:
	dprint(DBG_EXTENT, "insert new extent\n");
	hfsplus_ext_write_extent(hfsplus_handle, inode);

	memset(HFSPLUS_I(inode).cached_extents, 0, sizeof(hfsplus_extent_rec));
	HFSPLUS_I(inode).cached_extents[0].start_block = cpu_to_be32(start);
	HFSPLUS_I(inode).cached_extents[0].block_count = cpu_to_be32(len);
	hfsplus_dump_extent(HFSPLUS_I(inode).cached_extents);
	HFSPLUS_I(inode).flags |= HFSPLUS_FLG_EXT_DIRTY | HFSPLUS_FLG_EXT_NEW;
	HFSPLUS_I(inode).cached_start = HFSPLUS_I(inode).alloc_blocks;
	HFSPLUS_I(inode).cached_blocks = len;

	res = 0;
	goto out;
}
Exemplo n.º 11
0
/* Get a block at iblock for inode, possibly allocating if create */
int hfsplus_get_block(struct inode *inode, sector_t iblock,
		      struct buffer_head *bh_result, int create)
{
	struct super_block *sb;
	int res = -EIO;
	u32 ablock, dblock, mask;
	int shift;
	hfsplus_handle_t *hfsplus_handle, tmp_hfsplus_handle;

	tmp_hfsplus_handle.journaled = !HFSPLUS_JOURNAL_PRESENT;
	tmp_hfsplus_handle.handle = NULL;

	sb = inode->i_sb;

	/* Journal device */
	if (HFSPLUS_SB(sb).jnl.journaled == HFSPLUS_JOURNAL_PRESENT) {
		/* Write Metadata */
		if (((inode->i_mapping->a_ops == &hfsplus_journalled_btree_aops) || 
			(inode->i_mapping->a_ops == &hfsplus_journalled_aops)) && create) {
			hfsplus_handle = hfsplus_jbd_current_handle();
			if (hfsplus_handle == NULL) {
				printk("hfsplus_handle is NULL\n");
				hfsplus_handle = &tmp_hfsplus_handle; 
			}
		}
		else { 
			hfsplus_handle = &tmp_hfsplus_handle;
		}
	}
	/* Non-journal device */ 
	else {
		hfsplus_handle = &tmp_hfsplus_handle;
	}

	/* Convert inode block to disk allocation block */
	shift = HFSPLUS_SB(sb).alloc_blksz_shift - sb->s_blocksize_bits;
	ablock = iblock >> HFSPLUS_SB(sb).fs_shift;

	if (iblock >= HFSPLUS_I(inode).fs_blocks) {
		if (iblock > HFSPLUS_I(inode).fs_blocks || !create) {
			return -EIO;
		}
		if (ablock >= HFSPLUS_I(inode).alloc_blocks) {
			res = hfsplus_file_extend(hfsplus_handle, inode);
			if (res) {
				return res;
			}
		}
	} else
		create = 0;

	if (ablock < HFSPLUS_I(inode).first_blocks) {
		dblock = hfsplus_ext_find_block(HFSPLUS_I(inode).first_extents, ablock);
		goto done;
	}

	mutex_lock(&HFSPLUS_I(inode).extents_lock);
	res = hfsplus_ext_read_extent(hfsplus_handle, inode, ablock);
	if (!res) {
		dblock = hfsplus_ext_find_block(HFSPLUS_I(inode).cached_extents, ablock -
					     HFSPLUS_I(inode).cached_start);
	} else {
		mutex_unlock(&HFSPLUS_I(inode).extents_lock);
		return -EIO;
	}
	mutex_unlock(&HFSPLUS_I(inode).extents_lock);

done:
	dprint(DBG_EXTENT, "get_block(%lu): %llu - %u\n", inode->i_ino, (long long)iblock, dblock);
	mask = (1 << HFSPLUS_SB(sb).fs_shift) - 1;
	map_bh(bh_result, sb, (dblock << HFSPLUS_SB(sb).fs_shift) + HFSPLUS_SB(sb).blockoffset + (iblock & mask));
	if (create) {
		set_buffer_new(bh_result);
		HFSPLUS_I(inode).phys_size += sb->s_blocksize;
		HFSPLUS_I(inode).fs_blocks++;
		inode_add_bytes(inode, sb->s_blocksize);
		if (hfsplus_journalled_mark_inode_dirty(__FUNCTION__, hfsplus_handle, inode)) {
			printk("HFS+-fs: Error in %s()\n", __FUNCTION__);
			return -1;
		}
	}
	return 0;
}