linux/fs/reiserfs/tail_conversion.c
<<
>>
Prefs
   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 */
  25int 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 */
 167void 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 */
 202int 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}
 319