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); }
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; }