319 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright4 * details5 */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 is14 * not running. direct2indirect and indirect2direct can not run concurrently15 */16 17/*18 * Converts direct items to an unformatted node. Panics if file has no19 * tail. -ENOSPC if no disk space for conversion20 */21/*22 * path points to first direct item of the file regardless of how many of23 * them are there24 */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 key39 * of unfm pointer to be pasted40 */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 new56 * 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 first97 * 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 node106 * 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 found113 * last item of the file114 */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 not128 * up to date. this avoids overwriting good data from129 * writepage() with old data from the disk or buffer cache130 * Special case: unbh->b_page will be NULL if we are coming131 * 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 zero151 * 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 mostly176 * interested in removing it from per-sb j_dirty_buffers list, to avoid177 * BUG() on attempt to write not mapped buffer178 */179 if ((!list_empty(&bh->b_assoc_buffers) || bh->b_private) && bh->b_page) {180 struct inode *inode = bh->b_folio->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 item197 * inserted successfully inode is left locked. Return value is always198 * what we expect from it (number of cut bytes). But when tail remains199 * in the unformatted node, we set mode to SKIP_BALANCING and unlock200 * inode201 */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 for206 * unformatted node207 * 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 else232 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, not241 * append can be done either242 * we are in truncate or packing tail in file_release243 */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_CHECK256 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#endif263 }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 when273 * indirect2direct was called, so we know the bytes are still valid274 */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 node287 * to the direct item. In this case we used to adjust288 * indirect items's ih_free_space. Now ih_free_space is not289 * used, it would be ideal to write zeros to corresponding290 * unformatted node. For now i_size is considered as guard for291 * going out of file size292 */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 direct2indirect303 * conversion: there are two keys which have matching first three304 * key components. They only differ by the fourth one.305 */306 307 /*308 * We have inserted new direct item and must remove last309 * 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