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