Exemplo n.º 1
0
static inline void truncate (struct inode * inode)
{
	struct super_block *sb = inode->i_sb;
	block_t *idata = i_data(inode);
	int offsets[DEPTH];
	Indirect chain[DEPTH];
	Indirect *partial;
	block_t nr = 0;
	int n;
	int first_whole;
	long iblock;

	iblock = (inode->i_size + sb->s_blocksize -1) >> sb->s_blocksize_bits;
	block_truncate_page(inode->i_mapping, inode->i_size, get_block);

	n = block_to_path(inode, iblock, offsets);
	if (!n)
		return;

	if (n == 1) {
		free_data(inode, idata+offsets[0], idata + DIRECT);
		first_whole = 0;
		goto do_indirects;
	}

	first_whole = offsets[0] + 1 - DIRECT;
	partial = find_shared(inode, n, offsets, chain, &nr);
	if (nr) {
		if (partial == chain)
			mark_inode_dirty(inode);
		else
			mark_buffer_dirty_inode(partial->bh, inode);
		free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
	}
	/* Clear the ends of indirect blocks on the shared branch */
	while (partial > chain) {
		free_branches(inode, partial->p + 1, block_end(partial->bh),
				(chain+n-1) - partial);
		mark_buffer_dirty_inode(partial->bh, inode);
		brelse (partial->bh);
		partial--;
	}
do_indirects:
	/* Kill the remaining (whole) subtrees */
	while (first_whole < DEPTH-1) {
		nr = idata[DIRECT+first_whole];
		if (nr) {
			idata[DIRECT+first_whole] = 0;
			mark_inode_dirty(inode);
			free_branches(inode, &nr, &nr+1, first_whole+1);
		}
		first_whole++;
	}
	inode->i_mtime = inode->i_ctime = current_time(inode);
	mark_inode_dirty(inode);
}
Exemplo n.º 2
0
static bool add_address_range(struct dt_node *root,
			      const struct HDIF_ms_area_id *id,
			      const struct HDIF_ms_area_address_range *arange)
{
	struct dt_node *mem;
	u64 reg[2];
	char *name;
	u32 chip_id;
	size_t namesz = sizeof("memory@") + STR_MAX_CHARS(reg[0]);

	name = (char*)malloc(namesz);

	prlog(PR_DEBUG, "  Range: 0x%016llx..0x%016llx "
	      "on Chip 0x%x mattr: 0x%x\n",
	      (long long)arange->start, (long long)arange->end,
	      pcid_to_chip_id(arange->chip), arange->mirror_attr);

	/* reg contains start and length */
	reg[0] = cleanup_addr(be64_to_cpu(arange->start));
	reg[1] = cleanup_addr(be64_to_cpu(arange->end)) - reg[0];

	chip_id = pcid_to_chip_id(be32_to_cpu(arange->chip));

	if (be16_to_cpu(id->flags) & MS_AREA_SHARED) {
		/* Only enter shared nodes once. */ 
		mem = find_shared(root, be16_to_cpu(id->share_id),
				  reg[0], reg[1]);
		if (mem) {
			append_chip_id(mem, chip_id);
			return true;
		}
	}
	snprintf(name, namesz, "memory@%llx", (long long)reg[0]);

	mem = dt_new(root, name);
	dt_add_property_string(mem, "device_type", "memory");
	dt_add_property_cells(mem, "ibm,chip-id", chip_id);
	dt_add_property_u64s(mem, "reg", reg[0], reg[1]);
	if (be16_to_cpu(id->flags) & MS_AREA_SHARED)
		dt_add_property_cells(mem, DT_PRIVATE "share-id",
				      be16_to_cpu(id->share_id));

	free(name);

	return true;
}