root/fs/reiserfs/tail_conversion.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. direct2indirect
  2. reiserfs_unmap_buffer
  3. indirect2direct

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright
   4  * details
   5  */
   6 
   7 #include <linux/time.h>
   8 #include <linux/pagemap.h>
   9 #include <linux/buffer_head.h>
  10 #include "reiserfs.h"
  11 
  12 /*
  13  * access to tail : when one is going to read tail it must make sure, that is
  14  * not running.  direct2indirect and indirect2direct can not run concurrently
  15  */
  16 
  17 /*
  18  * Converts direct items to an unformatted node. Panics if file has no
  19  * tail. -ENOSPC if no disk space for conversion
  20  */
  21 /*
  22  * path points to first direct item of the file regardless of how many of
  23  * them are there
  24  */
  25 int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
  26                     struct treepath *path, struct buffer_head *unbh,
  27                     loff_t tail_offset)
  28 {
  29         struct super_block *sb = inode->i_sb;
  30         struct buffer_head *up_to_date_bh;
  31         struct item_head *p_le_ih = tp_item_head(path);
  32         unsigned long total_tail = 0;
  33 
  34         /* Key to search for the last byte of the converted item. */
  35         struct cpu_key end_key;
  36 
  37         /*
  38          * new indirect item to be inserted or key
  39          * of unfm pointer to be pasted
  40          */
  41         struct item_head ind_ih;
  42         int blk_size;
  43         /* returned value for reiserfs_insert_item and clones */
  44         int  retval;
  45         /* Handle on an unformatted node that will be inserted in the tree. */
  46         unp_t unfm_ptr;
  47 
  48         BUG_ON(!th->t_trans_id);
  49 
  50         REISERFS_SB(sb)->s_direct2indirect++;
  51 
  52         blk_size = sb->s_blocksize;
  53 
  54         /*
  55          * and key to search for append or insert pointer to the new
  56          * unformatted node.
  57          */
  58         copy_item_head(&ind_ih, p_le_ih);
  59         set_le_ih_k_offset(&ind_ih, tail_offset);
  60         set_le_ih_k_type(&ind_ih, TYPE_INDIRECT);
  61 
  62         /* Set the key to search for the place for new unfm pointer */
  63         make_cpu_key(&end_key, inode, tail_offset, TYPE_INDIRECT, 4);
  64 
  65         /* FIXME: we could avoid this */
  66         if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) {
  67                 reiserfs_error(sb, "PAP-14030",
  68                                "pasted or inserted byte exists in "
  69                                "the tree %K. Use fsck to repair.", &end_key);
  70                 pathrelse(path);
  71                 return -EIO;
  72         }
  73 
  74         p_le_ih = tp_item_head(path);
  75 
  76         unfm_ptr = cpu_to_le32(unbh->b_blocknr);
  77 
  78         if (is_statdata_le_ih(p_le_ih)) {
  79                 /* Insert new indirect item. */
  80                 set_ih_free_space(&ind_ih, 0);  /* delete at nearest future */
  81                 put_ih_item_len(&ind_ih, UNFM_P_SIZE);
  82                 PATH_LAST_POSITION(path)++;
  83                 retval =
  84                     reiserfs_insert_item(th, path, &end_key, &ind_ih, inode,
  85                                          (char *)&unfm_ptr);
  86         } else {
  87                 /* Paste into last indirect item of an object. */
  88                 retval = reiserfs_paste_into_item(th, path, &end_key, inode,
  89                                                     (char *)&unfm_ptr,
  90                                                     UNFM_P_SIZE);
  91         }
  92         if (retval) {
  93                 return retval;
  94         }
  95         /*
  96          * note: from here there are two keys which have matching first
  97          *  three key components. They only differ by the fourth one.
  98          */
  99 
 100         /* Set the key to search for the direct items of the file */
 101         make_cpu_key(&end_key, inode, max_reiserfs_offset(inode), TYPE_DIRECT,
 102                      4);
 103 
 104         /*
 105          * Move bytes from the direct items to the new unformatted node
 106          * and delete them.
 107          */
 108         while (1) {
 109                 int tail_size;
 110 
 111                 /*
 112                  * end_key.k_offset is set so, that we will always have found
 113                  * last item of the file
 114                  */
 115                 if (search_for_position_by_key(sb, &end_key, path) ==
 116                     POSITION_FOUND)
 117                         reiserfs_panic(sb, "PAP-14050",
 118                                        "direct item (%K) not found", &end_key);
 119                 p_le_ih = tp_item_head(path);
 120                 RFALSE(!is_direct_le_ih(p_le_ih),
 121                        "vs-14055: direct item expected(%K), found %h",
 122                        &end_key, p_le_ih);
 123                 tail_size = (le_ih_k_offset(p_le_ih) & (blk_size - 1))
 124                     + ih_item_len(p_le_ih) - 1;
 125 
 126                 /*
 127                  * we only send the unbh pointer if the buffer is not
 128                  * up to date.  this avoids overwriting good data from
 129                  * writepage() with old data from the disk or buffer cache
 130                  * Special case: unbh->b_page will be NULL if we are coming
 131                  * through DIRECT_IO handler here.
 132                  */
 133                 if (!unbh->b_page || buffer_uptodate(unbh)
 134                     || PageUptodate(unbh->b_page)) {
 135                         up_to_date_bh = NULL;
 136                 } else {
 137                         up_to_date_bh = unbh;
 138                 }
 139                 retval = reiserfs_delete_item(th, path, &end_key, inode,
 140                                                 up_to_date_bh);
 141 
 142                 total_tail += retval;
 143 
 144                 /* done: file does not have direct items anymore */
 145                 if (tail_size == retval)
 146                         break;
 147 
 148         }
 149         /*
 150          * if we've copied bytes from disk into the page, we need to zero
 151          * out the unused part of the block (it was not up to date before)
 152          */
 153         if (up_to_date_bh) {
 154                 unsigned pgoff =
 155                     (tail_offset + total_tail - 1) & (PAGE_SIZE - 1);
 156                 char *kaddr = kmap_atomic(up_to_date_bh->b_page);
 157                 memset(kaddr + pgoff, 0, blk_size - total_tail);
 158                 kunmap_atomic(kaddr);
 159         }
 160 
 161         REISERFS_I(inode)->i_first_direct_byte = U32_MAX;
 162 
 163         return 0;
 164 }
 165 
 166 /* stolen from fs/buffer.c */
 167 void reiserfs_unmap_buffer(struct buffer_head *bh)
 168 {
 169         lock_buffer(bh);
 170         if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
 171                 BUG();
 172         }
 173         clear_buffer_dirty(bh);
 174         /*
 175          * Remove the buffer from whatever list it belongs to. We are mostly
 176          * interested in removing it from per-sb j_dirty_buffers list, to avoid
 177          * BUG() on attempt to write not mapped buffer
 178          */
 179         if ((!list_empty(&bh->b_assoc_buffers) || bh->b_private) && bh->b_page) {
 180                 struct inode *inode = bh->b_page->mapping->host;
 181                 struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
 182                 spin_lock(&j->j_dirty_buffers_lock);
 183                 list_del_init(&bh->b_assoc_buffers);
 184                 reiserfs_free_jh(bh);
 185                 spin_unlock(&j->j_dirty_buffers_lock);
 186         }
 187         clear_buffer_mapped(bh);
 188         clear_buffer_req(bh);
 189         clear_buffer_new(bh);
 190         bh->b_bdev = NULL;
 191         unlock_buffer(bh);
 192 }
 193 
 194 /*
 195  * this first locks inode (neither reads nor sync are permitted),
 196  * reads tail through page cache, insert direct item. When direct item
 197  * inserted successfully inode is left locked. Return value is always
 198  * what we expect from it (number of cut bytes). But when tail remains
 199  * in the unformatted node, we set mode to SKIP_BALANCING and unlock
 200  * inode
 201  */
 202 int indirect2direct(struct reiserfs_transaction_handle *th,
 203                     struct inode *inode, struct page *page,
 204                     struct treepath *path,      /* path to the indirect item. */
 205                     const struct cpu_key *item_key,     /* Key to look for
 206                                                          * unformatted node
 207                                                          * pointer to be cut. */
 208                     loff_t n_new_file_size,     /* New file size. */
 209                     char *mode)
 210 {
 211         struct super_block *sb = inode->i_sb;
 212         struct item_head s_ih;
 213         unsigned long block_size = sb->s_blocksize;
 214         char *tail;
 215         int tail_len, round_tail_len;
 216         loff_t pos, pos1;       /* position of first byte of the tail */
 217         struct cpu_key key;
 218 
 219         BUG_ON(!th->t_trans_id);
 220 
 221         REISERFS_SB(sb)->s_indirect2direct++;
 222 
 223         *mode = M_SKIP_BALANCING;
 224 
 225         /* store item head path points to. */
 226         copy_item_head(&s_ih, tp_item_head(path));
 227 
 228         tail_len = (n_new_file_size & (block_size - 1));
 229         if (get_inode_sd_version(inode) == STAT_DATA_V2)
 230                 round_tail_len = ROUND_UP(tail_len);
 231         else
 232                 round_tail_len = tail_len;
 233 
 234         pos =
 235             le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE -
 236                                          1) * sb->s_blocksize;
 237         pos1 = pos;
 238 
 239         /*
 240          * we are protected by i_mutex. The tail can not disapper, not
 241          * append can be done either
 242          * we are in truncate or packing tail in file_release
 243          */
 244 
 245         tail = (char *)kmap(page);      /* this can schedule */
 246 
 247         if (path_changed(&s_ih, path)) {
 248                 /* re-search indirect item */
 249                 if (search_for_position_by_key(sb, item_key, path)
 250                     == POSITION_NOT_FOUND)
 251                         reiserfs_panic(sb, "PAP-5520",
 252                                        "item to be converted %K does not exist",
 253                                        item_key);
 254                 copy_item_head(&s_ih, tp_item_head(path));
 255 #ifdef CONFIG_REISERFS_CHECK
 256                 pos = le_ih_k_offset(&s_ih) - 1 +
 257                     (ih_item_len(&s_ih) / UNFM_P_SIZE -
 258                      1) * sb->s_blocksize;
 259                 if (pos != pos1)
 260                         reiserfs_panic(sb, "vs-5530", "tail position "
 261                                        "changed while we were reading it");
 262 #endif
 263         }
 264 
 265         /* Set direct item header to insert. */
 266         make_le_item_head(&s_ih, NULL, get_inode_item_key_version(inode),
 267                           pos1 + 1, TYPE_DIRECT, round_tail_len,
 268                           0xffff /*ih_free_space */ );
 269 
 270         /*
 271          * we want a pointer to the first byte of the tail in the page.
 272          * the page was locked and this part of the page was up to date when
 273          * indirect2direct was called, so we know the bytes are still valid
 274          */
 275         tail = tail + (pos & (PAGE_SIZE - 1));
 276 
 277         PATH_LAST_POSITION(path)++;
 278 
 279         key = *item_key;
 280         set_cpu_key_k_type(&key, TYPE_DIRECT);
 281         key.key_length = 4;
 282         /* Insert tail as new direct item in the tree */
 283         if (reiserfs_insert_item(th, path, &key, &s_ih, inode,
 284                                  tail ? tail : NULL) < 0) {
 285                 /*
 286                  * No disk memory. So we can not convert last unformatted node
 287                  * to the direct item.  In this case we used to adjust
 288                  * indirect items's ih_free_space. Now ih_free_space is not
 289                  * used, it would be ideal to write zeros to corresponding
 290                  * unformatted node. For now i_size is considered as guard for
 291                  * going out of file size
 292                  */
 293                 kunmap(page);
 294                 return block_size - round_tail_len;
 295         }
 296         kunmap(page);
 297 
 298         /* make sure to get the i_blocks changes from reiserfs_insert_item */
 299         reiserfs_update_sd(th, inode);
 300 
 301         /*
 302          * note: we have now the same as in above direct2indirect
 303          * conversion: there are two keys which have matching first three
 304          * key components. They only differ by the fourth one.
 305          */
 306 
 307         /*
 308          * We have inserted new direct item and must remove last
 309          * unformatted node.
 310          */
 311         *mode = M_CUT;
 312 
 313         /* we store position of first direct item in the in-core inode */
 314         /* mark_file_with_tail (inode, pos1 + 1); */
 315         REISERFS_I(inode)->i_first_direct_byte = pos1 + 1;
 316 
 317         return block_size - round_tail_len;
 318 }

/* [<][>][^][v][top][bottom][index][help] */