Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Linus Torvalds | 6967 | 51.21% | 29 | 9.86% |
Andrew Morton | 2288 | 16.82% | 40 | 13.61% |
Jeff Mahoney | 971 | 7.14% | 22 | 7.48% |
Vladimir V. Saveliev | 589 | 4.33% | 5 | 1.70% |
Chris Mason | 366 | 2.69% | 7 | 2.38% |
Linus Torvalds (pre-git) | 361 | 2.65% | 43 | 14.63% |
Christoph Hellwig | 268 | 1.97% | 25 | 8.50% |
Jan Kara | 255 | 1.87% | 10 | 3.40% |
Oleg Drokin | 236 | 1.73% | 7 | 2.38% |
Al Viro | 205 | 1.51% | 18 | 6.12% |
Matthew Wilcox | 175 | 1.29% | 9 | 3.06% |
Hans Reiser | 163 | 1.20% | 10 | 3.40% |
Jan Harkes | 105 | 0.77% | 3 | 1.02% |
Neil Brown | 84 | 0.62% | 2 | 0.68% |
Frédéric Weisbecker | 79 | 0.58% | 8 | 2.72% |
Jeff Layton | 65 | 0.48% | 3 | 1.02% |
Eric W. Biedermann | 56 | 0.41% | 1 | 0.34% |
Qu Fuping | 33 | 0.24% | 1 | 0.34% |
Lukas Czerner | 32 | 0.24% | 2 | 0.68% |
Edward Shishkin | 29 | 0.21% | 1 | 0.34% |
Marco Stornelli | 29 | 0.21% | 1 | 0.34% |
Aneesh Kumar K.V | 25 | 0.18% | 1 | 0.34% |
Dmitriy Monakhov | 22 | 0.16% | 2 | 0.68% |
Christian Brauner | 21 | 0.15% | 7 | 2.38% |
Hugh Dickins | 20 | 0.15% | 1 | 0.34% |
Kirill A. Shutemov | 20 | 0.15% | 1 | 0.34% |
Miklos Szeredi | 18 | 0.13% | 2 | 0.68% |
Dave Hansen | 17 | 0.12% | 1 | 0.34% |
Nicholas Piggin | 8 | 0.06% | 4 | 1.36% |
Eric Biggers | 8 | 0.06% | 1 | 0.34% |
Andi Kleen | 8 | 0.06% | 1 | 0.34% |
Andrey V. Savochkin | 8 | 0.06% | 1 | 0.34% |
Dave Jones | 7 | 0.05% | 2 | 0.68% |
Mark Fasheh | 7 | 0.05% | 1 | 0.34% |
David Howells | 6 | 0.04% | 2 | 0.68% |
Matt Mackall | 6 | 0.04% | 1 | 0.34% |
Josef 'Jeff' Sipek | 6 | 0.04% | 1 | 0.34% |
Suzuki K. Poulose | 5 | 0.04% | 1 | 0.34% |
Omar Sandoval | 5 | 0.04% | 1 | 0.34% |
Evgeniy Dushistov | 5 | 0.04% | 1 | 0.34% |
Michael Christie | 4 | 0.03% | 1 | 0.34% |
Fabian Frederick | 4 | 0.03% | 2 | 0.68% |
Deepa Dinamani | 3 | 0.02% | 1 | 0.34% |
Adrian Bunk | 3 | 0.02% | 2 | 0.68% |
Namjae Jeon | 2 | 0.01% | 1 | 0.34% |
Alexey Dobriyan | 2 | 0.01% | 1 | 0.34% |
Kent Overstreet | 2 | 0.01% | 1 | 0.34% |
Jes Sorensen | 2 | 0.01% | 1 | 0.34% |
Kees Cook | 2 | 0.01% | 1 | 0.34% |
Sergey Senozhatsky | 1 | 0.01% | 1 | 0.34% |
Liao Pingfang | 1 | 0.01% | 1 | 0.34% |
Johannes Weiner | 1 | 0.01% | 1 | 0.34% |
Christoph Lameter | 1 | 0.01% | 1 | 0.34% |
Total | 13606 | 294 |
/* * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README */ #include <linux/time.h> #include <linux/fs.h> #include "reiserfs.h" #include "acl.h" #include "xattr.h" #include <linux/exportfs.h> #include <linux/pagemap.h> #include <linux/highmem.h> #include <linux/slab.h> #include <linux/uaccess.h> #include <asm/unaligned.h> #include <linux/buffer_head.h> #include <linux/mpage.h> #include <linux/writeback.h> #include <linux/quotaops.h> #include <linux/swap.h> #include <linux/uio.h> #include <linux/bio.h> int reiserfs_commit_write(struct file *f, struct page *page, unsigned from, unsigned to); void reiserfs_evict_inode(struct inode *inode) { /* * We need blocks for transaction + (user+group) quota * update (possibly delete) */ int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb); struct reiserfs_transaction_handle th; int err; if (!inode->i_nlink && !is_bad_inode(inode)) dquot_initialize(inode); truncate_inode_pages_final(&inode->i_data); if (inode->i_nlink) goto no_delete; /* * The = 0 happens when we abort creating a new inode * for some reason like lack of space.. * also handles bad_inode case */ if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { reiserfs_delete_xattrs(inode); reiserfs_write_lock(inode->i_sb); if (journal_begin(&th, inode->i_sb, jbegin_count)) goto out; reiserfs_update_inode_transaction(inode); reiserfs_discard_prealloc(&th, inode); err = reiserfs_delete_object(&th, inode); /* * Do quota update inside a transaction for journaled quotas. * We must do that after delete_object so that quota updates * go into the same transaction as stat data deletion */ if (!err) { int depth = reiserfs_write_unlock_nested(inode->i_sb); dquot_free_inode(inode); reiserfs_write_lock_nested(inode->i_sb, depth); } if (journal_end(&th)) goto out; /* * check return value from reiserfs_delete_object after * ending the transaction */ if (err) goto out; /* * all items of file are deleted, so we can remove * "save" link * we can't do anything about an error here */ remove_save_link(inode, 0 /* not truncate */); out: reiserfs_write_unlock(inode->i_sb); } else { /* no object items are in the tree */ ; } /* note this must go after the journal_end to prevent deadlock */ clear_inode(inode); dquot_drop(inode); inode->i_blocks = 0; return; no_delete: clear_inode(inode); dquot_drop(inode); } static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid, __u32 objectid, loff_t offset, int type, int length) { key->version = version; key->on_disk_key.k_dir_id = dirid; key->on_disk_key.k_objectid = objectid; set_cpu_key_k_offset(key, offset); set_cpu_key_k_type(key, type); key->key_length = length; } /* * take base of inode_key (it comes from inode always) (dirid, objectid) * and version from an inode, set offset and type of key */ void make_cpu_key(struct cpu_key *key, struct inode *inode, loff_t offset, int type, int length) { _make_cpu_key(key, get_inode_item_key_version(inode), le32_to_cpu(INODE_PKEY(inode)->k_dir_id), le32_to_cpu(INODE_PKEY(inode)->k_objectid), offset, type, length); } /* when key is 0, do not set version and short key */ inline void make_le_item_head(struct item_head *ih, const struct cpu_key *key, int version, loff_t offset, int type, int length, int entry_count /*or ih_free_space */ ) { if (key) { ih->ih_key.k_dir_id = cpu_to_le32(key->on_disk_key.k_dir_id); ih->ih_key.k_objectid = cpu_to_le32(key->on_disk_key.k_objectid); } put_ih_version(ih, version); set_le_ih_k_offset(ih, offset); set_le_ih_k_type(ih, type); put_ih_item_len(ih, length); /* set_ih_free_space (ih, 0); */ /* * for directory items it is entry count, for directs and stat * datas - 0xffff, for indirects - 0 */ put_ih_entry_count(ih, entry_count); } /* * FIXME: we might cache recently accessed indirect item * Ugh. Not too eager for that.... * I cut the code until such time as I see a convincing argument (benchmark). * I don't want a bloated inode struct..., and I don't like code complexity.... */ /* * cutting the code is fine, since it really isn't in use yet and is easy * to add back in. But, Vladimir has a really good idea here. Think * about what happens for reading a file. For each page, * The VFS layer calls reiserfs_read_folio, who searches the tree to find * an indirect item. This indirect item has X number of pointers, where * X is a big number if we've done the block allocation right. But, * we only use one or two of these pointers during each call to read_folio, * needlessly researching again later on. * * The size of the cache could be dynamic based on the size of the file. * * I'd also like to see us cache the location the stat data item, since * we are needlessly researching for that frequently. * * --chris */ /* * If this page has a file tail in it, and * it was read in by get_block_create_0, the page data is valid, * but tail is still sitting in a direct item, and we can't write to * it. So, look through this page, and check all the mapped buffers * to make sure they have valid block numbers. Any that don't need * to be unmapped, so that __block_write_begin will correctly call * reiserfs_get_block to convert the tail into an unformatted node */ static inline void fix_tail_page_for_writing(struct page *page) { struct buffer_head *head, *next, *bh; if (page && page_has_buffers(page)) { head = page_buffers(page); bh = head; do { next = bh->b_this_page; if (buffer_mapped(bh) && bh->b_blocknr == 0) { reiserfs_unmap_buffer(bh); } bh = next; } while (bh != head); } } /* * reiserfs_get_block does not need to allocate a block only if it has been * done already or non-hole position has been found in the indirect item */ static inline int allocation_needed(int retval, b_blocknr_t allocated, struct item_head *ih, __le32 * item, int pos_in_item) { if (allocated) return 0; if (retval == POSITION_FOUND && is_indirect_le_ih(ih) && get_block_num(item, pos_in_item)) return 0; return 1; } static inline int indirect_item_found(int retval, struct item_head *ih) { return (retval == POSITION_FOUND) && is_indirect_le_ih(ih); } static inline void set_block_dev_mapped(struct buffer_head *bh, b_blocknr_t block, struct inode *inode) { map_bh(bh, inode->i_sb, block); } /* * files which were created in the earlier version can not be longer, * than 2 gb */ static int file_capable(struct inode *inode, sector_t block) { /* it is new file. */ if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 || /* old file, but 'block' is inside of 2gb */ block < (1 << (31 - inode->i_sb->s_blocksize_bits))) return 1; return 0; } static int restart_transaction(struct reiserfs_transaction_handle *th, struct inode *inode, struct treepath *path) { struct super_block *s = th->t_super; int err; BUG_ON(!th->t_trans_id); BUG_ON(!th->t_refcount); pathrelse(path); /* we cannot restart while nested */ if (th->t_refcount > 1) { return 0; } reiserfs_update_sd(th, inode); err = journal_end(th); if (!err) { err = journal_begin(th, s, JOURNAL_PER_BALANCE_CNT * 6); if (!err) reiserfs_update_inode_transaction(inode); } return err; } /* * it is called by get_block when create == 0. Returns block number * for 'block'-th logical block of file. When it hits direct item it * returns 0 (being called from bmap) or read direct item into piece * of page (bh_result) * Please improve the english/clarity in the comment above, as it is * hard to understand. */ static int _get_block_create_0(struct inode *inode, sector_t block, struct buffer_head *bh_result, int args) { INITIALIZE_PATH(path); struct cpu_key key; struct buffer_head *bh; struct item_head *ih, tmp_ih; b_blocknr_t blocknr; char *p; int chars; int ret; int result; int done = 0; unsigned long offset; /* prepare the key to look for the 'block'-th block of file */ make_cpu_key(&key, inode, (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY, 3); result = search_for_position_by_key(inode->i_sb, &key, &path); if (result != POSITION_FOUND) { pathrelse(&path); if (result == IO_ERROR) return -EIO; /* * We do not return -ENOENT if there is a hole but page is * uptodate, because it means that there is some MMAPED data * associated with it that is yet to be written to disk. */ if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page)) { return -ENOENT; } return 0; } bh = get_last_bh(&path); ih = tp_item_head(&path); if (is_indirect_le_ih(ih)) { __le32 *ind_item = (__le32 *) ih_item_body(bh, ih); /* * FIXME: here we could cache indirect item or part of it in * the inode to avoid search_by_key in case of subsequent * access to file */ blocknr = get_block_num(ind_item, path.pos_in_item); ret = 0; if (blocknr) { map_bh(bh_result, inode->i_sb, blocknr); if (path.pos_in_item == ((ih_item_len(ih) / UNFM_P_SIZE) - 1)) { set_buffer_boundary(bh_result); } } else /* * We do not return -ENOENT if there is a hole but * page is uptodate, because it means that there is * some MMAPED data associated with it that is * yet to be written to disk. */ if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page)) { ret = -ENOENT; } pathrelse(&path); return ret; } /* requested data are in direct item(s) */ if (!(args & GET_BLOCK_READ_DIRECT)) { /* * we are called by bmap. FIXME: we can not map block of file * when it is stored in direct item(s) */ pathrelse(&path); return -ENOENT; } /* * if we've got a direct item, and the buffer or page was uptodate, * we don't want to pull data off disk again. skip to the * end, where we map the buffer and return */ if (buffer_uptodate(bh_result)) { goto finished; } else /* * grab_tail_page can trigger calls to reiserfs_get_block on * up to date pages without any buffers. If the page is up * to date, we don't want read old data off disk. Set the up * to date bit on the buffer instead and jump to the end */ if (!bh_result->b_page || PageUptodate(bh_result->b_page)) { set_buffer_uptodate(bh_result); goto finished; } /* read file tail into part of page */ offset = (cpu_key_k_offset(&key) - 1) & (PAGE_SIZE - 1); copy_item_head(&tmp_ih, ih); /* * we only want to kmap if we are reading the tail into the page. * this is not the common case, so we don't kmap until we are * sure we need to. But, this means the item might move if * kmap schedules */ p = (char *)kmap(bh_result->b_page); p += offset; memset(p, 0, inode->i_sb->s_blocksize); do { if (!is_direct_le_ih(ih)) { BUG(); } /* * make sure we don't read more bytes than actually exist in * the file. This can happen in odd cases where i_size isn't * correct, and when direct item padding results in a few * extra bytes at the end of the direct item */ if ((le_ih_k_offset(ih) + path.pos_in_item) > inode->i_size) break; if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > inode->i_size) { chars = inode->i_size - (le_ih_k_offset(ih) - 1) - path.pos_in_item; done = 1; } else { chars = ih_item_len(ih) - path.pos_in_item; } memcpy(p, ih_item_body(bh, ih) + path.pos_in_item, chars); if (done) break; p += chars; /* * we done, if read direct item is not the last item of * node FIXME: we could try to check right delimiting key * to see whether direct item continues in the right * neighbor or rely on i_size */ if (PATH_LAST_POSITION(&path) != (B_NR_ITEMS(bh) - 1)) break; /* update key to look for the next piece */ set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + chars); result = search_for_position_by_key(inode->i_sb, &key, &path); if (result != POSITION_FOUND) /* i/o error most likely */ break; bh = get_last_bh(&path); ih = tp_item_head(&path); } while (1); flush_dcache_page(bh_result->b_page); kunmap(bh_result->b_page); finished: pathrelse(&path); if (result == IO_ERROR) return -EIO; /* * this buffer has valid data, but isn't valid for io. mapping it to * block #0 tells the rest of reiserfs it just has a tail in it */ map_bh(bh_result, inode->i_sb, 0); set_buffer_uptodate(bh_result); return 0; } /* * this is called to create file map. So, _get_block_create_0 will not * read direct item */ static int reiserfs_bmap(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) { if (!file_capable(inode, block)) return -EFBIG; reiserfs_write_lock(inode->i_sb); /* do not read the direct item */ _get_block_create_0(inode, block, bh_result, 0); reiserfs_write_unlock(inode->i_sb); return 0; } /* * special version of get_block that is only used by grab_tail_page right * now. It is sent to __block_write_begin, and when you try to get a * block past the end of the file (or a block from a hole) it returns * -ENOENT instead of a valid buffer. __block_write_begin expects to * be able to do i/o on the buffers returned, unless an error value * is also returned. * * So, this allows __block_write_begin to be used for reading a single block * in a page. Where it does not produce a valid page for holes, or past the * end of the file. This turns out to be exactly what we need for reading * tails for conversion. * * The point of the wrapper is forcing a certain value for create, even * though the VFS layer is calling this function with create==1. If you * don't want to send create == GET_BLOCK_NO_HOLE to reiserfs_get_block, * don't use this function. */ static int reiserfs_get_block_create_0(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) { return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE); } /* * This is special helper for reiserfs_get_block in case we are executing * direct_IO request. */ static int reiserfs_get_blocks_direct_io(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { int ret; bh_result->b_page = NULL; /* * We set the b_size before reiserfs_get_block call since it is * referenced in convert_tail_for_hole() that may be called from * reiserfs_get_block() */ bh_result->b_size = i_blocksize(inode); ret = reiserfs_get_block(inode, iblock, bh_result, create | GET_BLOCK_NO_DANGLE); if (ret) goto out; /* don't allow direct io onto tail pages */ if (buffer_mapped(bh_result) && bh_result->b_blocknr == 0) { /* * make sure future calls to the direct io funcs for this * offset in the file fail by unmapping the buffer */ clear_buffer_mapped(bh_result); ret = -EINVAL; } /* * Possible unpacked tail. Flush the data before pages have * disappeared */ if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) { int err; reiserfs_write_lock(inode->i_sb); err = reiserfs_commit_for_inode(inode); REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; reiserfs_write_unlock(inode->i_sb); if (err < 0) ret = err; } out: return ret; } /* * helper function for when reiserfs_get_block is called for a hole * but the file tail is still in a direct item * bh_result is the buffer head for the hole * tail_offset is the offset of the start of the tail in the file * * This calls prepare_write, which will start a new transaction * you should not be in a transaction, or have any paths held when you * call this. */ static int convert_tail_for_hole(struct inode *inode, struct buffer_head *bh_result, loff_t tail_offset) { unsigned long index; unsigned long tail_end; unsigned long tail_start; struct page *tail_page; struct page *hole_page = bh_result->b_page; int retval = 0; if ((tail_offset & (bh_result->b_size - 1)) != 1) return -EIO; /* always try to read until the end of the block */ tail_start = tail_offset & (PAGE_SIZE - 1); tail_end = (tail_start | (bh_result->b_size - 1)) + 1; index = tail_offset >> PAGE_SHIFT; /* * hole_page can be zero in case of direct_io, we are sure * that we cannot get here if we write with O_DIRECT into tail page */ if (!hole_page || index != hole_page->index) { tail_page = grab_cache_page(inode->i_mapping, index); retval = -ENOMEM; if (!tail_page) { goto out; } } else { tail_page = hole_page; } /* * we don't have to make sure the conversion did not happen while * we were locking the page because anyone that could convert * must first take i_mutex. * * We must fix the tail page for writing because it might have buffers * that are mapped, but have a block number of 0. This indicates tail * data that has been read directly into the page, and * __block_write_begin won't trigger a get_block in this case. */ fix_tail_page_for_writing(tail_page); retval = __reiserfs_write_begin(tail_page, tail_start, tail_end - tail_start); if (retval) goto unlock; /* tail conversion might change the data in the page */ flush_dcache_page(tail_page); retval = reiserfs_commit_write(NULL, tail_page, tail_start, tail_end); unlock: if (tail_page != hole_page) { unlock_page(tail_page); put_page(tail_page); } out: return retval; } static inline int _allocate_block(struct reiserfs_transaction_handle *th, sector_t block, struct inode *inode, b_blocknr_t * allocated_block_nr, struct treepath *path, int flags) { BUG_ON(!th->t_trans_id); #ifdef REISERFS_PREALLOCATE if (!(flags & GET_BLOCK_NO_IMUX)) { return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, path, block); } #endif return reiserfs_new_unf_blocknrs(th, inode, allocated_block_nr, path, block); } int reiserfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create) { int repeat, retval = 0; /* b_blocknr_t is (unsigned) 32 bit int*/ b_blocknr_t allocated_block_nr = 0; INITIALIZE_PATH(path); int pos_in_item; struct cpu_key key; struct buffer_head *bh, *unbh = NULL; struct item_head *ih, tmp_ih; __le32 *item; int done; int fs_gen; struct reiserfs_transaction_handle *th = NULL; /* * space reserved in transaction batch: * . 3 balancings in direct->indirect conversion * . 1 block involved into reiserfs_update_sd() * XXX in practically impossible worst case direct2indirect() * can incur (much) more than 3 balancings. * quota update for user, group */ int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb); int version; int dangle = 1; loff_t new_offset = (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1; reiserfs_write_lock(inode->i_sb); version = get_inode_item_key_version(inode); if (!file_capable(inode, block)) { reiserfs_write_unlock(inode->i_sb); return -EFBIG; } /* * if !create, we aren't changing the FS, so we don't need to * log anything, so we don't need to start a transaction */ if (!(create & GET_BLOCK_CREATE)) { int ret; /* find number of block-th logical block of the file */ ret = _get_block_create_0(inode, block, bh_result, create | GET_BLOCK_READ_DIRECT); reiserfs_write_unlock(inode->i_sb); return ret; } /* * if we're already in a transaction, make sure to close * any new transactions we start in this func */ if ((create & GET_BLOCK_NO_DANGLE) || reiserfs_transaction_running(inode->i_sb)) dangle = 0; /* * If file is of such a size, that it might have a tail and * tails are enabled we should mark it as possibly needing * tail packing on close */ if ((have_large_tails(inode->i_sb) && inode->i_size < i_block_size(inode) * 4) || (have_small_tails(inode->i_sb) && inode->i_size < i_block_size(inode))) REISERFS_I(inode)->i_flags |= i_pack_on_close_mask; /* set the key of the first byte in the 'block'-th block of file */ make_cpu_key(&key, inode, new_offset, TYPE_ANY, 3 /*key length */ ); if ((new_offset + inode->i_sb->s_blocksize - 1) > inode->i_size) { start_trans: th = reiserfs_persistent_transaction(inode->i_sb, jbegin_count); if (!th) { retval = -ENOMEM; goto failure; } reiserfs_update_inode_transaction(inode); } research: retval = search_for_position_by_key(inode->i_sb, &key, &path); if (retval == IO_ERROR) { retval = -EIO; goto failure; } bh = get_last_bh(&path); ih = tp_item_head(&path); item = tp_item_body(&path); pos_in_item = path.pos_in_item; fs_gen = get_generation(inode->i_sb); copy_item_head(&tmp_ih, ih); if (allocation_needed (retval, allocated_block_nr, ih, item, pos_in_item)) { /* we have to allocate block for the unformatted node */ if (!th) { pathrelse(&path); goto start_trans; } repeat = _allocate_block(th, block, inode, &allocated_block_nr, &path, create); /* * restart the transaction to give the journal a chance to free * some blocks. releases the path, so we have to go back to * research if we succeed on the second try */ if (repeat == NO_DISK_SPACE || repeat == QUOTA_EXCEEDED) { SB_JOURNAL(inode->i_sb)->j_next_async_flush = 1; retval = restart_transaction(th, inode, &path); if (retval) goto failure; repeat = _allocate_block(th, block, inode, &allocated_block_nr, NULL, create); if (repeat != NO_DISK_SPACE && repeat != QUOTA_EXCEEDED) { goto research; } if (repeat == QUOTA_EXCEEDED) retval = -EDQUOT; else retval = -ENOSPC; goto failure; } if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { goto research; } } if (indirect_item_found(retval, ih)) { b_blocknr_t unfm_ptr; /* * 'block'-th block is in the file already (there is * corresponding cell in some indirect item). But it may be * zero unformatted node pointer (hole) */ unfm_ptr = get_block_num(item, pos_in_item); if (unfm_ptr == 0) { /* use allocated block to plug the hole */ reiserfs_prepare_for_journal(inode->i_sb, bh, 1); if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { reiserfs_restore_prepared_buffer(inode->i_sb, bh); goto research; } set_buffer_new(bh_result); if (buffer_dirty(bh_result) && reiserfs_data_ordered(inode->i_sb)) reiserfs_add_ordered_list(inode, bh_result); put_block_num(item, pos_in_item, allocated_block_nr); unfm_ptr = allocated_block_nr; journal_mark_dirty(th, bh); reiserfs_update_sd(th, inode); } set_block_dev_mapped(bh_result, unfm_ptr, inode); pathrelse(&path); retval = 0; if (!dangle && th) retval = reiserfs_end_persistent_transaction(th); reiserfs_write_unlock(inode->i_sb); /* * the item was found, so new blocks were not added to the file * there is no need to make sure the inode is updated with this * transaction */ return retval; } if (!th) { pathrelse(&path); goto start_trans; } /* * desired position is not found or is in the direct item. We have * to append file with holes up to 'block'-th block converting * direct items to indirect one if necessary */ done = 0; do { if (is_statdata_le_ih(ih)) { __le32 unp = 0; struct cpu_key tmp_key; /* indirect item has to be inserted */ make_le_item_head(&tmp_ih, &key, version, 1, TYPE_INDIRECT, UNFM_P_SIZE, 0 /* free_space */ ); /* * we are going to add 'block'-th block to the file. * Use allocated block for that */ if (cpu_key_k_offset(&key) == 1) { unp = cpu_to_le32(allocated_block_nr); set_block_dev_mapped(bh_result, allocated_block_nr, inode); set_buffer_new(bh_result); done = 1; } tmp_key = key; /* ;) */ set_cpu_key_k_offset(&tmp_key, 1); PATH_LAST_POSITION(&path)++; retval = reiserfs_insert_item(th, &path, &tmp_key, &tmp_ih, inode, (char *)&unp); if (retval) { reiserfs_free_block(th, inode, allocated_block_nr, 1); /* * retval == -ENOSPC, -EDQUOT or -EIO * or -EEXIST */ goto failure; } } else if (is_direct_le_ih(ih)) { /* direct item has to be converted */ loff_t tail_offset; tail_offset = ((le_ih_k_offset(ih) - 1) & ~(inode->i_sb->s_blocksize - 1)) + 1; /* * direct item we just found fits into block we have * to map. Convert it into unformatted node: use * bh_result for the conversion */ if (tail_offset == cpu_key_k_offset(&key)) { set_block_dev_mapped(bh_result, allocated_block_nr, inode); unbh = bh_result; done = 1; } else { /* * we have to pad file tail stored in direct * item(s) up to block size and convert it * to unformatted node. FIXME: this should * also get into page cache */ pathrelse(&path); /* * ugly, but we can only end the transaction if * we aren't nested */ BUG_ON(!th->t_refcount); if (th->t_refcount == 1) { retval = reiserfs_end_persistent_transaction (th); th = NULL; if (retval) goto failure; } retval = convert_tail_for_hole(inode, bh_result, tail_offset); if (retval) { if (retval != -ENOSPC) reiserfs_error(inode->i_sb, "clm-6004", "convert tail failed " "inode %lu, error %d", inode->i_ino, retval); if (allocated_block_nr) { /* * the bitmap, the super, * and the stat data == 3 */ if (!th) th = reiserfs_persistent_transaction(inode->i_sb, 3); if (th) reiserfs_free_block(th, inode, allocated_block_nr, 1); } goto failure; } goto research; } retval = direct2indirect(th, inode, &path, unbh, tail_offset); if (retval) { reiserfs_unmap_buffer(unbh); reiserfs_free_block(th, inode, allocated_block_nr, 1); goto failure; } /* * it is important the set_buffer_uptodate is done * after the direct2indirect. The buffer might * contain valid data newer than the data on disk * (read by read_folio, changed, and then sent here by * writepage). direct2indirect needs to know if unbh * was already up to date, so it can decide if the * data in unbh needs to be replaced with data from * the disk */ set_buffer_uptodate(unbh); /* * unbh->b_page == NULL in case of DIRECT_IO request, * this means buffer will disappear shortly, so it * should not be added to */ if (unbh->b_page) { /* * we've converted the tail, so we must * flush unbh before the transaction commits */ reiserfs_add_tail_list(inode, unbh); /* * mark it dirty now to prevent commit_write * from adding this buffer to the inode's * dirty buffer list */ /* * AKPM: changed __mark_buffer_dirty to * mark_buffer_dirty(). It's still atomic, * but it sets the page dirty too, which makes * it eligible for writeback at any time by the * VM (which was also the case with * __mark_buffer_dirty()) */ mark_buffer_dirty(unbh); } } else { /* * append indirect item with holes if needed, when * appending pointer to 'block'-th block use block, * which is already allocated */ struct cpu_key tmp_key; /* * We use this in case we need to allocate * only one block which is a fastpath */ unp_t unf_single = 0; unp_t *un; __u64 max_to_insert = MAX_ITEM_LEN(inode->i_sb->s_blocksize) / UNFM_P_SIZE; __u64 blocks_needed; RFALSE(pos_in_item != ih_item_len(ih) / UNFM_P_SIZE, "vs-804: invalid position for append"); /* * indirect item has to be appended, * set up key of that position * (key type is unimportant) */ make_cpu_key(&tmp_key, inode, le_key_k_offset(version, &ih->ih_key) + op_bytes_number(ih, inode->i_sb->s_blocksize), TYPE_INDIRECT, 3); RFALSE(cpu_key_k_offset(&tmp_key) > cpu_key_k_offset(&key), "green-805: invalid offset"); blocks_needed = 1 + ((cpu_key_k_offset(&key) - cpu_key_k_offset(&tmp_key)) >> inode->i_sb-> s_blocksize_bits); if (blocks_needed == 1) { un = &unf_single; } else { un = kcalloc(min(blocks_needed, max_to_insert), UNFM_P_SIZE, GFP_NOFS); if (!un) { un = &unf_single; blocks_needed = 1; max_to_insert = 0; } } if (blocks_needed <= max_to_insert) { /* * we are going to add target block to * the file. Use allocated block for that */ un[blocks_needed - 1] = cpu_to_le32(allocated_block_nr); set_block_dev_mapped(bh_result, allocated_block_nr, inode); set_buffer_new(bh_result); done = 1; } else { /* paste hole to the indirect item */ /* * If kcalloc failed, max_to_insert becomes * zero and it means we only have space for * one block */ blocks_needed = max_to_insert ? max_to_insert : 1; } retval = reiserfs_paste_into_item(th, &path, &tmp_key, inode, (char *)un, UNFM_P_SIZE * blocks_needed); if (blocks_needed != 1) kfree(un); if (retval) { reiserfs_free_block(th, inode, allocated_block_nr, 1); goto failure; } if (!done) { /* * We need to mark new file size in case * this function will be interrupted/aborted * later on. And we may do this only for * holes. */ inode->i_size += inode->i_sb->s_blocksize * blocks_needed; } } if (done == 1) break; /* * this loop could log more blocks than we had originally * asked for. So, we have to allow the transaction to end * if it is too big or too full. Update the inode so things * are consistent if we crash before the function returns * release the path so that anybody waiting on the path before * ending their transaction will be able to continue. */ if (journal_transaction_should_end(th, th->t_blocks_allocated)) { retval = restart_transaction(th, inode, &path); if (retval) goto failure; } /* * inserting indirect pointers for a hole can take a * long time. reschedule if needed and also release the write * lock for others. */ reiserfs_cond_resched(inode->i_sb); retval = search_for_position_by_key(inode->i_sb, &key, &path); if (retval == IO_ERROR) { retval = -EIO; goto failure; } if (retval == POSITION_FOUND) { reiserfs_warning(inode->i_sb, "vs-825", "%K should not be found", &key); retval = -EEXIST; if (allocated_block_nr) reiserfs_free_block(th, inode, allocated_block_nr, 1); pathrelse(&path); goto failure; } bh = get_last_bh(&path); ih = tp_item_head(&path); item = tp_item_body(&path); pos_in_item = path.pos_in_item; } while (1); retval = 0; failure: if (th && (!dangle || (retval && !th->t_trans_id))) { int err; if (th->t_trans_id) reiserfs_update_sd(th, inode); err = reiserfs_end_persistent_transaction(th); if (err) retval = err; } reiserfs_write_unlock(inode->i_sb); reiserfs_check_path(&path); return retval; } static void reiserfs_readahead(struct readahead_control *rac) { mpage_readahead(rac, reiserfs_get_block); } /* * Compute real number of used bytes by file * Following three functions can go away when we'll have enough space in * stat item */ static int real_space_diff(struct inode *inode, int sd_size) { int bytes; loff_t blocksize = inode->i_sb->s_blocksize; if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) return sd_size; /* * End of file is also in full block with indirect reference, so round * up to the next block. * * there is just no way to know if the tail is actually packed * on the file, so we have to assume it isn't. When we pack the * tail, we add 4 bytes to pretend there really is an unformatted * node pointer */ bytes = ((inode->i_size + (blocksize - 1)) >> inode->i_sb->s_blocksize_bits) * UNFM_P_SIZE + sd_size; return bytes; } static inline loff_t to_real_used_space(struct inode *inode, ulong blocks, int sd_size) { if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) { return inode->i_size + (loff_t) (real_space_diff(inode, sd_size)); } return ((loff_t) real_space_diff(inode, sd_size)) + (((loff_t) blocks) << 9); } /* Compute number of blocks used by file in ReiserFS counting */ static inline ulong to_fake_used_blocks(struct inode *inode, int sd_size) { loff_t bytes = inode_get_bytes(inode); loff_t real_space = real_space_diff(inode, sd_size); /* keeps fsck and non-quota versions of reiserfs happy */ if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) { bytes += (loff_t) 511; } /* * files from before the quota patch might i_blocks such that * bytes < real_space. Deal with that here to prevent it from * going negative. */ if (bytes < real_space) return 0; return (bytes - real_space) >> 9; } /* * BAD: new directories have stat data of new type and all other items * of old type. Version stored in the inode says about body items, so * in update_stat_data we can not rely on inode, but have to check * item version directly */ /* called by read_locked_inode */ static void init_inode(struct inode *inode, struct treepath *path) { struct buffer_head *bh; struct item_head *ih; __u32 rdev; bh = PATH_PLAST_BUFFER(path); ih = tp_item_head(path); copy_key(INODE_PKEY(inode), &ih->ih_key); INIT_LIST_HEAD(&REISERFS_I(inode)->i_prealloc_list); REISERFS_I(inode)->i_flags = 0; REISERFS_I(inode)->i_prealloc_block = 0; REISERFS_I(inode)->i_prealloc_count = 0; REISERFS_I(inode)->i_trans_id = 0; REISERFS_I(inode)->i_jl = NULL; reiserfs_init_xattr_rwsem(inode); if (stat_data_v1(ih)) { struct stat_data_v1 *sd = (struct stat_data_v1 *)ih_item_body(bh, ih); unsigned long blocks; set_inode_item_key_version(inode, KEY_FORMAT_3_5); set_inode_sd_version(inode, STAT_DATA_V1); inode->i_mode = sd_v1_mode(sd); set_nlink(inode, sd_v1_nlink(sd)); i_uid_write(inode, sd_v1_uid(sd)); i_gid_write(inode, sd_v1_gid(sd)); inode->i_size = sd_v1_size(sd); inode_set_atime(inode, sd_v1_atime(sd), 0); inode_set_mtime(inode, sd_v1_mtime(sd), 0); inode_set_ctime(inode, sd_v1_ctime(sd), 0); inode->i_blocks = sd_v1_blocks(sd); inode->i_generation = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); blocks = (inode->i_size + 511) >> 9; blocks = _ROUND_UP(blocks, inode->i_sb->s_blocksize >> 9); /* * there was a bug in <=3.5.23 when i_blocks could take * negative values. Starting from 3.5.17 this value could * even be stored in stat data. For such files we set * i_blocks based on file size. Just 2 notes: this can be * wrong for sparse files. On-disk value will be only * updated if file's inode will ever change */ if (inode->i_blocks > blocks) { inode->i_blocks = blocks; } rdev = sd_v1_rdev(sd); REISERFS_I(inode)->i_first_direct_byte = sd_v1_first_direct_byte(sd); /* * an early bug in the quota code can give us an odd * number for the block count. This is incorrect, fix it here. */ if (inode->i_blocks & 1) { inode->i_blocks++; } inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks, SD_V1_SIZE)); /* * nopack is initially zero for v1 objects. For v2 objects, * nopack is initialised from sd_attrs */ REISERFS_I(inode)->i_flags &= ~i_nopack_mask; } else { /* * new stat data found, but object may have old items * (directories and symlinks) */ struct stat_data *sd = (struct stat_data *)ih_item_body(bh, ih); inode->i_mode = sd_v2_mode(sd); set_nlink(inode, sd_v2_nlink(sd)); i_uid_write(inode, sd_v2_uid(sd)); inode->i_size = sd_v2_size(sd); i_gid_write(inode, sd_v2_gid(sd)); inode_set_mtime(inode, sd_v2_mtime(sd), 0); inode_set_atime(inode, sd_v2_atime(sd), 0); inode_set_ctime(inode, sd_v2_ctime(sd), 0); inode->i_blocks = sd_v2_blocks(sd); rdev = sd_v2_rdev(sd); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) inode->i_generation = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); else inode->i_generation = sd_v2_generation(sd); if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) set_inode_item_key_version(inode, KEY_FORMAT_3_5); else set_inode_item_key_version(inode, KEY_FORMAT_3_6); REISERFS_I(inode)->i_first_direct_byte = 0; set_inode_sd_version(inode, STAT_DATA_V2); inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks, SD_V2_SIZE)); /* * read persistent inode attributes from sd and initialise * generic inode flags from them */ REISERFS_I(inode)->i_attrs = sd_v2_attrs(sd); sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode); } pathrelse(path); if (S_ISREG(inode->i_mode)) { inode->i_op = &reiserfs_file_inode_operations; inode->i_fop = &reiserfs_file_operations; inode->i_mapping->a_ops = &reiserfs_address_space_operations; } else if (S_ISDIR(inode->i_mode)) { inode->i_op = &reiserfs_dir_inode_operations; inode->i_fop = &reiserfs_dir_operations; } else if (S_ISLNK(inode->i_mode)) { inode->i_op = &reiserfs_symlink_inode_operations; inode_nohighmem(inode); inode->i_mapping->a_ops = &reiserfs_address_space_operations; } else { inode->i_blocks = 0; inode->i_op = &reiserfs_special_inode_operations; init_special_inode(inode, inode->i_mode, new_decode_dev(rdev)); } } /* update new stat data with inode fields */ static void inode2sd(void *sd, struct inode *inode, loff_t size) { struct stat_data *sd_v2 = (struct stat_data *)sd; set_sd_v2_mode(sd_v2, inode->i_mode); set_sd_v2_nlink(sd_v2, inode->i_nlink); set_sd_v2_uid(sd_v2, i_uid_read(inode)); set_sd_v2_size(sd_v2, size); set_sd_v2_gid(sd_v2, i_gid_read(inode)); set_sd_v2_mtime(sd_v2, inode_get_mtime_sec(inode)); set_sd_v2_atime(sd_v2, inode_get_atime_sec(inode)); set_sd_v2_ctime(sd_v2, inode_get_ctime_sec(inode)); set_sd_v2_blocks(sd_v2, to_fake_used_blocks(inode, SD_V2_SIZE)); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) set_sd_v2_rdev(sd_v2, new_encode_dev(inode->i_rdev)); else set_sd_v2_generation(sd_v2, inode->i_generation); set_sd_v2_attrs(sd_v2, REISERFS_I(inode)->i_attrs); } /* used to copy inode's fields to old stat data */ static void inode2sd_v1(void *sd, struct inode *inode, loff_t size) { struct stat_data_v1 *sd_v1 = (struct stat_data_v1 *)sd; set_sd_v1_mode(sd_v1, inode->i_mode); set_sd_v1_uid(sd_v1, i_uid_read(inode)); set_sd_v1_gid(sd_v1, i_gid_read(inode)); set_sd_v1_nlink(sd_v1, inode->i_nlink); set_sd_v1_size(sd_v1, size); set_sd_v1_atime(sd_v1, inode_get_atime_sec(inode)); set_sd_v1_ctime(sd_v1, inode_get_ctime_sec(inode)); set_sd_v1_mtime(sd_v1, inode_get_mtime_sec(inode)); if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) set_sd_v1_rdev(sd_v1, new_encode_dev(inode->i_rdev)); else set_sd_v1_blocks(sd_v1, to_fake_used_blocks(inode, SD_V1_SIZE)); /* Sigh. i_first_direct_byte is back */ set_sd_v1_first_direct_byte(sd_v1, REISERFS_I(inode)->i_first_direct_byte); } /* * NOTE, you must prepare the buffer head before sending it here, * and then log it after the call */ static void update_stat_data(struct treepath *path, struct inode *inode, loff_t size) { struct buffer_head *bh; struct item_head *ih; bh = PATH_PLAST_BUFFER(path); ih = tp_item_head(path); if (!is_statdata_le_ih(ih)) reiserfs_panic(inode->i_sb, "vs-13065", "key %k, found item %h", INODE_PKEY(inode), ih); /* path points to old stat data */ if (stat_data_v1(ih)) { inode2sd_v1(ih_item_body(bh, ih), inode, size); } else { inode2sd(ih_item_body(bh, ih), inode, size); } return; } void reiserfs_update_sd_size(struct reiserfs_transaction_handle *th, struct inode *inode, loff_t size) { struct cpu_key key; INITIALIZE_PATH(path); struct buffer_head *bh; int fs_gen; struct item_head *ih, tmp_ih; int retval; BUG_ON(!th->t_trans_id); /* key type is unimportant */ make_cpu_key(&key, inode, SD_OFFSET, TYPE_STAT_DATA, 3); for (;;) { int pos; /* look for the object's stat data */ retval = search_item(inode->i_sb, &key, &path); if (retval == IO_ERROR) { reiserfs_error(inode->i_sb, "vs-13050", "i/o failure occurred trying to " "update %K stat data", &key); return; } if (retval == ITEM_NOT_FOUND) { pos = PATH_LAST_POSITION(&path); pathrelse(&path); if (inode->i_nlink == 0) { /*reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: i_nlink == 0, stat data not found"); */ return; } reiserfs_warning(inode->i_sb, "vs-13060", "stat data of object %k (nlink == %d) " "not found (pos %d)", INODE_PKEY(inode), inode->i_nlink, pos); reiserfs_check_path(&path); return; } /* * sigh, prepare_for_journal might schedule. When it * schedules the FS might change. We have to detect that, * and loop back to the search if the stat data item has moved */ bh = get_last_bh(&path); ih = tp_item_head(&path); copy_item_head(&tmp_ih, ih); fs_gen = get_generation(inode->i_sb); reiserfs_prepare_for_journal(inode->i_sb, bh, 1); /* Stat_data item has been moved after scheduling. */ if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { reiserfs_restore_prepared_buffer(inode->i_sb, bh); continue; } break; } update_stat_data(&path, inode, size); journal_mark_dirty(th, bh); pathrelse(&path); return; } /* * reiserfs_read_locked_inode is called to read the inode off disk, and it * does a make_bad_inode when things go wrong. But, we need to make sure * and clear the key in the private portion of the inode, otherwise a * corresponding iput might try to delete whatever object the inode last * represented. */ static void reiserfs_make_bad_inode(struct inode *inode) { memset(INODE_PKEY(inode), 0, KEY_SIZE); make_bad_inode(inode); } /* * initially this function was derived from minix or ext2's analog and * evolved as the prototype did */ int reiserfs_init_locked_inode(struct inode *inode, void *p) { struct reiserfs_iget_args *args = (struct reiserfs_iget_args *)p; inode->i_ino = args->objectid; INODE_PKEY(inode)->k_dir_id = cpu_to_le32(args->dirid); return 0; } /* * looks for stat data in the tree, and fills up the fields of in-core * inode stat data fields */ void reiserfs_read_locked_inode(struct inode *inode, struct reiserfs_iget_args *args) { INITIALIZE_PATH(path_to_sd); struct cpu_key key; unsigned long dirino; int retval; dirino = args->dirid; /* * set version 1, version 2 could be used too, because stat data * key is the same in both versions */ _make_cpu_key(&key, KEY_FORMAT_3_5, dirino, inode->i_ino, 0, 0, 3); /* look for the object's stat data */ retval = search_item(inode->i_sb, &key, &path_to_sd); if (retval == IO_ERROR) { reiserfs_error(inode->i_sb, "vs-13070", "i/o failure occurred trying to find " "stat data of %K", &key); reiserfs_make_bad_inode(inode); return; } /* a stale NFS handle can trigger this without it being an error */ if (retval != ITEM_FOUND) { pathrelse(&path_to_sd); reiserfs_make_bad_inode(inode); clear_nlink(inode); return; } init_inode(inode, &path_to_sd); /* * It is possible that knfsd is trying to access inode of a file * that is being removed from the disk by some other thread. As we * update sd on unlink all that is required is to check for nlink * here. This bug was first found by Sizif when debugging * SquidNG/Butterfly, forgotten, and found again after Philippe * Gramoulle <philippe.gramoulle@mmania.com> reproduced it. * More logical fix would require changes in fs/inode.c:iput() to * remove inode from hash-table _after_ fs cleaned disk stuff up and * in iget() to return NULL if I_FREEING inode is found in * hash-table. */ /* * Currently there is one place where it's ok to meet inode with * nlink==0: processing of open-unlinked and half-truncated files * during mount (fs/reiserfs/super.c:finish_unfinished()). */ if ((inode->i_nlink == 0) && !REISERFS_SB(inode->i_sb)->s_is_unlinked_ok) { reiserfs_warning(inode->i_sb, "vs-13075", "dead inode read from disk %K. " "This is likely to be race with knfsd. Ignore", &key); reiserfs_make_bad_inode(inode); } /* init inode should be relsing */ reiserfs_check_path(&path_to_sd); /* * Stat data v1 doesn't support ACLs. */ if (get_inode_sd_version(inode) == STAT_DATA_V1) cache_no_acl(inode); } /* * reiserfs_find_actor() - "find actor" reiserfs supplies to iget5_locked(). * * @inode: inode from hash table to check * @opaque: "cookie" passed to iget5_locked(). This is &reiserfs_iget_args. * * This function is called by iget5_locked() to distinguish reiserfs inodes * having the same inode numbers. Such inodes can only exist due to some * error condition. One of them should be bad. Inodes with identical * inode numbers (objectids) are distinguished by parent directory ids. * */ int reiserfs_find_actor(struct inode *inode, void *opaque) { struct reiserfs_iget_args *args; args = opaque; /* args is already in CPU order */ return (inode->i_ino == args->objectid) && (le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args->dirid); } struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key) { struct inode *inode; struct reiserfs_iget_args args; int depth; args.objectid = key->on_disk_key.k_objectid; args.dirid = key->on_disk_key.k_dir_id; depth = reiserfs_write_unlock_nested(s); inode = iget5_locked(s, key->on_disk_key.k_objectid, reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args)); reiserfs_write_lock_nested(s, depth); if (!inode) return ERR_PTR(-ENOMEM); if (inode->i_state & I_NEW) { reiserfs_read_locked_inode(inode, &args); unlock_new_inode(inode); } if (comp_short_keys(INODE_PKEY(inode), key) || is_bad_inode(inode)) { /* either due to i/o error or a stale NFS handle */ iput(inode); inode = NULL; } return inode; } static struct dentry *reiserfs_get_dentry(struct super_block *sb, u32 objectid, u32 dir_id, u32 generation) { struct cpu_key key; struct inode *inode; key.on_disk_key.k_objectid = objectid; key.on_disk_key.k_dir_id = dir_id; reiserfs_write_lock(sb); inode = reiserfs_iget(sb, &key); if (inode && !IS_ERR(inode) && generation != 0 && generation != inode->i_generation) { iput(inode); inode = NULL; } reiserfs_write_unlock(sb); return d_obtain_alias(inode); } struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { /* * fhtype happens to reflect the number of u32s encoded. * due to a bug in earlier code, fhtype might indicate there * are more u32s then actually fitted. * so if fhtype seems to be more than len, reduce fhtype. * Valid types are: * 2 - objectid + dir_id - legacy support * 3 - objectid + dir_id + generation * 4 - objectid + dir_id + objectid and dirid of parent - legacy * 5 - objectid + dir_id + generation + objectid and dirid of parent * 6 - as above plus generation of directory * 6 does not fit in NFSv2 handles */ if (fh_type > fh_len) { if (fh_type != 6 || fh_len != 5) reiserfs_warning(sb, "reiserfs-13077", "nfsd/reiserfs, fhtype=%d, len=%d - odd", fh_type, fh_len); fh_type = fh_len; } if (fh_len < 2) return NULL; return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1], (fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0); } struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type) { if (fh_type > fh_len) fh_type = fh_len; if (fh_type < 4) return NULL; return reiserfs_get_dentry(sb, (fh_type >= 5) ? fid->raw[3] : fid->raw[2], (fh_type >= 5) ? fid->raw[4] : fid->raw[3], (fh_type == 6) ? fid->raw[5] : 0); } int reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp, struct inode *parent) { int maxlen = *lenp; if (parent && (maxlen < 5)) { *lenp = 5; return FILEID_INVALID; } else if (maxlen < 3) { *lenp = 3; return FILEID_INVALID; } data[0] = inode->i_ino; data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id); data[2] = inode->i_generation; *lenp = 3; if (parent) { data[3] = parent->i_ino; data[4] = le32_to_cpu(INODE_PKEY(parent)->k_dir_id); *lenp = 5; if (maxlen >= 6) { data[5] = parent->i_generation; *lenp = 6; } } return *lenp; } /* * looks for stat data, then copies fields to it, marks the buffer * containing stat data as dirty */ /* * reiserfs inodes are never really dirty, since the dirty inode call * always logs them. This call allows the VFS inode marking routines * to properly mark inodes for datasync and such, but only actually * does something when called for a synchronous update. */ int reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc) { struct reiserfs_transaction_handle th; int jbegin_count = 1; if (sb_rdonly(inode->i_sb)) return -EROFS; /* * memory pressure can sometimes initiate write_inode calls with * sync == 1, * these cases are just when the system needs ram, not when the * inode needs to reach disk for safety, and they can safely be * ignored because the altered inode has already been logged. */ if (wbc->sync_mode == WB_SYNC_ALL && !(current->flags & PF_MEMALLOC)) { reiserfs_write_lock(inode->i_sb); if (!journal_begin(&th, inode->i_sb, jbegin_count)) { reiserfs_update_sd(&th, inode); journal_end_sync(&th); } reiserfs_write_unlock(inode->i_sb); } return 0; } /* * stat data of new object is inserted already, this inserts the item * containing "." and ".." entries */ static int reiserfs_new_directory(struct reiserfs_transaction_handle *th, struct inode *inode, struct item_head *ih, struct treepath *path, struct inode *dir) { struct super_block *sb = th->t_super; char empty_dir[EMPTY_DIR_SIZE]; char *body = empty_dir; struct cpu_key key; int retval; BUG_ON(!th->t_trans_id); _make_cpu_key(&key, KEY_FORMAT_3_5, le32_to_cpu(ih->ih_key.k_dir_id), le32_to_cpu(ih->ih_key.k_objectid), DOT_OFFSET, TYPE_DIRENTRY, 3 /*key length */ ); /* * compose item head for new item. Directories consist of items of * old type (ITEM_VERSION_1). Do not set key (second arg is 0), it * is done by reiserfs_new_inode */ if (old_format_only(sb)) { make_le_item_head(ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2); make_empty_dir_item_v1(body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid, INODE_PKEY(dir)->k_dir_id, INODE_PKEY(dir)->k_objectid); } else { make_le_item_head(ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2); make_empty_dir_item(body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid, INODE_PKEY(dir)->k_dir_id, INODE_PKEY(dir)->k_objectid); } /* look for place in the tree for new item */ retval = search_item(sb, &key, path); if (retval == IO_ERROR) { reiserfs_error(sb, "vs-13080", "i/o failure occurred creating new directory"); return -EIO; } if (retval == ITEM_FOUND) { pathrelse(path); reiserfs_warning(sb, "vs-13070", "object with this key exists (%k)", &(ih->ih_key)); return -EEXIST; } /* insert item, that is empty directory item */ return reiserfs_insert_item(th, path, &key, ih, inode, body); } /* * stat data of object has been inserted, this inserts the item * containing the body of symlink */ static int reiserfs_new_symlink(struct reiserfs_transaction_handle *th, struct inode *inode, struct item_head *ih, struct treepath *path, const char *symname, int item_len) { struct super_block *sb = th->t_super; struct cpu_key key; int retval; BUG_ON(!th->t_trans_id); _make_cpu_key(&key, KEY_FORMAT_3_5, le32_to_cpu(ih->ih_key.k_dir_id), le32_to_cpu(ih->ih_key.k_objectid), 1, TYPE_DIRECT, 3 /*key length */ ); make_le_item_head(ih, NULL, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0 /*free_space */ ); /* look for place in the tree for new item */ retval = search_item(sb, &key, path); if (retval == IO_ERROR) { reiserfs_error(sb, "vs-13080", "i/o failure occurred creating new symlink"); return -EIO; } if (retval == ITEM_FOUND) { pathrelse(path); reiserfs_warning(sb, "vs-13080", "object with this key exists (%k)", &(ih->ih_key)); return -EEXIST; } /* insert item, that is body of symlink */ return reiserfs_insert_item(th, path, &key, ih, inode, symname); } /* * inserts the stat data into the tree, and then calls * reiserfs_new_directory (to insert ".", ".." item if new object is * directory) or reiserfs_new_symlink (to insert symlink body if new * object is symlink) or nothing (if new object is regular file) * NOTE! uid and gid must already be set in the inode. If we return * non-zero due to an error, we have to drop the quota previously allocated * for the fresh inode. This can only be done outside a transaction, so * if we return non-zero, we also end the transaction. * * @th: active transaction handle * @dir: parent directory for new inode * @mode: mode of new inode * @symname: symlink contents if inode is symlink * @isize: 0 for regular file, EMPTY_DIR_SIZE for dirs, strlen(symname) for * symlinks * @inode: inode to be filled * @security: optional security context to associate with this inode */ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, struct inode *dir, umode_t mode, const char *symname, /* 0 for regular, EMTRY_DIR_SIZE for dirs, strlen (symname) for symlinks) */ loff_t i_size, struct dentry *dentry, struct inode *inode, struct reiserfs_security_handle *security) { struct super_block *sb = dir->i_sb; struct reiserfs_iget_args args; INITIALIZE_PATH(path_to_key); struct cpu_key key; struct item_head ih; struct stat_data sd; int retval; int err; int depth; BUG_ON(!th->t_trans_id); depth = reiserfs_write_unlock_nested(sb); err = dquot_alloc_inode(inode); reiserfs_write_lock_nested(sb, depth); if (err) goto out_end_trans; if (!dir->i_nlink) { err = -EPERM; goto out_bad_inode; } /* item head of new item */ ih.ih_key.k_dir_id = reiserfs_choose_packing(dir); ih.ih_key.k_objectid = cpu_to_le32(reiserfs_get_unused_objectid(th)); if (!ih.ih_key.k_objectid) { err = -ENOMEM; goto out_bad_inode; } args.objectid = inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid); if (old_format_only(sb)) make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT); else make_le_item_head(&ih, NULL, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT); memcpy(INODE_PKEY(inode), &ih.ih_key, KEY_SIZE); args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); depth = reiserfs_write_unlock_nested(inode->i_sb); err = insert_inode_locked4(inode, args.objectid, reiserfs_find_actor, &args); reiserfs_write_lock_nested(inode->i_sb, depth); if (err) { err = -EINVAL; goto out_bad_inode; } if (old_format_only(sb)) /* * not a perfect generation count, as object ids can be reused, * but this is as good as reiserfs can do right now. * note that the private part of inode isn't filled in yet, * we have to use the directory. */ inode->i_generation = le32_to_cpu(INODE_PKEY(dir)->k_objectid); else #if defined( USE_INODE_GENERATION_COUNTER ) inode->i_generation = le32_to_cpu(REISERFS_SB(sb)->s_rs->s_inode_generation); #else inode->i_generation = ++event; #endif /* fill stat data */ set_nlink(inode, (S_ISDIR(mode) ? 2 : 1)); /* uid and gid must already be set by the caller for quota init */ simple_inode_init_ts(inode); inode->i_size = i_size; inode->i_blocks = 0; inode->i_bytes = 0; REISERFS_I(inode)->i_first_direct_byte = S_ISLNK(mode) ? 1 : U32_MAX /*NO_BYTES_IN_DIRECT_ITEM */ ; INIT_LIST_HEAD(&REISERFS_I(inode)->i_prealloc_list); REISERFS_I(inode)->i_flags = 0; REISERFS_I(inode)->i_prealloc_block = 0; REISERFS_I(inode)->i_prealloc_count = 0; REISERFS_I(inode)->i_trans_id = 0; REISERFS_I(inode)->i_jl = NULL; REISERFS_I(inode)->i_attrs = REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); reiserfs_init_xattr_rwsem(inode); /* key to search for correct place for new stat data */ _make_cpu_key(&key, KEY_FORMAT_3_6, le32_to_cpu(ih.ih_key.k_dir_id), le32_to_cpu(ih.ih_key.k_objectid), SD_OFFSET, TYPE_STAT_DATA, 3 /*key length */ ); /* find proper place for inserting of stat data */ retval = search_item(sb, &key, &path_to_key); if (retval == IO_ERROR) { err = -EIO; goto out_bad_inode; } if (retval == ITEM_FOUND) { pathrelse(&path_to_key); err = -EEXIST; goto out_bad_inode; } if (old_format_only(sb)) { /* i_uid or i_gid is too big to be stored in stat data v3.5 */ if (i_uid_read(inode) & ~0xffff || i_gid_read(inode) & ~0xffff) { pathrelse(&path_to_key); err = -EINVAL; goto out_bad_inode; } inode2sd_v1(&sd, inode, inode->i_size); } else { inode2sd(&sd, inode, inode->i_size); } /* * store in in-core inode the key of stat data and version all * object items will have (directory items will have old offset * format, other new objects will consist of new items) */ if (old_format_only(sb) || S_ISDIR(mode) || S_ISLNK(mode)) set_inode_item_key_version(inode, KEY_FORMAT_3_5); else set_inode_item_key_version(inode, KEY_FORMAT_3_6); if (old_format_only(sb)) set_inode_sd_version(inode, STAT_DATA_V1); else set_inode_sd_version(inode, STAT_DATA_V2); /* insert the stat data into the tree */ #ifdef DISPLACE_NEW_PACKING_LOCALITIES if (REISERFS_I(dir)->new_packing_locality) th->displace_new_blocks = 1; #endif retval = reiserfs_insert_item(th, &path_to_key, &key, &ih, inode, (char *)(&sd)); if (retval) { err = retval; reiserfs_check_path(&path_to_key); goto out_bad_inode; } #ifdef DISPLACE_NEW_PACKING_LOCALITIES if (!th->displace_new_blocks) REISERFS_I(dir)->new_packing_locality = 0; #endif if (S_ISDIR(mode)) { /* insert item with "." and ".." */ retval = reiserfs_new_directory(th, inode, &ih, &path_to_key, dir); } if (S_ISLNK(mode)) { /* insert body of symlink */ if (!old_format_only(sb)) i_size = ROUND_UP(i_size); retval = reiserfs_new_symlink(th, inode, &ih, &path_to_key, symname, i_size); } if (retval) { err = retval; reiserfs_check_path(&path_to_key); journal_end(th); goto out_inserted_sd; } /* * Mark it private if we're creating the privroot * or something under it. */ if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) reiserfs_init_priv_inode(inode); if (reiserfs_posixacl(inode->i_sb)) { reiserfs_write_unlock(inode->i_sb); retval = reiserfs_inherit_default_acl(th, dir, dentry, inode); reiserfs_write_lock(inode->i_sb); if (retval) { err = retval; reiserfs_check_path(&path_to_key); journal_end(th); goto out_inserted_sd; } } else if (inode->i_sb->s_flags & SB_POSIXACL) { reiserfs_warning(inode->i_sb, "jdm-13090", "ACLs aren't enabled in the fs, " "but vfs thinks they are!"); } if (security->name) { reiserfs_write_unlock(inode->i_sb); retval = reiserfs_security_write(th, inode, security); reiserfs_write_lock(inode->i_sb); if (retval) { err = retval; reiserfs_check_path(&path_to_key); retval = journal_end(th); if (retval) err = retval; goto out_inserted_sd; } } reiserfs_update_sd(th, inode); reiserfs_check_path(&path_to_key); return 0; out_bad_inode: /* Invalidate the object, nothing was inserted yet */ INODE_PKEY(inode)->k_objectid = 0; /* Quota change must be inside a transaction for journaling */ depth = reiserfs_write_unlock_nested(inode->i_sb); dquot_free_inode(inode); reiserfs_write_lock_nested(inode->i_sb, depth); out_end_trans: journal_end(th); /* * Drop can be outside and it needs more credits so it's better * to have it outside */ depth = reiserfs_write_unlock_nested(inode->i_sb); dquot_drop(inode); reiserfs_write_lock_nested(inode->i_sb, depth); inode->i_flags |= S_NOQUOTA; make_bad_inode(inode); out_inserted_sd: clear_nlink(inode); th->t_trans_id = 0; /* so the caller can't use this handle later */ if (inode->i_state & I_NEW) unlock_new_inode(inode); iput(inode); return err; } /* * finds the tail page in the page cache, * reads the last block in. * * On success, page_result is set to a locked, pinned page, and bh_result * is set to an up to date buffer for the last block in the file. returns 0. * * tail conversion is not done, so bh_result might not be valid for writing * check buffer_mapped(bh_result) and bh_result->b_blocknr != 0 before * trying to write the block. * * on failure, nonzero is returned, page_result and bh_result are untouched. */ static int grab_tail_page(struct inode *inode, struct page **page_result, struct buffer_head **bh_result) { /* * we want the page with the last byte in the file, * not the page that will hold the next byte for appending */ unsigned long index = (inode->i_size - 1) >> PAGE_SHIFT; unsigned long pos = 0; unsigned long start = 0; unsigned long blocksize = inode->i_sb->s_blocksize; unsigned long offset = (inode->i_size) & (PAGE_SIZE - 1); struct buffer_head *bh; struct buffer_head *head; struct page *page; int error; /* * we know that we are only called with inode->i_size > 0. * we also know that a file tail can never be as big as a block * If i_size % blocksize == 0, our file is currently block aligned * and it won't need converting or zeroing after a truncate. */ if ((offset & (blocksize - 1)) == 0) { return -ENOENT; } page = grab_cache_page(inode->i_mapping, index); error = -ENOMEM; if (!page) { goto out; } /* start within the page of the last block in the file */ start = (offset / blocksize) * blocksize; error = __block_write_begin(page, start, offset - start, reiserfs_get_block_create_0); if (error) goto unlock; head = page_buffers(page); bh = head; do { if (pos >= start) { break; } bh = bh->b_this_page; pos += blocksize; } while (bh != head); if (!buffer_uptodate(bh)) { /* * note, this should never happen, prepare_write should be * taking care of this for us. If the buffer isn't up to * date, I've screwed up the code to find the buffer, or the * code to call prepare_write */ reiserfs_error(inode->i_sb, "clm-6000", "error reading block %lu", bh->b_blocknr); error = -EIO; goto unlock; } *bh_result = bh; *page_result = page; out: return error; unlock: unlock_page(page); put_page(page); return error; } /* * vfs version of truncate file. Must NOT be called with * a transaction already started. * * some code taken from block_truncate_page */ int reiserfs_truncate_file(struct inode *inode, int update_timestamps) { struct reiserfs_transaction_handle th; /* we want the offset for the first byte after the end of the file */ unsigned long offset = inode->i_size & (PAGE_SIZE - 1); unsigned blocksize = inode->i_sb->s_blocksize; unsigned length; struct page *page = NULL; int error; struct buffer_head *bh = NULL; int err2; reiserfs_write_lock(inode->i_sb); if (inode->i_size > 0) { error = grab_tail_page(inode, &page, &bh); if (error) { /* * -ENOENT means we truncated past the end of the * file, and get_block_create_0 could not find a * block to read in, which is ok. */ if (error != -ENOENT) reiserfs_error(inode->i_sb, "clm-6001", "grab_tail_page failed %d", error); page = NULL; bh = NULL; } } /* * so, if page != NULL, we have a buffer head for the offset at * the end of the file. if the bh is mapped, and bh->b_blocknr != 0, * then we have an unformatted node. Otherwise, we have a direct item, * and no zeroing is required on disk. We zero after the truncate, * because the truncate might pack the item anyway * (it will unmap bh if it packs). * * it is enough to reserve space in transaction for 2 balancings: * one for "save" link adding and another for the first * cut_from_item. 1 is for update_sd */ error = journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1); if (error) goto out; reiserfs_update_inode_transaction(inode); if (update_timestamps) /* * we are doing real truncate: if the system crashes * before the last transaction of truncating gets committed * - on reboot the file either appears truncated properly * or not truncated at all */ add_save_link(&th, inode, 1); err2 = reiserfs_do_truncate(&th, inode, page, update_timestamps); error = journal_end(&th); if (error) goto out; /* check reiserfs_do_truncate after ending the transaction */ if (err2) { error = err2; goto out; } if (update_timestamps) { error = remove_save_link(inode, 1 /* truncate */); if (error) goto out; } if (page) { length = offset & (blocksize - 1); /* if we are not on a block boundary */ if (length) { length = blocksize - length; zero_user(page, offset, length); if (buffer_mapped(bh) && bh->b_blocknr != 0) { mark_buffer_dirty(bh); } } unlock_page(page); put_page(page); } reiserfs_write_unlock(inode->i_sb); return 0; out: if (page) { unlock_page(page); put_page(page); } reiserfs_write_unlock(inode->i_sb); return error; } static int map_block_for_writepage(struct inode *inode, struct buffer_head *bh_result, unsigned long block) { struct reiserfs_transaction_handle th; int fs_gen; struct item_head tmp_ih; struct item_head *ih; struct buffer_head *bh; __le32 *item; struct cpu_key key; INITIALIZE_PATH(path); int pos_in_item; int jbegin_count = JOURNAL_PER_BALANCE_CNT; loff_t byte_offset = ((loff_t)block << inode->i_sb->s_blocksize_bits)+1; int retval; int use_get_block = 0; int bytes_copied = 0; int copy_size; int trans_running = 0; /* * catch places below that try to log something without * starting a trans */ th.t_trans_id = 0; if (!buffer_uptodate(bh_result)) { return -EIO; } kmap(bh_result->b_page); start_over: reiserfs_write_lock(inode->i_sb); make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3); research: retval = search_for_position_by_key(inode->i_sb, &key, &path); if (retval != POSITION_FOUND) { use_get_block = 1; goto out; } bh = get_last_bh(&path); ih = tp_item_head(&path); item = tp_item_body(&path); pos_in_item = path.pos_in_item; /* we've found an unformatted node */ if (indirect_item_found(retval, ih)) { if (bytes_copied > 0) { reiserfs_warning(inode->i_sb, "clm-6002", "bytes_copied %d", bytes_copied); } if (!get_block_num(item, pos_in_item)) { /* crap, we are writing to a hole */ use_get_block = 1; goto out; } set_block_dev_mapped(bh_result, get_block_num(item, pos_in_item), inode); } else if (is_direct_le_ih(ih)) { char *p; p = page_address(bh_result->b_page); p += (byte_offset - 1) & (PAGE_SIZE - 1); copy_size = ih_item_len(ih) - pos_in_item; fs_gen = get_generation(inode->i_sb); copy_item_head(&tmp_ih, ih); if (!trans_running) { /* vs-3050 is gone, no need to drop the path */ retval = journal_begin(&th, inode->i_sb, jbegin_count); if (retval) goto out; reiserfs_update_inode_transaction(inode); trans_running = 1; if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { reiserfs_restore_prepared_buffer(inode->i_sb, bh); goto research; } } reiserfs_prepare_for_journal(inode->i_sb, bh, 1); if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) { reiserfs_restore_prepared_buffer(inode->i_sb, bh); goto research; } memcpy(ih_item_body(bh, ih) + pos_in_item, p + bytes_copied, copy_size); journal_mark_dirty(&th, bh); bytes_copied += copy_size; set_block_dev_mapped(bh_result, 0, inode); /* are there still bytes left? */ if (bytes_copied < bh_result->b_size && (byte_offset + bytes_copied) < inode->i_size) { set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + copy_size); goto research; } } else { reiserfs_warning(inode->i_sb, "clm-6003", "bad item inode %lu", inode->i_ino); retval = -EIO; goto out; } retval = 0; out: pathrelse(&path); if (trans_running) { int err = journal_end(&th); if (err) retval = err; trans_running = 0; } reiserfs_write_unlock(inode->i_sb); /* this is where we fill in holes in the file. */ if (use_get_block) { retval = reiserfs_get_block(inode, block, bh_result, GET_BLOCK_CREATE | GET_BLOCK_NO_IMUX | GET_BLOCK_NO_DANGLE); if (!retval) { if (!buffer_mapped(bh_result) || bh_result->b_blocknr == 0) { /* get_block failed to find a mapped unformatted node. */ use_get_block = 0; goto start_over; } } } kunmap(bh_result->b_page); if (!retval && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) { /* * we've copied data from the page into the direct item, so the * buffer in the page is now clean, mark it to reflect that. */ lock_buffer(bh_result); clear_buffer_dirty(bh_result); unlock_buffer(bh_result); } return retval; } /* * mason@suse.com: updated in 2.5.54 to follow the same general io * start/recovery path as __block_write_full_folio, along with special * code to handle reiserfs tails. */ static int reiserfs_write_full_folio(struct folio *folio, struct writeback_control *wbc) { struct inode *inode = folio->mapping->host; unsigned long end_index = inode->i_size >> PAGE_SHIFT; int error = 0; unsigned long block; sector_t last_block; struct buffer_head *head, *bh; int partial = 0; int nr = 0; int checked = folio_test_checked(folio); struct reiserfs_transaction_handle th; struct super_block *s = inode->i_sb; int bh_per_page = PAGE_SIZE / s->s_blocksize; th.t_trans_id = 0; /* no logging allowed when nonblocking or from PF_MEMALLOC */ if (checked && (current->flags & PF_MEMALLOC)) { folio_redirty_for_writepage(wbc, folio); folio_unlock(folio); return 0; } /* * The folio dirty bit is cleared before writepage is called, which * means we have to tell create_empty_buffers to make dirty buffers * The folio really should be up to date at this point, so tossing * in the BH_Uptodate is just a sanity check. */ head = folio_buffers(folio); if (!head) head = create_empty_buffers(folio, s->s_blocksize, (1 << BH_Dirty) | (1 << BH_Uptodate)); /* * last folio in the file, zero out any contents past the * last byte in the file */ if (folio->index >= end_index) { unsigned last_offset; last_offset = inode->i_size & (PAGE_SIZE - 1); /* no file contents in this folio */ if (folio->index >= end_index + 1 || !last_offset) { folio_unlock(folio); return 0; } folio_zero_segment(folio, last_offset, folio_size(folio)); } bh = head; block = folio->index << (PAGE_SHIFT - s->s_blocksize_bits); last_block = (i_size_read(inode) - 1) >> inode->i_blkbits; /* first map all the buffers, logging any direct items we find */ do { if (block > last_block) { /* * This can happen when the block size is less than * the folio size. The corresponding bytes in the folio * were zero filled above */ clear_buffer_dirty(bh); set_buffer_uptodate(bh); } else if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) || bh->b_blocknr == 0)) { /* * not mapped yet, or it points to a direct item, search * the btree for the mapping info, and log any direct * items found */ if ((error = map_block_for_writepage(inode, bh, block))) { goto fail; } } bh = bh->b_this_page; block++; } while (bh != head); /* * we start the transaction after map_block_for_writepage, * because it can create holes in the file (an unbounded operation). * starting it here, we can make a reliable estimate for how many * blocks we're going to log */ if (checked) { folio_clear_checked(folio); reiserfs_write_lock(s); error = journal_begin(&th, s, bh_per_page + 1); if (error) { reiserfs_write_unlock(s); goto fail; } reiserfs_update_inode_transaction(inode); } /* now go through and lock any dirty buffers on the folio */ do { get_bh(bh); if (!buffer_mapped(bh)) continue; if (buffer_mapped(bh) && bh->b_blocknr == 0) continue; if (checked) { reiserfs_prepare_for_journal(s, bh, 1); journal_mark_dirty(&th, bh); continue; } /* * from this point on, we know the buffer is mapped to a * real block and not a direct item */ if (wbc->sync_mode != WB_SYNC_NONE) { lock_buffer(bh); } else { if (!trylock_buffer(bh)) { folio_redirty_for_writepage(wbc, folio); continue; } } if (test_clear_buffer_dirty(bh)) { mark_buffer_async_write(bh); } else { unlock_buffer(bh); } } while ((bh = bh->b_this_page) != head); if (checked) { error = journal_end(&th); reiserfs_write_unlock(s); if (error) goto fail; } BUG_ON(folio_test_writeback(folio)); folio_start_writeback(folio); folio_unlock(folio); /* * since any buffer might be the only dirty buffer on the folio, * the first submit_bh can bring the folio out of writeback. * be careful with the buffers. */ do { struct buffer_head *next = bh->b_this_page; if (buffer_async_write(bh)) { submit_bh(REQ_OP_WRITE, bh); nr++; } put_bh(bh); bh = next; } while (bh != head); error = 0; done: if (nr == 0) { /* * if this folio only had a direct item, it is very possible for * no io to be required without there being an error. Or, * someone else could have locked them and sent them down the * pipe without locking the folio */ bh = head; do { if (!buffer_uptodate(bh)) { partial = 1; break; } bh = bh->b_this_page; } while (bh != head); if (!partial) folio_mark_uptodate(folio); folio_end_writeback(folio); } return error; fail: /* * catches various errors, we need to make sure any valid dirty blocks * get to the media. The folio is currently locked and not marked for * writeback */ folio_clear_uptodate(folio); bh = head; do { get_bh(bh); if (buffer_mapped(bh) && buffer_dirty(bh) && bh->b_blocknr) { lock_buffer(bh); mark_buffer_async_write(bh); } else { /* * clear any dirty bits that might have come from * getting attached to a dirty folio */ clear_buffer_dirty(bh); } bh = bh->b_this_page; } while (bh != head); folio_set_error(folio); BUG_ON(folio_test_writeback(folio)); folio_start_writeback(folio); folio_unlock(folio); do { struct buffer_head *next = bh->b_this_page; if (buffer_async_write(bh)) { clear_buffer_dirty(bh); submit_bh(REQ_OP_WRITE, bh); nr++; } put_bh(bh); bh = next; } while (bh != head); goto done; } static int reiserfs_read_folio(struct file *f, struct folio *folio) { return block_read_full_folio(folio, reiserfs_get_block); } static int reiserfs_writepage(struct page *page, struct writeback_control *wbc) { struct folio *folio = page_folio(page); struct inode *inode = folio->mapping->host; reiserfs_wait_on_write_block(inode->i_sb); return reiserfs_write_full_folio(folio, wbc); } static void reiserfs_truncate_failed_write(struct inode *inode) { truncate_inode_pages(inode->i_mapping, inode->i_size); reiserfs_truncate_file(inode, 0); } static int reiserfs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, struct page **pagep, void **fsdata) { struct inode *inode; struct page *page; pgoff_t index; int ret; int old_ref = 0; inode = mapping->host; index = pos >> PAGE_SHIFT; page = grab_cache_page_write_begin(mapping, index); if (!page) return -ENOMEM; *pagep = page; reiserfs_wait_on_write_block(inode->i_sb); fix_tail_page_for_writing(page); if (reiserfs_transaction_running(inode->i_sb)) { struct reiserfs_transaction_handle *th; th = (struct reiserfs_transaction_handle *)current-> journal_info; BUG_ON(!th->t_refcount); BUG_ON(!th->t_trans_id); old_ref = th->t_refcount; th->t_refcount++; } ret = __block_write_begin(page, pos, len, reiserfs_get_block); if (ret && reiserfs_transaction_running(inode->i_sb)) { struct reiserfs_transaction_handle *th = current->journal_info; /* * this gets a little ugly. If reiserfs_get_block returned an * error and left a transacstion running, we've got to close * it, and we've got to free handle if it was a persistent * transaction. * * But, if we had nested into an existing transaction, we need * to just drop the ref count on the handle. * * If old_ref == 0, the transaction is from reiserfs_get_block, * and it was a persistent trans. Otherwise, it was nested * above. */ if (th->t_refcount > old_ref) { if (old_ref) th->t_refcount--; else { int err; reiserfs_write_lock(inode->i_sb); err = reiserfs_end_persistent_transaction(th); reiserfs_write_unlock(inode->i_sb); if (err) ret = err; } } } if (ret) { unlock_page(page); put_page(page); /* Truncate allocated blocks */ reiserfs_truncate_failed_write(inode); } return ret; } int __reiserfs_write_begin(struct page *page, unsigned from, unsigned len) { struct inode *inode = page->mapping->host; int ret; int old_ref = 0; int depth; depth = reiserfs_write_unlock_nested(inode->i_sb); reiserfs_wait_on_write_block(inode->i_sb); reiserfs_write_lock_nested(inode->i_sb, depth); fix_tail_page_for_writing(page); if (reiserfs_transaction_running(inode->i_sb)) { struct reiserfs_transaction_handle *th; th = (struct reiserfs_transaction_handle *)current-> journal_info; BUG_ON(!th->t_refcount); BUG_ON(!th->t_trans_id); old_ref = th->t_refcount; th->t_refcount++; } ret = __block_write_begin(page, from, len, reiserfs_get_block); if (ret && reiserfs_transaction_running(inode->i_sb)) { struct reiserfs_transaction_handle *th = current->journal_info; /* * this gets a little ugly. If reiserfs_get_block returned an * error and left a transacstion running, we've got to close * it, and we've got to free handle if it was a persistent * transaction. * * But, if we had nested into an existing transaction, we need * to just drop the ref count on the handle. * * If old_ref == 0, the transaction is from reiserfs_get_block, * and it was a persistent trans. Otherwise, it was nested * above. */ if (th->t_refcount > old_ref) { if (old_ref) th->t_refcount--; else { int err; reiserfs_write_lock(inode->i_sb); err = reiserfs_end_persistent_transaction(th); reiserfs_write_unlock(inode->i_sb); if (err) ret = err; } } } return ret; } static sector_t reiserfs_aop_bmap(struct address_space *as, sector_t block) { return generic_block_bmap(as, block, reiserfs_bmap); } static int reiserfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) { struct folio *folio = page_folio(page); struct inode *inode = page->mapping->host; int ret = 0; int update_sd = 0; struct reiserfs_transaction_handle *th; unsigned start; bool locked = false; reiserfs_wait_on_write_block(inode->i_sb); if (reiserfs_transaction_running(inode->i_sb)) th = current->journal_info; else th = NULL; start = pos & (PAGE_SIZE - 1); if (unlikely(copied < len)) { if (!folio_test_uptodate(folio)) copied = 0; folio_zero_new_buffers(folio, start + copied, start + len); } flush_dcache_folio(folio); reiserfs_commit_page(inode, page, start, start + copied); /* * generic_commit_write does this for us, but does not update the * transaction tracking stuff when the size changes. So, we have * to do the i_size updates here. */ if (pos + copied > inode->i_size) { struct reiserfs_transaction_handle myth; reiserfs_write_lock(inode->i_sb); locked = true; /* * If the file have grown beyond the border where it * can have a tail, unmark it as needing a tail * packing */ if ((have_large_tails(inode->i_sb) && inode->i_size > i_block_size(inode) * 4) || (have_small_tails(inode->i_sb) && inode->i_size > i_block_size(inode))) REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; ret = journal_begin(&myth, inode->i_sb, 1); if (ret) goto journal_error; reiserfs_update_inode_transaction(inode); inode->i_size = pos + copied; /* * this will just nest into our transaction. It's important * to use mark_inode_dirty so the inode gets pushed around on * the dirty lists, and so that O_SYNC works as expected */ mark_inode_dirty(inode); reiserfs_update_sd(&myth, inode); update_sd = 1; ret = journal_end(&myth); if (ret) goto journal_error; } if (th) { if (!locked) { reiserfs_write_lock(inode->i_sb); locked = true; } if (!update_sd) mark_inode_dirty(inode); ret = reiserfs_end_persistent_transaction(th); if (ret) goto out; } out: if (locked) reiserfs_write_unlock(inode->i_sb); unlock_page(page); put_page(page); if (pos + len > inode->i_size) reiserfs_truncate_failed_write(inode); return ret == 0 ? copied : ret; journal_error: reiserfs_write_unlock(inode->i_sb); locked = false; if (th) { if (!update_sd) reiserfs_update_sd(th, inode); ret = reiserfs_end_persistent_transaction(th); } goto out; } int reiserfs_commit_write(struct file *f, struct page *page, unsigned from, unsigned to) { struct inode *inode = page->mapping->host; loff_t pos = ((loff_t) page->index << PAGE_SHIFT) + to; int ret = 0; int update_sd = 0; struct reiserfs_transaction_handle *th = NULL; int depth; depth = reiserfs_write_unlock_nested(inode->i_sb); reiserfs_wait_on_write_block(inode->i_sb); reiserfs_write_lock_nested(inode->i_sb, depth); if (reiserfs_transaction_running(inode->i_sb)) { th = current->journal_info; } reiserfs_commit_page(inode, page, from, to); /* * generic_commit_write does this for us, but does not update the * transaction tracking stuff when the size changes. So, we have * to do the i_size updates here. */ if (pos > inode->i_size) { struct reiserfs_transaction_handle myth; /* * If the file have grown beyond the border where it * can have a tail, unmark it as needing a tail * packing */ if ((have_large_tails(inode->i_sb) && inode->i_size > i_block_size(inode) * 4) || (have_small_tails(inode->i_sb) && inode->i_size > i_block_size(inode))) REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask; ret = journal_begin(&myth, inode->i_sb, 1); if (ret) goto journal_error; reiserfs_update_inode_transaction(inode); inode->i_size = pos; /* * this will just nest into our transaction. It's important * to use mark_inode_dirty so the inode gets pushed around * on the dirty lists, and so that O_SYNC works as expected */ mark_inode_dirty(inode); reiserfs_update_sd(&myth, inode); update_sd = 1; ret = journal_end(&myth); if (ret) goto journal_error; } if (th) { if (!update_sd) mark_inode_dirty(inode); ret = reiserfs_end_persistent_transaction(th); if (ret) goto out; } out: return ret; journal_error: if (th) { if (!update_sd) reiserfs_update_sd(th, inode); ret = reiserfs_end_persistent_transaction(th); } return ret; } void sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode) { if (reiserfs_attrs(inode->i_sb)) { if (sd_attrs & REISERFS_SYNC_FL) inode->i_flags |= S_SYNC; else inode->i_flags &= ~S_SYNC; if (sd_attrs & REISERFS_IMMUTABLE_FL) inode->i_flags |= S_IMMUTABLE; else inode->i_flags &= ~S_IMMUTABLE; if (sd_attrs & REISERFS_APPEND_FL) inode->i_flags |= S_APPEND; else inode->i_flags &= ~S_APPEND; if (sd_attrs & REISERFS_NOATIME_FL) inode->i_flags |= S_NOATIME; else inode->i_flags &= ~S_NOATIME; if (sd_attrs & REISERFS_NOTAIL_FL) REISERFS_I(inode)->i_flags |= i_nopack_mask; else REISERFS_I(inode)->i_flags &= ~i_nopack_mask; } } /* * decide if this buffer needs to stay around for data logging or ordered * write purposes */ static int invalidate_folio_can_drop(struct inode *inode, struct buffer_head *bh) { int ret = 1; struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb); lock_buffer(bh); spin_lock(&j->j_dirty_buffers_lock); if (!buffer_mapped(bh)) { goto free_jh; } /* * the page is locked, and the only places that log a data buffer * also lock the page. */ if (reiserfs_file_data_log(inode)) { /* * very conservative, leave the buffer pinned if * anyone might need it. */ if (buffer_journaled(bh) || buffer_journal_dirty(bh)) { ret = 0; } } else if (buffer_dirty(bh)) { struct reiserfs_journal_list *jl; struct reiserfs_jh *jh = bh->b_private; /* * why is this safe? * reiserfs_setattr updates i_size in the on disk * stat data before allowing vmtruncate to be called. * * If buffer was put onto the ordered list for this * transaction, we know for sure either this transaction * or an older one already has updated i_size on disk, * and this ordered data won't be referenced in the file * if we crash. * * if the buffer was put onto the ordered list for an older * transaction, we need to leave it around */ if (jh && (jl = jh->jl) && jl != SB_JOURNAL(inode->i_sb)->j_current_jl) ret = 0; } free_jh: if (ret && bh->b_private) { reiserfs_free_jh(bh); } spin_unlock(&j->j_dirty_buffers_lock); unlock_buffer(bh); return ret; } /* clm -- taken from fs/buffer.c:block_invalidate_folio */ static void reiserfs_invalidate_folio(struct folio *folio, size_t offset, size_t length) { struct buffer_head *head, *bh, *next; struct inode *inode = folio->mapping->host; unsigned int curr_off = 0; unsigned int stop = offset + length; int partial_page = (offset || length < folio_size(folio)); int ret = 1; BUG_ON(!folio_test_locked(folio)); if (!partial_page) folio_clear_checked(folio); head = folio_buffers(folio); if (!head) goto out; bh = head; do { unsigned int next_off = curr_off + bh->b_size; next = bh->b_this_page; if (next_off > stop) goto out; /* * is this block fully invalidated? */ if (offset <= curr_off) { if (invalidate_folio_can_drop(inode, bh)) reiserfs_unmap_buffer(bh); else ret = 0; } curr_off = next_off; bh = next; } while (bh != head); /* * We release buffers only if the entire page is being invalidated. * The get_block cached value has been unconditionally invalidated, * so real IO is not possible anymore. */ if (!partial_page && ret) { ret = filemap_release_folio(folio, 0); /* maybe should BUG_ON(!ret); - neilb */ } out: return; } static bool reiserfs_dirty_folio(struct address_space *mapping, struct folio *folio) { if (reiserfs_file_data_log(mapping->host)) { folio_set_checked(folio); return filemap_dirty_folio(mapping, folio); } return block_dirty_folio(mapping, folio); } /* * Returns true if the folio's buffers were dropped. The folio is locked. * * Takes j_dirty_buffers_lock to protect the b_assoc_buffers list_heads * in the buffers at folio_buffers(folio). * * even in -o notail mode, we can't be sure an old mount without -o notail * didn't create files with tails. */ static bool reiserfs_release_folio(struct folio *folio, gfp_t unused_gfp_flags) { struct inode *inode = folio->mapping->host; struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb); struct buffer_head *head; struct buffer_head *bh; bool ret = true; WARN_ON(folio_test_checked(folio)); spin_lock(&j->j_dirty_buffers_lock); head = folio_buffers(folio); bh = head; do { if (bh->b_private) { if (!buffer_dirty(bh) && !buffer_locked(bh)) { reiserfs_free_jh(bh); } else { ret = false; break; } } bh = bh->b_this_page; } while (bh != head); if (ret) ret = try_to_free_buffers(folio); spin_unlock(&j->j_dirty_buffers_lock); return ret; } /* * We thank Mingming Cao for helping us understand in great detail what * to do in this section of the code. */ static ssize_t reiserfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) { struct file *file = iocb->ki_filp; struct inode *inode = file->f_mapping->host; size_t count = iov_iter_count(iter); ssize_t ret; ret = blockdev_direct_IO(iocb, inode, iter, reiserfs_get_blocks_direct_io); /* * In case of error extending write may have instantiated a few * blocks outside i_size. Trim these off again. */ if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) { loff_t isize = i_size_read(inode); loff_t end = iocb->ki_pos + count; if ((end > isize) && inode_newsize_ok(inode, isize) == 0) { truncate_setsize(inode, isize); reiserfs_vfs_truncate_file(inode); } } return ret; } int reiserfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); unsigned int ia_valid; int error; error = setattr_prepare(&nop_mnt_idmap, dentry, attr); if (error) return error; /* must be turned off for recursive notify_change calls */ ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); if (is_quota_modification(&nop_mnt_idmap, inode, attr)) { error = dquot_initialize(inode); if (error) return error; } reiserfs_write_lock(inode->i_sb); if (attr->ia_valid & ATTR_SIZE) { /* * version 2 items will be caught by the s_maxbytes check * done for us in vmtruncate */ if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 && attr->ia_size > MAX_NON_LFS) { reiserfs_write_unlock(inode->i_sb); error = -EFBIG; goto out; } inode_dio_wait(inode); /* fill in hole pointers in the expanding truncate case. */ if (attr->ia_size > inode->i_size) { loff_t pos = attr->ia_size; if ((pos & (inode->i_sb->s_blocksize - 1)) == 0) pos++; error = generic_cont_expand_simple(inode, pos); if (REISERFS_I(inode)->i_prealloc_count > 0) { int err; struct reiserfs_transaction_handle th; /* we're changing at most 2 bitmaps, inode + super */ err = journal_begin(&th, inode->i_sb, 4); if (!err) { reiserfs_discard_prealloc(&th, inode); err = journal_end(&th); } if (err) error = err; } if (error) { reiserfs_write_unlock(inode->i_sb); goto out; } /* * file size is changed, ctime and mtime are * to be updated */ attr->ia_valid |= (ATTR_MTIME | ATTR_CTIME); } } reiserfs_write_unlock(inode->i_sb); if ((((attr->ia_valid & ATTR_UID) && (from_kuid(&init_user_ns, attr->ia_uid) & ~0xffff)) || ((attr->ia_valid & ATTR_GID) && (from_kgid(&init_user_ns, attr->ia_gid) & ~0xffff))) && (get_inode_sd_version(inode) == STAT_DATA_V1)) { /* stat data of format v3.5 has 16 bit uid and gid */ error = -EINVAL; goto out; } if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) || (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) { struct reiserfs_transaction_handle th; int jbegin_count = 2 * (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) + REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) + 2; error = reiserfs_chown_xattrs(inode, attr); if (error) return error; /* * (user+group)*(old+new) structure - we count quota * info and , inode write (sb, inode) */ reiserfs_write_lock(inode->i_sb); error = journal_begin(&th, inode->i_sb, jbegin_count); reiserfs_write_unlock(inode->i_sb); if (error) goto out; error = dquot_transfer(&nop_mnt_idmap, inode, attr); reiserfs_write_lock(inode->i_sb); if (error) { journal_end(&th); reiserfs_write_unlock(inode->i_sb); goto out; } /* * Update corresponding info in inode so that everything * is in one transaction */ if (attr->ia_valid & ATTR_UID) inode->i_uid = attr->ia_uid; if (attr->ia_valid & ATTR_GID) inode->i_gid = attr->ia_gid; mark_inode_dirty(inode); error = journal_end(&th); reiserfs_write_unlock(inode->i_sb); if (error) goto out; } if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size != i_size_read(inode)) { error = inode_newsize_ok(inode, attr->ia_size); if (!error) { /* * Could race against reiserfs_file_release * if called from NFS, so take tailpack mutex. */ mutex_lock(&REISERFS_I(inode)->tailpack); truncate_setsize(inode, attr->ia_size); reiserfs_truncate_file(inode, 1); mutex_unlock(&REISERFS_I(inode)->tailpack); } } if (!error) { setattr_copy(&nop_mnt_idmap, inode, attr); mark_inode_dirty(inode); } if (!error && reiserfs_posixacl(inode->i_sb)) { if (attr->ia_valid & ATTR_MODE) error = reiserfs_acl_chmod(dentry); } out: return error; } const struct address_space_operations reiserfs_address_space_operations = { .writepage = reiserfs_writepage, .read_folio = reiserfs_read_folio, .readahead = reiserfs_readahead, .release_folio = reiserfs_release_folio, .invalidate_folio = reiserfs_invalidate_folio, .write_begin = reiserfs_write_begin, .write_end = reiserfs_write_end, .bmap = reiserfs_aop_bmap, .direct_IO = reiserfs_direct_IO, .dirty_folio = reiserfs_dirty_folio, };
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1