-static char prepare_for_delete_or_cut(
- struct reiserfs_transaction_handle *th,
- struct inode * inode,
- struct path * p_s_path,
- const struct cpu_key * p_s_item_key,
- int * p_n_removed, /* Number of unformatted nodes which were removed
- from end of the file. */
- int * p_n_cut_size,
- unsigned long long n_new_file_length /* MAX_KEY_OFFSET in case of delete. */
- ) {
- struct super_block * p_s_sb = inode->i_sb;
- struct item_head * p_le_ih = PATH_PITEM_HEAD(p_s_path);
- struct buffer_head * p_s_bh = PATH_PLAST_BUFFER(p_s_path);
-
- BUG_ON (!th->t_trans_id);
-
- /* Stat_data item. */
- if ( is_statdata_le_ih (p_le_ih) ) {
-
- RFALSE( n_new_file_length != max_reiserfs_offset (inode),
- "PAP-5210: mode must be M_DELETE");
-
- *p_n_cut_size = -(IH_SIZE + ih_item_len(p_le_ih));
- return M_DELETE;
- }
-
-
- /* Directory item. */
- if ( is_direntry_le_ih (p_le_ih) )
- return prepare_for_direntry_item (p_s_path, p_le_ih, inode, n_new_file_length, p_n_cut_size);
-
- /* Direct item. */
- if ( is_direct_le_ih (p_le_ih) )
- return prepare_for_direct_item (p_s_path, p_le_ih, inode, n_new_file_length, p_n_cut_size);
-
-
- /* Case of an indirect item. */
- {
- int n_unfm_number, /* Number of the item unformatted nodes. */
- n_counter,
- n_blk_size;
- __u32 * p_n_unfm_pointer; /* Pointer to the unformatted node number. */
- __u32 tmp;
- struct item_head s_ih; /* Item header. */
- char c_mode; /* Returned mode of the balance. */
- int need_research;
-
-
- n_blk_size = p_s_sb->s_blocksize;
-
- /* Search for the needed object indirect item until there are no unformatted nodes to be removed. */
- do {
- need_research = 0;
- p_s_bh = PATH_PLAST_BUFFER(p_s_path);
- /* Copy indirect item header to a temp variable. */
- copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
- /* Calculate number of unformatted nodes in this item. */
- n_unfm_number = I_UNFM_NUM(&s_ih);
-
- RFALSE( ! is_indirect_le_ih(&s_ih) || ! n_unfm_number ||
- pos_in_item (p_s_path) + 1 != n_unfm_number,
- "PAP-5240: invalid item %h "
- "n_unfm_number = %d *p_n_pos_in_item = %d",
- &s_ih, n_unfm_number, pos_in_item (p_s_path));
-
- /* Calculate balance mode and position in the item to remove unformatted nodes. */
- if ( n_new_file_length == max_reiserfs_offset (inode) ) {/* Case of delete. */
- pos_in_item (p_s_path) = 0;
- *p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
- c_mode = M_DELETE;
- }
- else { /* Case of truncate. */
- if ( n_new_file_length < le_ih_k_offset (&s_ih) ) {
- pos_in_item (p_s_path) = 0;
- *p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
- c_mode = M_DELETE; /* Delete this item. */
- }
- else {
- /* indirect item must be truncated starting from *p_n_pos_in_item-th position */
- pos_in_item (p_s_path) = (n_new_file_length + n_blk_size - le_ih_k_offset (&s_ih) ) >> p_s_sb->s_blocksize_bits;
-
- RFALSE( pos_in_item (p_s_path) > n_unfm_number,
- "PAP-5250: invalid position in the item");
-
- /* Either convert last unformatted node of indirect item to direct item or increase
- its free space. */
- if ( pos_in_item (p_s_path) == n_unfm_number ) {
- *p_n_cut_size = 0; /* Nothing to cut. */
- return M_CONVERT; /* Maybe convert last unformatted node to the direct item. */
- }
- /* Calculate size to cut. */
- *p_n_cut_size = -(ih_item_len(&s_ih) - pos_in_item(p_s_path) * UNFM_P_SIZE);