From: Hans Reiser This is an update for reiser4 in 2.6.11-mm3. It is an additional patch to the set of reiser4 patches. Signed-off-by: Andrew Morton --- 25-akpm/fs/reiser4/carry.h | 2 25-akpm/fs/reiser4/carry_ops.c | 1 25-akpm/fs/reiser4/cluster.h | 2 25-akpm/fs/reiser4/context.c | 16 25-akpm/fs/reiser4/flush.c | 132 ------- 25-akpm/fs/reiser4/inode.c | 93 ----- 25-akpm/fs/reiser4/inode.h | 2 25-akpm/fs/reiser4/jnode.h | 10 25-akpm/fs/reiser4/lock.c | 14 25-akpm/fs/reiser4/page_cache.c | 5 25-akpm/fs/reiser4/page_cache.h | 3 25-akpm/fs/reiser4/plugin/compress/minilzo.c | 398 ----------------------- 25-akpm/fs/reiser4/plugin/cryptcompress.c | 239 ++++++++----- 25-akpm/fs/reiser4/plugin/cryptcompress.h | 2 25-akpm/fs/reiser4/plugin/file/file.c | 42 +- 25-akpm/fs/reiser4/plugin/file/tail_conversion.c | 4 25-akpm/fs/reiser4/plugin/item/blackbox.c | 2 25-akpm/fs/reiser4/plugin/item/cde.c | 2 25-akpm/fs/reiser4/plugin/item/ctail.c | 65 --- 25-akpm/fs/reiser4/plugin/item/extent_item_ops.c | 97 ----- 25-akpm/fs/reiser4/plugin/item/sde.c | 2 25-akpm/fs/reiser4/plugin/item/tail.c | 2 25-akpm/fs/reiser4/plugin/item/tail.h | 1 25-akpm/fs/reiser4/plugin/object.c | 2 25-akpm/fs/reiser4/plugin/object.h | 3 25-akpm/fs/reiser4/plugin/plugin.h | 2 25-akpm/fs/reiser4/tree.c | 65 +-- 25-akpm/fs/reiser4/tree.h | 12 25-akpm/fs/reiser4/tree_walk.c | 4 25-akpm/fs/reiser4/vfs_ops.c | 12 30 files changed, 259 insertions(+), 977 deletions(-) diff -puN fs/reiser4/carry.h~reiser4-update fs/reiser4/carry.h --- 25/fs/reiser4/carry.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/carry.h 2005-03-15 22:44:12.000000000 -0800 @@ -159,6 +159,8 @@ struct cut_kill_params { /* if this is not NULL, smallest actually removed key is stored * here. */ reiser4_key *smallest_removed; + /* kill_node_content() is called for file truncate */ + int truncate; }; struct carry_cut_data { diff -puN fs/reiser4/carry_ops.c~reiser4-update fs/reiser4/carry_ops.c --- 25/fs/reiser4/carry_ops.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/carry_ops.c 2005-03-15 22:44:12.000000000 -0800 @@ -1283,6 +1283,7 @@ carry_delete(carry_op * op /* operation kdata.params.from_key = NULL; kdata.params.to_key = NULL; kdata.params.smallest_removed = NULL; + kdata.params.truncate = 1; kdata.flags = op->u.delete.flags; kdata.inode = 0; kdata.left = 0; diff -puN fs/reiser4/cluster.h~reiser4-update fs/reiser4/cluster.h --- 25/fs/reiser4/cluster.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/cluster.h 2005-03-15 22:44:12.000000000 -0800 @@ -233,7 +233,7 @@ void set_hint_cluster(struct inode * ino int get_disk_cluster_locked(reiser4_cluster_t * clust, struct inode * inode, znode_lock_mode lock_mode); void reset_cluster_params(reiser4_cluster_t * clust); int prepare_page_cluster(struct inode *inode, reiser4_cluster_t *clust, int capture); -void release_cluster_pages(reiser4_cluster_t * clust, int from); +void release_cluster_pages_nocapture(reiser4_cluster_t *); void put_cluster_handle(reiser4_cluster_t * clust, tfm_action act); int grab_tfm_stream(struct inode * inode, tfm_cluster_t * tc, tfm_action act, tfm_stream_id id); int tfm_cluster_is_uptodate (tfm_cluster_t * tc); diff -puN fs/reiser4/context.c~reiser4-update fs/reiser4/context.c --- 25/fs/reiser4/context.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/context.c 2005-03-15 22:44:12.000000000 -0800 @@ -47,20 +47,6 @@ static context_list_head active_contexts /* lock protecting access to active_contexts. */ spinlock_t active_contexts_lock; -#if 0 -void -check_contexts(void) -{ - reiser4_context *ctx; - - spin_lock(&active_contexts_lock); - for_all_type_safe_list(context, &active_contexts, ctx) { - assert("vs-$BIGNUM", ctx->magic == context_magic); - } - spin_unlock(&active_contexts_lock); -} -#endif /* 0 */ - #endif /* REISER4_DEBUG */ /* initialise context and bind it to the current thread @@ -111,7 +97,6 @@ init_context(reiser4_context * context / spin_lock(&active_contexts_lock); context_list_check(&active_contexts); context_list_push_front(&active_contexts, context); - /*check_contexts();*/ spin_unlock(&active_contexts_lock); context->task = current; #endif @@ -248,7 +233,6 @@ done_context(reiser4_context * context / #if REISER4_DEBUG /* remove from active contexts */ spin_lock(&active_contexts_lock); - /*check_contexts();*/ context_list_remove(parent); spin_unlock(&active_contexts_lock); #endif diff -puN fs/reiser4/flush.c~reiser4-update fs/reiser4/flush.c --- 25/fs/reiser4/flush.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/flush.c 2005-03-15 22:44:12.000000000 -0800 @@ -433,6 +433,7 @@ assert("nikita-3435", \ extent_is_unallocated(&scan->parent_coord), \ extent_unit_index(&scan->parent_coord) == index_jnode(scan->node))) + /* This flush_cnt variable is used to track the number of concurrent flush operations, useful for debugging. It is initialized in txnmgr.c out of laziness (because flush has no static initializer function...) */ @@ -508,7 +509,7 @@ static int delete_empty_node (znode * no assert("zam-1020", node_is_empty(node)); assert("zam-1023", znode_is_wlocked(node)); - return delete_node(node, &smallest_removed, NULL); + return delete_node(node, &smallest_removed, NULL, 1); } /* Prepare flush position for alloc_pos_and_ancestors() and squalloc() */ @@ -557,135 +558,6 @@ static int prepare_flush_pos(flush_pos_t return ret; } -#if REISER4_DEBUG - -const char *coord_tween_tostring(between_enum n); - -#if 0 - -static void -jnode_tostring_internal(jnode * node, char *buf) -{ - const char *state; - char atom[32]; - char block[48]; - char items[32]; - int fmttd; - int dirty; - int lockit; - - lockit = spin_trylock_jnode(node); - - fmttd = jnode_is_znode(node); - dirty = JF_ISSET(node, JNODE_DIRTY); - - sprintf(block, " block=%s page=%p state=%lx", sprint_address(jnode_get_block(node)), node->pg, node->state); - - if (JF_ISSET(node, JNODE_OVRWR)) { - state = dirty ? "wandr,dirty" : "wandr"; - } else if (JF_ISSET(node, JNODE_RELOC) && JF_ISSET(node, JNODE_CREATED)) { - state = dirty ? "creat,dirty" : "creat"; - } else if (JF_ISSET(node, JNODE_RELOC)) { - state = dirty ? "reloc,dirty" : "reloc"; - } else if (JF_ISSET(node, JNODE_CREATED)) { - assert("jmacd-61554", dirty); - state = "fresh"; - block[0] = 0; - } else { - state = dirty ? "dirty" : "clean"; - } - - if (node->atom == NULL) { - atom[0] = 0; - } else { - sprintf(atom, " atom=%u", node->atom->atom_id); - } - - items[0] = 0; - if (!fmttd) { - sprintf(items, " index=%lu", index_jnode(node)); - } - - sprintf(buf + strlen(buf), - "%s=%p [%s%s%s level=%u%s%s]", - fmttd ? "z" : "j", - node, - state, atom, block, jnode_get_level(node), items, JF_ISSET(node, JNODE_FLUSH_QUEUED) ? " fq" : ""); - - if (lockit == 1) { - UNLOCK_JNODE(node); - } -} - -reiser4_internal const char * -jnode_tostring(jnode * node) -{ - static char fmtbuf[256]; - fmtbuf[0] = 0; - jnode_tostring_internal(node, fmtbuf); - return fmtbuf; -} - -reiser4_internal const char * -znode_tostring(znode * node) -{ - return jnode_tostring(ZJNODE(node)); -} - - -reiser4_internal const char * -pos_tostring(flush_pos_t * pos) -{ - static char fmtbuf[256]; - load_count load; - fmtbuf[0] = 0; - - init_load_count(&load); - - if (pos->state == POS_ON_EPOINT) { - assert("jmacd-79123", pos->lock.node == pos->load.node); - - strcat(fmtbuf, "par:"); - jnode_tostring_internal(ZJNODE(pos->lock.node), fmtbuf); - - if (incr_load_count_znode(&load, pos->lock.node)) { - return "*error*"; - } - - if (coord_is_before_leftmost(&pos->coord)) { - sprintf(fmtbuf + strlen(fmtbuf), "[left]"); - } else if (coord_is_after_rightmost(&pos->coord)) { - sprintf(fmtbuf + strlen(fmtbuf), "[right]"); - } else { - sprintf(fmtbuf + strlen(fmtbuf), "[%s i=%u/%u", - coord_tween_tostring(pos->coord.between), - pos->coord.item_pos, node_num_items(pos->coord.node)); - - if (!coord_is_existing_item(&pos->coord)) { - sprintf(fmtbuf + strlen(fmtbuf), "]"); - } else { - - sprintf(fmtbuf + strlen(fmtbuf), ",u=%u/%u %s]", - pos->coord.unit_pos, - coord_num_units(&pos->coord), coord_is_existing_unit(&pos->coord) - ? (item_is_extent(&pos->coord) ? - "ext" : (item_is_internal(&pos->coord) ? "int" : "other")) - : "tween"); - } - } - } else if (pos->lock.node != NULL) { - strcat(fmtbuf, "pt:"); - jnode_tostring_internal(ZJNODE(pos->lock.node), fmtbuf); - } - - done_load_count(&load); - return fmtbuf; -} - -#endif /* 0 */ - -#endif /* REISER4_TRACE */ - /* TODO LIST (no particular order): */ /* I have labelled most of the legitimate FIXME comments in this file with letters to indicate which issue they relate to. There are a few miscellaneous FIXMEs with diff -puN fs/reiser4/inode.c~reiser4-update fs/reiser4/inode.c --- 25/fs/reiser4/inode.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/inode.c 2005-03-15 22:44:12.000000000 -0800 @@ -608,12 +608,20 @@ inode_set_plugin(struct inode *inode, re } reiser4_internal void +inode_check_scale_nolock(struct inode *inode, __u64 old, __u64 new) +{ + assert("edward-1287", inode != NULL); + if (!dscale_fit(old, new)) + inode_clr_flag(inode, REISER4_SDLEN_KNOWN); + return; +} + +reiser4_internal void inode_check_scale(struct inode *inode, __u64 old, __u64 new) { assert("nikita-2875", inode != NULL); spin_lock_inode(inode); - if (!dscale_fit(old, new)) - inode_clr_flag(inode, REISER4_SDLEN_KNOWN); + inode_check_scale_nolock(inode, old, new); spin_unlock_inode(inode); } @@ -678,87 +686,8 @@ inode_set_vroot(struct inode *inode, zno UNLOCK_INODE(info); } -#if 0 -reiser4_internal int -get_reiser4_inode_by_key (struct inode ** result, const reiser4_key * key) -{ - struct super_block * super = reiser4_get_current_sb(); - struct inode * inode; - - /* We do not need to read reiser4 inode from disk and initialize all - * reiser4 inode fields. */ - inode = iget_locked(super, (unsigned long)get_key_objectid(key)); - if (inode == NULL) - return -ENOMEM; - if (is_bad_inode(inode)) { - iput(inode); - return -EIO; - } - - if (inode->i_state & I_NEW) { - reiser4_inode * inode_data = reiser4_inode_data(inode); - - /* These inode fields are required for tree traversal. */ - set_inode_oid(inode, get_key_objectid(key)); - inode_data->locality_id = get_key_locality(key); -#if REISER4_LARGE_KEY - inode_data->ordering = get_key_ordering(key); -#endif - - inode->i_mapping->a_ops = &reiser4_as_operations; - unlock_new_inode(inode); - } - - *result = inode; - return 0; -} -#endif /* 0 */ - - -#if REISER4_DEBUG_OUTPUT -/* Debugging aid: print information about inode. */ -reiser4_internal void -print_inode(const char *prefix /* prefix to print */ , - const struct inode *i /* inode to print */ ) -{ - reiser4_key inode_key; - reiser4_inode *ref; - - if (i == NULL) { - printk("%s: inode: null\n", prefix); - return; - } - printk("%s: ino: %lu, count: %i, link: %i, mode: %o, size: %llu\n", - prefix, i->i_ino, atomic_read(&i->i_count), i->i_nlink, i->i_mode, (unsigned long long) i->i_size); - printk("\tuid: %i, gid: %i, dev: %i, rdev: %i\n", i->i_uid, i->i_gid, i->i_sb->s_dev, i->i_rdev); - printk("\tatime: [%li,%li], mtime: [%li,%li], ctime: [%li,%li]\n", - i->i_atime.tv_sec, i->i_atime.tv_nsec, - i->i_mtime.tv_sec, i->i_mtime.tv_nsec, - i->i_ctime.tv_sec, i->i_ctime.tv_nsec); - printk("\tblkbits: %i, blksize: %lu, blocks: %lu, bytes: %u\n", - i->i_blkbits, i->i_blksize, i->i_blocks, i->i_bytes); - printk("\tversion: %lu, generation: %i, state: %lu, flags: %u\n", - i->i_version, i->i_generation, i->i_state, i->i_flags); - printk("\tis_reiser4_inode: %i\n", is_reiser4_inode(i)); - print_key("\tkey", build_sd_key(i, &inode_key)); - ref = reiser4_inode_data(i); - print_plugin("\tfile", file_plugin_to_plugin(ref->pset->file)); - print_plugin("\tdir", dir_plugin_to_plugin(ref->pset->dir)); - print_plugin("\tperm", perm_plugin_to_plugin(ref->pset->perm)); - print_plugin("\tformatting", formatting_plugin_to_plugin(ref->pset->formatting)); - print_plugin("\thash", hash_plugin_to_plugin(ref->pset->hash)); - print_plugin("\tsd", item_plugin_to_plugin(ref->pset->sd)); - - /* FIXME-VS: this segfaults trying to print seal's coord */ - print_seal("\tsd_seal", &ref->sd_seal); - print_coord("\tsd_coord", &ref->sd_coord, 0); - printk("\tflags: %#lx, extmask: %#llx, pmask: %i, locality: %llu\n", - *inode_flags(i), ref->extmask, - ref->plugin_mask, ref->locality_id); -} -#endif - #if REISER4_DEBUG + void inode_invariant(const struct inode *inode) { diff -puN fs/reiser4/inode.h~reiser4-update fs/reiser4/inode.h --- 25/fs/reiser4/inode.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/inode.h 2005-03-15 22:44:12.000000000 -0800 @@ -321,8 +321,6 @@ extern int is_reiser4_inode(const struct extern int setup_inode_ops(struct inode *inode, reiser4_object_create_data *); extern struct inode *reiser4_iget(struct super_block *super, const reiser4_key * key, int silent); extern void reiser4_iget_complete (struct inode * inode); - - extern void inode_set_flag(struct inode *inode, reiser4_file_plugin_flags f); extern void inode_clr_flag(struct inode *inode, reiser4_file_plugin_flags f); extern int inode_get_flag(const struct inode *inode, reiser4_file_plugin_flags f); diff -puN fs/reiser4/jnode.h~reiser4-update fs/reiser4/jnode.h --- 25/fs/reiser4/jnode.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/jnode.h 2005-03-15 22:44:12.000000000 -0800 @@ -457,18 +457,18 @@ extern int jnodes_tree_init(reiser4_tree extern int jnodes_tree_done(reiser4_tree * tree); #if REISER4_DEBUG + extern int znode_is_any_locked(const znode * node); extern void jnode_list_remove(jnode * node); -#else -#define jnode_list_remove(node) noop -#endif - -#if REISER4_DEBUG extern void info_jnode(const char *prefix, const jnode * node); extern void print_jnode(const char *prefix, const jnode * node); + #else + +#define jnode_list_remove(node) noop #define info_jnode(p, n) noop #define print_jnode(p, n) noop + #endif int znode_is_root(const znode * node) NONNULL; diff -puN fs/reiser4/lock.c~reiser4-update fs/reiser4/lock.c --- 25/fs/reiser4/lock.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/lock.c 2005-03-15 22:44:12.000000000 -0800 @@ -1153,20 +1153,6 @@ done_lh(lock_handle * handle) longterm_unlock_znode(handle); } -/* What kind of lock? */ -#if 0 -reiser4_internal znode_lock_mode lock_mode(lock_handle * handle) -{ - if (handle->owner == NULL) { - return ZNODE_NO_LOCK; - } else if (znode_is_rlocked(handle->node)) { - return ZNODE_READ_LOCK; - } else { - return ZNODE_WRITE_LOCK; - } -} -#endif /* 0 */ - /* Transfer a lock handle (presumably so that variables can be moved between stack and heap locations). */ static void diff -puN fs/reiser4/page_cache.c~reiser4-update fs/reiser4/page_cache.c --- 25/fs/reiser4/page_cache.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/page_cache.c 2005-03-15 22:44:12.000000000 -0800 @@ -714,7 +714,8 @@ truncate_jnodes_range(struct inode *inod } reiser4_internal void -reiser4_invalidate_pages(struct address_space *mapping, pgoff_t from, unsigned long count) +reiser4_invalidate_pages(struct address_space *mapping, pgoff_t from, + unsigned long count, int even_cows) { loff_t from_bytes, count_bytes; @@ -723,7 +724,7 @@ reiser4_invalidate_pages(struct address_ from_bytes = ((loff_t)from) << PAGE_CACHE_SHIFT; count_bytes = ((loff_t)count) << PAGE_CACHE_SHIFT; - unmap_mapping_range(mapping, from_bytes, count_bytes, 1/*even cows*/); + unmap_mapping_range(mapping, from_bytes, count_bytes, even_cows); truncate_inode_pages_range(mapping, from_bytes, from_bytes + count_bytes - 1); truncate_jnodes_range(mapping->host, from, count); } diff -puN fs/reiser4/page_cache.h~reiser4-update fs/reiser4/page_cache.h --- 25/fs/reiser4/page_cache.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/page_cache.h 2005-03-15 22:44:12.000000000 -0800 @@ -35,7 +35,8 @@ static inline void lock_and_wait_page_wr extern int page_io(struct page *page, jnode * node, int rw, int gfp); extern int reiser4_writepage(struct page *page, struct writeback_control *wbc); extern void drop_page(struct page *page); -extern void reiser4_invalidate_pages(struct address_space *, pgoff_t from, unsigned long count); +extern void reiser4_invalidate_pages(struct address_space *, pgoff_t from, + unsigned long count, int even_cows); extern void capture_reiser4_inodes (struct super_block *, struct writeback_control *); #define PAGECACHE_TAG_REISER4_MOVED PAGECACHE_TAG_DIRTY diff -puN fs/reiser4/plugin/compress/minilzo.c~reiser4-update fs/reiser4/plugin/compress/minilzo.c --- 25/fs/reiser4/plugin/compress/minilzo.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/compress/minilzo.c 2005-03-15 22:44:12.000000000 -0800 @@ -2384,403 +2384,5 @@ lookbehind_overrun: # define COPY4(dst,src) __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src)) #endif -#if 0 - -#if defined(DO_DECOMPRESS) -static int -DO_DECOMPRESS ( const lzo_byte *in , lzo_uint in_len, - lzo_byte *out, lzo_uintp out_len, - lzo_voidp wrkmem ) -#endif -{ - register lzo_byte *op; - register const lzo_byte *ip; - register lzo_uint t; -#if defined(COPY_DICT) - lzo_uint m_off; - const lzo_byte *dict_end; -#else - register const lzo_byte *m_pos; -#endif - - const lzo_byte * const ip_end = in + in_len; -#if defined(HAVE_ANY_OP) - lzo_byte * const op_end = out + *out_len; -#endif -#if defined(LZO1Z) - lzo_uint last_m_off = 0; -#endif - - LZO_UNUSED(wrkmem); - -#if defined(__LZO_QUERY_DECOMPRESS) - if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem)) - return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0); -#endif - -#if defined(COPY_DICT) - if (dict) - { - if (dict_len > M4_MAX_OFFSET) - { - dict += dict_len - M4_MAX_OFFSET; - dict_len = M4_MAX_OFFSET; - } - dict_end = dict + dict_len; - } - else - { - dict_len = 0; - dict_end = NULL; - } -#endif - - *out_len = 0; - - op = out; - ip = in; - - if (*ip > 17) - { - t = *ip++ - 17; - if (t < 4) - goto match_next; - assert("lzo-22", t > 0); NEED_OP(t); NEED_IP(t+1); - do *op++ = *ip++; while (--t > 0); - goto first_literal_run; - } - - while (TEST_IP && TEST_OP) - { - t = *ip++; - if (t >= 16) - goto match; - if (t == 0) - { - NEED_IP(1); - while (*ip == 0) - { - t += 255; - ip++; - NEED_IP(1); - } - t += 15 + *ip++; - } - assert("lzo-23", t > 0); NEED_OP(t+3); NEED_IP(t+4); -#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) -#if !defined(LZO_UNALIGNED_OK_4) - if (PTR_ALIGNED2_4(op,ip)) - { -#endif - COPY4(op,ip); - op += 4; ip += 4; - if (--t > 0) - { - if (t >= 4) - { - do { - COPY4(op,ip); - op += 4; ip += 4; t -= 4; - } while (t >= 4); - if (t > 0) do *op++ = *ip++; while (--t > 0); - } - else - do *op++ = *ip++; while (--t > 0); - } -#if !defined(LZO_UNALIGNED_OK_4) - } - else -#endif -#endif -#if !defined(LZO_UNALIGNED_OK_4) - { - *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; - do *op++ = *ip++; while (--t > 0); - } -#endif - -first_literal_run: - - t = *ip++; - if (t >= 16) - goto match; -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); - last_m_off = m_off; -#else - m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); -#endif - NEED_OP(3); - t = 3; COPY_DICT(t,m_off) -#else -#if defined(LZO1Z) - t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); - m_pos = op - t; - last_m_off = t; -#else - m_pos = op - (1 + M2_MAX_OFFSET); - m_pos -= t >> 2; - m_pos -= *ip++ << 2; -#endif - TEST_LOOKBEHIND(m_pos,out); NEED_OP(3); - *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; -#endif - goto match_done; - - while (TEST_IP && TEST_OP) - { -match: - if (t >= 64) - { -#if defined(COPY_DICT) -#if defined(LZO1X) - m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); - t = (t >> 5) - 1; -#elif defined(LZO1Y) - m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); - t = (t >> 4) - 3; -#elif defined(LZO1Z) - m_off = t & 0x1f; - if (m_off >= 0x1c) - m_off = last_m_off; - else - { - m_off = 1 + (m_off << 6) + (*ip++ >> 2); - last_m_off = m_off; - } - t = (t >> 5) - 1; -#endif -#else -#if defined(LZO1X) - m_pos = op - 1; - m_pos -= (t >> 2) & 7; - m_pos -= *ip++ << 3; - t = (t >> 5) - 1; -#elif defined(LZO1Y) - m_pos = op - 1; - m_pos -= (t >> 2) & 3; - m_pos -= *ip++ << 2; - t = (t >> 4) - 3; -#elif defined(LZO1Z) - { - lzo_uint off = t & 0x1f; - m_pos = op; - if (off >= 0x1c) - { - assert(last_m_off > 0); - m_pos -= last_m_off; - } - else - { - off = 1 + (off << 6) + (*ip++ >> 2); - m_pos -= off; - last_m_off = off; - } - } - t = (t >> 5) - 1; -#endif - TEST_LOOKBEHIND(m_pos,out); assert("lzo-24", t > 0); NEED_OP(t+3-1); - goto copy_match; -#endif - } - else if (t >= 32) - { - t &= 31; - if (t == 0) - { - NEED_IP(1); - while (*ip == 0) - { - t += 255; - ip++; - NEED_IP(1); - } - t += 31 + *ip++; - } -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); - last_m_off = m_off; -#else - m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); -#endif -#else -#if defined(LZO1Z) - { - lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); - m_pos = op - off; - last_m_off = off; - } -#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) - m_pos = op - 1; - m_pos -= (* (const lzo_ushortp) ip) >> 2; -#else - m_pos = op - 1; - m_pos -= (ip[0] >> 2) + (ip[1] << 6); -#endif -#endif - ip += 2; - } - else if (t >= 16) - { -#if defined(COPY_DICT) - m_off = (t & 8) << 11; -#else - m_pos = op; - m_pos -= (t & 8) << 11; -#endif - t &= 7; - if (t == 0) - { - NEED_IP(1); - while (*ip == 0) - { - t += 255; - ip++; - NEED_IP(1); - } - t += 7 + *ip++; - } -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off += (ip[0] << 6) + (ip[1] >> 2); -#else - m_off += (ip[0] >> 2) + (ip[1] << 6); -#endif - ip += 2; - if (m_off == 0) - goto eof_found; - m_off += 0x4000; -#if defined(LZO1Z) - last_m_off = m_off; -#endif -#else -#if defined(LZO1Z) - m_pos -= (ip[0] << 6) + (ip[1] >> 2); -#elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN) - m_pos -= (* (const lzo_ushortp) ip) >> 2; -#else - m_pos -= (ip[0] >> 2) + (ip[1] << 6); -#endif - ip += 2; - if (m_pos == op) - goto eof_found; - m_pos -= 0x4000; -#if defined(LZO1Z) - last_m_off = op - m_pos; -#endif -#endif - } - else - { -#if defined(COPY_DICT) -#if defined(LZO1Z) - m_off = 1 + (t << 6) + (*ip++ >> 2); - last_m_off = m_off; -#else - m_off = 1 + (t >> 2) + (*ip++ << 2); -#endif - NEED_OP(2); - t = 2; COPY_DICT(t,m_off) -#else -#if defined(LZO1Z) - t = 1 + (t << 6) + (*ip++ >> 2); - m_pos = op - t; - last_m_off = t; -#else - m_pos = op - 1; - m_pos -= t >> 2; - m_pos -= *ip++ << 2; -#endif - TEST_LOOKBEHIND(m_pos,out); NEED_OP(2); - *op++ = *m_pos++; *op++ = *m_pos; -#endif - goto match_done; - } - -#if defined(COPY_DICT) - - NEED_OP(t+3-1); - t += 3-1; COPY_DICT(t,m_off) - -#else - - TEST_LOOKBEHIND(m_pos,out); assert("lzo-25", t > 0); NEED_OP(t+3-1); -#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4) -#if !defined(LZO_UNALIGNED_OK_4) - if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) - { - assert((op - m_pos) >= 4); -#else - if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) - { -#endif - COPY4(op,m_pos); - op += 4; m_pos += 4; t -= 4 - (3 - 1); - do { - COPY4(op,m_pos); - op += 4; m_pos += 4; t -= 4; - } while (t >= 4); - if (t > 0) do *op++ = *m_pos++; while (--t > 0); - } - else -#endif - { -copy_match: - *op++ = *m_pos++; *op++ = *m_pos++; - do *op++ = *m_pos++; while (--t > 0); - } - -#endif - -match_done: -#if defined(LZO1Z) - t = ip[-1] & 3; -#else - t = ip[-2] & 3; -#endif - if (t == 0) - break; - -match_next: - assert("lzo-26", t > 0); NEED_OP(t); NEED_IP(t+1); - do *op++ = *ip++; while (--t > 0); - t = *ip++; - } - } - -#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP) - *out_len = op - out; - return LZO_E_EOF_NOT_FOUND; -#endif - -eof_found: - assert("lzo-27", t == 1); - *out_len = op - out; - return (ip == ip_end ? LZO_E_OK : - (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); - -#if defined(HAVE_NEED_IP) -input_overrun: - *out_len = op - out; - return LZO_E_INPUT_OVERRUN; -#endif - -#if defined(HAVE_NEED_OP) -output_overrun: - *out_len = op - out; - return LZO_E_OUTPUT_OVERRUN; -#endif - -#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND) -lookbehind_overrun: - *out_len = op - out; - return LZO_E_LOOKBEHIND_OVERRUN; -#endif -} - -#endif /* 0 */ - /***** End of minilzo.c *****/ diff -puN fs/reiser4/plugin/cryptcompress.c~reiser4-update fs/reiser4/plugin/cryptcompress.c --- 25/fs/reiser4/plugin/cryptcompress.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/cryptcompress.c 2005-03-15 22:44:12.000000000 -0800 @@ -53,11 +53,14 @@ int ctail_read_cluster (reiser4_cluster_ reiser4_key * append_cluster_key_ctail(const coord_t *, reiser4_key *); int setattr_reserve(reiser4_tree *); int writepage_ctail(struct page *); -int cut_file_items(struct inode *inode, loff_t new_size, int update_sd, loff_t cur_size); +int update_file_size(struct inode * inode, reiser4_key * key, int update_sd); +int cut_file_items(struct inode *inode, loff_t new_size, int update_sd, loff_t cur_size, + int (*update_actor)(struct inode *, reiser4_key *, int)); int delete_object(struct inode *inode, int mode); int ctail_insert_unprepped_cluster(reiser4_cluster_t * clust, struct inode * inode); int hint_is_set(const hint_t *hint); reiser4_plugin * get_default_plugin(pset_member memb); +void inode_check_scale_nolock(struct inode * inode, __u64 old, __u64 new); /* get cryptcompress specific portion of inode */ reiser4_internal cryptcompress_info_t * @@ -453,20 +456,6 @@ inode_scaled_cluster_size (struct inode return inode_scaled_offset(inode, inode_cluster_size(inode)); } -/* return true if the cluster contains specified page */ -#if 0 -static int -page_of_cluster(struct page * page, reiser4_cluster_t * clust, struct inode * inode) -{ - assert("edward-162", page != NULL); - assert("edward-163", clust != NULL); - assert("edward-164", inode != NULL); - assert("edward-165", inode_get_flag(inode, REISER4_CLUSTER_KNOWN)); - - return (pg_to_clust(page->index, inode) == clust->index); -} -#endif - static int new_cluster(reiser4_cluster_t * clust, struct inode * inode) { @@ -505,17 +494,6 @@ set_cluster_nrpages(reiser4_cluster_t * return; } -#if 0 -reiser4_internal void -set_nrpages_by_inode(reiser4_cluster_t * clust, struct inode * inode) -{ - assert("edward-785", clust != NULL); - assert("edward-786", inode != NULL); - - clust->nr_pages = count_to_nrpages(fsize_to_count(clust, inode)); -} -#endif /* 0 */ - /* plugin->key_by_inode() */ /* see plugin/plugin.h for details */ reiser4_internal int @@ -1147,6 +1125,29 @@ set_cluster_pages_dirty(reiser4_cluster_ } } +static void +clear_cluster_pages_dirty(reiser4_cluster_t * clust) +{ + int i; + assert("edward-1275", clust != NULL); + + for (i = 0; i < clust->nr_pages; i++) { + assert("edward-1276", clust->pages[i] != NULL); + + lock_page(clust->pages[i]); + if (!PageDirty(clust->pages[i])) { + warning("edward-985", "Page of index %lu (inode %llu)" + " is not dirty\n", clust->pages[i]->index, + (unsigned long long)get_inode_oid(clust->pages[i]->mapping->host)); + } + else { + assert("edward-1277", PageUptodate(clust->pages[i])); + reiser4_clear_page_dirty(clust->pages[i]); + } + unlock_page(clust->pages[i]); + } +} + /* update i_size by window */ static void inode_set_new_size(reiser4_cluster_t * clust, struct inode * inode) @@ -1175,7 +1176,8 @@ inode_set_new_size(reiser4_cluster_t * c impossible("edward-1184", "bad page cluster option"); break; } - INODE_SET_FIELD(inode, i_size, size); + inode_check_scale_nolock(inode, inode->i_size, size); + inode->i_size = size; return; } @@ -1185,7 +1187,8 @@ inode_set_new_size(reiser4_cluster_t * c */ static void make_cluster_jnode_dirty_locked(reiser4_cluster_t * clust, jnode * node, - loff_t * old_isize, struct inode * inode) + loff_t * old_isize, struct inode * inode, + int * put_jnode) { int i; int old_refcnt; @@ -1198,6 +1201,8 @@ make_cluster_jnode_dirty_locked(reiser4_ assert("edward-1263", clust->reserved_prepped == estimate_insert_cluster(inode, 0)); assert("edward-1264", clust->reserved_unprepped == 0); + + *put_jnode = 0; if (jnode_is_dirty(node)) { /* there are >= 1 pages already referenced by this jnode */ assert("edward-973", count_to_nrpages(off_to_count(*old_isize, clust->index, inode))); @@ -1212,6 +1217,7 @@ make_cluster_jnode_dirty_locked(reiser4_ old_refcnt = 0; jnode_make_dirty_locked(node); clust->reserved = 0; + *put_jnode = 1; } #if REISER4_DEBUG clust->reserved_prepped -= estimate_insert_cluster(inode, 0); @@ -1223,7 +1229,6 @@ make_cluster_jnode_dirty_locked(reiser4_ assert("edward-975", clust->pages[i]); assert("edward-976", old_refcnt < inode_cluster_size(inode)); assert("edward-1185", PageUptodate(clust->pages[i])); - assert("edward-977", PageDirty(clust->pages[i])); page_cache_release(clust->pages[i]); } @@ -1233,7 +1238,6 @@ make_cluster_jnode_dirty_locked(reiser4_ for (i = new_refcnt + 1; i <= old_refcnt; i++) { assert("edward-1187", clust->pages[i]); assert("edward-1188", PageUptodate(clust->pages[i])); - assert("edward-1189", PageDirty(clust->pages[i])); page_cache_release(clust->pages[i]); } @@ -1253,6 +1257,7 @@ try_capture_cluster(reiser4_cluster_t * int result = 0; loff_t old_size = inode->i_size; jnode * node; + int put_jnode = 0; assert("edward-1029", clust != NULL); assert("edward-1030", clust->reserved == 1); @@ -1264,20 +1269,25 @@ try_capture_cluster(reiser4_cluster_t * assert("edward-1035", node != NULL); - if (clust->win) + if (clust->win) { + spin_lock_inode(inode); + LOCK_JNODE(node); inode_set_new_size(clust, inode); - + } + else LOCK_JNODE(node); result = try_capture(node, ZNODE_WRITE_LOCK, 0, 0); - if (result) { - assert("edward-1034", 0); - UNLOCK_JNODE(node); - return result; - } - make_cluster_jnode_dirty_locked(clust, node, &old_size, inode); + if (result) + goto exit; + make_cluster_jnode_dirty_locked(clust, node, &old_size, inode, &put_jnode); + exit: + assert("edward-1034", !result); UNLOCK_JNODE(node); + if (clust->win) + spin_unlock_inode(inode); + if (put_jnode) jput(node); - return 0; + return result; } /* Collect unlocked cluster pages and jnode */ @@ -1371,13 +1381,13 @@ set_cluster_unlinked(reiser4_cluster_t * } /* put cluster pages */ -reiser4_internal void +static void release_cluster_pages(reiser4_cluster_t * clust, int from) { int i; assert("edward-447", clust != NULL); - assert("edward-448", from < clust->nr_pages); + assert("edward-448", from <= clust->nr_pages); for (i = from; i < clust->nr_pages; i++) { @@ -1388,6 +1398,21 @@ release_cluster_pages(reiser4_cluster_t } static void +release_cluster_pages_capture(reiser4_cluster_t * clust) +{ + assert("edward-1278", clust != NULL); + assert("edward-1279", clust->nr_pages != 0); + + return release_cluster_pages(clust, 1); +} + +reiser4_internal void +release_cluster_pages_nocapture(reiser4_cluster_t * clust) +{ + return release_cluster_pages(clust, 0); +} + +static void release_cluster_pages_and_jnode(reiser4_cluster_t * clust) { jnode * node; @@ -1534,27 +1559,22 @@ forget_cluster_pages(struct page ** page for (i = 0; i < nr; i++) { assert("edward-1045", pages[i] != NULL); - assert("edward-1046", PageUptodate(pages[i])); - page_cache_release(pages[i]); } } -/* . first, make cluster's jnode clean (the order is essential to - avoid synchronization issues) - . prepare input tfm-stream that we should transform if at least - one attached page is dirty. +/* Prepare input stream for transform operations. + Try to do it in one step. Return -E_REPEAT when it is + impossible because of races with concurrent processes. */ - reiser4_internal int flush_cluster_pages(reiser4_cluster_t * clust, jnode * node, -struct inode * inode) + struct inode * inode) { int result = 0; int i; int nr_pages = 0; - int do_transform = 0; - tfm_cluster_t * tc; + tfm_cluster_t * tc = &clust->tc; assert("edward-980", node != NULL); assert("edward-236", inode != NULL); @@ -1563,8 +1583,6 @@ struct inode * inode) assert("edward-241", schedulable()); assert("edward-718", crc_inode_ok(inode)); - tc = &clust->tc; - LOCK_JNODE(node); if (!jnode_is_dirty(node)) { @@ -1576,9 +1594,8 @@ struct inode * inode) /* race with another flush */ UNLOCK_JNODE(node); - return -E_REPEAT; + return RETERR(-E_REPEAT); } - tc->len = fsize_to_count(clust, inode); clust->nr_pages = count_to_nrpages(tc->len); @@ -1589,6 +1606,11 @@ struct inode * inode) cluster_reserved2grabbed(estimate_insert_cluster(inode, 0)); uncapture_cluster_jnode(node); + /* Try to create input stream for the found size (tc->len). + Starting from this point the page cluster can be modified + (truncated, appended) by concurrent processes, so we need + to worry if the constructed stream is valid */ + assert("edward-1224", schedulable()); result = grab_tfm_stream(inode, tc, TFM_WRITE, INPUT_STREAM); @@ -1598,28 +1620,52 @@ struct inode * inode) nr_pages = find_get_pages(inode->i_mapping, clust_to_pg(clust->index, inode), clust->nr_pages, clust->pages); - assert("edward-1047", nr_pages == clust->nr_pages); - + if (nr_pages != clust->nr_pages) { + /* the page cluster get truncated, try again */ + assert("edward-1280", nr_pages < clust->nr_pages); + warning("edward-1281", "Page cluster of index %lu (inode %llu)" + " get truncated from %u to %u pages\n", + clust->index, + (unsigned long long)get_inode_oid(inode), + clust->nr_pages, + nr_pages); + forget_cluster_pages(clust->pages, nr_pages); + return RETERR(-E_REPEAT); + } for (i = 0; i < clust->nr_pages; i++){ char * data; assert("edward-242", clust->pages[i] != NULL); - lock_page(clust->pages[i]); - - assert("edward-1048", - clust->pages[i]->index == clust_to_pg(clust->index, inode) + i); - assert("edward-1049", PageLocked(clust->pages[i])); - assert("edward-1050", PageUptodate(clust->pages[i])); - - if (!PageDirty(clust->pages[i])) - warning("edward-985", "Page of index %lu (inode %llu)" - " is already flushed\n", clust->pages[i]->index, + if (clust->pages[i]->index != clust_to_pg(clust->index, inode) + i) { + /* holes in the indices of found group of pages: + page cluster get truncated, transform impossible */ + warning("edward-1282", + "Hole in the indices: " + "Page %d in the cluster of index %lu " + "(inode %llu) has index %lu\n", + i, clust->index, + (unsigned long long)get_inode_oid(inode), + clust->pages[i]->index); + + forget_cluster_pages(clust->pages, nr_pages); + result = RETERR(-E_REPEAT); + goto finish; + } + if (!PageUptodate(clust->pages[i])) { + /* page cluster get truncated, transform impossible */ + assert("edward-1283", !PageDirty(clust->pages[i])); + warning("edward-1284", + "Page of index %lu (inode %llu) " + "is not uptodate\n", clust->pages[i]->index, (unsigned long long)get_inode_oid(inode)); - else { - reiser4_clear_page_dirty(clust->pages[i]); - do_transform = 1; + + forget_cluster_pages(clust->pages, nr_pages); + result = RETERR(-E_REPEAT); + goto finish; } + /* ok with this page, flush it to the input stream */ + lock_page(clust->pages[i]); data = kmap(clust->pages[i]); assert("edward-986", off_to_pgcount(tc->len, i) != 0); @@ -1628,18 +1674,12 @@ struct inode * inode) data, off_to_pgcount(tc->len, i)); kunmap(clust->pages[i]); unlock_page(clust->pages[i]); - if (i) - /* do not touch jnode's page */ - page_cache_release(clust->pages[i]); - } - if (!do_transform) { - /* rare case: all the attached pages are clean */ - warning("edward-987", "Nothing to update in disk cluster" - " (index %lu, inode %llu\n)", - clust->index, (unsigned long long)get_inode_oid(inode)); - forget_cluster_pages(clust->pages, clust->nr_pages); - result = -E_REPEAT; } + /* input stream is ready for transform */ + + clear_cluster_pages_dirty(clust); + finish: + release_cluster_pages_capture(clust); return result; } @@ -2108,7 +2148,7 @@ truncate_page_cluster(struct inode *inod if (!node) { truncate_inode_pages_range(inode->i_mapping, clust_to_off(index, inode), - pg_to_off(pages[found - 1]->index) + PAGE_CACHE_SIZE - 1); + clust_to_off(index, inode) + inode_cluster_size(inode) - 1); return; } /* jnode is present and may be dirty, if so, put @@ -2117,7 +2157,6 @@ truncate_page_cluster(struct inode *inod found = find_get_pages(inode->i_mapping, clust_to_pg(index, inode), nr_pages, pages); - assert("edward-1197", found != 0); LOCK_JNODE(node); if (jnode_is_dirty(node)) { @@ -2128,10 +2167,9 @@ truncate_page_cluster(struct inode *inod get_current_super_private(), estimate_insert_cluster(inode, 0)); - /* clear dirty bit to make sure that concurrent - flush won't start convert the disk cluster */ - JF_CLR(node, JNODE_DIRTY); - UNLOCK_JNODE(node); + /* clear dirty bit so concurrent flush + won't convert the disk cluster */ + uncapture_cluster_jnode(node); assert("edward-1198", found == nr_pages); assert("edward-1199", PageUptodate(pages[0])); @@ -2150,7 +2188,7 @@ truncate_page_cluster(struct inode *inod forget_cluster_pages(pages, found); truncate_inode_pages_range(inode->i_mapping, clust_to_off(index, inode), - pg_to_off(pages[found - 1]->index) + PAGE_CACHE_SIZE - 1); + clust_to_off(index, inode) + inode_cluster_size(inode) - 1); assert("edward-1201", jnode_truncate_ok(inode, index)); return; } @@ -2663,17 +2701,17 @@ adjust_left_coord(coord_t * left_coord) reiser4_internal int cut_tree_worker_cryptcompress(tap_t * tap, const reiser4_key * from_key, const reiser4_key * to_key, reiser4_key * smallest_removed, - struct inode * object) + struct inode * object, int truncate, int *progress) { lock_handle next_node_lock; coord_t left_coord; int result; - long iterations = 0; assert("edward-1158", tap->coord->node != NULL); assert("edward-1159", znode_is_write_locked(tap->coord->node)); assert("edward-1160", znode_get_level(tap->coord->node) == LEAF_LEVEL); + *progress = 0; init_lh(&next_node_lock); while (1) { @@ -2693,7 +2731,7 @@ cut_tree_worker_cryptcompress(tap_t * ta return result; /* Prepare the second (right) point for cut_node() */ - if (iterations) + if (*progress) coord_init_last_unit(tap->coord, node); else if (item_plugin_by_coord(tap->coord)->b.lookup == NULL) @@ -2735,7 +2773,7 @@ cut_tree_worker_cryptcompress(tap_t * ta to_key, smallest_removed, next_node_lock.node, - object); + object, truncate); #if REISER4_DEBUG /*node_check(node, ~0U);*/ #endif @@ -2744,6 +2782,8 @@ cut_tree_worker_cryptcompress(tap_t * ta if (result) break; + ++ (*progress); + /* Check whether all items with keys >= from_key were removed * from the tree. */ if (keyle(smallest_removed, from_key)) @@ -2760,14 +2800,12 @@ cut_tree_worker_cryptcompress(tap_t * ta /* Break long cut_tree operation (deletion of a large file) if * atom requires commit. */ - if (iterations > CRC_CUT_TREE_MIN_ITERATIONS + if (*progress > CRC_CUT_TREE_MIN_ITERATIONS && current_atom_should_commit()) { result = -E_REPEAT; break; } - - ++ iterations; } done_lh(&next_node_lock); return result; @@ -2888,6 +2926,14 @@ body_truncate_ok(struct inode * inode, c } #endif +static int +update_cryptcompress_size(struct inode * inode, reiser4_key * key, int update_sd) +{ + return (get_key_offset(key) & ((loff_t)(inode_cluster_size(inode)) - 1) ? + 0 : + update_file_size(inode, key, update_sd)); +} + /* prune cryptcompress file in two steps (exclusive access should be acquired!) 1) cut all disk clusters but the last one partially truncated, 2) set zeroes and capture last partially truncated page cluster if the last @@ -2930,7 +2976,8 @@ prune_cryptcompress(struct inode * inode result = cut_file_items(inode, clust_to_off(fidx, inode), update_sd, - clust_to_off(aidx, inode)); + clust_to_off(aidx, inode), + update_cryptcompress_size); if (result) goto out; } diff -puN fs/reiser4/plugin/cryptcompress.h~reiser4-update fs/reiser4/plugin/cryptcompress.h --- 25/fs/reiser4/plugin/cryptcompress.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/cryptcompress.h 2005-03-15 22:44:12.000000000 -0800 @@ -447,7 +447,7 @@ void init_inode_data_cryptcompress(struc int pre_delete_cryptcompress(struct inode *); int cut_tree_worker_cryptcompress(tap_t * tap, const reiser4_key * from_key, const reiser4_key * to_key, reiser4_key * smallest_removed, - struct inode * object); + struct inode * object, int, int*); void hint_init_zero(hint_t *); void destroy_inode_cryptcompress(struct inode * inode); int crc_inode_ok(struct inode * inode); diff -puN fs/reiser4/plugin/file/file.c~reiser4-update fs/reiser4/plugin/file/file.c --- 25/fs/reiser4/plugin/file/file.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/file/file.c 2005-03-15 22:44:12.000000000 -0800 @@ -490,7 +490,8 @@ static int reserve_partial_page(reiser4_ } /* estimate and reserve space needed to cut one item and update one stat data */ -static int reserve_cut_iteration(reiser4_tree *tree) +static int +reserve_cut_iteration(reiser4_tree *tree) { __u64 estimate = estimate_one_item_removal(tree) + estimate_one_insert_into_item(tree); @@ -504,15 +505,29 @@ static int reserve_cut_iteration(reiser4 BA_CAN_COMMIT); } +reiser4_internal int +update_file_size(struct inode *inode, reiser4_key * key, int update_sd) +{ + int result = 0; + INODE_SET_FIELD(inode, i_size, get_key_offset(key)); + if (update_sd) { + inode->i_ctime = inode->i_mtime = CURRENT_TIME; + result = reiser4_update_sd(inode); + } + return result; +} + /* cut file items one by one starting from the last one until new file size (inode->i_size) is reached. Reserve space and update file stat data on every single cut from the tree */ reiser4_internal int -cut_file_items(struct inode *inode, loff_t new_size, int update_sd, loff_t cur_size) +cut_file_items(struct inode *inode, loff_t new_size, int update_sd, loff_t cur_size, + int (*update_actor)(struct inode *, reiser4_key *, int)) { reiser4_key from_key, to_key; reiser4_key smallest_removed; file_plugin * fplug = inode_file_plugin(inode); int result; + int progress = 0; assert("vs-1248", fplug == file_plugin_by_id(UNIX_FILE_PLUGIN_ID) || @@ -528,17 +543,14 @@ cut_file_items(struct inode *inode, loff break; result = cut_tree_object(current_tree, &from_key, &to_key, - &smallest_removed, inode); + &smallest_removed, inode, 1, &progress); if (result == -E_REPEAT) { /* -E_REPEAT is a signal to interrupt a long file truncation process */ - INODE_SET_FIELD(inode, i_size, get_key_offset(&smallest_removed)); - if (update_sd) { - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - result = reiser4_update_sd(inode); + if (progress) { + result = update_actor(inode, &smallest_removed, update_sd); if (result) break; } - all_grabbed2free(); reiser4_release_reserved(inode->i_sb); @@ -551,15 +563,11 @@ cut_file_items(struct inode *inode, loff if (result && !(result == CBK_COORD_NOTFOUND && new_size == 0 && inode->i_size == 0)) break; - INODE_SET_FIELD(inode, i_size, new_size); - if (update_sd) { + set_key_offset(&smallest_removed, new_size); /* Final sd update after the file gets its correct size */ - inode->i_ctime = inode->i_mtime = CURRENT_TIME; - result = reiser4_update_sd(inode); - } + result = update_actor(inode, &smallest_removed, update_sd); break; } - all_grabbed2free(); reiser4_release_reserved(inode->i_sb); @@ -580,7 +588,7 @@ shorten_file(struct inode *inode, loff_t /* all items of ordinary reiser4 file are grouped together. That is why we can use cut_tree. Plan B files (for instance) can not be truncated that simply */ - result = cut_file_items(inode, new_size, 1/*update_sd*/, get_key_offset(max_key())); + result = cut_file_items(inode, new_size, 1/*update_sd*/, get_key_offset(max_key()), update_file_size); if (result) return result; @@ -1944,7 +1952,7 @@ append_and_or_overwrite(hint_t *hint, st } zrelse(loaded); done_lh(&lh); - if (result && result != -E_REPEAT) + if (result && result != -E_REPEAT && result != -E_DEADLOCK) break; preempt_point(); } @@ -2019,7 +2027,7 @@ static int check_pages_unix_file(struct inode *inode) { reiser4_invalidate_pages(inode->i_mapping, 0, - (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT); + (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT, 0); return unpack(inode, 0 /* not forever */); } diff -puN fs/reiser4/plugin/file/tail_conversion.c~reiser4-update fs/reiser4/plugin/file/tail_conversion.c --- 25/fs/reiser4/plugin/file/tail_conversion.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/file/tail_conversion.c 2005-03-15 22:44:12.000000000 -0800 @@ -101,7 +101,7 @@ cut_formatting_items(struct inode *inode set_key_offset(&to, (__u64) (offset + count - 1)); /* cut everything between those keys */ - return cut_tree(tree_by_inode(inode), &from, &to, inode); + return cut_tree(tree_by_inode(inode), &from, &to, inode, 0); } static void @@ -606,7 +606,7 @@ extent2tail(unix_file_info_t *uf_info) * extent->tail conversion should be performed in one * transaction. */ - result = cut_tree(tree_by_inode(inode), &from, &to, inode); + result = cut_tree(tree_by_inode(inode), &from, &to, inode, 0); if (result) { page_cache_release(page); diff -puN fs/reiser4/plugin/item/blackbox.c~reiser4-update fs/reiser4/plugin/item/blackbox.c --- 25/fs/reiser4/plugin/item/blackbox.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/item/blackbox.c 2005-03-15 22:44:12.000000000 -0800 @@ -127,7 +127,7 @@ update_black_box(reiser4_tree *tree, reiser4_internal int kill_black_box(reiser4_tree *tree, const reiser4_key *key) { - return cut_tree(tree, key, key, NULL); + return cut_tree(tree, key, key, NULL, 1); } diff -puN fs/reiser4/plugin/item/cde.c~reiser4-update fs/reiser4/plugin/item/cde.c --- 25/fs/reiser4/plugin/item/cde.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/item/cde.c 2005-03-15 22:44:12.000000000 -0800 @@ -1042,7 +1042,7 @@ rem_entry_cde(struct inode *dir /* direc of @coord. */ coord_dup(&shadow, coord); - result = kill_node_content(coord, &shadow, NULL, NULL, NULL, NULL, NULL); + result = kill_node_content(coord, &shadow, NULL, NULL, NULL, NULL, NULL, 0); if (result == 0) { /* NOTE-NIKITA quota plugin? */ DQUOT_FREE_SPACE_NODIRTY(dir, length); diff -puN fs/reiser4/plugin/item/ctail.c~reiser4-update fs/reiser4/plugin/item/ctail.c --- 25/fs/reiser4/plugin/item/ctail.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/item/ctail.c 2005-03-15 22:44:12.000000000 -0800 @@ -243,7 +243,7 @@ ctail_ok (const coord_t *coord) } /* plugin->u.item.b.lookup: - NULL. (we are looking only for exact keys from item headers) */ + NULL: We are looking for item keys only */ reiser4_internal int check_ctail (const coord_t * coord, const char **error) { @@ -659,6 +659,7 @@ do_readpage_ctail(reiser4_cluster_t * cl switch (clust->dstat) { case UNPR_DISK_CLUSTER: + assert("edward-1285", 0); #if REISER4_DEBUG warning("edward-1168", "page %lu is not uptodate and disk cluster %lu (inode %llu) is unprepped\n", @@ -762,7 +763,7 @@ ctail_read_page_cluster(reiser4_cluster_ } tfm_cluster_clr_uptodate(&clust->tc); out: - release_cluster_pages(clust, 0); + release_cluster_pages_nocapture(clust); assert("edward-1060", !result); return result; @@ -1062,66 +1063,6 @@ int ctail_insert_unprepped_cluster(reise return result; } -/* Create a disk cluster of special 'minimal' format */ -#if 0 -int ctail_make_unprepped_cluster(reiser4_cluster_t * clust, struct inode * inode) -{ - char buf[UCTAIL_NR_UNITS]; - flow_t f; - int result; - - assert("edward-1085", inode != NULL); - assert("edward-1086", clust->hint != NULL); - assert("edward-1062", clust->dstat == FAKE_DISK_CLUSTER); - assert("edward-1164", clust->reserved == 1); - assert("edward-675", get_current_context()->grabbed_blocks == - estimate_insert_cluster(inode, 1)); - - result = get_disk_cluster_locked(clust, inode, ZNODE_WRITE_LOCK); - if (cbk_errored(result)) - return result; - assert("edward-1211", result == CBK_COORD_NOTFOUND); - assert("edward-1063", znode_is_write_locked(clust->hint->coord.lh->node)); - - memset(buf, 0, (size_t)UCTAIL_NR_UNITS); - - flow_by_inode_cryptcompress(inode, - buf, - 0 /* kernel space */, - UCTAIL_NR_UNITS, - clust_to_off(clust->index, inode), - WRITE_OP, - &f); -#if 0 - if (clust->hint->coord.base_coord.between == AT_UNIT) { - assert("edward-887", clust->hint->coord.base_coord.unit_pos == 0); - clust->hint->coord.base_coord.between = AFTER_ITEM; - } -#endif - clust->hint->coord.base_coord.between = AFTER_ITEM; - clust->hint->coord.base_coord.unit_pos = 0; - - result = insert_crc_flow(&clust->hint->coord.base_coord, clust->hint->coord.lh, &f, inode); - all_grabbed2free(); - if (result) - return result; - - assert("edward-743", crc_inode_ok(inode)); - assert("edward-871", znode_is_write_locked(clust->hint->coord.lh->node)); - assert("edward-677", reiser4_clustered_blocks(reiser4_get_current_sb())); - assert("edward-872", znode_convertible(clust->hint->coord.base_coord.node)); -#if REISER4_DEBUG - if (!znode_is_dirty(clust->hint->coord.base_coord.node)) { - warning("edward-958", - "unprepped cluster inserted (clust %lu, inode %llu), " - "but znode is not dirty\n", - clust->index, (unsigned long long)get_inode_oid(inode)); - } -#endif - return 0; -} -#endif /* 0 */ - static int do_convert_ctail(flush_pos_t * pos, crc_write_mode_t mode) { diff -puN fs/reiser4/plugin/item/extent_item_ops.c~reiser4-update fs/reiser4/plugin/item/extent_item_ops.c --- 25/fs/reiser4/plugin/item/extent_item_ops.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/item/extent_item_ops.c 2005-03-15 22:44:12.000000000 -0800 @@ -61,99 +61,6 @@ mergeable_extent(const coord_t *p1, cons return 1; } -/* item_plugin->b.show */ -#if 0 -reiser4_internal void -show_extent(struct seq_file *m, coord_t *coord) -{ - reiser4_extent *ext; - ext = extent_by_coord(coord); - seq_printf(m, "%llu %llu", extent_get_start(ext), extent_get_width(ext)); -} -#endif /* 0 */ - - -#if REISER4_DEBUG_OUTPUT - -/* Audited by: green(2002.06.13) */ -static const char * -state2label(extent_state state) -{ - const char *label; - - label = 0; - switch (state) { - case HOLE_EXTENT: - label = "hole"; - break; - - case UNALLOCATED_EXTENT: - label = "unalloc"; - break; - - case ALLOCATED_EXTENT: - label = "alloc"; - break; - } - assert("vs-376", label); - return label; -} - -/* item_plugin->b.print */ -reiser4_internal void -print_extent(const char *prefix, coord_t *coord) -{ - reiser4_extent *ext; - unsigned i, nr; - - if (prefix) - printk("%s:", prefix); - - nr = nr_units_extent(coord); - ext = (reiser4_extent *) item_body_by_coord(coord); - - printk("%u: ", nr); - for (i = 0; i < nr; i++, ext++) { - printk("[%Lu (%Lu) %s]", extent_get_start(ext), extent_get_width(ext), state2label(state_of_extent(ext))); - } - printk("\n"); -} - -/* item_plugin->b.item_stat */ -reiser4_internal void -item_stat_extent(const coord_t *coord, void *vp) -{ - reiser4_extent *ext; - struct extent_stat *ex_stat; - unsigned i, nr_units; - - ex_stat = (struct extent_stat *) vp; - - ext = extent_item(coord); - nr_units = nr_units_extent(coord); - - for (i = 0; i < nr_units; i++) { - switch (state_of_extent(ext + i)) { - case ALLOCATED_EXTENT: - ex_stat->allocated_units++; - ex_stat->allocated_blocks += extent_get_width(ext + i); - break; - case UNALLOCATED_EXTENT: - ex_stat->unallocated_units++; - ex_stat->unallocated_blocks += extent_get_width(ext + i); - break; - case HOLE_EXTENT: - ex_stat->hole_units++; - ex_stat->hole_blocks += extent_get_width(ext + i); - break; - default: - assert("vs-1419", 0); - } - } -} - -#endif /* REISER4_DEBUG_OUTPUT */ - /* item_plugin->b.nr_units */ reiser4_internal pos_in_node_t nr_units_extent(const coord_t *coord) @@ -496,7 +403,9 @@ kill_hook_extent(const coord_t *coord, p assert("vs-1545", inode != NULL); if (inode != NULL) /* take care of pages and jnodes corresponding to part of item being killed */ - reiser4_invalidate_pages(inode->i_mapping, from_off, to_off - from_off); + reiser4_invalidate_pages( + inode->i_mapping, from_off, to_off - from_off, + kdata->params.truncate); ext = extent_item(coord) + from; offset = (get_key_offset(&min_item_key) + extent_size(coord, from)) >> PAGE_CACHE_SHIFT; diff -puN fs/reiser4/plugin/item/sde.c~reiser4-update fs/reiser4/plugin/item/sde.c --- 25/fs/reiser4/plugin/item/sde.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/item/sde.c 2005-03-15 22:44:12.000000000 -0800 @@ -191,7 +191,7 @@ rem_entry_de(struct inode *dir /* direct of @coord. */ coord_dup(&shadow, coord); - result = kill_node_content(coord, &shadow, NULL, NULL, NULL, NULL, NULL); + result = kill_node_content(coord, &shadow, NULL, NULL, NULL, NULL, NULL, 0); if (result == 0) { /* NOTE-NIKITA quota plugin */ DQUOT_FREE_SPACE_NODIRTY(dir, length); diff -puN fs/reiser4/plugin/item/tail.c~reiser4-update fs/reiser4/plugin/item/tail.c --- 25/fs/reiser4/plugin/item/tail.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/item/tail.c 2005-03-15 22:44:12.000000000 -0800 @@ -216,7 +216,7 @@ kill_hook_tail(const coord_t *coord, pos item_key_by_coord(coord, &key); start = get_key_offset(&key) + from; end = start + count; - fake_kill_hook_tail(kdata->inode, start, end); + fake_kill_hook_tail(kdata->inode, start, end, kdata->params.truncate); return 0; } diff -puN fs/reiser4/plugin/item/tail.h~reiser4-update fs/reiser4/plugin/item/tail.h --- 25/fs/reiser4/plugin/item/tail.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/item/tail.h 2005-03-15 22:44:12.000000000 -0800 @@ -36,7 +36,6 @@ reiser4_key *append_key_tail(const coord void init_coord_extension_tail(uf_coord_t *, loff_t offset); int get_block_address_tail(const coord_t *coord, sector_t block, struct buffer_head *bh); - int item_balance_dirty_pages(struct address_space *mapping, const flow_t *f, hint_t *hint, int back_to_dirty, int set_hint); diff -puN fs/reiser4/plugin/object.c~reiser4-update fs/reiser4/plugin/object.c --- 25/fs/reiser4/plugin/object.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/object.c 2005-03-15 22:44:12.000000000 -0800 @@ -502,7 +502,7 @@ common_object_delete_no_reserve(struct i DQUOT_DROP(inode); build_sd_key(inode, &sd_key); - result = cut_tree(tree_by_inode(inode), &sd_key, &sd_key, NULL); + result = cut_tree(tree_by_inode(inode), &sd_key, &sd_key, NULL, 0); if (result == 0) { inode_set_flag(inode, REISER4_NO_SD); result = oid_release(inode->i_sb, get_inode_oid(inode)); diff -puN fs/reiser4/plugin/object.h~reiser4-update fs/reiser4/plugin/object.h --- 25/fs/reiser4/plugin/object.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/object.h 2005-03-15 22:44:12.000000000 -0800 @@ -25,9 +25,6 @@ extern reiser4_block_nr estimate_update_ extern int prepare_write_common (struct file *, struct page *, unsigned, unsigned); extern int key_by_inode_and_offset_common(struct inode *, loff_t, reiser4_key *); extern int setattr_common(struct inode *, struct iattr *); -extern int cut_tree_worker_common(tap_t * tap, const reiser4_key * from_key, - const reiser4_key * to_key, reiser4_key * smallest_removed, - struct inode * object); extern reiser4_plugin_ops cryptcompress_plugin_ops; diff -puN fs/reiser4/plugin/plugin.h~reiser4-update fs/reiser4/plugin/plugin.h --- 25/fs/reiser4/plugin/plugin.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/plugin/plugin.h 2005-03-15 22:44:12.000000000 -0800 @@ -288,7 +288,7 @@ Elena doing this for you if that helps. * operation was interrupted for allowing atom commit . */ int (*cut_tree_worker)(tap_t * tap, const reiser4_key * from_key, const reiser4_key * to_key, - reiser4_key * smallest_removed, struct inode * object); + reiser4_key * smallest_removed, struct inode * object, int, int*); /* truncate file to zero size. called by reiser4_drop_inode before truncate_inode_pages */ int (*pre_delete)(struct inode *); diff -puN fs/reiser4/tree.c~reiser4-update fs/reiser4/tree.c --- 25/fs/reiser4/tree.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/tree.c 2005-03-15 22:44:12.000000000 -0800 @@ -1280,8 +1280,9 @@ kill_node_content(coord_t * from /* coor * removed */ , znode * locked_left_neighbor, /* this is set when kill_node_content is called with left neighbor * locked (in squalloc_right_twig_cut, namely) */ - struct inode *inode /* inode of file whose item (or its part) is to be killed. This is necessary to - invalidate pages together with item pointing to them */) + struct inode *inode, /* inode of file whose item (or its part) is to be killed. This is necessary to + invalidate pages together with item pointing to them */ + int truncate) /* this call is made for file truncate) */ { int result; carry_pool *pool; @@ -1303,6 +1304,7 @@ kill_node_content(coord_t * from /* coor kdata.params.from_key = from_key; kdata.params.to_key = to_key; kdata.params.smallest_removed = smallest_removed; + kdata.params.truncate = truncate; kdata.flags = 0; kdata.inode = inode; kdata.left = &left_child; @@ -1342,7 +1344,7 @@ kill_node_content(coord_t * from /* coor } void -fake_kill_hook_tail(struct inode *inode, loff_t start, loff_t end) +fake_kill_hook_tail(struct inode *inode, loff_t start, loff_t end, int truncate) { if (inode_get_flag(inode, REISER4_HAS_MMAP)) { pgoff_t start_pg, end_pg; @@ -1355,13 +1357,13 @@ fake_kill_hook_tail(struct inode *inode, * kill up to the page boundary. */ assert("vs-123456", start_pg == end_pg); - reiser4_invalidate_pages(inode->i_mapping, start_pg, 1); + reiser4_invalidate_pages(inode->i_mapping, start_pg, 1, truncate); } else if (start_pg != end_pg) { /* * page boundary is within killed portion of node. */ assert("vs-654321", end_pg - start_pg == 1); - reiser4_invalidate_pages(inode->i_mapping, end_pg, end_pg - start_pg); + reiser4_invalidate_pages(inode->i_mapping, end_pg, end_pg - start_pg, 1); } } inode_sub_bytes(inode, end - start); @@ -1374,6 +1376,7 @@ fake_kill_hook_tail(struct inode *inode, * @node: node to be deleted, * @smallest_removed: leftmost key of deleted node, * @object: inode pointer, if we truncate a file body. + * @truncate: true if called for file truncate. * * @return: 0 if success, error code otherwise. * @@ -1383,7 +1386,7 @@ fake_kill_hook_tail(struct inode *inode, * "i_blocks" and "i_bytes" fields of the @object. */ reiser4_internal int delete_node (znode * node, reiser4_key * smallest_removed, - struct inode * object) + struct inode * object, int truncate) { lock_handle parent_lock; coord_t cut_from; @@ -1468,7 +1471,7 @@ reiser4_internal int delete_node (znode containing item we remove and can not call item's kill hook. Instead we call function which does exactly the same things as tail kill hook in assumption that node we avoid reading contains only one item and that item is a tail one. */ - fake_kill_hook_tail(object, start_offset, end_offset); + fake_kill_hook_tail(object, start_offset, end_offset, truncate); } } failed: @@ -1487,6 +1490,9 @@ reiser4_internal int delete_node (znode * @from_key: the beginning of the deleted key range, * @to_key: the end of the deleted key range, * @smallest_removed: the smallest removed key, + * @truncate: true if called for file truncate. + * @progress: return true if a progress in file items deletions was made, + * @smallest_removed value is actual in that case. * * @return: 0 if success, error code otherwise, -E_REPEAT means that long cut_tree * operation was interrupted for allowing atom commit . @@ -1494,16 +1500,16 @@ reiser4_internal int delete_node (znode reiser4_internal int cut_tree_worker_common (tap_t * tap, const reiser4_key * from_key, const reiser4_key * to_key, reiser4_key * smallest_removed, - struct inode * object) + struct inode * object, int truncate, int *progress) { lock_handle next_node_lock; coord_t left_coord; int result; - long iterations = 0; assert("zam-931", tap->coord->node != NULL); assert("zam-932", znode_is_write_locked(tap->coord->node)); + *progress = 0; init_lh(&next_node_lock); while (1) { @@ -1518,17 +1524,17 @@ cut_tree_worker_common (tap_t * tap, con if (result != 0 && result != -E_NO_NEIGHBOR) break; /* Check can we delete the node as a whole. */ - if (iterations && znode_get_level(node) == LEAF_LEVEL && + if (*progress && znode_get_level(node) == LEAF_LEVEL && UNDER_RW(dk, current_tree, read, keyle(from_key, znode_get_ld_key(node)))) { - result = delete_node(node, smallest_removed, object); + result = delete_node(node, smallest_removed, object, truncate); } else { result = tap_load(tap); if (result) return result; /* Prepare the second (right) point for cut_node() */ - if (iterations) + if (*progress) coord_init_last_unit(tap->coord, node); else if (item_plugin_by_coord(tap->coord)->b.lookup == NULL) @@ -1571,19 +1577,17 @@ cut_tree_worker_common (tap_t * tap, con } /* cut data from one node */ - *smallest_removed = *min_key(); - result = kill_node_content(&left_coord, - tap->coord, - from_key, - to_key, - smallest_removed, - next_node_lock.node, - object); + // *smallest_removed = *min_key(); + result = kill_node_content(&left_coord, tap->coord, from_key, to_key, + smallest_removed, next_node_lock.node, + object, truncate); tap_relse(tap); } if (result) break; + ++ (*progress); + /* Check whether all items with keys >= from_key were removed * from the tree. */ if (keyle(smallest_removed, from_key)) @@ -1600,15 +1604,12 @@ cut_tree_worker_common (tap_t * tap, con /* Break long cut_tree operation (deletion of a large file) if * atom requires commit. */ - if (iterations > CUT_TREE_MIN_ITERATIONS + if (*progress > CUT_TREE_MIN_ITERATIONS && current_atom_should_commit()) { result = -E_REPEAT; break; } - - - ++ iterations; } done_lh(&next_node_lock); // assert("vs-301", !keyeq(&smallest_removed, min_key())); @@ -1652,17 +1653,18 @@ cut_tree_worker_common (tap_t * tap, con * @to_key: the end of the deleted key range, * @smallest_removed: the smallest removed key, * @object: owner of cutting items. + * @truncate: true if called for file truncate. + * @progress: return true if a progress in file items deletions was made, + * @smallest_removed value is actual in that case. * * @return: 0 if success, error code otherwise, -E_REPEAT means that long cut_tree * operation was interrupted for allowing atom commit . - * - * FIXME(Zam): the cut_tree interruption is not implemented. */ reiser4_internal int cut_tree_object(reiser4_tree * tree, const reiser4_key * from_key, const reiser4_key * to_key, reiser4_key * smallest_removed_p, - struct inode * object) + struct inode * object, int truncate, int *progress) { lock_handle lock; int result; @@ -1670,7 +1672,7 @@ cut_tree_object(reiser4_tree * tree, con coord_t right_coord; reiser4_key smallest_removed; int (*cut_tree_worker)(tap_t *, const reiser4_key *, const reiser4_key *, - reiser4_key *, struct inode *); + reiser4_key *, struct inode *, int, int *); STORE_COUNTERS; assert("umka-329", tree != NULL); @@ -1697,7 +1699,7 @@ cut_tree_object(reiser4_tree * tree, con cut_tree_worker = inode_file_plugin(object)->cut_tree_worker; tap_init(&tap, &right_coord, &lock, ZNODE_WRITE_LOCK); result = cut_tree_worker( - &tap, from_key, to_key, smallest_removed_p, object); + &tap, from_key, to_key, smallest_removed_p, object, truncate, progress); tap_done(&tap); preempt_point(); @@ -1731,12 +1733,13 @@ cut_tree_object(reiser4_tree * tree, con * cut_tree_object. */ reiser4_internal int cut_tree(reiser4_tree *tree, const reiser4_key *from, const reiser4_key *to, - struct inode *inode) + struct inode *inode, int truncate) { int result; + int progress; do { - result = cut_tree_object(tree, from, to, NULL, inode); + result = cut_tree_object(tree, from, to, NULL, inode, truncate, &progress); } while (result == -E_REPEAT); return result; diff -puN fs/reiser4/tree.h~reiser4-update fs/reiser4/tree.h --- 25/fs/reiser4/tree.h~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/tree.h 2005-03-15 22:44:12.000000000 -0800 @@ -386,7 +386,7 @@ int kill_node_content(coord_t *from, coo const reiser4_key *from_key, const reiser4_key *to_key, reiser4_key *smallest_removed, znode *locked_left_neighbor, - struct inode *inode); + struct inode *inode, int truncate); int resize_item(coord_t * coord, reiser4_item_data * data, reiser4_key * key, lock_handle * lh, cop_insert_flag); @@ -397,12 +397,14 @@ int find_new_child_ptr(znode * parent, z int shift_right_of_but_excluding_insert_coord(coord_t * insert_coord); int shift_left_of_and_including_insert_coord(coord_t * insert_coord); -void fake_kill_hook_tail(struct inode *, loff_t start, loff_t end); +void fake_kill_hook_tail(struct inode *, loff_t start, loff_t end, int); -extern int cut_tree_object(reiser4_tree*, const reiser4_key*, const reiser4_key*, reiser4_key*, struct inode*); -extern int cut_tree(reiser4_tree *tree, const reiser4_key *from, const reiser4_key *to, struct inode*); +extern int cut_tree_worker_common(tap_t *, const reiser4_key *, const reiser4_key *, + reiser4_key *, struct inode *, int, int*); +extern int cut_tree_object(reiser4_tree*, const reiser4_key*, const reiser4_key*, reiser4_key*, struct inode*, int, int*); +extern int cut_tree(reiser4_tree *tree, const reiser4_key *from, const reiser4_key *to, struct inode*, int); -extern int delete_node(znode * node, reiser4_key *, struct inode *); +extern int delete_node(znode * node, reiser4_key *, struct inode *, int); extern int check_tree_pointer(const coord_t * pointer, const znode * child); extern int find_new_child_ptr(znode * parent, znode * child UNUSED_ARG, znode * left, coord_t * result); extern int find_child_ptr(znode * parent, znode * child, coord_t * result); diff -puN fs/reiser4/tree_walk.c~reiser4-update fs/reiser4/tree_walk.c --- 25/fs/reiser4/tree_walk.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/tree_walk.c 2005-03-15 22:44:12.000000000 -0800 @@ -926,8 +926,6 @@ struct tw_handle { int node_completed:1; }; -#if 0 - /* it locks the root node, handles the restarts inside */ static int lock_tree_root (lock_handle * lock, znode_lock_mode mode) { @@ -1222,8 +1220,6 @@ tree_walk (const reiser4_key *start_key, return ret; } -#endif /* 0 */ - /* Local variables: diff -puN fs/reiser4/vfs_ops.c~reiser4-update fs/reiser4/vfs_ops.c --- 25/fs/reiser4/vfs_ops.c~reiser4-update 2005-03-15 22:44:12.000000000 -0800 +++ 25-akpm/fs/reiser4/vfs_ops.c 2005-03-15 22:44:12.000000000 -0800 @@ -241,7 +241,8 @@ static kmem_cache_t *dentry_fsdata_slab; /* * initializer for dentry_fsdata_slab called during boot or module load. */ -static int init_dentry_fsdata(void) +static int +init_dentry_fsdata(void) { dentry_fsdata_slab = kmem_cache_create("dentry_fsdata", sizeof (reiser4_dentry_fsdata), @@ -255,7 +256,8 @@ static int init_dentry_fsdata(void) /* * dual to init_dentry_fsdata(). Called on module unload. */ -static void done_dentry_fsdata(void) +static void +done_dentry_fsdata(void) { kmem_cache_destroy(dentry_fsdata_slab); } @@ -303,7 +305,8 @@ static kmem_cache_t *file_fsdata_slab; /* * initialize file_fsdata_slab. This is called during boot or module load. */ -static int init_file_fsdata(void) +static int +init_file_fsdata(void) { file_fsdata_slab = kmem_cache_create("file_fsdata", sizeof (reiser4_file_fsdata), @@ -317,7 +320,8 @@ static int init_file_fsdata(void) /* * dual to init_file_fsdata(). Called during module unload. */ -static void done_file_fsdata(void) +static void +done_file_fsdata(void) { kmem_cache_destroy(file_fsdata_slab); } _