18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
38c2ecf20Sopenharmony_ci */
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/time.h>
68c2ecf20Sopenharmony_ci#include <linux/fs.h>
78c2ecf20Sopenharmony_ci#include "reiserfs.h"
88c2ecf20Sopenharmony_ci#include "acl.h"
98c2ecf20Sopenharmony_ci#include "xattr.h"
108c2ecf20Sopenharmony_ci#include <linux/exportfs.h>
118c2ecf20Sopenharmony_ci#include <linux/pagemap.h>
128c2ecf20Sopenharmony_ci#include <linux/highmem.h>
138c2ecf20Sopenharmony_ci#include <linux/slab.h>
148c2ecf20Sopenharmony_ci#include <linux/uaccess.h>
158c2ecf20Sopenharmony_ci#include <asm/unaligned.h>
168c2ecf20Sopenharmony_ci#include <linux/buffer_head.h>
178c2ecf20Sopenharmony_ci#include <linux/mpage.h>
188c2ecf20Sopenharmony_ci#include <linux/writeback.h>
198c2ecf20Sopenharmony_ci#include <linux/quotaops.h>
208c2ecf20Sopenharmony_ci#include <linux/swap.h>
218c2ecf20Sopenharmony_ci#include <linux/uio.h>
228c2ecf20Sopenharmony_ci#include <linux/bio.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciint reiserfs_commit_write(struct file *f, struct page *page,
258c2ecf20Sopenharmony_ci			  unsigned from, unsigned to);
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_civoid reiserfs_evict_inode(struct inode *inode)
288c2ecf20Sopenharmony_ci{
298c2ecf20Sopenharmony_ci	/*
308c2ecf20Sopenharmony_ci	 * We need blocks for transaction + (user+group) quota
318c2ecf20Sopenharmony_ci	 * update (possibly delete)
328c2ecf20Sopenharmony_ci	 */
338c2ecf20Sopenharmony_ci	int jbegin_count =
348c2ecf20Sopenharmony_ci	    JOURNAL_PER_BALANCE_CNT * 2 +
358c2ecf20Sopenharmony_ci	    2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
368c2ecf20Sopenharmony_ci	struct reiserfs_transaction_handle th;
378c2ecf20Sopenharmony_ci	int err;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	if (!inode->i_nlink && !is_bad_inode(inode))
408c2ecf20Sopenharmony_ci		dquot_initialize(inode);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	truncate_inode_pages_final(&inode->i_data);
438c2ecf20Sopenharmony_ci	if (inode->i_nlink)
448c2ecf20Sopenharmony_ci		goto no_delete;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	/*
478c2ecf20Sopenharmony_ci	 * The = 0 happens when we abort creating a new inode
488c2ecf20Sopenharmony_ci	 * for some reason like lack of space..
498c2ecf20Sopenharmony_ci	 * also handles bad_inode case
508c2ecf20Sopenharmony_ci	 */
518c2ecf20Sopenharmony_ci	if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) {
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci		reiserfs_delete_xattrs(inode);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci		reiserfs_write_lock(inode->i_sb);
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci		if (journal_begin(&th, inode->i_sb, jbegin_count))
588c2ecf20Sopenharmony_ci			goto out;
598c2ecf20Sopenharmony_ci		reiserfs_update_inode_transaction(inode);
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci		reiserfs_discard_prealloc(&th, inode);
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci		err = reiserfs_delete_object(&th, inode);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci		/*
668c2ecf20Sopenharmony_ci		 * Do quota update inside a transaction for journaled quotas.
678c2ecf20Sopenharmony_ci		 * We must do that after delete_object so that quota updates
688c2ecf20Sopenharmony_ci		 * go into the same transaction as stat data deletion
698c2ecf20Sopenharmony_ci		 */
708c2ecf20Sopenharmony_ci		if (!err) {
718c2ecf20Sopenharmony_ci			int depth = reiserfs_write_unlock_nested(inode->i_sb);
728c2ecf20Sopenharmony_ci			dquot_free_inode(inode);
738c2ecf20Sopenharmony_ci			reiserfs_write_lock_nested(inode->i_sb, depth);
748c2ecf20Sopenharmony_ci		}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci		if (journal_end(&th))
778c2ecf20Sopenharmony_ci			goto out;
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci		/*
808c2ecf20Sopenharmony_ci		 * check return value from reiserfs_delete_object after
818c2ecf20Sopenharmony_ci		 * ending the transaction
828c2ecf20Sopenharmony_ci		 */
838c2ecf20Sopenharmony_ci		if (err)
848c2ecf20Sopenharmony_ci		    goto out;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci		/*
878c2ecf20Sopenharmony_ci		 * all items of file are deleted, so we can remove
888c2ecf20Sopenharmony_ci		 * "save" link
898c2ecf20Sopenharmony_ci		 * we can't do anything about an error here
908c2ecf20Sopenharmony_ci		 */
918c2ecf20Sopenharmony_ci		remove_save_link(inode, 0 /* not truncate */);
928c2ecf20Sopenharmony_ciout:
938c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
948c2ecf20Sopenharmony_ci	} else {
958c2ecf20Sopenharmony_ci		/* no object items are in the tree */
968c2ecf20Sopenharmony_ci		;
978c2ecf20Sopenharmony_ci	}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	/* note this must go after the journal_end to prevent deadlock */
1008c2ecf20Sopenharmony_ci	clear_inode(inode);
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	dquot_drop(inode);
1038c2ecf20Sopenharmony_ci	inode->i_blocks = 0;
1048c2ecf20Sopenharmony_ci	return;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_cino_delete:
1078c2ecf20Sopenharmony_ci	clear_inode(inode);
1088c2ecf20Sopenharmony_ci	dquot_drop(inode);
1098c2ecf20Sopenharmony_ci}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cistatic void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid,
1128c2ecf20Sopenharmony_ci			  __u32 objectid, loff_t offset, int type, int length)
1138c2ecf20Sopenharmony_ci{
1148c2ecf20Sopenharmony_ci	key->version = version;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	key->on_disk_key.k_dir_id = dirid;
1178c2ecf20Sopenharmony_ci	key->on_disk_key.k_objectid = objectid;
1188c2ecf20Sopenharmony_ci	set_cpu_key_k_offset(key, offset);
1198c2ecf20Sopenharmony_ci	set_cpu_key_k_type(key, type);
1208c2ecf20Sopenharmony_ci	key->key_length = length;
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/*
1248c2ecf20Sopenharmony_ci * take base of inode_key (it comes from inode always) (dirid, objectid)
1258c2ecf20Sopenharmony_ci * and version from an inode, set offset and type of key
1268c2ecf20Sopenharmony_ci */
1278c2ecf20Sopenharmony_civoid make_cpu_key(struct cpu_key *key, struct inode *inode, loff_t offset,
1288c2ecf20Sopenharmony_ci		  int type, int length)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	_make_cpu_key(key, get_inode_item_key_version(inode),
1318c2ecf20Sopenharmony_ci		      le32_to_cpu(INODE_PKEY(inode)->k_dir_id),
1328c2ecf20Sopenharmony_ci		      le32_to_cpu(INODE_PKEY(inode)->k_objectid), offset, type,
1338c2ecf20Sopenharmony_ci		      length);
1348c2ecf20Sopenharmony_ci}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/* when key is 0, do not set version and short key */
1378c2ecf20Sopenharmony_ciinline void make_le_item_head(struct item_head *ih, const struct cpu_key *key,
1388c2ecf20Sopenharmony_ci			      int version,
1398c2ecf20Sopenharmony_ci			      loff_t offset, int type, int length,
1408c2ecf20Sopenharmony_ci			      int entry_count /*or ih_free_space */ )
1418c2ecf20Sopenharmony_ci{
1428c2ecf20Sopenharmony_ci	if (key) {
1438c2ecf20Sopenharmony_ci		ih->ih_key.k_dir_id = cpu_to_le32(key->on_disk_key.k_dir_id);
1448c2ecf20Sopenharmony_ci		ih->ih_key.k_objectid =
1458c2ecf20Sopenharmony_ci		    cpu_to_le32(key->on_disk_key.k_objectid);
1468c2ecf20Sopenharmony_ci	}
1478c2ecf20Sopenharmony_ci	put_ih_version(ih, version);
1488c2ecf20Sopenharmony_ci	set_le_ih_k_offset(ih, offset);
1498c2ecf20Sopenharmony_ci	set_le_ih_k_type(ih, type);
1508c2ecf20Sopenharmony_ci	put_ih_item_len(ih, length);
1518c2ecf20Sopenharmony_ci	/*    set_ih_free_space (ih, 0); */
1528c2ecf20Sopenharmony_ci	/*
1538c2ecf20Sopenharmony_ci	 * for directory items it is entry count, for directs and stat
1548c2ecf20Sopenharmony_ci	 * datas - 0xffff, for indirects - 0
1558c2ecf20Sopenharmony_ci	 */
1568c2ecf20Sopenharmony_ci	put_ih_entry_count(ih, entry_count);
1578c2ecf20Sopenharmony_ci}
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci/*
1608c2ecf20Sopenharmony_ci * FIXME: we might cache recently accessed indirect item
1618c2ecf20Sopenharmony_ci * Ugh.  Not too eager for that....
1628c2ecf20Sopenharmony_ci * I cut the code until such time as I see a convincing argument (benchmark).
1638c2ecf20Sopenharmony_ci * I don't want a bloated inode struct..., and I don't like code complexity....
1648c2ecf20Sopenharmony_ci */
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci/*
1678c2ecf20Sopenharmony_ci * cutting the code is fine, since it really isn't in use yet and is easy
1688c2ecf20Sopenharmony_ci * to add back in.  But, Vladimir has a really good idea here.  Think
1698c2ecf20Sopenharmony_ci * about what happens for reading a file.  For each page,
1708c2ecf20Sopenharmony_ci * The VFS layer calls reiserfs_readpage, who searches the tree to find
1718c2ecf20Sopenharmony_ci * an indirect item.  This indirect item has X number of pointers, where
1728c2ecf20Sopenharmony_ci * X is a big number if we've done the block allocation right.  But,
1738c2ecf20Sopenharmony_ci * we only use one or two of these pointers during each call to readpage,
1748c2ecf20Sopenharmony_ci * needlessly researching again later on.
1758c2ecf20Sopenharmony_ci *
1768c2ecf20Sopenharmony_ci * The size of the cache could be dynamic based on the size of the file.
1778c2ecf20Sopenharmony_ci *
1788c2ecf20Sopenharmony_ci * I'd also like to see us cache the location the stat data item, since
1798c2ecf20Sopenharmony_ci * we are needlessly researching for that frequently.
1808c2ecf20Sopenharmony_ci *
1818c2ecf20Sopenharmony_ci * --chris
1828c2ecf20Sopenharmony_ci */
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci/*
1858c2ecf20Sopenharmony_ci * If this page has a file tail in it, and
1868c2ecf20Sopenharmony_ci * it was read in by get_block_create_0, the page data is valid,
1878c2ecf20Sopenharmony_ci * but tail is still sitting in a direct item, and we can't write to
1888c2ecf20Sopenharmony_ci * it.  So, look through this page, and check all the mapped buffers
1898c2ecf20Sopenharmony_ci * to make sure they have valid block numbers.  Any that don't need
1908c2ecf20Sopenharmony_ci * to be unmapped, so that __block_write_begin will correctly call
1918c2ecf20Sopenharmony_ci * reiserfs_get_block to convert the tail into an unformatted node
1928c2ecf20Sopenharmony_ci */
1938c2ecf20Sopenharmony_cistatic inline void fix_tail_page_for_writing(struct page *page)
1948c2ecf20Sopenharmony_ci{
1958c2ecf20Sopenharmony_ci	struct buffer_head *head, *next, *bh;
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	if (page && page_has_buffers(page)) {
1988c2ecf20Sopenharmony_ci		head = page_buffers(page);
1998c2ecf20Sopenharmony_ci		bh = head;
2008c2ecf20Sopenharmony_ci		do {
2018c2ecf20Sopenharmony_ci			next = bh->b_this_page;
2028c2ecf20Sopenharmony_ci			if (buffer_mapped(bh) && bh->b_blocknr == 0) {
2038c2ecf20Sopenharmony_ci				reiserfs_unmap_buffer(bh);
2048c2ecf20Sopenharmony_ci			}
2058c2ecf20Sopenharmony_ci			bh = next;
2068c2ecf20Sopenharmony_ci		} while (bh != head);
2078c2ecf20Sopenharmony_ci	}
2088c2ecf20Sopenharmony_ci}
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci/*
2118c2ecf20Sopenharmony_ci * reiserfs_get_block does not need to allocate a block only if it has been
2128c2ecf20Sopenharmony_ci * done already or non-hole position has been found in the indirect item
2138c2ecf20Sopenharmony_ci */
2148c2ecf20Sopenharmony_cistatic inline int allocation_needed(int retval, b_blocknr_t allocated,
2158c2ecf20Sopenharmony_ci				    struct item_head *ih,
2168c2ecf20Sopenharmony_ci				    __le32 * item, int pos_in_item)
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	if (allocated)
2198c2ecf20Sopenharmony_ci		return 0;
2208c2ecf20Sopenharmony_ci	if (retval == POSITION_FOUND && is_indirect_le_ih(ih) &&
2218c2ecf20Sopenharmony_ci	    get_block_num(item, pos_in_item))
2228c2ecf20Sopenharmony_ci		return 0;
2238c2ecf20Sopenharmony_ci	return 1;
2248c2ecf20Sopenharmony_ci}
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_cistatic inline int indirect_item_found(int retval, struct item_head *ih)
2278c2ecf20Sopenharmony_ci{
2288c2ecf20Sopenharmony_ci	return (retval == POSITION_FOUND) && is_indirect_le_ih(ih);
2298c2ecf20Sopenharmony_ci}
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_cistatic inline void set_block_dev_mapped(struct buffer_head *bh,
2328c2ecf20Sopenharmony_ci					b_blocknr_t block, struct inode *inode)
2338c2ecf20Sopenharmony_ci{
2348c2ecf20Sopenharmony_ci	map_bh(bh, inode->i_sb, block);
2358c2ecf20Sopenharmony_ci}
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci/*
2388c2ecf20Sopenharmony_ci * files which were created in the earlier version can not be longer,
2398c2ecf20Sopenharmony_ci * than 2 gb
2408c2ecf20Sopenharmony_ci */
2418c2ecf20Sopenharmony_cistatic int file_capable(struct inode *inode, sector_t block)
2428c2ecf20Sopenharmony_ci{
2438c2ecf20Sopenharmony_ci	/* it is new file. */
2448c2ecf20Sopenharmony_ci	if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 ||
2458c2ecf20Sopenharmony_ci	    /* old file, but 'block' is inside of 2gb */
2468c2ecf20Sopenharmony_ci	    block < (1 << (31 - inode->i_sb->s_blocksize_bits)))
2478c2ecf20Sopenharmony_ci		return 1;
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	return 0;
2508c2ecf20Sopenharmony_ci}
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_cistatic int restart_transaction(struct reiserfs_transaction_handle *th,
2538c2ecf20Sopenharmony_ci			       struct inode *inode, struct treepath *path)
2548c2ecf20Sopenharmony_ci{
2558c2ecf20Sopenharmony_ci	struct super_block *s = th->t_super;
2568c2ecf20Sopenharmony_ci	int err;
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	BUG_ON(!th->t_trans_id);
2598c2ecf20Sopenharmony_ci	BUG_ON(!th->t_refcount);
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci	pathrelse(path);
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	/* we cannot restart while nested */
2648c2ecf20Sopenharmony_ci	if (th->t_refcount > 1) {
2658c2ecf20Sopenharmony_ci		return 0;
2668c2ecf20Sopenharmony_ci	}
2678c2ecf20Sopenharmony_ci	reiserfs_update_sd(th, inode);
2688c2ecf20Sopenharmony_ci	err = journal_end(th);
2698c2ecf20Sopenharmony_ci	if (!err) {
2708c2ecf20Sopenharmony_ci		err = journal_begin(th, s, JOURNAL_PER_BALANCE_CNT * 6);
2718c2ecf20Sopenharmony_ci		if (!err)
2728c2ecf20Sopenharmony_ci			reiserfs_update_inode_transaction(inode);
2738c2ecf20Sopenharmony_ci	}
2748c2ecf20Sopenharmony_ci	return err;
2758c2ecf20Sopenharmony_ci}
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci/*
2788c2ecf20Sopenharmony_ci * it is called by get_block when create == 0. Returns block number
2798c2ecf20Sopenharmony_ci * for 'block'-th logical block of file. When it hits direct item it
2808c2ecf20Sopenharmony_ci * returns 0 (being called from bmap) or read direct item into piece
2818c2ecf20Sopenharmony_ci * of page (bh_result)
2828c2ecf20Sopenharmony_ci * Please improve the english/clarity in the comment above, as it is
2838c2ecf20Sopenharmony_ci * hard to understand.
2848c2ecf20Sopenharmony_ci */
2858c2ecf20Sopenharmony_cistatic int _get_block_create_0(struct inode *inode, sector_t block,
2868c2ecf20Sopenharmony_ci			       struct buffer_head *bh_result, int args)
2878c2ecf20Sopenharmony_ci{
2888c2ecf20Sopenharmony_ci	INITIALIZE_PATH(path);
2898c2ecf20Sopenharmony_ci	struct cpu_key key;
2908c2ecf20Sopenharmony_ci	struct buffer_head *bh;
2918c2ecf20Sopenharmony_ci	struct item_head *ih, tmp_ih;
2928c2ecf20Sopenharmony_ci	b_blocknr_t blocknr;
2938c2ecf20Sopenharmony_ci	char *p = NULL;
2948c2ecf20Sopenharmony_ci	int chars;
2958c2ecf20Sopenharmony_ci	int ret;
2968c2ecf20Sopenharmony_ci	int result;
2978c2ecf20Sopenharmony_ci	int done = 0;
2988c2ecf20Sopenharmony_ci	unsigned long offset;
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci	/* prepare the key to look for the 'block'-th block of file */
3018c2ecf20Sopenharmony_ci	make_cpu_key(&key, inode,
3028c2ecf20Sopenharmony_ci		     (loff_t) block * inode->i_sb->s_blocksize + 1, TYPE_ANY,
3038c2ecf20Sopenharmony_ci		     3);
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	result = search_for_position_by_key(inode->i_sb, &key, &path);
3068c2ecf20Sopenharmony_ci	if (result != POSITION_FOUND) {
3078c2ecf20Sopenharmony_ci		pathrelse(&path);
3088c2ecf20Sopenharmony_ci		if (p)
3098c2ecf20Sopenharmony_ci			kunmap(bh_result->b_page);
3108c2ecf20Sopenharmony_ci		if (result == IO_ERROR)
3118c2ecf20Sopenharmony_ci			return -EIO;
3128c2ecf20Sopenharmony_ci		/*
3138c2ecf20Sopenharmony_ci		 * We do not return -ENOENT if there is a hole but page is
3148c2ecf20Sopenharmony_ci		 * uptodate, because it means that there is some MMAPED data
3158c2ecf20Sopenharmony_ci		 * associated with it that is yet to be written to disk.
3168c2ecf20Sopenharmony_ci		 */
3178c2ecf20Sopenharmony_ci		if ((args & GET_BLOCK_NO_HOLE)
3188c2ecf20Sopenharmony_ci		    && !PageUptodate(bh_result->b_page)) {
3198c2ecf20Sopenharmony_ci			return -ENOENT;
3208c2ecf20Sopenharmony_ci		}
3218c2ecf20Sopenharmony_ci		return 0;
3228c2ecf20Sopenharmony_ci	}
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	bh = get_last_bh(&path);
3258c2ecf20Sopenharmony_ci	ih = tp_item_head(&path);
3268c2ecf20Sopenharmony_ci	if (is_indirect_le_ih(ih)) {
3278c2ecf20Sopenharmony_ci		__le32 *ind_item = (__le32 *) ih_item_body(bh, ih);
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci		/*
3308c2ecf20Sopenharmony_ci		 * FIXME: here we could cache indirect item or part of it in
3318c2ecf20Sopenharmony_ci		 * the inode to avoid search_by_key in case of subsequent
3328c2ecf20Sopenharmony_ci		 * access to file
3338c2ecf20Sopenharmony_ci		 */
3348c2ecf20Sopenharmony_ci		blocknr = get_block_num(ind_item, path.pos_in_item);
3358c2ecf20Sopenharmony_ci		ret = 0;
3368c2ecf20Sopenharmony_ci		if (blocknr) {
3378c2ecf20Sopenharmony_ci			map_bh(bh_result, inode->i_sb, blocknr);
3388c2ecf20Sopenharmony_ci			if (path.pos_in_item ==
3398c2ecf20Sopenharmony_ci			    ((ih_item_len(ih) / UNFM_P_SIZE) - 1)) {
3408c2ecf20Sopenharmony_ci				set_buffer_boundary(bh_result);
3418c2ecf20Sopenharmony_ci			}
3428c2ecf20Sopenharmony_ci		} else
3438c2ecf20Sopenharmony_ci			/*
3448c2ecf20Sopenharmony_ci			 * We do not return -ENOENT if there is a hole but
3458c2ecf20Sopenharmony_ci			 * page is uptodate, because it means that there is
3468c2ecf20Sopenharmony_ci			 * some MMAPED data associated with it that is
3478c2ecf20Sopenharmony_ci			 * yet to be written to disk.
3488c2ecf20Sopenharmony_ci			 */
3498c2ecf20Sopenharmony_ci		if ((args & GET_BLOCK_NO_HOLE)
3508c2ecf20Sopenharmony_ci			    && !PageUptodate(bh_result->b_page)) {
3518c2ecf20Sopenharmony_ci			ret = -ENOENT;
3528c2ecf20Sopenharmony_ci		}
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci		pathrelse(&path);
3558c2ecf20Sopenharmony_ci		if (p)
3568c2ecf20Sopenharmony_ci			kunmap(bh_result->b_page);
3578c2ecf20Sopenharmony_ci		return ret;
3588c2ecf20Sopenharmony_ci	}
3598c2ecf20Sopenharmony_ci	/* requested data are in direct item(s) */
3608c2ecf20Sopenharmony_ci	if (!(args & GET_BLOCK_READ_DIRECT)) {
3618c2ecf20Sopenharmony_ci		/*
3628c2ecf20Sopenharmony_ci		 * we are called by bmap. FIXME: we can not map block of file
3638c2ecf20Sopenharmony_ci		 * when it is stored in direct item(s)
3648c2ecf20Sopenharmony_ci		 */
3658c2ecf20Sopenharmony_ci		pathrelse(&path);
3668c2ecf20Sopenharmony_ci		if (p)
3678c2ecf20Sopenharmony_ci			kunmap(bh_result->b_page);
3688c2ecf20Sopenharmony_ci		return -ENOENT;
3698c2ecf20Sopenharmony_ci	}
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci	/*
3728c2ecf20Sopenharmony_ci	 * if we've got a direct item, and the buffer or page was uptodate,
3738c2ecf20Sopenharmony_ci	 * we don't want to pull data off disk again.  skip to the
3748c2ecf20Sopenharmony_ci	 * end, where we map the buffer and return
3758c2ecf20Sopenharmony_ci	 */
3768c2ecf20Sopenharmony_ci	if (buffer_uptodate(bh_result)) {
3778c2ecf20Sopenharmony_ci		goto finished;
3788c2ecf20Sopenharmony_ci	} else
3798c2ecf20Sopenharmony_ci		/*
3808c2ecf20Sopenharmony_ci		 * grab_tail_page can trigger calls to reiserfs_get_block on
3818c2ecf20Sopenharmony_ci		 * up to date pages without any buffers.  If the page is up
3828c2ecf20Sopenharmony_ci		 * to date, we don't want read old data off disk.  Set the up
3838c2ecf20Sopenharmony_ci		 * to date bit on the buffer instead and jump to the end
3848c2ecf20Sopenharmony_ci		 */
3858c2ecf20Sopenharmony_ci	if (!bh_result->b_page || PageUptodate(bh_result->b_page)) {
3868c2ecf20Sopenharmony_ci		set_buffer_uptodate(bh_result);
3878c2ecf20Sopenharmony_ci		goto finished;
3888c2ecf20Sopenharmony_ci	}
3898c2ecf20Sopenharmony_ci	/* read file tail into part of page */
3908c2ecf20Sopenharmony_ci	offset = (cpu_key_k_offset(&key) - 1) & (PAGE_SIZE - 1);
3918c2ecf20Sopenharmony_ci	copy_item_head(&tmp_ih, ih);
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ci	/*
3948c2ecf20Sopenharmony_ci	 * we only want to kmap if we are reading the tail into the page.
3958c2ecf20Sopenharmony_ci	 * this is not the common case, so we don't kmap until we are
3968c2ecf20Sopenharmony_ci	 * sure we need to.  But, this means the item might move if
3978c2ecf20Sopenharmony_ci	 * kmap schedules
3988c2ecf20Sopenharmony_ci	 */
3998c2ecf20Sopenharmony_ci	if (!p)
4008c2ecf20Sopenharmony_ci		p = (char *)kmap(bh_result->b_page);
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	p += offset;
4038c2ecf20Sopenharmony_ci	memset(p, 0, inode->i_sb->s_blocksize);
4048c2ecf20Sopenharmony_ci	do {
4058c2ecf20Sopenharmony_ci		if (!is_direct_le_ih(ih)) {
4068c2ecf20Sopenharmony_ci			BUG();
4078c2ecf20Sopenharmony_ci		}
4088c2ecf20Sopenharmony_ci		/*
4098c2ecf20Sopenharmony_ci		 * make sure we don't read more bytes than actually exist in
4108c2ecf20Sopenharmony_ci		 * the file.  This can happen in odd cases where i_size isn't
4118c2ecf20Sopenharmony_ci		 * correct, and when direct item padding results in a few
4128c2ecf20Sopenharmony_ci		 * extra bytes at the end of the direct item
4138c2ecf20Sopenharmony_ci		 */
4148c2ecf20Sopenharmony_ci		if ((le_ih_k_offset(ih) + path.pos_in_item) > inode->i_size)
4158c2ecf20Sopenharmony_ci			break;
4168c2ecf20Sopenharmony_ci		if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > inode->i_size) {
4178c2ecf20Sopenharmony_ci			chars =
4188c2ecf20Sopenharmony_ci			    inode->i_size - (le_ih_k_offset(ih) - 1) -
4198c2ecf20Sopenharmony_ci			    path.pos_in_item;
4208c2ecf20Sopenharmony_ci			done = 1;
4218c2ecf20Sopenharmony_ci		} else {
4228c2ecf20Sopenharmony_ci			chars = ih_item_len(ih) - path.pos_in_item;
4238c2ecf20Sopenharmony_ci		}
4248c2ecf20Sopenharmony_ci		memcpy(p, ih_item_body(bh, ih) + path.pos_in_item, chars);
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_ci		if (done)
4278c2ecf20Sopenharmony_ci			break;
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ci		p += chars;
4308c2ecf20Sopenharmony_ci
4318c2ecf20Sopenharmony_ci		/*
4328c2ecf20Sopenharmony_ci		 * we done, if read direct item is not the last item of
4338c2ecf20Sopenharmony_ci		 * node FIXME: we could try to check right delimiting key
4348c2ecf20Sopenharmony_ci		 * to see whether direct item continues in the right
4358c2ecf20Sopenharmony_ci		 * neighbor or rely on i_size
4368c2ecf20Sopenharmony_ci		 */
4378c2ecf20Sopenharmony_ci		if (PATH_LAST_POSITION(&path) != (B_NR_ITEMS(bh) - 1))
4388c2ecf20Sopenharmony_ci			break;
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci		/* update key to look for the next piece */
4418c2ecf20Sopenharmony_ci		set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + chars);
4428c2ecf20Sopenharmony_ci		result = search_for_position_by_key(inode->i_sb, &key, &path);
4438c2ecf20Sopenharmony_ci		if (result != POSITION_FOUND)
4448c2ecf20Sopenharmony_ci			/* i/o error most likely */
4458c2ecf20Sopenharmony_ci			break;
4468c2ecf20Sopenharmony_ci		bh = get_last_bh(&path);
4478c2ecf20Sopenharmony_ci		ih = tp_item_head(&path);
4488c2ecf20Sopenharmony_ci	} while (1);
4498c2ecf20Sopenharmony_ci
4508c2ecf20Sopenharmony_ci	flush_dcache_page(bh_result->b_page);
4518c2ecf20Sopenharmony_ci	kunmap(bh_result->b_page);
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_cifinished:
4548c2ecf20Sopenharmony_ci	pathrelse(&path);
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci	if (result == IO_ERROR)
4578c2ecf20Sopenharmony_ci		return -EIO;
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci	/*
4608c2ecf20Sopenharmony_ci	 * this buffer has valid data, but isn't valid for io.  mapping it to
4618c2ecf20Sopenharmony_ci	 * block #0 tells the rest of reiserfs it just has a tail in it
4628c2ecf20Sopenharmony_ci	 */
4638c2ecf20Sopenharmony_ci	map_bh(bh_result, inode->i_sb, 0);
4648c2ecf20Sopenharmony_ci	set_buffer_uptodate(bh_result);
4658c2ecf20Sopenharmony_ci	return 0;
4668c2ecf20Sopenharmony_ci}
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci/*
4698c2ecf20Sopenharmony_ci * this is called to create file map. So, _get_block_create_0 will not
4708c2ecf20Sopenharmony_ci * read direct item
4718c2ecf20Sopenharmony_ci */
4728c2ecf20Sopenharmony_cistatic int reiserfs_bmap(struct inode *inode, sector_t block,
4738c2ecf20Sopenharmony_ci			 struct buffer_head *bh_result, int create)
4748c2ecf20Sopenharmony_ci{
4758c2ecf20Sopenharmony_ci	if (!file_capable(inode, block))
4768c2ecf20Sopenharmony_ci		return -EFBIG;
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci	reiserfs_write_lock(inode->i_sb);
4798c2ecf20Sopenharmony_ci	/* do not read the direct item */
4808c2ecf20Sopenharmony_ci	_get_block_create_0(inode, block, bh_result, 0);
4818c2ecf20Sopenharmony_ci	reiserfs_write_unlock(inode->i_sb);
4828c2ecf20Sopenharmony_ci	return 0;
4838c2ecf20Sopenharmony_ci}
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci/*
4868c2ecf20Sopenharmony_ci * special version of get_block that is only used by grab_tail_page right
4878c2ecf20Sopenharmony_ci * now.  It is sent to __block_write_begin, and when you try to get a
4888c2ecf20Sopenharmony_ci * block past the end of the file (or a block from a hole) it returns
4898c2ecf20Sopenharmony_ci * -ENOENT instead of a valid buffer.  __block_write_begin expects to
4908c2ecf20Sopenharmony_ci * be able to do i/o on the buffers returned, unless an error value
4918c2ecf20Sopenharmony_ci * is also returned.
4928c2ecf20Sopenharmony_ci *
4938c2ecf20Sopenharmony_ci * So, this allows __block_write_begin to be used for reading a single block
4948c2ecf20Sopenharmony_ci * in a page.  Where it does not produce a valid page for holes, or past the
4958c2ecf20Sopenharmony_ci * end of the file.  This turns out to be exactly what we need for reading
4968c2ecf20Sopenharmony_ci * tails for conversion.
4978c2ecf20Sopenharmony_ci *
4988c2ecf20Sopenharmony_ci * The point of the wrapper is forcing a certain value for create, even
4998c2ecf20Sopenharmony_ci * though the VFS layer is calling this function with create==1.  If you
5008c2ecf20Sopenharmony_ci * don't want to send create == GET_BLOCK_NO_HOLE to reiserfs_get_block,
5018c2ecf20Sopenharmony_ci * don't use this function.
5028c2ecf20Sopenharmony_ci*/
5038c2ecf20Sopenharmony_cistatic int reiserfs_get_block_create_0(struct inode *inode, sector_t block,
5048c2ecf20Sopenharmony_ci				       struct buffer_head *bh_result,
5058c2ecf20Sopenharmony_ci				       int create)
5068c2ecf20Sopenharmony_ci{
5078c2ecf20Sopenharmony_ci	return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE);
5088c2ecf20Sopenharmony_ci}
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_ci/*
5118c2ecf20Sopenharmony_ci * This is special helper for reiserfs_get_block in case we are executing
5128c2ecf20Sopenharmony_ci * direct_IO request.
5138c2ecf20Sopenharmony_ci */
5148c2ecf20Sopenharmony_cistatic int reiserfs_get_blocks_direct_io(struct inode *inode,
5158c2ecf20Sopenharmony_ci					 sector_t iblock,
5168c2ecf20Sopenharmony_ci					 struct buffer_head *bh_result,
5178c2ecf20Sopenharmony_ci					 int create)
5188c2ecf20Sopenharmony_ci{
5198c2ecf20Sopenharmony_ci	int ret;
5208c2ecf20Sopenharmony_ci
5218c2ecf20Sopenharmony_ci	bh_result->b_page = NULL;
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci	/*
5248c2ecf20Sopenharmony_ci	 * We set the b_size before reiserfs_get_block call since it is
5258c2ecf20Sopenharmony_ci	 * referenced in convert_tail_for_hole() that may be called from
5268c2ecf20Sopenharmony_ci	 * reiserfs_get_block()
5278c2ecf20Sopenharmony_ci	 */
5288c2ecf20Sopenharmony_ci	bh_result->b_size = i_blocksize(inode);
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci	ret = reiserfs_get_block(inode, iblock, bh_result,
5318c2ecf20Sopenharmony_ci				 create | GET_BLOCK_NO_DANGLE);
5328c2ecf20Sopenharmony_ci	if (ret)
5338c2ecf20Sopenharmony_ci		goto out;
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ci	/* don't allow direct io onto tail pages */
5368c2ecf20Sopenharmony_ci	if (buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
5378c2ecf20Sopenharmony_ci		/*
5388c2ecf20Sopenharmony_ci		 * make sure future calls to the direct io funcs for this
5398c2ecf20Sopenharmony_ci		 * offset in the file fail by unmapping the buffer
5408c2ecf20Sopenharmony_ci		 */
5418c2ecf20Sopenharmony_ci		clear_buffer_mapped(bh_result);
5428c2ecf20Sopenharmony_ci		ret = -EINVAL;
5438c2ecf20Sopenharmony_ci	}
5448c2ecf20Sopenharmony_ci
5458c2ecf20Sopenharmony_ci	/*
5468c2ecf20Sopenharmony_ci	 * Possible unpacked tail. Flush the data before pages have
5478c2ecf20Sopenharmony_ci	 * disappeared
5488c2ecf20Sopenharmony_ci	 */
5498c2ecf20Sopenharmony_ci	if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) {
5508c2ecf20Sopenharmony_ci		int err;
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci		reiserfs_write_lock(inode->i_sb);
5538c2ecf20Sopenharmony_ci
5548c2ecf20Sopenharmony_ci		err = reiserfs_commit_for_inode(inode);
5558c2ecf20Sopenharmony_ci		REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
5588c2ecf20Sopenharmony_ci
5598c2ecf20Sopenharmony_ci		if (err < 0)
5608c2ecf20Sopenharmony_ci			ret = err;
5618c2ecf20Sopenharmony_ci	}
5628c2ecf20Sopenharmony_ciout:
5638c2ecf20Sopenharmony_ci	return ret;
5648c2ecf20Sopenharmony_ci}
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci/*
5678c2ecf20Sopenharmony_ci * helper function for when reiserfs_get_block is called for a hole
5688c2ecf20Sopenharmony_ci * but the file tail is still in a direct item
5698c2ecf20Sopenharmony_ci * bh_result is the buffer head for the hole
5708c2ecf20Sopenharmony_ci * tail_offset is the offset of the start of the tail in the file
5718c2ecf20Sopenharmony_ci *
5728c2ecf20Sopenharmony_ci * This calls prepare_write, which will start a new transaction
5738c2ecf20Sopenharmony_ci * you should not be in a transaction, or have any paths held when you
5748c2ecf20Sopenharmony_ci * call this.
5758c2ecf20Sopenharmony_ci */
5768c2ecf20Sopenharmony_cistatic int convert_tail_for_hole(struct inode *inode,
5778c2ecf20Sopenharmony_ci				 struct buffer_head *bh_result,
5788c2ecf20Sopenharmony_ci				 loff_t tail_offset)
5798c2ecf20Sopenharmony_ci{
5808c2ecf20Sopenharmony_ci	unsigned long index;
5818c2ecf20Sopenharmony_ci	unsigned long tail_end;
5828c2ecf20Sopenharmony_ci	unsigned long tail_start;
5838c2ecf20Sopenharmony_ci	struct page *tail_page;
5848c2ecf20Sopenharmony_ci	struct page *hole_page = bh_result->b_page;
5858c2ecf20Sopenharmony_ci	int retval = 0;
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci	if ((tail_offset & (bh_result->b_size - 1)) != 1)
5888c2ecf20Sopenharmony_ci		return -EIO;
5898c2ecf20Sopenharmony_ci
5908c2ecf20Sopenharmony_ci	/* always try to read until the end of the block */
5918c2ecf20Sopenharmony_ci	tail_start = tail_offset & (PAGE_SIZE - 1);
5928c2ecf20Sopenharmony_ci	tail_end = (tail_start | (bh_result->b_size - 1)) + 1;
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_ci	index = tail_offset >> PAGE_SHIFT;
5958c2ecf20Sopenharmony_ci	/*
5968c2ecf20Sopenharmony_ci	 * hole_page can be zero in case of direct_io, we are sure
5978c2ecf20Sopenharmony_ci	 * that we cannot get here if we write with O_DIRECT into tail page
5988c2ecf20Sopenharmony_ci	 */
5998c2ecf20Sopenharmony_ci	if (!hole_page || index != hole_page->index) {
6008c2ecf20Sopenharmony_ci		tail_page = grab_cache_page(inode->i_mapping, index);
6018c2ecf20Sopenharmony_ci		retval = -ENOMEM;
6028c2ecf20Sopenharmony_ci		if (!tail_page) {
6038c2ecf20Sopenharmony_ci			goto out;
6048c2ecf20Sopenharmony_ci		}
6058c2ecf20Sopenharmony_ci	} else {
6068c2ecf20Sopenharmony_ci		tail_page = hole_page;
6078c2ecf20Sopenharmony_ci	}
6088c2ecf20Sopenharmony_ci
6098c2ecf20Sopenharmony_ci	/*
6108c2ecf20Sopenharmony_ci	 * we don't have to make sure the conversion did not happen while
6118c2ecf20Sopenharmony_ci	 * we were locking the page because anyone that could convert
6128c2ecf20Sopenharmony_ci	 * must first take i_mutex.
6138c2ecf20Sopenharmony_ci	 *
6148c2ecf20Sopenharmony_ci	 * We must fix the tail page for writing because it might have buffers
6158c2ecf20Sopenharmony_ci	 * that are mapped, but have a block number of 0.  This indicates tail
6168c2ecf20Sopenharmony_ci	 * data that has been read directly into the page, and
6178c2ecf20Sopenharmony_ci	 * __block_write_begin won't trigger a get_block in this case.
6188c2ecf20Sopenharmony_ci	 */
6198c2ecf20Sopenharmony_ci	fix_tail_page_for_writing(tail_page);
6208c2ecf20Sopenharmony_ci	retval = __reiserfs_write_begin(tail_page, tail_start,
6218c2ecf20Sopenharmony_ci				      tail_end - tail_start);
6228c2ecf20Sopenharmony_ci	if (retval)
6238c2ecf20Sopenharmony_ci		goto unlock;
6248c2ecf20Sopenharmony_ci
6258c2ecf20Sopenharmony_ci	/* tail conversion might change the data in the page */
6268c2ecf20Sopenharmony_ci	flush_dcache_page(tail_page);
6278c2ecf20Sopenharmony_ci
6288c2ecf20Sopenharmony_ci	retval = reiserfs_commit_write(NULL, tail_page, tail_start, tail_end);
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_ciunlock:
6318c2ecf20Sopenharmony_ci	if (tail_page != hole_page) {
6328c2ecf20Sopenharmony_ci		unlock_page(tail_page);
6338c2ecf20Sopenharmony_ci		put_page(tail_page);
6348c2ecf20Sopenharmony_ci	}
6358c2ecf20Sopenharmony_ciout:
6368c2ecf20Sopenharmony_ci	return retval;
6378c2ecf20Sopenharmony_ci}
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_cistatic inline int _allocate_block(struct reiserfs_transaction_handle *th,
6408c2ecf20Sopenharmony_ci				  sector_t block,
6418c2ecf20Sopenharmony_ci				  struct inode *inode,
6428c2ecf20Sopenharmony_ci				  b_blocknr_t * allocated_block_nr,
6438c2ecf20Sopenharmony_ci				  struct treepath *path, int flags)
6448c2ecf20Sopenharmony_ci{
6458c2ecf20Sopenharmony_ci	BUG_ON(!th->t_trans_id);
6468c2ecf20Sopenharmony_ci
6478c2ecf20Sopenharmony_ci#ifdef REISERFS_PREALLOCATE
6488c2ecf20Sopenharmony_ci	if (!(flags & GET_BLOCK_NO_IMUX)) {
6498c2ecf20Sopenharmony_ci		return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr,
6508c2ecf20Sopenharmony_ci						  path, block);
6518c2ecf20Sopenharmony_ci	}
6528c2ecf20Sopenharmony_ci#endif
6538c2ecf20Sopenharmony_ci	return reiserfs_new_unf_blocknrs(th, inode, allocated_block_nr, path,
6548c2ecf20Sopenharmony_ci					 block);
6558c2ecf20Sopenharmony_ci}
6568c2ecf20Sopenharmony_ci
6578c2ecf20Sopenharmony_ciint reiserfs_get_block(struct inode *inode, sector_t block,
6588c2ecf20Sopenharmony_ci		       struct buffer_head *bh_result, int create)
6598c2ecf20Sopenharmony_ci{
6608c2ecf20Sopenharmony_ci	int repeat, retval = 0;
6618c2ecf20Sopenharmony_ci	/* b_blocknr_t is (unsigned) 32 bit int*/
6628c2ecf20Sopenharmony_ci	b_blocknr_t allocated_block_nr = 0;
6638c2ecf20Sopenharmony_ci	INITIALIZE_PATH(path);
6648c2ecf20Sopenharmony_ci	int pos_in_item;
6658c2ecf20Sopenharmony_ci	struct cpu_key key;
6668c2ecf20Sopenharmony_ci	struct buffer_head *bh, *unbh = NULL;
6678c2ecf20Sopenharmony_ci	struct item_head *ih, tmp_ih;
6688c2ecf20Sopenharmony_ci	__le32 *item;
6698c2ecf20Sopenharmony_ci	int done;
6708c2ecf20Sopenharmony_ci	int fs_gen;
6718c2ecf20Sopenharmony_ci	struct reiserfs_transaction_handle *th = NULL;
6728c2ecf20Sopenharmony_ci	/*
6738c2ecf20Sopenharmony_ci	 * space reserved in transaction batch:
6748c2ecf20Sopenharmony_ci	 * . 3 balancings in direct->indirect conversion
6758c2ecf20Sopenharmony_ci	 * . 1 block involved into reiserfs_update_sd()
6768c2ecf20Sopenharmony_ci	 * XXX in practically impossible worst case direct2indirect()
6778c2ecf20Sopenharmony_ci	 * can incur (much) more than 3 balancings.
6788c2ecf20Sopenharmony_ci	 * quota update for user, group
6798c2ecf20Sopenharmony_ci	 */
6808c2ecf20Sopenharmony_ci	int jbegin_count =
6818c2ecf20Sopenharmony_ci	    JOURNAL_PER_BALANCE_CNT * 3 + 1 +
6828c2ecf20Sopenharmony_ci	    2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb);
6838c2ecf20Sopenharmony_ci	int version;
6848c2ecf20Sopenharmony_ci	int dangle = 1;
6858c2ecf20Sopenharmony_ci	loff_t new_offset =
6868c2ecf20Sopenharmony_ci	    (((loff_t) block) << inode->i_sb->s_blocksize_bits) + 1;
6878c2ecf20Sopenharmony_ci
6888c2ecf20Sopenharmony_ci	reiserfs_write_lock(inode->i_sb);
6898c2ecf20Sopenharmony_ci	version = get_inode_item_key_version(inode);
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_ci	if (!file_capable(inode, block)) {
6928c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
6938c2ecf20Sopenharmony_ci		return -EFBIG;
6948c2ecf20Sopenharmony_ci	}
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_ci	/*
6978c2ecf20Sopenharmony_ci	 * if !create, we aren't changing the FS, so we don't need to
6988c2ecf20Sopenharmony_ci	 * log anything, so we don't need to start a transaction
6998c2ecf20Sopenharmony_ci	 */
7008c2ecf20Sopenharmony_ci	if (!(create & GET_BLOCK_CREATE)) {
7018c2ecf20Sopenharmony_ci		int ret;
7028c2ecf20Sopenharmony_ci		/* find number of block-th logical block of the file */
7038c2ecf20Sopenharmony_ci		ret = _get_block_create_0(inode, block, bh_result,
7048c2ecf20Sopenharmony_ci					  create | GET_BLOCK_READ_DIRECT);
7058c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
7068c2ecf20Sopenharmony_ci		return ret;
7078c2ecf20Sopenharmony_ci	}
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci	/*
7108c2ecf20Sopenharmony_ci	 * if we're already in a transaction, make sure to close
7118c2ecf20Sopenharmony_ci	 * any new transactions we start in this func
7128c2ecf20Sopenharmony_ci	 */
7138c2ecf20Sopenharmony_ci	if ((create & GET_BLOCK_NO_DANGLE) ||
7148c2ecf20Sopenharmony_ci	    reiserfs_transaction_running(inode->i_sb))
7158c2ecf20Sopenharmony_ci		dangle = 0;
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_ci	/*
7188c2ecf20Sopenharmony_ci	 * If file is of such a size, that it might have a tail and
7198c2ecf20Sopenharmony_ci	 * tails are enabled  we should mark it as possibly needing
7208c2ecf20Sopenharmony_ci	 * tail packing on close
7218c2ecf20Sopenharmony_ci	 */
7228c2ecf20Sopenharmony_ci	if ((have_large_tails(inode->i_sb)
7238c2ecf20Sopenharmony_ci	     && inode->i_size < i_block_size(inode) * 4)
7248c2ecf20Sopenharmony_ci	    || (have_small_tails(inode->i_sb)
7258c2ecf20Sopenharmony_ci		&& inode->i_size < i_block_size(inode)))
7268c2ecf20Sopenharmony_ci		REISERFS_I(inode)->i_flags |= i_pack_on_close_mask;
7278c2ecf20Sopenharmony_ci
7288c2ecf20Sopenharmony_ci	/* set the key of the first byte in the 'block'-th block of file */
7298c2ecf20Sopenharmony_ci	make_cpu_key(&key, inode, new_offset, TYPE_ANY, 3 /*key length */ );
7308c2ecf20Sopenharmony_ci	if ((new_offset + inode->i_sb->s_blocksize - 1) > inode->i_size) {
7318c2ecf20Sopenharmony_cistart_trans:
7328c2ecf20Sopenharmony_ci		th = reiserfs_persistent_transaction(inode->i_sb, jbegin_count);
7338c2ecf20Sopenharmony_ci		if (!th) {
7348c2ecf20Sopenharmony_ci			retval = -ENOMEM;
7358c2ecf20Sopenharmony_ci			goto failure;
7368c2ecf20Sopenharmony_ci		}
7378c2ecf20Sopenharmony_ci		reiserfs_update_inode_transaction(inode);
7388c2ecf20Sopenharmony_ci	}
7398c2ecf20Sopenharmony_ciresearch:
7408c2ecf20Sopenharmony_ci
7418c2ecf20Sopenharmony_ci	retval = search_for_position_by_key(inode->i_sb, &key, &path);
7428c2ecf20Sopenharmony_ci	if (retval == IO_ERROR) {
7438c2ecf20Sopenharmony_ci		retval = -EIO;
7448c2ecf20Sopenharmony_ci		goto failure;
7458c2ecf20Sopenharmony_ci	}
7468c2ecf20Sopenharmony_ci
7478c2ecf20Sopenharmony_ci	bh = get_last_bh(&path);
7488c2ecf20Sopenharmony_ci	ih = tp_item_head(&path);
7498c2ecf20Sopenharmony_ci	item = tp_item_body(&path);
7508c2ecf20Sopenharmony_ci	pos_in_item = path.pos_in_item;
7518c2ecf20Sopenharmony_ci
7528c2ecf20Sopenharmony_ci	fs_gen = get_generation(inode->i_sb);
7538c2ecf20Sopenharmony_ci	copy_item_head(&tmp_ih, ih);
7548c2ecf20Sopenharmony_ci
7558c2ecf20Sopenharmony_ci	if (allocation_needed
7568c2ecf20Sopenharmony_ci	    (retval, allocated_block_nr, ih, item, pos_in_item)) {
7578c2ecf20Sopenharmony_ci		/* we have to allocate block for the unformatted node */
7588c2ecf20Sopenharmony_ci		if (!th) {
7598c2ecf20Sopenharmony_ci			pathrelse(&path);
7608c2ecf20Sopenharmony_ci			goto start_trans;
7618c2ecf20Sopenharmony_ci		}
7628c2ecf20Sopenharmony_ci
7638c2ecf20Sopenharmony_ci		repeat =
7648c2ecf20Sopenharmony_ci		    _allocate_block(th, block, inode, &allocated_block_nr,
7658c2ecf20Sopenharmony_ci				    &path, create);
7668c2ecf20Sopenharmony_ci
7678c2ecf20Sopenharmony_ci		/*
7688c2ecf20Sopenharmony_ci		 * restart the transaction to give the journal a chance to free
7698c2ecf20Sopenharmony_ci		 * some blocks.  releases the path, so we have to go back to
7708c2ecf20Sopenharmony_ci		 * research if we succeed on the second try
7718c2ecf20Sopenharmony_ci		 */
7728c2ecf20Sopenharmony_ci		if (repeat == NO_DISK_SPACE || repeat == QUOTA_EXCEEDED) {
7738c2ecf20Sopenharmony_ci			SB_JOURNAL(inode->i_sb)->j_next_async_flush = 1;
7748c2ecf20Sopenharmony_ci			retval = restart_transaction(th, inode, &path);
7758c2ecf20Sopenharmony_ci			if (retval)
7768c2ecf20Sopenharmony_ci				goto failure;
7778c2ecf20Sopenharmony_ci			repeat =
7788c2ecf20Sopenharmony_ci			    _allocate_block(th, block, inode,
7798c2ecf20Sopenharmony_ci					    &allocated_block_nr, NULL, create);
7808c2ecf20Sopenharmony_ci
7818c2ecf20Sopenharmony_ci			if (repeat != NO_DISK_SPACE && repeat != QUOTA_EXCEEDED) {
7828c2ecf20Sopenharmony_ci				goto research;
7838c2ecf20Sopenharmony_ci			}
7848c2ecf20Sopenharmony_ci			if (repeat == QUOTA_EXCEEDED)
7858c2ecf20Sopenharmony_ci				retval = -EDQUOT;
7868c2ecf20Sopenharmony_ci			else
7878c2ecf20Sopenharmony_ci				retval = -ENOSPC;
7888c2ecf20Sopenharmony_ci			goto failure;
7898c2ecf20Sopenharmony_ci		}
7908c2ecf20Sopenharmony_ci
7918c2ecf20Sopenharmony_ci		if (fs_changed(fs_gen, inode->i_sb)
7928c2ecf20Sopenharmony_ci		    && item_moved(&tmp_ih, &path)) {
7938c2ecf20Sopenharmony_ci			goto research;
7948c2ecf20Sopenharmony_ci		}
7958c2ecf20Sopenharmony_ci	}
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ci	if (indirect_item_found(retval, ih)) {
7988c2ecf20Sopenharmony_ci		b_blocknr_t unfm_ptr;
7998c2ecf20Sopenharmony_ci		/*
8008c2ecf20Sopenharmony_ci		 * 'block'-th block is in the file already (there is
8018c2ecf20Sopenharmony_ci		 * corresponding cell in some indirect item). But it may be
8028c2ecf20Sopenharmony_ci		 * zero unformatted node pointer (hole)
8038c2ecf20Sopenharmony_ci		 */
8048c2ecf20Sopenharmony_ci		unfm_ptr = get_block_num(item, pos_in_item);
8058c2ecf20Sopenharmony_ci		if (unfm_ptr == 0) {
8068c2ecf20Sopenharmony_ci			/* use allocated block to plug the hole */
8078c2ecf20Sopenharmony_ci			reiserfs_prepare_for_journal(inode->i_sb, bh, 1);
8088c2ecf20Sopenharmony_ci			if (fs_changed(fs_gen, inode->i_sb)
8098c2ecf20Sopenharmony_ci			    && item_moved(&tmp_ih, &path)) {
8108c2ecf20Sopenharmony_ci				reiserfs_restore_prepared_buffer(inode->i_sb,
8118c2ecf20Sopenharmony_ci								 bh);
8128c2ecf20Sopenharmony_ci				goto research;
8138c2ecf20Sopenharmony_ci			}
8148c2ecf20Sopenharmony_ci			set_buffer_new(bh_result);
8158c2ecf20Sopenharmony_ci			if (buffer_dirty(bh_result)
8168c2ecf20Sopenharmony_ci			    && reiserfs_data_ordered(inode->i_sb))
8178c2ecf20Sopenharmony_ci				reiserfs_add_ordered_list(inode, bh_result);
8188c2ecf20Sopenharmony_ci			put_block_num(item, pos_in_item, allocated_block_nr);
8198c2ecf20Sopenharmony_ci			unfm_ptr = allocated_block_nr;
8208c2ecf20Sopenharmony_ci			journal_mark_dirty(th, bh);
8218c2ecf20Sopenharmony_ci			reiserfs_update_sd(th, inode);
8228c2ecf20Sopenharmony_ci		}
8238c2ecf20Sopenharmony_ci		set_block_dev_mapped(bh_result, unfm_ptr, inode);
8248c2ecf20Sopenharmony_ci		pathrelse(&path);
8258c2ecf20Sopenharmony_ci		retval = 0;
8268c2ecf20Sopenharmony_ci		if (!dangle && th)
8278c2ecf20Sopenharmony_ci			retval = reiserfs_end_persistent_transaction(th);
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
8308c2ecf20Sopenharmony_ci
8318c2ecf20Sopenharmony_ci		/*
8328c2ecf20Sopenharmony_ci		 * the item was found, so new blocks were not added to the file
8338c2ecf20Sopenharmony_ci		 * there is no need to make sure the inode is updated with this
8348c2ecf20Sopenharmony_ci		 * transaction
8358c2ecf20Sopenharmony_ci		 */
8368c2ecf20Sopenharmony_ci		return retval;
8378c2ecf20Sopenharmony_ci	}
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_ci	if (!th) {
8408c2ecf20Sopenharmony_ci		pathrelse(&path);
8418c2ecf20Sopenharmony_ci		goto start_trans;
8428c2ecf20Sopenharmony_ci	}
8438c2ecf20Sopenharmony_ci
8448c2ecf20Sopenharmony_ci	/*
8458c2ecf20Sopenharmony_ci	 * desired position is not found or is in the direct item. We have
8468c2ecf20Sopenharmony_ci	 * to append file with holes up to 'block'-th block converting
8478c2ecf20Sopenharmony_ci	 * direct items to indirect one if necessary
8488c2ecf20Sopenharmony_ci	 */
8498c2ecf20Sopenharmony_ci	done = 0;
8508c2ecf20Sopenharmony_ci	do {
8518c2ecf20Sopenharmony_ci		if (is_statdata_le_ih(ih)) {
8528c2ecf20Sopenharmony_ci			__le32 unp = 0;
8538c2ecf20Sopenharmony_ci			struct cpu_key tmp_key;
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_ci			/* indirect item has to be inserted */
8568c2ecf20Sopenharmony_ci			make_le_item_head(&tmp_ih, &key, version, 1,
8578c2ecf20Sopenharmony_ci					  TYPE_INDIRECT, UNFM_P_SIZE,
8588c2ecf20Sopenharmony_ci					  0 /* free_space */ );
8598c2ecf20Sopenharmony_ci
8608c2ecf20Sopenharmony_ci			/*
8618c2ecf20Sopenharmony_ci			 * we are going to add 'block'-th block to the file.
8628c2ecf20Sopenharmony_ci			 * Use allocated block for that
8638c2ecf20Sopenharmony_ci			 */
8648c2ecf20Sopenharmony_ci			if (cpu_key_k_offset(&key) == 1) {
8658c2ecf20Sopenharmony_ci				unp = cpu_to_le32(allocated_block_nr);
8668c2ecf20Sopenharmony_ci				set_block_dev_mapped(bh_result,
8678c2ecf20Sopenharmony_ci						     allocated_block_nr, inode);
8688c2ecf20Sopenharmony_ci				set_buffer_new(bh_result);
8698c2ecf20Sopenharmony_ci				done = 1;
8708c2ecf20Sopenharmony_ci			}
8718c2ecf20Sopenharmony_ci			tmp_key = key;	/* ;) */
8728c2ecf20Sopenharmony_ci			set_cpu_key_k_offset(&tmp_key, 1);
8738c2ecf20Sopenharmony_ci			PATH_LAST_POSITION(&path)++;
8748c2ecf20Sopenharmony_ci
8758c2ecf20Sopenharmony_ci			retval =
8768c2ecf20Sopenharmony_ci			    reiserfs_insert_item(th, &path, &tmp_key, &tmp_ih,
8778c2ecf20Sopenharmony_ci						 inode, (char *)&unp);
8788c2ecf20Sopenharmony_ci			if (retval) {
8798c2ecf20Sopenharmony_ci				reiserfs_free_block(th, inode,
8808c2ecf20Sopenharmony_ci						    allocated_block_nr, 1);
8818c2ecf20Sopenharmony_ci				/*
8828c2ecf20Sopenharmony_ci				 * retval == -ENOSPC, -EDQUOT or -EIO
8838c2ecf20Sopenharmony_ci				 * or -EEXIST
8848c2ecf20Sopenharmony_ci				 */
8858c2ecf20Sopenharmony_ci				goto failure;
8868c2ecf20Sopenharmony_ci			}
8878c2ecf20Sopenharmony_ci		} else if (is_direct_le_ih(ih)) {
8888c2ecf20Sopenharmony_ci			/* direct item has to be converted */
8898c2ecf20Sopenharmony_ci			loff_t tail_offset;
8908c2ecf20Sopenharmony_ci
8918c2ecf20Sopenharmony_ci			tail_offset =
8928c2ecf20Sopenharmony_ci			    ((le_ih_k_offset(ih) -
8938c2ecf20Sopenharmony_ci			      1) & ~(inode->i_sb->s_blocksize - 1)) + 1;
8948c2ecf20Sopenharmony_ci
8958c2ecf20Sopenharmony_ci			/*
8968c2ecf20Sopenharmony_ci			 * direct item we just found fits into block we have
8978c2ecf20Sopenharmony_ci			 * to map. Convert it into unformatted node: use
8988c2ecf20Sopenharmony_ci			 * bh_result for the conversion
8998c2ecf20Sopenharmony_ci			 */
9008c2ecf20Sopenharmony_ci			if (tail_offset == cpu_key_k_offset(&key)) {
9018c2ecf20Sopenharmony_ci				set_block_dev_mapped(bh_result,
9028c2ecf20Sopenharmony_ci						     allocated_block_nr, inode);
9038c2ecf20Sopenharmony_ci				unbh = bh_result;
9048c2ecf20Sopenharmony_ci				done = 1;
9058c2ecf20Sopenharmony_ci			} else {
9068c2ecf20Sopenharmony_ci				/*
9078c2ecf20Sopenharmony_ci				 * we have to pad file tail stored in direct
9088c2ecf20Sopenharmony_ci				 * item(s) up to block size and convert it
9098c2ecf20Sopenharmony_ci				 * to unformatted node. FIXME: this should
9108c2ecf20Sopenharmony_ci				 * also get into page cache
9118c2ecf20Sopenharmony_ci				 */
9128c2ecf20Sopenharmony_ci
9138c2ecf20Sopenharmony_ci				pathrelse(&path);
9148c2ecf20Sopenharmony_ci				/*
9158c2ecf20Sopenharmony_ci				 * ugly, but we can only end the transaction if
9168c2ecf20Sopenharmony_ci				 * we aren't nested
9178c2ecf20Sopenharmony_ci				 */
9188c2ecf20Sopenharmony_ci				BUG_ON(!th->t_refcount);
9198c2ecf20Sopenharmony_ci				if (th->t_refcount == 1) {
9208c2ecf20Sopenharmony_ci					retval =
9218c2ecf20Sopenharmony_ci					    reiserfs_end_persistent_transaction
9228c2ecf20Sopenharmony_ci					    (th);
9238c2ecf20Sopenharmony_ci					th = NULL;
9248c2ecf20Sopenharmony_ci					if (retval)
9258c2ecf20Sopenharmony_ci						goto failure;
9268c2ecf20Sopenharmony_ci				}
9278c2ecf20Sopenharmony_ci
9288c2ecf20Sopenharmony_ci				retval =
9298c2ecf20Sopenharmony_ci				    convert_tail_for_hole(inode, bh_result,
9308c2ecf20Sopenharmony_ci							  tail_offset);
9318c2ecf20Sopenharmony_ci				if (retval) {
9328c2ecf20Sopenharmony_ci					if (retval != -ENOSPC)
9338c2ecf20Sopenharmony_ci						reiserfs_error(inode->i_sb,
9348c2ecf20Sopenharmony_ci							"clm-6004",
9358c2ecf20Sopenharmony_ci							"convert tail failed "
9368c2ecf20Sopenharmony_ci							"inode %lu, error %d",
9378c2ecf20Sopenharmony_ci							inode->i_ino,
9388c2ecf20Sopenharmony_ci							retval);
9398c2ecf20Sopenharmony_ci					if (allocated_block_nr) {
9408c2ecf20Sopenharmony_ci						/*
9418c2ecf20Sopenharmony_ci						 * the bitmap, the super,
9428c2ecf20Sopenharmony_ci						 * and the stat data == 3
9438c2ecf20Sopenharmony_ci						 */
9448c2ecf20Sopenharmony_ci						if (!th)
9458c2ecf20Sopenharmony_ci							th = reiserfs_persistent_transaction(inode->i_sb, 3);
9468c2ecf20Sopenharmony_ci						if (th)
9478c2ecf20Sopenharmony_ci							reiserfs_free_block(th,
9488c2ecf20Sopenharmony_ci									    inode,
9498c2ecf20Sopenharmony_ci									    allocated_block_nr,
9508c2ecf20Sopenharmony_ci									    1);
9518c2ecf20Sopenharmony_ci					}
9528c2ecf20Sopenharmony_ci					goto failure;
9538c2ecf20Sopenharmony_ci				}
9548c2ecf20Sopenharmony_ci				goto research;
9558c2ecf20Sopenharmony_ci			}
9568c2ecf20Sopenharmony_ci			retval =
9578c2ecf20Sopenharmony_ci			    direct2indirect(th, inode, &path, unbh,
9588c2ecf20Sopenharmony_ci					    tail_offset);
9598c2ecf20Sopenharmony_ci			if (retval) {
9608c2ecf20Sopenharmony_ci				reiserfs_unmap_buffer(unbh);
9618c2ecf20Sopenharmony_ci				reiserfs_free_block(th, inode,
9628c2ecf20Sopenharmony_ci						    allocated_block_nr, 1);
9638c2ecf20Sopenharmony_ci				goto failure;
9648c2ecf20Sopenharmony_ci			}
9658c2ecf20Sopenharmony_ci			/*
9668c2ecf20Sopenharmony_ci			 * it is important the set_buffer_uptodate is done
9678c2ecf20Sopenharmony_ci			 * after the direct2indirect.  The buffer might
9688c2ecf20Sopenharmony_ci			 * contain valid data newer than the data on disk
9698c2ecf20Sopenharmony_ci			 * (read by readpage, changed, and then sent here by
9708c2ecf20Sopenharmony_ci			 * writepage).  direct2indirect needs to know if unbh
9718c2ecf20Sopenharmony_ci			 * was already up to date, so it can decide if the
9728c2ecf20Sopenharmony_ci			 * data in unbh needs to be replaced with data from
9738c2ecf20Sopenharmony_ci			 * the disk
9748c2ecf20Sopenharmony_ci			 */
9758c2ecf20Sopenharmony_ci			set_buffer_uptodate(unbh);
9768c2ecf20Sopenharmony_ci
9778c2ecf20Sopenharmony_ci			/*
9788c2ecf20Sopenharmony_ci			 * unbh->b_page == NULL in case of DIRECT_IO request,
9798c2ecf20Sopenharmony_ci			 * this means buffer will disappear shortly, so it
9808c2ecf20Sopenharmony_ci			 * should not be added to
9818c2ecf20Sopenharmony_ci			 */
9828c2ecf20Sopenharmony_ci			if (unbh->b_page) {
9838c2ecf20Sopenharmony_ci				/*
9848c2ecf20Sopenharmony_ci				 * we've converted the tail, so we must
9858c2ecf20Sopenharmony_ci				 * flush unbh before the transaction commits
9868c2ecf20Sopenharmony_ci				 */
9878c2ecf20Sopenharmony_ci				reiserfs_add_tail_list(inode, unbh);
9888c2ecf20Sopenharmony_ci
9898c2ecf20Sopenharmony_ci				/*
9908c2ecf20Sopenharmony_ci				 * mark it dirty now to prevent commit_write
9918c2ecf20Sopenharmony_ci				 * from adding this buffer to the inode's
9928c2ecf20Sopenharmony_ci				 * dirty buffer list
9938c2ecf20Sopenharmony_ci				 */
9948c2ecf20Sopenharmony_ci				/*
9958c2ecf20Sopenharmony_ci				 * AKPM: changed __mark_buffer_dirty to
9968c2ecf20Sopenharmony_ci				 * mark_buffer_dirty().  It's still atomic,
9978c2ecf20Sopenharmony_ci				 * but it sets the page dirty too, which makes
9988c2ecf20Sopenharmony_ci				 * it eligible for writeback at any time by the
9998c2ecf20Sopenharmony_ci				 * VM (which was also the case with
10008c2ecf20Sopenharmony_ci				 * __mark_buffer_dirty())
10018c2ecf20Sopenharmony_ci				 */
10028c2ecf20Sopenharmony_ci				mark_buffer_dirty(unbh);
10038c2ecf20Sopenharmony_ci			}
10048c2ecf20Sopenharmony_ci		} else {
10058c2ecf20Sopenharmony_ci			/*
10068c2ecf20Sopenharmony_ci			 * append indirect item with holes if needed, when
10078c2ecf20Sopenharmony_ci			 * appending pointer to 'block'-th block use block,
10088c2ecf20Sopenharmony_ci			 * which is already allocated
10098c2ecf20Sopenharmony_ci			 */
10108c2ecf20Sopenharmony_ci			struct cpu_key tmp_key;
10118c2ecf20Sopenharmony_ci			/*
10128c2ecf20Sopenharmony_ci			 * We use this in case we need to allocate
10138c2ecf20Sopenharmony_ci			 * only one block which is a fastpath
10148c2ecf20Sopenharmony_ci			 */
10158c2ecf20Sopenharmony_ci			unp_t unf_single = 0;
10168c2ecf20Sopenharmony_ci			unp_t *un;
10178c2ecf20Sopenharmony_ci			__u64 max_to_insert =
10188c2ecf20Sopenharmony_ci			    MAX_ITEM_LEN(inode->i_sb->s_blocksize) /
10198c2ecf20Sopenharmony_ci			    UNFM_P_SIZE;
10208c2ecf20Sopenharmony_ci			__u64 blocks_needed;
10218c2ecf20Sopenharmony_ci
10228c2ecf20Sopenharmony_ci			RFALSE(pos_in_item != ih_item_len(ih) / UNFM_P_SIZE,
10238c2ecf20Sopenharmony_ci			       "vs-804: invalid position for append");
10248c2ecf20Sopenharmony_ci			/*
10258c2ecf20Sopenharmony_ci			 * indirect item has to be appended,
10268c2ecf20Sopenharmony_ci			 * set up key of that position
10278c2ecf20Sopenharmony_ci			 * (key type is unimportant)
10288c2ecf20Sopenharmony_ci			 */
10298c2ecf20Sopenharmony_ci			make_cpu_key(&tmp_key, inode,
10308c2ecf20Sopenharmony_ci				     le_key_k_offset(version,
10318c2ecf20Sopenharmony_ci						     &ih->ih_key) +
10328c2ecf20Sopenharmony_ci				     op_bytes_number(ih,
10338c2ecf20Sopenharmony_ci						     inode->i_sb->s_blocksize),
10348c2ecf20Sopenharmony_ci				     TYPE_INDIRECT, 3);
10358c2ecf20Sopenharmony_ci
10368c2ecf20Sopenharmony_ci			RFALSE(cpu_key_k_offset(&tmp_key) > cpu_key_k_offset(&key),
10378c2ecf20Sopenharmony_ci			       "green-805: invalid offset");
10388c2ecf20Sopenharmony_ci			blocks_needed =
10398c2ecf20Sopenharmony_ci			    1 +
10408c2ecf20Sopenharmony_ci			    ((cpu_key_k_offset(&key) -
10418c2ecf20Sopenharmony_ci			      cpu_key_k_offset(&tmp_key)) >> inode->i_sb->
10428c2ecf20Sopenharmony_ci			     s_blocksize_bits);
10438c2ecf20Sopenharmony_ci
10448c2ecf20Sopenharmony_ci			if (blocks_needed == 1) {
10458c2ecf20Sopenharmony_ci				un = &unf_single;
10468c2ecf20Sopenharmony_ci			} else {
10478c2ecf20Sopenharmony_ci				un = kcalloc(min(blocks_needed, max_to_insert),
10488c2ecf20Sopenharmony_ci					     UNFM_P_SIZE, GFP_NOFS);
10498c2ecf20Sopenharmony_ci				if (!un) {
10508c2ecf20Sopenharmony_ci					un = &unf_single;
10518c2ecf20Sopenharmony_ci					blocks_needed = 1;
10528c2ecf20Sopenharmony_ci					max_to_insert = 0;
10538c2ecf20Sopenharmony_ci				}
10548c2ecf20Sopenharmony_ci			}
10558c2ecf20Sopenharmony_ci			if (blocks_needed <= max_to_insert) {
10568c2ecf20Sopenharmony_ci				/*
10578c2ecf20Sopenharmony_ci				 * we are going to add target block to
10588c2ecf20Sopenharmony_ci				 * the file. Use allocated block for that
10598c2ecf20Sopenharmony_ci				 */
10608c2ecf20Sopenharmony_ci				un[blocks_needed - 1] =
10618c2ecf20Sopenharmony_ci				    cpu_to_le32(allocated_block_nr);
10628c2ecf20Sopenharmony_ci				set_block_dev_mapped(bh_result,
10638c2ecf20Sopenharmony_ci						     allocated_block_nr, inode);
10648c2ecf20Sopenharmony_ci				set_buffer_new(bh_result);
10658c2ecf20Sopenharmony_ci				done = 1;
10668c2ecf20Sopenharmony_ci			} else {
10678c2ecf20Sopenharmony_ci				/* paste hole to the indirect item */
10688c2ecf20Sopenharmony_ci				/*
10698c2ecf20Sopenharmony_ci				 * If kcalloc failed, max_to_insert becomes
10708c2ecf20Sopenharmony_ci				 * zero and it means we only have space for
10718c2ecf20Sopenharmony_ci				 * one block
10728c2ecf20Sopenharmony_ci				 */
10738c2ecf20Sopenharmony_ci				blocks_needed =
10748c2ecf20Sopenharmony_ci				    max_to_insert ? max_to_insert : 1;
10758c2ecf20Sopenharmony_ci			}
10768c2ecf20Sopenharmony_ci			retval =
10778c2ecf20Sopenharmony_ci			    reiserfs_paste_into_item(th, &path, &tmp_key, inode,
10788c2ecf20Sopenharmony_ci						     (char *)un,
10798c2ecf20Sopenharmony_ci						     UNFM_P_SIZE *
10808c2ecf20Sopenharmony_ci						     blocks_needed);
10818c2ecf20Sopenharmony_ci
10828c2ecf20Sopenharmony_ci			if (blocks_needed != 1)
10838c2ecf20Sopenharmony_ci				kfree(un);
10848c2ecf20Sopenharmony_ci
10858c2ecf20Sopenharmony_ci			if (retval) {
10868c2ecf20Sopenharmony_ci				reiserfs_free_block(th, inode,
10878c2ecf20Sopenharmony_ci						    allocated_block_nr, 1);
10888c2ecf20Sopenharmony_ci				goto failure;
10898c2ecf20Sopenharmony_ci			}
10908c2ecf20Sopenharmony_ci			if (!done) {
10918c2ecf20Sopenharmony_ci				/*
10928c2ecf20Sopenharmony_ci				 * We need to mark new file size in case
10938c2ecf20Sopenharmony_ci				 * this function will be interrupted/aborted
10948c2ecf20Sopenharmony_ci				 * later on. And we may do this only for
10958c2ecf20Sopenharmony_ci				 * holes.
10968c2ecf20Sopenharmony_ci				 */
10978c2ecf20Sopenharmony_ci				inode->i_size +=
10988c2ecf20Sopenharmony_ci				    inode->i_sb->s_blocksize * blocks_needed;
10998c2ecf20Sopenharmony_ci			}
11008c2ecf20Sopenharmony_ci		}
11018c2ecf20Sopenharmony_ci
11028c2ecf20Sopenharmony_ci		if (done == 1)
11038c2ecf20Sopenharmony_ci			break;
11048c2ecf20Sopenharmony_ci
11058c2ecf20Sopenharmony_ci		/*
11068c2ecf20Sopenharmony_ci		 * this loop could log more blocks than we had originally
11078c2ecf20Sopenharmony_ci		 * asked for.  So, we have to allow the transaction to end
11088c2ecf20Sopenharmony_ci		 * if it is too big or too full.  Update the inode so things
11098c2ecf20Sopenharmony_ci		 * are consistent if we crash before the function returns
11108c2ecf20Sopenharmony_ci		 * release the path so that anybody waiting on the path before
11118c2ecf20Sopenharmony_ci		 * ending their transaction will be able to continue.
11128c2ecf20Sopenharmony_ci		 */
11138c2ecf20Sopenharmony_ci		if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
11148c2ecf20Sopenharmony_ci			retval = restart_transaction(th, inode, &path);
11158c2ecf20Sopenharmony_ci			if (retval)
11168c2ecf20Sopenharmony_ci				goto failure;
11178c2ecf20Sopenharmony_ci		}
11188c2ecf20Sopenharmony_ci		/*
11198c2ecf20Sopenharmony_ci		 * inserting indirect pointers for a hole can take a
11208c2ecf20Sopenharmony_ci		 * long time.  reschedule if needed and also release the write
11218c2ecf20Sopenharmony_ci		 * lock for others.
11228c2ecf20Sopenharmony_ci		 */
11238c2ecf20Sopenharmony_ci		reiserfs_cond_resched(inode->i_sb);
11248c2ecf20Sopenharmony_ci
11258c2ecf20Sopenharmony_ci		retval = search_for_position_by_key(inode->i_sb, &key, &path);
11268c2ecf20Sopenharmony_ci		if (retval == IO_ERROR) {
11278c2ecf20Sopenharmony_ci			retval = -EIO;
11288c2ecf20Sopenharmony_ci			goto failure;
11298c2ecf20Sopenharmony_ci		}
11308c2ecf20Sopenharmony_ci		if (retval == POSITION_FOUND) {
11318c2ecf20Sopenharmony_ci			reiserfs_warning(inode->i_sb, "vs-825",
11328c2ecf20Sopenharmony_ci					 "%K should not be found", &key);
11338c2ecf20Sopenharmony_ci			retval = -EEXIST;
11348c2ecf20Sopenharmony_ci			if (allocated_block_nr)
11358c2ecf20Sopenharmony_ci				reiserfs_free_block(th, inode,
11368c2ecf20Sopenharmony_ci						    allocated_block_nr, 1);
11378c2ecf20Sopenharmony_ci			pathrelse(&path);
11388c2ecf20Sopenharmony_ci			goto failure;
11398c2ecf20Sopenharmony_ci		}
11408c2ecf20Sopenharmony_ci		bh = get_last_bh(&path);
11418c2ecf20Sopenharmony_ci		ih = tp_item_head(&path);
11428c2ecf20Sopenharmony_ci		item = tp_item_body(&path);
11438c2ecf20Sopenharmony_ci		pos_in_item = path.pos_in_item;
11448c2ecf20Sopenharmony_ci	} while (1);
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_ci	retval = 0;
11478c2ecf20Sopenharmony_ci
11488c2ecf20Sopenharmony_cifailure:
11498c2ecf20Sopenharmony_ci	if (th && (!dangle || (retval && !th->t_trans_id))) {
11508c2ecf20Sopenharmony_ci		int err;
11518c2ecf20Sopenharmony_ci		if (th->t_trans_id)
11528c2ecf20Sopenharmony_ci			reiserfs_update_sd(th, inode);
11538c2ecf20Sopenharmony_ci		err = reiserfs_end_persistent_transaction(th);
11548c2ecf20Sopenharmony_ci		if (err)
11558c2ecf20Sopenharmony_ci			retval = err;
11568c2ecf20Sopenharmony_ci	}
11578c2ecf20Sopenharmony_ci
11588c2ecf20Sopenharmony_ci	reiserfs_write_unlock(inode->i_sb);
11598c2ecf20Sopenharmony_ci	reiserfs_check_path(&path);
11608c2ecf20Sopenharmony_ci	return retval;
11618c2ecf20Sopenharmony_ci}
11628c2ecf20Sopenharmony_ci
11638c2ecf20Sopenharmony_cistatic void reiserfs_readahead(struct readahead_control *rac)
11648c2ecf20Sopenharmony_ci{
11658c2ecf20Sopenharmony_ci	mpage_readahead(rac, reiserfs_get_block);
11668c2ecf20Sopenharmony_ci}
11678c2ecf20Sopenharmony_ci
11688c2ecf20Sopenharmony_ci/*
11698c2ecf20Sopenharmony_ci * Compute real number of used bytes by file
11708c2ecf20Sopenharmony_ci * Following three functions can go away when we'll have enough space in
11718c2ecf20Sopenharmony_ci * stat item
11728c2ecf20Sopenharmony_ci */
11738c2ecf20Sopenharmony_cistatic int real_space_diff(struct inode *inode, int sd_size)
11748c2ecf20Sopenharmony_ci{
11758c2ecf20Sopenharmony_ci	int bytes;
11768c2ecf20Sopenharmony_ci	loff_t blocksize = inode->i_sb->s_blocksize;
11778c2ecf20Sopenharmony_ci
11788c2ecf20Sopenharmony_ci	if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode))
11798c2ecf20Sopenharmony_ci		return sd_size;
11808c2ecf20Sopenharmony_ci
11818c2ecf20Sopenharmony_ci	/*
11828c2ecf20Sopenharmony_ci	 * End of file is also in full block with indirect reference, so round
11838c2ecf20Sopenharmony_ci	 * up to the next block.
11848c2ecf20Sopenharmony_ci	 *
11858c2ecf20Sopenharmony_ci	 * there is just no way to know if the tail is actually packed
11868c2ecf20Sopenharmony_ci	 * on the file, so we have to assume it isn't.  When we pack the
11878c2ecf20Sopenharmony_ci	 * tail, we add 4 bytes to pretend there really is an unformatted
11888c2ecf20Sopenharmony_ci	 * node pointer
11898c2ecf20Sopenharmony_ci	 */
11908c2ecf20Sopenharmony_ci	bytes =
11918c2ecf20Sopenharmony_ci	    ((inode->i_size +
11928c2ecf20Sopenharmony_ci	      (blocksize - 1)) >> inode->i_sb->s_blocksize_bits) * UNFM_P_SIZE +
11938c2ecf20Sopenharmony_ci	    sd_size;
11948c2ecf20Sopenharmony_ci	return bytes;
11958c2ecf20Sopenharmony_ci}
11968c2ecf20Sopenharmony_ci
11978c2ecf20Sopenharmony_cistatic inline loff_t to_real_used_space(struct inode *inode, ulong blocks,
11988c2ecf20Sopenharmony_ci					int sd_size)
11998c2ecf20Sopenharmony_ci{
12008c2ecf20Sopenharmony_ci	if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
12018c2ecf20Sopenharmony_ci		return inode->i_size +
12028c2ecf20Sopenharmony_ci		    (loff_t) (real_space_diff(inode, sd_size));
12038c2ecf20Sopenharmony_ci	}
12048c2ecf20Sopenharmony_ci	return ((loff_t) real_space_diff(inode, sd_size)) +
12058c2ecf20Sopenharmony_ci	    (((loff_t) blocks) << 9);
12068c2ecf20Sopenharmony_ci}
12078c2ecf20Sopenharmony_ci
12088c2ecf20Sopenharmony_ci/* Compute number of blocks used by file in ReiserFS counting */
12098c2ecf20Sopenharmony_cistatic inline ulong to_fake_used_blocks(struct inode *inode, int sd_size)
12108c2ecf20Sopenharmony_ci{
12118c2ecf20Sopenharmony_ci	loff_t bytes = inode_get_bytes(inode);
12128c2ecf20Sopenharmony_ci	loff_t real_space = real_space_diff(inode, sd_size);
12138c2ecf20Sopenharmony_ci
12148c2ecf20Sopenharmony_ci	/* keeps fsck and non-quota versions of reiserfs happy */
12158c2ecf20Sopenharmony_ci	if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
12168c2ecf20Sopenharmony_ci		bytes += (loff_t) 511;
12178c2ecf20Sopenharmony_ci	}
12188c2ecf20Sopenharmony_ci
12198c2ecf20Sopenharmony_ci	/*
12208c2ecf20Sopenharmony_ci	 * files from before the quota patch might i_blocks such that
12218c2ecf20Sopenharmony_ci	 * bytes < real_space.  Deal with that here to prevent it from
12228c2ecf20Sopenharmony_ci	 * going negative.
12238c2ecf20Sopenharmony_ci	 */
12248c2ecf20Sopenharmony_ci	if (bytes < real_space)
12258c2ecf20Sopenharmony_ci		return 0;
12268c2ecf20Sopenharmony_ci	return (bytes - real_space) >> 9;
12278c2ecf20Sopenharmony_ci}
12288c2ecf20Sopenharmony_ci
12298c2ecf20Sopenharmony_ci/*
12308c2ecf20Sopenharmony_ci * BAD: new directories have stat data of new type and all other items
12318c2ecf20Sopenharmony_ci * of old type. Version stored in the inode says about body items, so
12328c2ecf20Sopenharmony_ci * in update_stat_data we can not rely on inode, but have to check
12338c2ecf20Sopenharmony_ci * item version directly
12348c2ecf20Sopenharmony_ci */
12358c2ecf20Sopenharmony_ci
12368c2ecf20Sopenharmony_ci/* called by read_locked_inode */
12378c2ecf20Sopenharmony_cistatic void init_inode(struct inode *inode, struct treepath *path)
12388c2ecf20Sopenharmony_ci{
12398c2ecf20Sopenharmony_ci	struct buffer_head *bh;
12408c2ecf20Sopenharmony_ci	struct item_head *ih;
12418c2ecf20Sopenharmony_ci	__u32 rdev;
12428c2ecf20Sopenharmony_ci
12438c2ecf20Sopenharmony_ci	bh = PATH_PLAST_BUFFER(path);
12448c2ecf20Sopenharmony_ci	ih = tp_item_head(path);
12458c2ecf20Sopenharmony_ci
12468c2ecf20Sopenharmony_ci	copy_key(INODE_PKEY(inode), &ih->ih_key);
12478c2ecf20Sopenharmony_ci
12488c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&REISERFS_I(inode)->i_prealloc_list);
12498c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_flags = 0;
12508c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_prealloc_block = 0;
12518c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_prealloc_count = 0;
12528c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_trans_id = 0;
12538c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_jl = NULL;
12548c2ecf20Sopenharmony_ci	reiserfs_init_xattr_rwsem(inode);
12558c2ecf20Sopenharmony_ci
12568c2ecf20Sopenharmony_ci	if (stat_data_v1(ih)) {
12578c2ecf20Sopenharmony_ci		struct stat_data_v1 *sd =
12588c2ecf20Sopenharmony_ci		    (struct stat_data_v1 *)ih_item_body(bh, ih);
12598c2ecf20Sopenharmony_ci		unsigned long blocks;
12608c2ecf20Sopenharmony_ci
12618c2ecf20Sopenharmony_ci		set_inode_item_key_version(inode, KEY_FORMAT_3_5);
12628c2ecf20Sopenharmony_ci		set_inode_sd_version(inode, STAT_DATA_V1);
12638c2ecf20Sopenharmony_ci		inode->i_mode = sd_v1_mode(sd);
12648c2ecf20Sopenharmony_ci		set_nlink(inode, sd_v1_nlink(sd));
12658c2ecf20Sopenharmony_ci		i_uid_write(inode, sd_v1_uid(sd));
12668c2ecf20Sopenharmony_ci		i_gid_write(inode, sd_v1_gid(sd));
12678c2ecf20Sopenharmony_ci		inode->i_size = sd_v1_size(sd);
12688c2ecf20Sopenharmony_ci		inode->i_atime.tv_sec = sd_v1_atime(sd);
12698c2ecf20Sopenharmony_ci		inode->i_mtime.tv_sec = sd_v1_mtime(sd);
12708c2ecf20Sopenharmony_ci		inode->i_ctime.tv_sec = sd_v1_ctime(sd);
12718c2ecf20Sopenharmony_ci		inode->i_atime.tv_nsec = 0;
12728c2ecf20Sopenharmony_ci		inode->i_ctime.tv_nsec = 0;
12738c2ecf20Sopenharmony_ci		inode->i_mtime.tv_nsec = 0;
12748c2ecf20Sopenharmony_ci
12758c2ecf20Sopenharmony_ci		inode->i_blocks = sd_v1_blocks(sd);
12768c2ecf20Sopenharmony_ci		inode->i_generation = le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
12778c2ecf20Sopenharmony_ci		blocks = (inode->i_size + 511) >> 9;
12788c2ecf20Sopenharmony_ci		blocks = _ROUND_UP(blocks, inode->i_sb->s_blocksize >> 9);
12798c2ecf20Sopenharmony_ci
12808c2ecf20Sopenharmony_ci		/*
12818c2ecf20Sopenharmony_ci		 * there was a bug in <=3.5.23 when i_blocks could take
12828c2ecf20Sopenharmony_ci		 * negative values. Starting from 3.5.17 this value could
12838c2ecf20Sopenharmony_ci		 * even be stored in stat data. For such files we set
12848c2ecf20Sopenharmony_ci		 * i_blocks based on file size. Just 2 notes: this can be
12858c2ecf20Sopenharmony_ci		 * wrong for sparse files. On-disk value will be only
12868c2ecf20Sopenharmony_ci		 * updated if file's inode will ever change
12878c2ecf20Sopenharmony_ci		 */
12888c2ecf20Sopenharmony_ci		if (inode->i_blocks > blocks) {
12898c2ecf20Sopenharmony_ci			inode->i_blocks = blocks;
12908c2ecf20Sopenharmony_ci		}
12918c2ecf20Sopenharmony_ci
12928c2ecf20Sopenharmony_ci		rdev = sd_v1_rdev(sd);
12938c2ecf20Sopenharmony_ci		REISERFS_I(inode)->i_first_direct_byte =
12948c2ecf20Sopenharmony_ci		    sd_v1_first_direct_byte(sd);
12958c2ecf20Sopenharmony_ci
12968c2ecf20Sopenharmony_ci		/*
12978c2ecf20Sopenharmony_ci		 * an early bug in the quota code can give us an odd
12988c2ecf20Sopenharmony_ci		 * number for the block count.  This is incorrect, fix it here.
12998c2ecf20Sopenharmony_ci		 */
13008c2ecf20Sopenharmony_ci		if (inode->i_blocks & 1) {
13018c2ecf20Sopenharmony_ci			inode->i_blocks++;
13028c2ecf20Sopenharmony_ci		}
13038c2ecf20Sopenharmony_ci		inode_set_bytes(inode,
13048c2ecf20Sopenharmony_ci				to_real_used_space(inode, inode->i_blocks,
13058c2ecf20Sopenharmony_ci						   SD_V1_SIZE));
13068c2ecf20Sopenharmony_ci		/*
13078c2ecf20Sopenharmony_ci		 * nopack is initially zero for v1 objects. For v2 objects,
13088c2ecf20Sopenharmony_ci		 * nopack is initialised from sd_attrs
13098c2ecf20Sopenharmony_ci		 */
13108c2ecf20Sopenharmony_ci		REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
13118c2ecf20Sopenharmony_ci	} else {
13128c2ecf20Sopenharmony_ci		/*
13138c2ecf20Sopenharmony_ci		 * new stat data found, but object may have old items
13148c2ecf20Sopenharmony_ci		 * (directories and symlinks)
13158c2ecf20Sopenharmony_ci		 */
13168c2ecf20Sopenharmony_ci		struct stat_data *sd = (struct stat_data *)ih_item_body(bh, ih);
13178c2ecf20Sopenharmony_ci
13188c2ecf20Sopenharmony_ci		inode->i_mode = sd_v2_mode(sd);
13198c2ecf20Sopenharmony_ci		set_nlink(inode, sd_v2_nlink(sd));
13208c2ecf20Sopenharmony_ci		i_uid_write(inode, sd_v2_uid(sd));
13218c2ecf20Sopenharmony_ci		inode->i_size = sd_v2_size(sd);
13228c2ecf20Sopenharmony_ci		i_gid_write(inode, sd_v2_gid(sd));
13238c2ecf20Sopenharmony_ci		inode->i_mtime.tv_sec = sd_v2_mtime(sd);
13248c2ecf20Sopenharmony_ci		inode->i_atime.tv_sec = sd_v2_atime(sd);
13258c2ecf20Sopenharmony_ci		inode->i_ctime.tv_sec = sd_v2_ctime(sd);
13268c2ecf20Sopenharmony_ci		inode->i_ctime.tv_nsec = 0;
13278c2ecf20Sopenharmony_ci		inode->i_mtime.tv_nsec = 0;
13288c2ecf20Sopenharmony_ci		inode->i_atime.tv_nsec = 0;
13298c2ecf20Sopenharmony_ci		inode->i_blocks = sd_v2_blocks(sd);
13308c2ecf20Sopenharmony_ci		rdev = sd_v2_rdev(sd);
13318c2ecf20Sopenharmony_ci		if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
13328c2ecf20Sopenharmony_ci			inode->i_generation =
13338c2ecf20Sopenharmony_ci			    le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
13348c2ecf20Sopenharmony_ci		else
13358c2ecf20Sopenharmony_ci			inode->i_generation = sd_v2_generation(sd);
13368c2ecf20Sopenharmony_ci
13378c2ecf20Sopenharmony_ci		if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
13388c2ecf20Sopenharmony_ci			set_inode_item_key_version(inode, KEY_FORMAT_3_5);
13398c2ecf20Sopenharmony_ci		else
13408c2ecf20Sopenharmony_ci			set_inode_item_key_version(inode, KEY_FORMAT_3_6);
13418c2ecf20Sopenharmony_ci		REISERFS_I(inode)->i_first_direct_byte = 0;
13428c2ecf20Sopenharmony_ci		set_inode_sd_version(inode, STAT_DATA_V2);
13438c2ecf20Sopenharmony_ci		inode_set_bytes(inode,
13448c2ecf20Sopenharmony_ci				to_real_used_space(inode, inode->i_blocks,
13458c2ecf20Sopenharmony_ci						   SD_V2_SIZE));
13468c2ecf20Sopenharmony_ci		/*
13478c2ecf20Sopenharmony_ci		 * read persistent inode attributes from sd and initialise
13488c2ecf20Sopenharmony_ci		 * generic inode flags from them
13498c2ecf20Sopenharmony_ci		 */
13508c2ecf20Sopenharmony_ci		REISERFS_I(inode)->i_attrs = sd_v2_attrs(sd);
13518c2ecf20Sopenharmony_ci		sd_attrs_to_i_attrs(sd_v2_attrs(sd), inode);
13528c2ecf20Sopenharmony_ci	}
13538c2ecf20Sopenharmony_ci
13548c2ecf20Sopenharmony_ci	pathrelse(path);
13558c2ecf20Sopenharmony_ci	if (S_ISREG(inode->i_mode)) {
13568c2ecf20Sopenharmony_ci		inode->i_op = &reiserfs_file_inode_operations;
13578c2ecf20Sopenharmony_ci		inode->i_fop = &reiserfs_file_operations;
13588c2ecf20Sopenharmony_ci		inode->i_mapping->a_ops = &reiserfs_address_space_operations;
13598c2ecf20Sopenharmony_ci	} else if (S_ISDIR(inode->i_mode)) {
13608c2ecf20Sopenharmony_ci		inode->i_op = &reiserfs_dir_inode_operations;
13618c2ecf20Sopenharmony_ci		inode->i_fop = &reiserfs_dir_operations;
13628c2ecf20Sopenharmony_ci	} else if (S_ISLNK(inode->i_mode)) {
13638c2ecf20Sopenharmony_ci		inode->i_op = &reiserfs_symlink_inode_operations;
13648c2ecf20Sopenharmony_ci		inode_nohighmem(inode);
13658c2ecf20Sopenharmony_ci		inode->i_mapping->a_ops = &reiserfs_address_space_operations;
13668c2ecf20Sopenharmony_ci	} else {
13678c2ecf20Sopenharmony_ci		inode->i_blocks = 0;
13688c2ecf20Sopenharmony_ci		inode->i_op = &reiserfs_special_inode_operations;
13698c2ecf20Sopenharmony_ci		init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
13708c2ecf20Sopenharmony_ci	}
13718c2ecf20Sopenharmony_ci}
13728c2ecf20Sopenharmony_ci
13738c2ecf20Sopenharmony_ci/* update new stat data with inode fields */
13748c2ecf20Sopenharmony_cistatic void inode2sd(void *sd, struct inode *inode, loff_t size)
13758c2ecf20Sopenharmony_ci{
13768c2ecf20Sopenharmony_ci	struct stat_data *sd_v2 = (struct stat_data *)sd;
13778c2ecf20Sopenharmony_ci
13788c2ecf20Sopenharmony_ci	set_sd_v2_mode(sd_v2, inode->i_mode);
13798c2ecf20Sopenharmony_ci	set_sd_v2_nlink(sd_v2, inode->i_nlink);
13808c2ecf20Sopenharmony_ci	set_sd_v2_uid(sd_v2, i_uid_read(inode));
13818c2ecf20Sopenharmony_ci	set_sd_v2_size(sd_v2, size);
13828c2ecf20Sopenharmony_ci	set_sd_v2_gid(sd_v2, i_gid_read(inode));
13838c2ecf20Sopenharmony_ci	set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec);
13848c2ecf20Sopenharmony_ci	set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec);
13858c2ecf20Sopenharmony_ci	set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec);
13868c2ecf20Sopenharmony_ci	set_sd_v2_blocks(sd_v2, to_fake_used_blocks(inode, SD_V2_SIZE));
13878c2ecf20Sopenharmony_ci	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
13888c2ecf20Sopenharmony_ci		set_sd_v2_rdev(sd_v2, new_encode_dev(inode->i_rdev));
13898c2ecf20Sopenharmony_ci	else
13908c2ecf20Sopenharmony_ci		set_sd_v2_generation(sd_v2, inode->i_generation);
13918c2ecf20Sopenharmony_ci	set_sd_v2_attrs(sd_v2, REISERFS_I(inode)->i_attrs);
13928c2ecf20Sopenharmony_ci}
13938c2ecf20Sopenharmony_ci
13948c2ecf20Sopenharmony_ci/* used to copy inode's fields to old stat data */
13958c2ecf20Sopenharmony_cistatic void inode2sd_v1(void *sd, struct inode *inode, loff_t size)
13968c2ecf20Sopenharmony_ci{
13978c2ecf20Sopenharmony_ci	struct stat_data_v1 *sd_v1 = (struct stat_data_v1 *)sd;
13988c2ecf20Sopenharmony_ci
13998c2ecf20Sopenharmony_ci	set_sd_v1_mode(sd_v1, inode->i_mode);
14008c2ecf20Sopenharmony_ci	set_sd_v1_uid(sd_v1, i_uid_read(inode));
14018c2ecf20Sopenharmony_ci	set_sd_v1_gid(sd_v1, i_gid_read(inode));
14028c2ecf20Sopenharmony_ci	set_sd_v1_nlink(sd_v1, inode->i_nlink);
14038c2ecf20Sopenharmony_ci	set_sd_v1_size(sd_v1, size);
14048c2ecf20Sopenharmony_ci	set_sd_v1_atime(sd_v1, inode->i_atime.tv_sec);
14058c2ecf20Sopenharmony_ci	set_sd_v1_ctime(sd_v1, inode->i_ctime.tv_sec);
14068c2ecf20Sopenharmony_ci	set_sd_v1_mtime(sd_v1, inode->i_mtime.tv_sec);
14078c2ecf20Sopenharmony_ci
14088c2ecf20Sopenharmony_ci	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
14098c2ecf20Sopenharmony_ci		set_sd_v1_rdev(sd_v1, new_encode_dev(inode->i_rdev));
14108c2ecf20Sopenharmony_ci	else
14118c2ecf20Sopenharmony_ci		set_sd_v1_blocks(sd_v1, to_fake_used_blocks(inode, SD_V1_SIZE));
14128c2ecf20Sopenharmony_ci
14138c2ecf20Sopenharmony_ci	/* Sigh. i_first_direct_byte is back */
14148c2ecf20Sopenharmony_ci	set_sd_v1_first_direct_byte(sd_v1,
14158c2ecf20Sopenharmony_ci				    REISERFS_I(inode)->i_first_direct_byte);
14168c2ecf20Sopenharmony_ci}
14178c2ecf20Sopenharmony_ci
14188c2ecf20Sopenharmony_ci/*
14198c2ecf20Sopenharmony_ci * NOTE, you must prepare the buffer head before sending it here,
14208c2ecf20Sopenharmony_ci * and then log it after the call
14218c2ecf20Sopenharmony_ci */
14228c2ecf20Sopenharmony_cistatic void update_stat_data(struct treepath *path, struct inode *inode,
14238c2ecf20Sopenharmony_ci			     loff_t size)
14248c2ecf20Sopenharmony_ci{
14258c2ecf20Sopenharmony_ci	struct buffer_head *bh;
14268c2ecf20Sopenharmony_ci	struct item_head *ih;
14278c2ecf20Sopenharmony_ci
14288c2ecf20Sopenharmony_ci	bh = PATH_PLAST_BUFFER(path);
14298c2ecf20Sopenharmony_ci	ih = tp_item_head(path);
14308c2ecf20Sopenharmony_ci
14318c2ecf20Sopenharmony_ci	if (!is_statdata_le_ih(ih))
14328c2ecf20Sopenharmony_ci		reiserfs_panic(inode->i_sb, "vs-13065", "key %k, found item %h",
14338c2ecf20Sopenharmony_ci			       INODE_PKEY(inode), ih);
14348c2ecf20Sopenharmony_ci
14358c2ecf20Sopenharmony_ci	/* path points to old stat data */
14368c2ecf20Sopenharmony_ci	if (stat_data_v1(ih)) {
14378c2ecf20Sopenharmony_ci		inode2sd_v1(ih_item_body(bh, ih), inode, size);
14388c2ecf20Sopenharmony_ci	} else {
14398c2ecf20Sopenharmony_ci		inode2sd(ih_item_body(bh, ih), inode, size);
14408c2ecf20Sopenharmony_ci	}
14418c2ecf20Sopenharmony_ci
14428c2ecf20Sopenharmony_ci	return;
14438c2ecf20Sopenharmony_ci}
14448c2ecf20Sopenharmony_ci
14458c2ecf20Sopenharmony_civoid reiserfs_update_sd_size(struct reiserfs_transaction_handle *th,
14468c2ecf20Sopenharmony_ci			     struct inode *inode, loff_t size)
14478c2ecf20Sopenharmony_ci{
14488c2ecf20Sopenharmony_ci	struct cpu_key key;
14498c2ecf20Sopenharmony_ci	INITIALIZE_PATH(path);
14508c2ecf20Sopenharmony_ci	struct buffer_head *bh;
14518c2ecf20Sopenharmony_ci	int fs_gen;
14528c2ecf20Sopenharmony_ci	struct item_head *ih, tmp_ih;
14538c2ecf20Sopenharmony_ci	int retval;
14548c2ecf20Sopenharmony_ci
14558c2ecf20Sopenharmony_ci	BUG_ON(!th->t_trans_id);
14568c2ecf20Sopenharmony_ci
14578c2ecf20Sopenharmony_ci	/* key type is unimportant */
14588c2ecf20Sopenharmony_ci	make_cpu_key(&key, inode, SD_OFFSET, TYPE_STAT_DATA, 3);
14598c2ecf20Sopenharmony_ci
14608c2ecf20Sopenharmony_ci	for (;;) {
14618c2ecf20Sopenharmony_ci		int pos;
14628c2ecf20Sopenharmony_ci		/* look for the object's stat data */
14638c2ecf20Sopenharmony_ci		retval = search_item(inode->i_sb, &key, &path);
14648c2ecf20Sopenharmony_ci		if (retval == IO_ERROR) {
14658c2ecf20Sopenharmony_ci			reiserfs_error(inode->i_sb, "vs-13050",
14668c2ecf20Sopenharmony_ci				       "i/o failure occurred trying to "
14678c2ecf20Sopenharmony_ci				       "update %K stat data", &key);
14688c2ecf20Sopenharmony_ci			return;
14698c2ecf20Sopenharmony_ci		}
14708c2ecf20Sopenharmony_ci		if (retval == ITEM_NOT_FOUND) {
14718c2ecf20Sopenharmony_ci			pos = PATH_LAST_POSITION(&path);
14728c2ecf20Sopenharmony_ci			pathrelse(&path);
14738c2ecf20Sopenharmony_ci			if (inode->i_nlink == 0) {
14748c2ecf20Sopenharmony_ci				/*reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: i_nlink == 0, stat data not found"); */
14758c2ecf20Sopenharmony_ci				return;
14768c2ecf20Sopenharmony_ci			}
14778c2ecf20Sopenharmony_ci			reiserfs_warning(inode->i_sb, "vs-13060",
14788c2ecf20Sopenharmony_ci					 "stat data of object %k (nlink == %d) "
14798c2ecf20Sopenharmony_ci					 "not found (pos %d)",
14808c2ecf20Sopenharmony_ci					 INODE_PKEY(inode), inode->i_nlink,
14818c2ecf20Sopenharmony_ci					 pos);
14828c2ecf20Sopenharmony_ci			reiserfs_check_path(&path);
14838c2ecf20Sopenharmony_ci			return;
14848c2ecf20Sopenharmony_ci		}
14858c2ecf20Sopenharmony_ci
14868c2ecf20Sopenharmony_ci		/*
14878c2ecf20Sopenharmony_ci		 * sigh, prepare_for_journal might schedule.  When it
14888c2ecf20Sopenharmony_ci		 * schedules the FS might change.  We have to detect that,
14898c2ecf20Sopenharmony_ci		 * and loop back to the search if the stat data item has moved
14908c2ecf20Sopenharmony_ci		 */
14918c2ecf20Sopenharmony_ci		bh = get_last_bh(&path);
14928c2ecf20Sopenharmony_ci		ih = tp_item_head(&path);
14938c2ecf20Sopenharmony_ci		copy_item_head(&tmp_ih, ih);
14948c2ecf20Sopenharmony_ci		fs_gen = get_generation(inode->i_sb);
14958c2ecf20Sopenharmony_ci		reiserfs_prepare_for_journal(inode->i_sb, bh, 1);
14968c2ecf20Sopenharmony_ci
14978c2ecf20Sopenharmony_ci		/* Stat_data item has been moved after scheduling. */
14988c2ecf20Sopenharmony_ci		if (fs_changed(fs_gen, inode->i_sb)
14998c2ecf20Sopenharmony_ci		    && item_moved(&tmp_ih, &path)) {
15008c2ecf20Sopenharmony_ci			reiserfs_restore_prepared_buffer(inode->i_sb, bh);
15018c2ecf20Sopenharmony_ci			continue;
15028c2ecf20Sopenharmony_ci		}
15038c2ecf20Sopenharmony_ci		break;
15048c2ecf20Sopenharmony_ci	}
15058c2ecf20Sopenharmony_ci	update_stat_data(&path, inode, size);
15068c2ecf20Sopenharmony_ci	journal_mark_dirty(th, bh);
15078c2ecf20Sopenharmony_ci	pathrelse(&path);
15088c2ecf20Sopenharmony_ci	return;
15098c2ecf20Sopenharmony_ci}
15108c2ecf20Sopenharmony_ci
15118c2ecf20Sopenharmony_ci/*
15128c2ecf20Sopenharmony_ci * reiserfs_read_locked_inode is called to read the inode off disk, and it
15138c2ecf20Sopenharmony_ci * does a make_bad_inode when things go wrong.  But, we need to make sure
15148c2ecf20Sopenharmony_ci * and clear the key in the private portion of the inode, otherwise a
15158c2ecf20Sopenharmony_ci * corresponding iput might try to delete whatever object the inode last
15168c2ecf20Sopenharmony_ci * represented.
15178c2ecf20Sopenharmony_ci */
15188c2ecf20Sopenharmony_cistatic void reiserfs_make_bad_inode(struct inode *inode)
15198c2ecf20Sopenharmony_ci{
15208c2ecf20Sopenharmony_ci	memset(INODE_PKEY(inode), 0, KEY_SIZE);
15218c2ecf20Sopenharmony_ci	make_bad_inode(inode);
15228c2ecf20Sopenharmony_ci}
15238c2ecf20Sopenharmony_ci
15248c2ecf20Sopenharmony_ci/*
15258c2ecf20Sopenharmony_ci * initially this function was derived from minix or ext2's analog and
15268c2ecf20Sopenharmony_ci * evolved as the prototype did
15278c2ecf20Sopenharmony_ci */
15288c2ecf20Sopenharmony_ciint reiserfs_init_locked_inode(struct inode *inode, void *p)
15298c2ecf20Sopenharmony_ci{
15308c2ecf20Sopenharmony_ci	struct reiserfs_iget_args *args = (struct reiserfs_iget_args *)p;
15318c2ecf20Sopenharmony_ci	inode->i_ino = args->objectid;
15328c2ecf20Sopenharmony_ci	INODE_PKEY(inode)->k_dir_id = cpu_to_le32(args->dirid);
15338c2ecf20Sopenharmony_ci	return 0;
15348c2ecf20Sopenharmony_ci}
15358c2ecf20Sopenharmony_ci
15368c2ecf20Sopenharmony_ci/*
15378c2ecf20Sopenharmony_ci * looks for stat data in the tree, and fills up the fields of in-core
15388c2ecf20Sopenharmony_ci * inode stat data fields
15398c2ecf20Sopenharmony_ci */
15408c2ecf20Sopenharmony_civoid reiserfs_read_locked_inode(struct inode *inode,
15418c2ecf20Sopenharmony_ci				struct reiserfs_iget_args *args)
15428c2ecf20Sopenharmony_ci{
15438c2ecf20Sopenharmony_ci	INITIALIZE_PATH(path_to_sd);
15448c2ecf20Sopenharmony_ci	struct cpu_key key;
15458c2ecf20Sopenharmony_ci	unsigned long dirino;
15468c2ecf20Sopenharmony_ci	int retval;
15478c2ecf20Sopenharmony_ci
15488c2ecf20Sopenharmony_ci	dirino = args->dirid;
15498c2ecf20Sopenharmony_ci
15508c2ecf20Sopenharmony_ci	/*
15518c2ecf20Sopenharmony_ci	 * set version 1, version 2 could be used too, because stat data
15528c2ecf20Sopenharmony_ci	 * key is the same in both versions
15538c2ecf20Sopenharmony_ci	 */
15548c2ecf20Sopenharmony_ci	_make_cpu_key(&key, KEY_FORMAT_3_5, dirino, inode->i_ino, 0, 0, 3);
15558c2ecf20Sopenharmony_ci
15568c2ecf20Sopenharmony_ci	/* look for the object's stat data */
15578c2ecf20Sopenharmony_ci	retval = search_item(inode->i_sb, &key, &path_to_sd);
15588c2ecf20Sopenharmony_ci	if (retval == IO_ERROR) {
15598c2ecf20Sopenharmony_ci		reiserfs_error(inode->i_sb, "vs-13070",
15608c2ecf20Sopenharmony_ci			       "i/o failure occurred trying to find "
15618c2ecf20Sopenharmony_ci			       "stat data of %K", &key);
15628c2ecf20Sopenharmony_ci		reiserfs_make_bad_inode(inode);
15638c2ecf20Sopenharmony_ci		return;
15648c2ecf20Sopenharmony_ci	}
15658c2ecf20Sopenharmony_ci
15668c2ecf20Sopenharmony_ci	/* a stale NFS handle can trigger this without it being an error */
15678c2ecf20Sopenharmony_ci	if (retval != ITEM_FOUND) {
15688c2ecf20Sopenharmony_ci		pathrelse(&path_to_sd);
15698c2ecf20Sopenharmony_ci		reiserfs_make_bad_inode(inode);
15708c2ecf20Sopenharmony_ci		clear_nlink(inode);
15718c2ecf20Sopenharmony_ci		return;
15728c2ecf20Sopenharmony_ci	}
15738c2ecf20Sopenharmony_ci
15748c2ecf20Sopenharmony_ci	init_inode(inode, &path_to_sd);
15758c2ecf20Sopenharmony_ci
15768c2ecf20Sopenharmony_ci	/*
15778c2ecf20Sopenharmony_ci	 * It is possible that knfsd is trying to access inode of a file
15788c2ecf20Sopenharmony_ci	 * that is being removed from the disk by some other thread. As we
15798c2ecf20Sopenharmony_ci	 * update sd on unlink all that is required is to check for nlink
15808c2ecf20Sopenharmony_ci	 * here. This bug was first found by Sizif when debugging
15818c2ecf20Sopenharmony_ci	 * SquidNG/Butterfly, forgotten, and found again after Philippe
15828c2ecf20Sopenharmony_ci	 * Gramoulle <philippe.gramoulle@mmania.com> reproduced it.
15838c2ecf20Sopenharmony_ci
15848c2ecf20Sopenharmony_ci	 * More logical fix would require changes in fs/inode.c:iput() to
15858c2ecf20Sopenharmony_ci	 * remove inode from hash-table _after_ fs cleaned disk stuff up and
15868c2ecf20Sopenharmony_ci	 * in iget() to return NULL if I_FREEING inode is found in
15878c2ecf20Sopenharmony_ci	 * hash-table.
15888c2ecf20Sopenharmony_ci	 */
15898c2ecf20Sopenharmony_ci
15908c2ecf20Sopenharmony_ci	/*
15918c2ecf20Sopenharmony_ci	 * Currently there is one place where it's ok to meet inode with
15928c2ecf20Sopenharmony_ci	 * nlink==0: processing of open-unlinked and half-truncated files
15938c2ecf20Sopenharmony_ci	 * during mount (fs/reiserfs/super.c:finish_unfinished()).
15948c2ecf20Sopenharmony_ci	 */
15958c2ecf20Sopenharmony_ci	if ((inode->i_nlink == 0) &&
15968c2ecf20Sopenharmony_ci	    !REISERFS_SB(inode->i_sb)->s_is_unlinked_ok) {
15978c2ecf20Sopenharmony_ci		reiserfs_warning(inode->i_sb, "vs-13075",
15988c2ecf20Sopenharmony_ci				 "dead inode read from disk %K. "
15998c2ecf20Sopenharmony_ci				 "This is likely to be race with knfsd. Ignore",
16008c2ecf20Sopenharmony_ci				 &key);
16018c2ecf20Sopenharmony_ci		reiserfs_make_bad_inode(inode);
16028c2ecf20Sopenharmony_ci	}
16038c2ecf20Sopenharmony_ci
16048c2ecf20Sopenharmony_ci	/* init inode should be relsing */
16058c2ecf20Sopenharmony_ci	reiserfs_check_path(&path_to_sd);
16068c2ecf20Sopenharmony_ci
16078c2ecf20Sopenharmony_ci	/*
16088c2ecf20Sopenharmony_ci	 * Stat data v1 doesn't support ACLs.
16098c2ecf20Sopenharmony_ci	 */
16108c2ecf20Sopenharmony_ci	if (get_inode_sd_version(inode) == STAT_DATA_V1)
16118c2ecf20Sopenharmony_ci		cache_no_acl(inode);
16128c2ecf20Sopenharmony_ci}
16138c2ecf20Sopenharmony_ci
16148c2ecf20Sopenharmony_ci/*
16158c2ecf20Sopenharmony_ci * reiserfs_find_actor() - "find actor" reiserfs supplies to iget5_locked().
16168c2ecf20Sopenharmony_ci *
16178c2ecf20Sopenharmony_ci * @inode:    inode from hash table to check
16188c2ecf20Sopenharmony_ci * @opaque:   "cookie" passed to iget5_locked(). This is &reiserfs_iget_args.
16198c2ecf20Sopenharmony_ci *
16208c2ecf20Sopenharmony_ci * This function is called by iget5_locked() to distinguish reiserfs inodes
16218c2ecf20Sopenharmony_ci * having the same inode numbers. Such inodes can only exist due to some
16228c2ecf20Sopenharmony_ci * error condition. One of them should be bad. Inodes with identical
16238c2ecf20Sopenharmony_ci * inode numbers (objectids) are distinguished by parent directory ids.
16248c2ecf20Sopenharmony_ci *
16258c2ecf20Sopenharmony_ci */
16268c2ecf20Sopenharmony_ciint reiserfs_find_actor(struct inode *inode, void *opaque)
16278c2ecf20Sopenharmony_ci{
16288c2ecf20Sopenharmony_ci	struct reiserfs_iget_args *args;
16298c2ecf20Sopenharmony_ci
16308c2ecf20Sopenharmony_ci	args = opaque;
16318c2ecf20Sopenharmony_ci	/* args is already in CPU order */
16328c2ecf20Sopenharmony_ci	return (inode->i_ino == args->objectid) &&
16338c2ecf20Sopenharmony_ci	    (le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args->dirid);
16348c2ecf20Sopenharmony_ci}
16358c2ecf20Sopenharmony_ci
16368c2ecf20Sopenharmony_cistruct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key)
16378c2ecf20Sopenharmony_ci{
16388c2ecf20Sopenharmony_ci	struct inode *inode;
16398c2ecf20Sopenharmony_ci	struct reiserfs_iget_args args;
16408c2ecf20Sopenharmony_ci	int depth;
16418c2ecf20Sopenharmony_ci
16428c2ecf20Sopenharmony_ci	args.objectid = key->on_disk_key.k_objectid;
16438c2ecf20Sopenharmony_ci	args.dirid = key->on_disk_key.k_dir_id;
16448c2ecf20Sopenharmony_ci	depth = reiserfs_write_unlock_nested(s);
16458c2ecf20Sopenharmony_ci	inode = iget5_locked(s, key->on_disk_key.k_objectid,
16468c2ecf20Sopenharmony_ci			     reiserfs_find_actor, reiserfs_init_locked_inode,
16478c2ecf20Sopenharmony_ci			     (void *)(&args));
16488c2ecf20Sopenharmony_ci	reiserfs_write_lock_nested(s, depth);
16498c2ecf20Sopenharmony_ci	if (!inode)
16508c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
16518c2ecf20Sopenharmony_ci
16528c2ecf20Sopenharmony_ci	if (inode->i_state & I_NEW) {
16538c2ecf20Sopenharmony_ci		reiserfs_read_locked_inode(inode, &args);
16548c2ecf20Sopenharmony_ci		unlock_new_inode(inode);
16558c2ecf20Sopenharmony_ci	}
16568c2ecf20Sopenharmony_ci
16578c2ecf20Sopenharmony_ci	if (comp_short_keys(INODE_PKEY(inode), key) || is_bad_inode(inode)) {
16588c2ecf20Sopenharmony_ci		/* either due to i/o error or a stale NFS handle */
16598c2ecf20Sopenharmony_ci		iput(inode);
16608c2ecf20Sopenharmony_ci		inode = NULL;
16618c2ecf20Sopenharmony_ci	}
16628c2ecf20Sopenharmony_ci	return inode;
16638c2ecf20Sopenharmony_ci}
16648c2ecf20Sopenharmony_ci
16658c2ecf20Sopenharmony_cistatic struct dentry *reiserfs_get_dentry(struct super_block *sb,
16668c2ecf20Sopenharmony_ci	u32 objectid, u32 dir_id, u32 generation)
16678c2ecf20Sopenharmony_ci
16688c2ecf20Sopenharmony_ci{
16698c2ecf20Sopenharmony_ci	struct cpu_key key;
16708c2ecf20Sopenharmony_ci	struct inode *inode;
16718c2ecf20Sopenharmony_ci
16728c2ecf20Sopenharmony_ci	key.on_disk_key.k_objectid = objectid;
16738c2ecf20Sopenharmony_ci	key.on_disk_key.k_dir_id = dir_id;
16748c2ecf20Sopenharmony_ci	reiserfs_write_lock(sb);
16758c2ecf20Sopenharmony_ci	inode = reiserfs_iget(sb, &key);
16768c2ecf20Sopenharmony_ci	if (inode && !IS_ERR(inode) && generation != 0 &&
16778c2ecf20Sopenharmony_ci	    generation != inode->i_generation) {
16788c2ecf20Sopenharmony_ci		iput(inode);
16798c2ecf20Sopenharmony_ci		inode = NULL;
16808c2ecf20Sopenharmony_ci	}
16818c2ecf20Sopenharmony_ci	reiserfs_write_unlock(sb);
16828c2ecf20Sopenharmony_ci
16838c2ecf20Sopenharmony_ci	return d_obtain_alias(inode);
16848c2ecf20Sopenharmony_ci}
16858c2ecf20Sopenharmony_ci
16868c2ecf20Sopenharmony_cistruct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
16878c2ecf20Sopenharmony_ci		int fh_len, int fh_type)
16888c2ecf20Sopenharmony_ci{
16898c2ecf20Sopenharmony_ci	/*
16908c2ecf20Sopenharmony_ci	 * fhtype happens to reflect the number of u32s encoded.
16918c2ecf20Sopenharmony_ci	 * due to a bug in earlier code, fhtype might indicate there
16928c2ecf20Sopenharmony_ci	 * are more u32s then actually fitted.
16938c2ecf20Sopenharmony_ci	 * so if fhtype seems to be more than len, reduce fhtype.
16948c2ecf20Sopenharmony_ci	 * Valid types are:
16958c2ecf20Sopenharmony_ci	 *   2 - objectid + dir_id - legacy support
16968c2ecf20Sopenharmony_ci	 *   3 - objectid + dir_id + generation
16978c2ecf20Sopenharmony_ci	 *   4 - objectid + dir_id + objectid and dirid of parent - legacy
16988c2ecf20Sopenharmony_ci	 *   5 - objectid + dir_id + generation + objectid and dirid of parent
16998c2ecf20Sopenharmony_ci	 *   6 - as above plus generation of directory
17008c2ecf20Sopenharmony_ci	 * 6 does not fit in NFSv2 handles
17018c2ecf20Sopenharmony_ci	 */
17028c2ecf20Sopenharmony_ci	if (fh_type > fh_len) {
17038c2ecf20Sopenharmony_ci		if (fh_type != 6 || fh_len != 5)
17048c2ecf20Sopenharmony_ci			reiserfs_warning(sb, "reiserfs-13077",
17058c2ecf20Sopenharmony_ci				"nfsd/reiserfs, fhtype=%d, len=%d - odd",
17068c2ecf20Sopenharmony_ci				fh_type, fh_len);
17078c2ecf20Sopenharmony_ci		fh_type = fh_len;
17088c2ecf20Sopenharmony_ci	}
17098c2ecf20Sopenharmony_ci	if (fh_len < 2)
17108c2ecf20Sopenharmony_ci		return NULL;
17118c2ecf20Sopenharmony_ci
17128c2ecf20Sopenharmony_ci	return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
17138c2ecf20Sopenharmony_ci		(fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
17148c2ecf20Sopenharmony_ci}
17158c2ecf20Sopenharmony_ci
17168c2ecf20Sopenharmony_cistruct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
17178c2ecf20Sopenharmony_ci		int fh_len, int fh_type)
17188c2ecf20Sopenharmony_ci{
17198c2ecf20Sopenharmony_ci	if (fh_type > fh_len)
17208c2ecf20Sopenharmony_ci		fh_type = fh_len;
17218c2ecf20Sopenharmony_ci	if (fh_type < 4)
17228c2ecf20Sopenharmony_ci		return NULL;
17238c2ecf20Sopenharmony_ci
17248c2ecf20Sopenharmony_ci	return reiserfs_get_dentry(sb,
17258c2ecf20Sopenharmony_ci		(fh_type >= 5) ? fid->raw[3] : fid->raw[2],
17268c2ecf20Sopenharmony_ci		(fh_type >= 5) ? fid->raw[4] : fid->raw[3],
17278c2ecf20Sopenharmony_ci		(fh_type == 6) ? fid->raw[5] : 0);
17288c2ecf20Sopenharmony_ci}
17298c2ecf20Sopenharmony_ci
17308c2ecf20Sopenharmony_ciint reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp,
17318c2ecf20Sopenharmony_ci		       struct inode *parent)
17328c2ecf20Sopenharmony_ci{
17338c2ecf20Sopenharmony_ci	int maxlen = *lenp;
17348c2ecf20Sopenharmony_ci
17358c2ecf20Sopenharmony_ci	if (parent && (maxlen < 5)) {
17368c2ecf20Sopenharmony_ci		*lenp = 5;
17378c2ecf20Sopenharmony_ci		return FILEID_INVALID;
17388c2ecf20Sopenharmony_ci	} else if (maxlen < 3) {
17398c2ecf20Sopenharmony_ci		*lenp = 3;
17408c2ecf20Sopenharmony_ci		return FILEID_INVALID;
17418c2ecf20Sopenharmony_ci	}
17428c2ecf20Sopenharmony_ci
17438c2ecf20Sopenharmony_ci	data[0] = inode->i_ino;
17448c2ecf20Sopenharmony_ci	data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
17458c2ecf20Sopenharmony_ci	data[2] = inode->i_generation;
17468c2ecf20Sopenharmony_ci	*lenp = 3;
17478c2ecf20Sopenharmony_ci	if (parent) {
17488c2ecf20Sopenharmony_ci		data[3] = parent->i_ino;
17498c2ecf20Sopenharmony_ci		data[4] = le32_to_cpu(INODE_PKEY(parent)->k_dir_id);
17508c2ecf20Sopenharmony_ci		*lenp = 5;
17518c2ecf20Sopenharmony_ci		if (maxlen >= 6) {
17528c2ecf20Sopenharmony_ci			data[5] = parent->i_generation;
17538c2ecf20Sopenharmony_ci			*lenp = 6;
17548c2ecf20Sopenharmony_ci		}
17558c2ecf20Sopenharmony_ci	}
17568c2ecf20Sopenharmony_ci	return *lenp;
17578c2ecf20Sopenharmony_ci}
17588c2ecf20Sopenharmony_ci
17598c2ecf20Sopenharmony_ci/*
17608c2ecf20Sopenharmony_ci * looks for stat data, then copies fields to it, marks the buffer
17618c2ecf20Sopenharmony_ci * containing stat data as dirty
17628c2ecf20Sopenharmony_ci */
17638c2ecf20Sopenharmony_ci/*
17648c2ecf20Sopenharmony_ci * reiserfs inodes are never really dirty, since the dirty inode call
17658c2ecf20Sopenharmony_ci * always logs them.  This call allows the VFS inode marking routines
17668c2ecf20Sopenharmony_ci * to properly mark inodes for datasync and such, but only actually
17678c2ecf20Sopenharmony_ci * does something when called for a synchronous update.
17688c2ecf20Sopenharmony_ci */
17698c2ecf20Sopenharmony_ciint reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc)
17708c2ecf20Sopenharmony_ci{
17718c2ecf20Sopenharmony_ci	struct reiserfs_transaction_handle th;
17728c2ecf20Sopenharmony_ci	int jbegin_count = 1;
17738c2ecf20Sopenharmony_ci
17748c2ecf20Sopenharmony_ci	if (sb_rdonly(inode->i_sb))
17758c2ecf20Sopenharmony_ci		return -EROFS;
17768c2ecf20Sopenharmony_ci	/*
17778c2ecf20Sopenharmony_ci	 * memory pressure can sometimes initiate write_inode calls with
17788c2ecf20Sopenharmony_ci	 * sync == 1,
17798c2ecf20Sopenharmony_ci	 * these cases are just when the system needs ram, not when the
17808c2ecf20Sopenharmony_ci	 * inode needs to reach disk for safety, and they can safely be
17818c2ecf20Sopenharmony_ci	 * ignored because the altered inode has already been logged.
17828c2ecf20Sopenharmony_ci	 */
17838c2ecf20Sopenharmony_ci	if (wbc->sync_mode == WB_SYNC_ALL && !(current->flags & PF_MEMALLOC)) {
17848c2ecf20Sopenharmony_ci		reiserfs_write_lock(inode->i_sb);
17858c2ecf20Sopenharmony_ci		if (!journal_begin(&th, inode->i_sb, jbegin_count)) {
17868c2ecf20Sopenharmony_ci			reiserfs_update_sd(&th, inode);
17878c2ecf20Sopenharmony_ci			journal_end_sync(&th);
17888c2ecf20Sopenharmony_ci		}
17898c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
17908c2ecf20Sopenharmony_ci	}
17918c2ecf20Sopenharmony_ci	return 0;
17928c2ecf20Sopenharmony_ci}
17938c2ecf20Sopenharmony_ci
17948c2ecf20Sopenharmony_ci/*
17958c2ecf20Sopenharmony_ci * stat data of new object is inserted already, this inserts the item
17968c2ecf20Sopenharmony_ci * containing "." and ".." entries
17978c2ecf20Sopenharmony_ci */
17988c2ecf20Sopenharmony_cistatic int reiserfs_new_directory(struct reiserfs_transaction_handle *th,
17998c2ecf20Sopenharmony_ci				  struct inode *inode,
18008c2ecf20Sopenharmony_ci				  struct item_head *ih, struct treepath *path,
18018c2ecf20Sopenharmony_ci				  struct inode *dir)
18028c2ecf20Sopenharmony_ci{
18038c2ecf20Sopenharmony_ci	struct super_block *sb = th->t_super;
18048c2ecf20Sopenharmony_ci	char empty_dir[EMPTY_DIR_SIZE];
18058c2ecf20Sopenharmony_ci	char *body = empty_dir;
18068c2ecf20Sopenharmony_ci	struct cpu_key key;
18078c2ecf20Sopenharmony_ci	int retval;
18088c2ecf20Sopenharmony_ci
18098c2ecf20Sopenharmony_ci	BUG_ON(!th->t_trans_id);
18108c2ecf20Sopenharmony_ci
18118c2ecf20Sopenharmony_ci	_make_cpu_key(&key, KEY_FORMAT_3_5, le32_to_cpu(ih->ih_key.k_dir_id),
18128c2ecf20Sopenharmony_ci		      le32_to_cpu(ih->ih_key.k_objectid), DOT_OFFSET,
18138c2ecf20Sopenharmony_ci		      TYPE_DIRENTRY, 3 /*key length */ );
18148c2ecf20Sopenharmony_ci
18158c2ecf20Sopenharmony_ci	/*
18168c2ecf20Sopenharmony_ci	 * compose item head for new item. Directories consist of items of
18178c2ecf20Sopenharmony_ci	 * old type (ITEM_VERSION_1). Do not set key (second arg is 0), it
18188c2ecf20Sopenharmony_ci	 * is done by reiserfs_new_inode
18198c2ecf20Sopenharmony_ci	 */
18208c2ecf20Sopenharmony_ci	if (old_format_only(sb)) {
18218c2ecf20Sopenharmony_ci		make_le_item_head(ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET,
18228c2ecf20Sopenharmony_ci				  TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
18238c2ecf20Sopenharmony_ci
18248c2ecf20Sopenharmony_ci		make_empty_dir_item_v1(body, ih->ih_key.k_dir_id,
18258c2ecf20Sopenharmony_ci				       ih->ih_key.k_objectid,
18268c2ecf20Sopenharmony_ci				       INODE_PKEY(dir)->k_dir_id,
18278c2ecf20Sopenharmony_ci				       INODE_PKEY(dir)->k_objectid);
18288c2ecf20Sopenharmony_ci	} else {
18298c2ecf20Sopenharmony_ci		make_le_item_head(ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET,
18308c2ecf20Sopenharmony_ci				  TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
18318c2ecf20Sopenharmony_ci
18328c2ecf20Sopenharmony_ci		make_empty_dir_item(body, ih->ih_key.k_dir_id,
18338c2ecf20Sopenharmony_ci				    ih->ih_key.k_objectid,
18348c2ecf20Sopenharmony_ci				    INODE_PKEY(dir)->k_dir_id,
18358c2ecf20Sopenharmony_ci				    INODE_PKEY(dir)->k_objectid);
18368c2ecf20Sopenharmony_ci	}
18378c2ecf20Sopenharmony_ci
18388c2ecf20Sopenharmony_ci	/* look for place in the tree for new item */
18398c2ecf20Sopenharmony_ci	retval = search_item(sb, &key, path);
18408c2ecf20Sopenharmony_ci	if (retval == IO_ERROR) {
18418c2ecf20Sopenharmony_ci		reiserfs_error(sb, "vs-13080",
18428c2ecf20Sopenharmony_ci			       "i/o failure occurred creating new directory");
18438c2ecf20Sopenharmony_ci		return -EIO;
18448c2ecf20Sopenharmony_ci	}
18458c2ecf20Sopenharmony_ci	if (retval == ITEM_FOUND) {
18468c2ecf20Sopenharmony_ci		pathrelse(path);
18478c2ecf20Sopenharmony_ci		reiserfs_warning(sb, "vs-13070",
18488c2ecf20Sopenharmony_ci				 "object with this key exists (%k)",
18498c2ecf20Sopenharmony_ci				 &(ih->ih_key));
18508c2ecf20Sopenharmony_ci		return -EEXIST;
18518c2ecf20Sopenharmony_ci	}
18528c2ecf20Sopenharmony_ci
18538c2ecf20Sopenharmony_ci	/* insert item, that is empty directory item */
18548c2ecf20Sopenharmony_ci	return reiserfs_insert_item(th, path, &key, ih, inode, body);
18558c2ecf20Sopenharmony_ci}
18568c2ecf20Sopenharmony_ci
18578c2ecf20Sopenharmony_ci/*
18588c2ecf20Sopenharmony_ci * stat data of object has been inserted, this inserts the item
18598c2ecf20Sopenharmony_ci * containing the body of symlink
18608c2ecf20Sopenharmony_ci */
18618c2ecf20Sopenharmony_cistatic int reiserfs_new_symlink(struct reiserfs_transaction_handle *th,
18628c2ecf20Sopenharmony_ci				struct inode *inode,
18638c2ecf20Sopenharmony_ci				struct item_head *ih,
18648c2ecf20Sopenharmony_ci				struct treepath *path, const char *symname,
18658c2ecf20Sopenharmony_ci				int item_len)
18668c2ecf20Sopenharmony_ci{
18678c2ecf20Sopenharmony_ci	struct super_block *sb = th->t_super;
18688c2ecf20Sopenharmony_ci	struct cpu_key key;
18698c2ecf20Sopenharmony_ci	int retval;
18708c2ecf20Sopenharmony_ci
18718c2ecf20Sopenharmony_ci	BUG_ON(!th->t_trans_id);
18728c2ecf20Sopenharmony_ci
18738c2ecf20Sopenharmony_ci	_make_cpu_key(&key, KEY_FORMAT_3_5,
18748c2ecf20Sopenharmony_ci		      le32_to_cpu(ih->ih_key.k_dir_id),
18758c2ecf20Sopenharmony_ci		      le32_to_cpu(ih->ih_key.k_objectid),
18768c2ecf20Sopenharmony_ci		      1, TYPE_DIRECT, 3 /*key length */ );
18778c2ecf20Sopenharmony_ci
18788c2ecf20Sopenharmony_ci	make_le_item_head(ih, NULL, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len,
18798c2ecf20Sopenharmony_ci			  0 /*free_space */ );
18808c2ecf20Sopenharmony_ci
18818c2ecf20Sopenharmony_ci	/* look for place in the tree for new item */
18828c2ecf20Sopenharmony_ci	retval = search_item(sb, &key, path);
18838c2ecf20Sopenharmony_ci	if (retval == IO_ERROR) {
18848c2ecf20Sopenharmony_ci		reiserfs_error(sb, "vs-13080",
18858c2ecf20Sopenharmony_ci			       "i/o failure occurred creating new symlink");
18868c2ecf20Sopenharmony_ci		return -EIO;
18878c2ecf20Sopenharmony_ci	}
18888c2ecf20Sopenharmony_ci	if (retval == ITEM_FOUND) {
18898c2ecf20Sopenharmony_ci		pathrelse(path);
18908c2ecf20Sopenharmony_ci		reiserfs_warning(sb, "vs-13080",
18918c2ecf20Sopenharmony_ci				 "object with this key exists (%k)",
18928c2ecf20Sopenharmony_ci				 &(ih->ih_key));
18938c2ecf20Sopenharmony_ci		return -EEXIST;
18948c2ecf20Sopenharmony_ci	}
18958c2ecf20Sopenharmony_ci
18968c2ecf20Sopenharmony_ci	/* insert item, that is body of symlink */
18978c2ecf20Sopenharmony_ci	return reiserfs_insert_item(th, path, &key, ih, inode, symname);
18988c2ecf20Sopenharmony_ci}
18998c2ecf20Sopenharmony_ci
19008c2ecf20Sopenharmony_ci/*
19018c2ecf20Sopenharmony_ci * inserts the stat data into the tree, and then calls
19028c2ecf20Sopenharmony_ci * reiserfs_new_directory (to insert ".", ".." item if new object is
19038c2ecf20Sopenharmony_ci * directory) or reiserfs_new_symlink (to insert symlink body if new
19048c2ecf20Sopenharmony_ci * object is symlink) or nothing (if new object is regular file)
19058c2ecf20Sopenharmony_ci
19068c2ecf20Sopenharmony_ci * NOTE! uid and gid must already be set in the inode.  If we return
19078c2ecf20Sopenharmony_ci * non-zero due to an error, we have to drop the quota previously allocated
19088c2ecf20Sopenharmony_ci * for the fresh inode.  This can only be done outside a transaction, so
19098c2ecf20Sopenharmony_ci * if we return non-zero, we also end the transaction.
19108c2ecf20Sopenharmony_ci *
19118c2ecf20Sopenharmony_ci * @th: active transaction handle
19128c2ecf20Sopenharmony_ci * @dir: parent directory for new inode
19138c2ecf20Sopenharmony_ci * @mode: mode of new inode
19148c2ecf20Sopenharmony_ci * @symname: symlink contents if inode is symlink
19158c2ecf20Sopenharmony_ci * @isize: 0 for regular file, EMPTY_DIR_SIZE for dirs, strlen(symname) for
19168c2ecf20Sopenharmony_ci *         symlinks
19178c2ecf20Sopenharmony_ci * @inode: inode to be filled
19188c2ecf20Sopenharmony_ci * @security: optional security context to associate with this inode
19198c2ecf20Sopenharmony_ci */
19208c2ecf20Sopenharmony_ciint reiserfs_new_inode(struct reiserfs_transaction_handle *th,
19218c2ecf20Sopenharmony_ci		       struct inode *dir, umode_t mode, const char *symname,
19228c2ecf20Sopenharmony_ci		       /* 0 for regular, EMTRY_DIR_SIZE for dirs,
19238c2ecf20Sopenharmony_ci		          strlen (symname) for symlinks) */
19248c2ecf20Sopenharmony_ci		       loff_t i_size, struct dentry *dentry,
19258c2ecf20Sopenharmony_ci		       struct inode *inode,
19268c2ecf20Sopenharmony_ci		       struct reiserfs_security_handle *security)
19278c2ecf20Sopenharmony_ci{
19288c2ecf20Sopenharmony_ci	struct super_block *sb = dir->i_sb;
19298c2ecf20Sopenharmony_ci	struct reiserfs_iget_args args;
19308c2ecf20Sopenharmony_ci	INITIALIZE_PATH(path_to_key);
19318c2ecf20Sopenharmony_ci	struct cpu_key key;
19328c2ecf20Sopenharmony_ci	struct item_head ih;
19338c2ecf20Sopenharmony_ci	struct stat_data sd;
19348c2ecf20Sopenharmony_ci	int retval;
19358c2ecf20Sopenharmony_ci	int err;
19368c2ecf20Sopenharmony_ci	int depth;
19378c2ecf20Sopenharmony_ci
19388c2ecf20Sopenharmony_ci	BUG_ON(!th->t_trans_id);
19398c2ecf20Sopenharmony_ci
19408c2ecf20Sopenharmony_ci	depth = reiserfs_write_unlock_nested(sb);
19418c2ecf20Sopenharmony_ci	err = dquot_alloc_inode(inode);
19428c2ecf20Sopenharmony_ci	reiserfs_write_lock_nested(sb, depth);
19438c2ecf20Sopenharmony_ci	if (err)
19448c2ecf20Sopenharmony_ci		goto out_end_trans;
19458c2ecf20Sopenharmony_ci	if (!dir->i_nlink) {
19468c2ecf20Sopenharmony_ci		err = -EPERM;
19478c2ecf20Sopenharmony_ci		goto out_bad_inode;
19488c2ecf20Sopenharmony_ci	}
19498c2ecf20Sopenharmony_ci
19508c2ecf20Sopenharmony_ci	/* item head of new item */
19518c2ecf20Sopenharmony_ci	ih.ih_key.k_dir_id = reiserfs_choose_packing(dir);
19528c2ecf20Sopenharmony_ci	ih.ih_key.k_objectid = cpu_to_le32(reiserfs_get_unused_objectid(th));
19538c2ecf20Sopenharmony_ci	if (!ih.ih_key.k_objectid) {
19548c2ecf20Sopenharmony_ci		err = -ENOMEM;
19558c2ecf20Sopenharmony_ci		goto out_bad_inode;
19568c2ecf20Sopenharmony_ci	}
19578c2ecf20Sopenharmony_ci	args.objectid = inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid);
19588c2ecf20Sopenharmony_ci	if (old_format_only(sb))
19598c2ecf20Sopenharmony_ci		make_le_item_head(&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET,
19608c2ecf20Sopenharmony_ci				  TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
19618c2ecf20Sopenharmony_ci	else
19628c2ecf20Sopenharmony_ci		make_le_item_head(&ih, NULL, KEY_FORMAT_3_6, SD_OFFSET,
19638c2ecf20Sopenharmony_ci				  TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);
19648c2ecf20Sopenharmony_ci	memcpy(INODE_PKEY(inode), &ih.ih_key, KEY_SIZE);
19658c2ecf20Sopenharmony_ci	args.dirid = le32_to_cpu(ih.ih_key.k_dir_id);
19668c2ecf20Sopenharmony_ci
19678c2ecf20Sopenharmony_ci	depth = reiserfs_write_unlock_nested(inode->i_sb);
19688c2ecf20Sopenharmony_ci	err = insert_inode_locked4(inode, args.objectid,
19698c2ecf20Sopenharmony_ci			     reiserfs_find_actor, &args);
19708c2ecf20Sopenharmony_ci	reiserfs_write_lock_nested(inode->i_sb, depth);
19718c2ecf20Sopenharmony_ci	if (err) {
19728c2ecf20Sopenharmony_ci		err = -EINVAL;
19738c2ecf20Sopenharmony_ci		goto out_bad_inode;
19748c2ecf20Sopenharmony_ci	}
19758c2ecf20Sopenharmony_ci
19768c2ecf20Sopenharmony_ci	if (old_format_only(sb))
19778c2ecf20Sopenharmony_ci		/*
19788c2ecf20Sopenharmony_ci		 * not a perfect generation count, as object ids can be reused,
19798c2ecf20Sopenharmony_ci		 * but this is as good as reiserfs can do right now.
19808c2ecf20Sopenharmony_ci		 * note that the private part of inode isn't filled in yet,
19818c2ecf20Sopenharmony_ci		 * we have to use the directory.
19828c2ecf20Sopenharmony_ci		 */
19838c2ecf20Sopenharmony_ci		inode->i_generation = le32_to_cpu(INODE_PKEY(dir)->k_objectid);
19848c2ecf20Sopenharmony_ci	else
19858c2ecf20Sopenharmony_ci#if defined( USE_INODE_GENERATION_COUNTER )
19868c2ecf20Sopenharmony_ci		inode->i_generation =
19878c2ecf20Sopenharmony_ci		    le32_to_cpu(REISERFS_SB(sb)->s_rs->s_inode_generation);
19888c2ecf20Sopenharmony_ci#else
19898c2ecf20Sopenharmony_ci		inode->i_generation = ++event;
19908c2ecf20Sopenharmony_ci#endif
19918c2ecf20Sopenharmony_ci
19928c2ecf20Sopenharmony_ci	/* fill stat data */
19938c2ecf20Sopenharmony_ci	set_nlink(inode, (S_ISDIR(mode) ? 2 : 1));
19948c2ecf20Sopenharmony_ci
19958c2ecf20Sopenharmony_ci	/* uid and gid must already be set by the caller for quota init */
19968c2ecf20Sopenharmony_ci
19978c2ecf20Sopenharmony_ci	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
19988c2ecf20Sopenharmony_ci	inode->i_size = i_size;
19998c2ecf20Sopenharmony_ci	inode->i_blocks = 0;
20008c2ecf20Sopenharmony_ci	inode->i_bytes = 0;
20018c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_first_direct_byte = S_ISLNK(mode) ? 1 :
20028c2ecf20Sopenharmony_ci	    U32_MAX /*NO_BYTES_IN_DIRECT_ITEM */ ;
20038c2ecf20Sopenharmony_ci
20048c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&REISERFS_I(inode)->i_prealloc_list);
20058c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_flags = 0;
20068c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_prealloc_block = 0;
20078c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_prealloc_count = 0;
20088c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_trans_id = 0;
20098c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_jl = NULL;
20108c2ecf20Sopenharmony_ci	REISERFS_I(inode)->i_attrs =
20118c2ecf20Sopenharmony_ci	    REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
20128c2ecf20Sopenharmony_ci	sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
20138c2ecf20Sopenharmony_ci	reiserfs_init_xattr_rwsem(inode);
20148c2ecf20Sopenharmony_ci
20158c2ecf20Sopenharmony_ci	/* key to search for correct place for new stat data */
20168c2ecf20Sopenharmony_ci	_make_cpu_key(&key, KEY_FORMAT_3_6, le32_to_cpu(ih.ih_key.k_dir_id),
20178c2ecf20Sopenharmony_ci		      le32_to_cpu(ih.ih_key.k_objectid), SD_OFFSET,
20188c2ecf20Sopenharmony_ci		      TYPE_STAT_DATA, 3 /*key length */ );
20198c2ecf20Sopenharmony_ci
20208c2ecf20Sopenharmony_ci	/* find proper place for inserting of stat data */
20218c2ecf20Sopenharmony_ci	retval = search_item(sb, &key, &path_to_key);
20228c2ecf20Sopenharmony_ci	if (retval == IO_ERROR) {
20238c2ecf20Sopenharmony_ci		err = -EIO;
20248c2ecf20Sopenharmony_ci		goto out_bad_inode;
20258c2ecf20Sopenharmony_ci	}
20268c2ecf20Sopenharmony_ci	if (retval == ITEM_FOUND) {
20278c2ecf20Sopenharmony_ci		pathrelse(&path_to_key);
20288c2ecf20Sopenharmony_ci		err = -EEXIST;
20298c2ecf20Sopenharmony_ci		goto out_bad_inode;
20308c2ecf20Sopenharmony_ci	}
20318c2ecf20Sopenharmony_ci	if (old_format_only(sb)) {
20328c2ecf20Sopenharmony_ci		/* i_uid or i_gid is too big to be stored in stat data v3.5 */
20338c2ecf20Sopenharmony_ci		if (i_uid_read(inode) & ~0xffff || i_gid_read(inode) & ~0xffff) {
20348c2ecf20Sopenharmony_ci			pathrelse(&path_to_key);
20358c2ecf20Sopenharmony_ci			err = -EINVAL;
20368c2ecf20Sopenharmony_ci			goto out_bad_inode;
20378c2ecf20Sopenharmony_ci		}
20388c2ecf20Sopenharmony_ci		inode2sd_v1(&sd, inode, inode->i_size);
20398c2ecf20Sopenharmony_ci	} else {
20408c2ecf20Sopenharmony_ci		inode2sd(&sd, inode, inode->i_size);
20418c2ecf20Sopenharmony_ci	}
20428c2ecf20Sopenharmony_ci	/*
20438c2ecf20Sopenharmony_ci	 * store in in-core inode the key of stat data and version all
20448c2ecf20Sopenharmony_ci	 * object items will have (directory items will have old offset
20458c2ecf20Sopenharmony_ci	 * format, other new objects will consist of new items)
20468c2ecf20Sopenharmony_ci	 */
20478c2ecf20Sopenharmony_ci	if (old_format_only(sb) || S_ISDIR(mode) || S_ISLNK(mode))
20488c2ecf20Sopenharmony_ci		set_inode_item_key_version(inode, KEY_FORMAT_3_5);
20498c2ecf20Sopenharmony_ci	else
20508c2ecf20Sopenharmony_ci		set_inode_item_key_version(inode, KEY_FORMAT_3_6);
20518c2ecf20Sopenharmony_ci	if (old_format_only(sb))
20528c2ecf20Sopenharmony_ci		set_inode_sd_version(inode, STAT_DATA_V1);
20538c2ecf20Sopenharmony_ci	else
20548c2ecf20Sopenharmony_ci		set_inode_sd_version(inode, STAT_DATA_V2);
20558c2ecf20Sopenharmony_ci
20568c2ecf20Sopenharmony_ci	/* insert the stat data into the tree */
20578c2ecf20Sopenharmony_ci#ifdef DISPLACE_NEW_PACKING_LOCALITIES
20588c2ecf20Sopenharmony_ci	if (REISERFS_I(dir)->new_packing_locality)
20598c2ecf20Sopenharmony_ci		th->displace_new_blocks = 1;
20608c2ecf20Sopenharmony_ci#endif
20618c2ecf20Sopenharmony_ci	retval =
20628c2ecf20Sopenharmony_ci	    reiserfs_insert_item(th, &path_to_key, &key, &ih, inode,
20638c2ecf20Sopenharmony_ci				 (char *)(&sd));
20648c2ecf20Sopenharmony_ci	if (retval) {
20658c2ecf20Sopenharmony_ci		err = retval;
20668c2ecf20Sopenharmony_ci		reiserfs_check_path(&path_to_key);
20678c2ecf20Sopenharmony_ci		goto out_bad_inode;
20688c2ecf20Sopenharmony_ci	}
20698c2ecf20Sopenharmony_ci#ifdef DISPLACE_NEW_PACKING_LOCALITIES
20708c2ecf20Sopenharmony_ci	if (!th->displace_new_blocks)
20718c2ecf20Sopenharmony_ci		REISERFS_I(dir)->new_packing_locality = 0;
20728c2ecf20Sopenharmony_ci#endif
20738c2ecf20Sopenharmony_ci	if (S_ISDIR(mode)) {
20748c2ecf20Sopenharmony_ci		/* insert item with "." and ".." */
20758c2ecf20Sopenharmony_ci		retval =
20768c2ecf20Sopenharmony_ci		    reiserfs_new_directory(th, inode, &ih, &path_to_key, dir);
20778c2ecf20Sopenharmony_ci	}
20788c2ecf20Sopenharmony_ci
20798c2ecf20Sopenharmony_ci	if (S_ISLNK(mode)) {
20808c2ecf20Sopenharmony_ci		/* insert body of symlink */
20818c2ecf20Sopenharmony_ci		if (!old_format_only(sb))
20828c2ecf20Sopenharmony_ci			i_size = ROUND_UP(i_size);
20838c2ecf20Sopenharmony_ci		retval =
20848c2ecf20Sopenharmony_ci		    reiserfs_new_symlink(th, inode, &ih, &path_to_key, symname,
20858c2ecf20Sopenharmony_ci					 i_size);
20868c2ecf20Sopenharmony_ci	}
20878c2ecf20Sopenharmony_ci	if (retval) {
20888c2ecf20Sopenharmony_ci		err = retval;
20898c2ecf20Sopenharmony_ci		reiserfs_check_path(&path_to_key);
20908c2ecf20Sopenharmony_ci		journal_end(th);
20918c2ecf20Sopenharmony_ci		goto out_inserted_sd;
20928c2ecf20Sopenharmony_ci	}
20938c2ecf20Sopenharmony_ci
20948c2ecf20Sopenharmony_ci	/*
20958c2ecf20Sopenharmony_ci	 * Mark it private if we're creating the privroot
20968c2ecf20Sopenharmony_ci	 * or something under it.
20978c2ecf20Sopenharmony_ci	 */
20988c2ecf20Sopenharmony_ci	if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) {
20998c2ecf20Sopenharmony_ci		inode->i_flags |= S_PRIVATE;
21008c2ecf20Sopenharmony_ci		inode->i_opflags &= ~IOP_XATTR;
21018c2ecf20Sopenharmony_ci	}
21028c2ecf20Sopenharmony_ci
21038c2ecf20Sopenharmony_ci	if (reiserfs_posixacl(inode->i_sb)) {
21048c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
21058c2ecf20Sopenharmony_ci		retval = reiserfs_inherit_default_acl(th, dir, dentry, inode);
21068c2ecf20Sopenharmony_ci		reiserfs_write_lock(inode->i_sb);
21078c2ecf20Sopenharmony_ci		if (retval) {
21088c2ecf20Sopenharmony_ci			err = retval;
21098c2ecf20Sopenharmony_ci			reiserfs_check_path(&path_to_key);
21108c2ecf20Sopenharmony_ci			journal_end(th);
21118c2ecf20Sopenharmony_ci			goto out_inserted_sd;
21128c2ecf20Sopenharmony_ci		}
21138c2ecf20Sopenharmony_ci	} else if (inode->i_sb->s_flags & SB_POSIXACL) {
21148c2ecf20Sopenharmony_ci		reiserfs_warning(inode->i_sb, "jdm-13090",
21158c2ecf20Sopenharmony_ci				 "ACLs aren't enabled in the fs, "
21168c2ecf20Sopenharmony_ci				 "but vfs thinks they are!");
21178c2ecf20Sopenharmony_ci	}
21188c2ecf20Sopenharmony_ci
21198c2ecf20Sopenharmony_ci	if (security->name) {
21208c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
21218c2ecf20Sopenharmony_ci		retval = reiserfs_security_write(th, inode, security);
21228c2ecf20Sopenharmony_ci		reiserfs_write_lock(inode->i_sb);
21238c2ecf20Sopenharmony_ci		if (retval) {
21248c2ecf20Sopenharmony_ci			err = retval;
21258c2ecf20Sopenharmony_ci			reiserfs_check_path(&path_to_key);
21268c2ecf20Sopenharmony_ci			retval = journal_end(th);
21278c2ecf20Sopenharmony_ci			if (retval)
21288c2ecf20Sopenharmony_ci				err = retval;
21298c2ecf20Sopenharmony_ci			goto out_inserted_sd;
21308c2ecf20Sopenharmony_ci		}
21318c2ecf20Sopenharmony_ci	}
21328c2ecf20Sopenharmony_ci
21338c2ecf20Sopenharmony_ci	reiserfs_update_sd(th, inode);
21348c2ecf20Sopenharmony_ci	reiserfs_check_path(&path_to_key);
21358c2ecf20Sopenharmony_ci
21368c2ecf20Sopenharmony_ci	return 0;
21378c2ecf20Sopenharmony_ci
21388c2ecf20Sopenharmony_ciout_bad_inode:
21398c2ecf20Sopenharmony_ci	/* Invalidate the object, nothing was inserted yet */
21408c2ecf20Sopenharmony_ci	INODE_PKEY(inode)->k_objectid = 0;
21418c2ecf20Sopenharmony_ci
21428c2ecf20Sopenharmony_ci	/* Quota change must be inside a transaction for journaling */
21438c2ecf20Sopenharmony_ci	depth = reiserfs_write_unlock_nested(inode->i_sb);
21448c2ecf20Sopenharmony_ci	dquot_free_inode(inode);
21458c2ecf20Sopenharmony_ci	reiserfs_write_lock_nested(inode->i_sb, depth);
21468c2ecf20Sopenharmony_ci
21478c2ecf20Sopenharmony_ciout_end_trans:
21488c2ecf20Sopenharmony_ci	journal_end(th);
21498c2ecf20Sopenharmony_ci	/*
21508c2ecf20Sopenharmony_ci	 * Drop can be outside and it needs more credits so it's better
21518c2ecf20Sopenharmony_ci	 * to have it outside
21528c2ecf20Sopenharmony_ci	 */
21538c2ecf20Sopenharmony_ci	depth = reiserfs_write_unlock_nested(inode->i_sb);
21548c2ecf20Sopenharmony_ci	dquot_drop(inode);
21558c2ecf20Sopenharmony_ci	reiserfs_write_lock_nested(inode->i_sb, depth);
21568c2ecf20Sopenharmony_ci	inode->i_flags |= S_NOQUOTA;
21578c2ecf20Sopenharmony_ci	make_bad_inode(inode);
21588c2ecf20Sopenharmony_ci
21598c2ecf20Sopenharmony_ciout_inserted_sd:
21608c2ecf20Sopenharmony_ci	clear_nlink(inode);
21618c2ecf20Sopenharmony_ci	th->t_trans_id = 0;	/* so the caller can't use this handle later */
21628c2ecf20Sopenharmony_ci	if (inode->i_state & I_NEW)
21638c2ecf20Sopenharmony_ci		unlock_new_inode(inode);
21648c2ecf20Sopenharmony_ci	iput(inode);
21658c2ecf20Sopenharmony_ci	return err;
21668c2ecf20Sopenharmony_ci}
21678c2ecf20Sopenharmony_ci
21688c2ecf20Sopenharmony_ci/*
21698c2ecf20Sopenharmony_ci * finds the tail page in the page cache,
21708c2ecf20Sopenharmony_ci * reads the last block in.
21718c2ecf20Sopenharmony_ci *
21728c2ecf20Sopenharmony_ci * On success, page_result is set to a locked, pinned page, and bh_result
21738c2ecf20Sopenharmony_ci * is set to an up to date buffer for the last block in the file.  returns 0.
21748c2ecf20Sopenharmony_ci *
21758c2ecf20Sopenharmony_ci * tail conversion is not done, so bh_result might not be valid for writing
21768c2ecf20Sopenharmony_ci * check buffer_mapped(bh_result) and bh_result->b_blocknr != 0 before
21778c2ecf20Sopenharmony_ci * trying to write the block.
21788c2ecf20Sopenharmony_ci *
21798c2ecf20Sopenharmony_ci * on failure, nonzero is returned, page_result and bh_result are untouched.
21808c2ecf20Sopenharmony_ci */
21818c2ecf20Sopenharmony_cistatic int grab_tail_page(struct inode *inode,
21828c2ecf20Sopenharmony_ci			  struct page **page_result,
21838c2ecf20Sopenharmony_ci			  struct buffer_head **bh_result)
21848c2ecf20Sopenharmony_ci{
21858c2ecf20Sopenharmony_ci
21868c2ecf20Sopenharmony_ci	/*
21878c2ecf20Sopenharmony_ci	 * we want the page with the last byte in the file,
21888c2ecf20Sopenharmony_ci	 * not the page that will hold the next byte for appending
21898c2ecf20Sopenharmony_ci	 */
21908c2ecf20Sopenharmony_ci	unsigned long index = (inode->i_size - 1) >> PAGE_SHIFT;
21918c2ecf20Sopenharmony_ci	unsigned long pos = 0;
21928c2ecf20Sopenharmony_ci	unsigned long start = 0;
21938c2ecf20Sopenharmony_ci	unsigned long blocksize = inode->i_sb->s_blocksize;
21948c2ecf20Sopenharmony_ci	unsigned long offset = (inode->i_size) & (PAGE_SIZE - 1);
21958c2ecf20Sopenharmony_ci	struct buffer_head *bh;
21968c2ecf20Sopenharmony_ci	struct buffer_head *head;
21978c2ecf20Sopenharmony_ci	struct page *page;
21988c2ecf20Sopenharmony_ci	int error;
21998c2ecf20Sopenharmony_ci
22008c2ecf20Sopenharmony_ci	/*
22018c2ecf20Sopenharmony_ci	 * we know that we are only called with inode->i_size > 0.
22028c2ecf20Sopenharmony_ci	 * we also know that a file tail can never be as big as a block
22038c2ecf20Sopenharmony_ci	 * If i_size % blocksize == 0, our file is currently block aligned
22048c2ecf20Sopenharmony_ci	 * and it won't need converting or zeroing after a truncate.
22058c2ecf20Sopenharmony_ci	 */
22068c2ecf20Sopenharmony_ci	if ((offset & (blocksize - 1)) == 0) {
22078c2ecf20Sopenharmony_ci		return -ENOENT;
22088c2ecf20Sopenharmony_ci	}
22098c2ecf20Sopenharmony_ci	page = grab_cache_page(inode->i_mapping, index);
22108c2ecf20Sopenharmony_ci	error = -ENOMEM;
22118c2ecf20Sopenharmony_ci	if (!page) {
22128c2ecf20Sopenharmony_ci		goto out;
22138c2ecf20Sopenharmony_ci	}
22148c2ecf20Sopenharmony_ci	/* start within the page of the last block in the file */
22158c2ecf20Sopenharmony_ci	start = (offset / blocksize) * blocksize;
22168c2ecf20Sopenharmony_ci
22178c2ecf20Sopenharmony_ci	error = __block_write_begin(page, start, offset - start,
22188c2ecf20Sopenharmony_ci				    reiserfs_get_block_create_0);
22198c2ecf20Sopenharmony_ci	if (error)
22208c2ecf20Sopenharmony_ci		goto unlock;
22218c2ecf20Sopenharmony_ci
22228c2ecf20Sopenharmony_ci	head = page_buffers(page);
22238c2ecf20Sopenharmony_ci	bh = head;
22248c2ecf20Sopenharmony_ci	do {
22258c2ecf20Sopenharmony_ci		if (pos >= start) {
22268c2ecf20Sopenharmony_ci			break;
22278c2ecf20Sopenharmony_ci		}
22288c2ecf20Sopenharmony_ci		bh = bh->b_this_page;
22298c2ecf20Sopenharmony_ci		pos += blocksize;
22308c2ecf20Sopenharmony_ci	} while (bh != head);
22318c2ecf20Sopenharmony_ci
22328c2ecf20Sopenharmony_ci	if (!buffer_uptodate(bh)) {
22338c2ecf20Sopenharmony_ci		/*
22348c2ecf20Sopenharmony_ci		 * note, this should never happen, prepare_write should be
22358c2ecf20Sopenharmony_ci		 * taking care of this for us.  If the buffer isn't up to
22368c2ecf20Sopenharmony_ci		 * date, I've screwed up the code to find the buffer, or the
22378c2ecf20Sopenharmony_ci		 * code to call prepare_write
22388c2ecf20Sopenharmony_ci		 */
22398c2ecf20Sopenharmony_ci		reiserfs_error(inode->i_sb, "clm-6000",
22408c2ecf20Sopenharmony_ci			       "error reading block %lu", bh->b_blocknr);
22418c2ecf20Sopenharmony_ci		error = -EIO;
22428c2ecf20Sopenharmony_ci		goto unlock;
22438c2ecf20Sopenharmony_ci	}
22448c2ecf20Sopenharmony_ci	*bh_result = bh;
22458c2ecf20Sopenharmony_ci	*page_result = page;
22468c2ecf20Sopenharmony_ci
22478c2ecf20Sopenharmony_ciout:
22488c2ecf20Sopenharmony_ci	return error;
22498c2ecf20Sopenharmony_ci
22508c2ecf20Sopenharmony_ciunlock:
22518c2ecf20Sopenharmony_ci	unlock_page(page);
22528c2ecf20Sopenharmony_ci	put_page(page);
22538c2ecf20Sopenharmony_ci	return error;
22548c2ecf20Sopenharmony_ci}
22558c2ecf20Sopenharmony_ci
22568c2ecf20Sopenharmony_ci/*
22578c2ecf20Sopenharmony_ci * vfs version of truncate file.  Must NOT be called with
22588c2ecf20Sopenharmony_ci * a transaction already started.
22598c2ecf20Sopenharmony_ci *
22608c2ecf20Sopenharmony_ci * some code taken from block_truncate_page
22618c2ecf20Sopenharmony_ci */
22628c2ecf20Sopenharmony_ciint reiserfs_truncate_file(struct inode *inode, int update_timestamps)
22638c2ecf20Sopenharmony_ci{
22648c2ecf20Sopenharmony_ci	struct reiserfs_transaction_handle th;
22658c2ecf20Sopenharmony_ci	/* we want the offset for the first byte after the end of the file */
22668c2ecf20Sopenharmony_ci	unsigned long offset = inode->i_size & (PAGE_SIZE - 1);
22678c2ecf20Sopenharmony_ci	unsigned blocksize = inode->i_sb->s_blocksize;
22688c2ecf20Sopenharmony_ci	unsigned length;
22698c2ecf20Sopenharmony_ci	struct page *page = NULL;
22708c2ecf20Sopenharmony_ci	int error;
22718c2ecf20Sopenharmony_ci	struct buffer_head *bh = NULL;
22728c2ecf20Sopenharmony_ci	int err2;
22738c2ecf20Sopenharmony_ci
22748c2ecf20Sopenharmony_ci	reiserfs_write_lock(inode->i_sb);
22758c2ecf20Sopenharmony_ci
22768c2ecf20Sopenharmony_ci	if (inode->i_size > 0) {
22778c2ecf20Sopenharmony_ci		error = grab_tail_page(inode, &page, &bh);
22788c2ecf20Sopenharmony_ci		if (error) {
22798c2ecf20Sopenharmony_ci			/*
22808c2ecf20Sopenharmony_ci			 * -ENOENT means we truncated past the end of the
22818c2ecf20Sopenharmony_ci			 * file, and get_block_create_0 could not find a
22828c2ecf20Sopenharmony_ci			 * block to read in, which is ok.
22838c2ecf20Sopenharmony_ci			 */
22848c2ecf20Sopenharmony_ci			if (error != -ENOENT)
22858c2ecf20Sopenharmony_ci				reiserfs_error(inode->i_sb, "clm-6001",
22868c2ecf20Sopenharmony_ci					       "grab_tail_page failed %d",
22878c2ecf20Sopenharmony_ci					       error);
22888c2ecf20Sopenharmony_ci			page = NULL;
22898c2ecf20Sopenharmony_ci			bh = NULL;
22908c2ecf20Sopenharmony_ci		}
22918c2ecf20Sopenharmony_ci	}
22928c2ecf20Sopenharmony_ci
22938c2ecf20Sopenharmony_ci	/*
22948c2ecf20Sopenharmony_ci	 * so, if page != NULL, we have a buffer head for the offset at
22958c2ecf20Sopenharmony_ci	 * the end of the file. if the bh is mapped, and bh->b_blocknr != 0,
22968c2ecf20Sopenharmony_ci	 * then we have an unformatted node.  Otherwise, we have a direct item,
22978c2ecf20Sopenharmony_ci	 * and no zeroing is required on disk.  We zero after the truncate,
22988c2ecf20Sopenharmony_ci	 * because the truncate might pack the item anyway
22998c2ecf20Sopenharmony_ci	 * (it will unmap bh if it packs).
23008c2ecf20Sopenharmony_ci	 *
23018c2ecf20Sopenharmony_ci	 * it is enough to reserve space in transaction for 2 balancings:
23028c2ecf20Sopenharmony_ci	 * one for "save" link adding and another for the first
23038c2ecf20Sopenharmony_ci	 * cut_from_item. 1 is for update_sd
23048c2ecf20Sopenharmony_ci	 */
23058c2ecf20Sopenharmony_ci	error = journal_begin(&th, inode->i_sb,
23068c2ecf20Sopenharmony_ci			      JOURNAL_PER_BALANCE_CNT * 2 + 1);
23078c2ecf20Sopenharmony_ci	if (error)
23088c2ecf20Sopenharmony_ci		goto out;
23098c2ecf20Sopenharmony_ci	reiserfs_update_inode_transaction(inode);
23108c2ecf20Sopenharmony_ci	if (update_timestamps)
23118c2ecf20Sopenharmony_ci		/*
23128c2ecf20Sopenharmony_ci		 * we are doing real truncate: if the system crashes
23138c2ecf20Sopenharmony_ci		 * before the last transaction of truncating gets committed
23148c2ecf20Sopenharmony_ci		 * - on reboot the file either appears truncated properly
23158c2ecf20Sopenharmony_ci		 * or not truncated at all
23168c2ecf20Sopenharmony_ci		 */
23178c2ecf20Sopenharmony_ci		add_save_link(&th, inode, 1);
23188c2ecf20Sopenharmony_ci	err2 = reiserfs_do_truncate(&th, inode, page, update_timestamps);
23198c2ecf20Sopenharmony_ci	error = journal_end(&th);
23208c2ecf20Sopenharmony_ci	if (error)
23218c2ecf20Sopenharmony_ci		goto out;
23228c2ecf20Sopenharmony_ci
23238c2ecf20Sopenharmony_ci	/* check reiserfs_do_truncate after ending the transaction */
23248c2ecf20Sopenharmony_ci	if (err2) {
23258c2ecf20Sopenharmony_ci		error = err2;
23268c2ecf20Sopenharmony_ci  		goto out;
23278c2ecf20Sopenharmony_ci	}
23288c2ecf20Sopenharmony_ci
23298c2ecf20Sopenharmony_ci	if (update_timestamps) {
23308c2ecf20Sopenharmony_ci		error = remove_save_link(inode, 1 /* truncate */);
23318c2ecf20Sopenharmony_ci		if (error)
23328c2ecf20Sopenharmony_ci			goto out;
23338c2ecf20Sopenharmony_ci	}
23348c2ecf20Sopenharmony_ci
23358c2ecf20Sopenharmony_ci	if (page) {
23368c2ecf20Sopenharmony_ci		length = offset & (blocksize - 1);
23378c2ecf20Sopenharmony_ci		/* if we are not on a block boundary */
23388c2ecf20Sopenharmony_ci		if (length) {
23398c2ecf20Sopenharmony_ci			length = blocksize - length;
23408c2ecf20Sopenharmony_ci			zero_user(page, offset, length);
23418c2ecf20Sopenharmony_ci			if (buffer_mapped(bh) && bh->b_blocknr != 0) {
23428c2ecf20Sopenharmony_ci				mark_buffer_dirty(bh);
23438c2ecf20Sopenharmony_ci			}
23448c2ecf20Sopenharmony_ci		}
23458c2ecf20Sopenharmony_ci		unlock_page(page);
23468c2ecf20Sopenharmony_ci		put_page(page);
23478c2ecf20Sopenharmony_ci	}
23488c2ecf20Sopenharmony_ci
23498c2ecf20Sopenharmony_ci	reiserfs_write_unlock(inode->i_sb);
23508c2ecf20Sopenharmony_ci
23518c2ecf20Sopenharmony_ci	return 0;
23528c2ecf20Sopenharmony_ciout:
23538c2ecf20Sopenharmony_ci	if (page) {
23548c2ecf20Sopenharmony_ci		unlock_page(page);
23558c2ecf20Sopenharmony_ci		put_page(page);
23568c2ecf20Sopenharmony_ci	}
23578c2ecf20Sopenharmony_ci
23588c2ecf20Sopenharmony_ci	reiserfs_write_unlock(inode->i_sb);
23598c2ecf20Sopenharmony_ci
23608c2ecf20Sopenharmony_ci	return error;
23618c2ecf20Sopenharmony_ci}
23628c2ecf20Sopenharmony_ci
23638c2ecf20Sopenharmony_cistatic int map_block_for_writepage(struct inode *inode,
23648c2ecf20Sopenharmony_ci				   struct buffer_head *bh_result,
23658c2ecf20Sopenharmony_ci				   unsigned long block)
23668c2ecf20Sopenharmony_ci{
23678c2ecf20Sopenharmony_ci	struct reiserfs_transaction_handle th;
23688c2ecf20Sopenharmony_ci	int fs_gen;
23698c2ecf20Sopenharmony_ci	struct item_head tmp_ih;
23708c2ecf20Sopenharmony_ci	struct item_head *ih;
23718c2ecf20Sopenharmony_ci	struct buffer_head *bh;
23728c2ecf20Sopenharmony_ci	__le32 *item;
23738c2ecf20Sopenharmony_ci	struct cpu_key key;
23748c2ecf20Sopenharmony_ci	INITIALIZE_PATH(path);
23758c2ecf20Sopenharmony_ci	int pos_in_item;
23768c2ecf20Sopenharmony_ci	int jbegin_count = JOURNAL_PER_BALANCE_CNT;
23778c2ecf20Sopenharmony_ci	loff_t byte_offset = ((loff_t)block << inode->i_sb->s_blocksize_bits)+1;
23788c2ecf20Sopenharmony_ci	int retval;
23798c2ecf20Sopenharmony_ci	int use_get_block = 0;
23808c2ecf20Sopenharmony_ci	int bytes_copied = 0;
23818c2ecf20Sopenharmony_ci	int copy_size;
23828c2ecf20Sopenharmony_ci	int trans_running = 0;
23838c2ecf20Sopenharmony_ci
23848c2ecf20Sopenharmony_ci	/*
23858c2ecf20Sopenharmony_ci	 * catch places below that try to log something without
23868c2ecf20Sopenharmony_ci	 * starting a trans
23878c2ecf20Sopenharmony_ci	 */
23888c2ecf20Sopenharmony_ci	th.t_trans_id = 0;
23898c2ecf20Sopenharmony_ci
23908c2ecf20Sopenharmony_ci	if (!buffer_uptodate(bh_result)) {
23918c2ecf20Sopenharmony_ci		return -EIO;
23928c2ecf20Sopenharmony_ci	}
23938c2ecf20Sopenharmony_ci
23948c2ecf20Sopenharmony_ci	kmap(bh_result->b_page);
23958c2ecf20Sopenharmony_cistart_over:
23968c2ecf20Sopenharmony_ci	reiserfs_write_lock(inode->i_sb);
23978c2ecf20Sopenharmony_ci	make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3);
23988c2ecf20Sopenharmony_ci
23998c2ecf20Sopenharmony_ciresearch:
24008c2ecf20Sopenharmony_ci	retval = search_for_position_by_key(inode->i_sb, &key, &path);
24018c2ecf20Sopenharmony_ci	if (retval != POSITION_FOUND) {
24028c2ecf20Sopenharmony_ci		use_get_block = 1;
24038c2ecf20Sopenharmony_ci		goto out;
24048c2ecf20Sopenharmony_ci	}
24058c2ecf20Sopenharmony_ci
24068c2ecf20Sopenharmony_ci	bh = get_last_bh(&path);
24078c2ecf20Sopenharmony_ci	ih = tp_item_head(&path);
24088c2ecf20Sopenharmony_ci	item = tp_item_body(&path);
24098c2ecf20Sopenharmony_ci	pos_in_item = path.pos_in_item;
24108c2ecf20Sopenharmony_ci
24118c2ecf20Sopenharmony_ci	/* we've found an unformatted node */
24128c2ecf20Sopenharmony_ci	if (indirect_item_found(retval, ih)) {
24138c2ecf20Sopenharmony_ci		if (bytes_copied > 0) {
24148c2ecf20Sopenharmony_ci			reiserfs_warning(inode->i_sb, "clm-6002",
24158c2ecf20Sopenharmony_ci					 "bytes_copied %d", bytes_copied);
24168c2ecf20Sopenharmony_ci		}
24178c2ecf20Sopenharmony_ci		if (!get_block_num(item, pos_in_item)) {
24188c2ecf20Sopenharmony_ci			/* crap, we are writing to a hole */
24198c2ecf20Sopenharmony_ci			use_get_block = 1;
24208c2ecf20Sopenharmony_ci			goto out;
24218c2ecf20Sopenharmony_ci		}
24228c2ecf20Sopenharmony_ci		set_block_dev_mapped(bh_result,
24238c2ecf20Sopenharmony_ci				     get_block_num(item, pos_in_item), inode);
24248c2ecf20Sopenharmony_ci	} else if (is_direct_le_ih(ih)) {
24258c2ecf20Sopenharmony_ci		char *p;
24268c2ecf20Sopenharmony_ci		p = page_address(bh_result->b_page);
24278c2ecf20Sopenharmony_ci		p += (byte_offset - 1) & (PAGE_SIZE - 1);
24288c2ecf20Sopenharmony_ci		copy_size = ih_item_len(ih) - pos_in_item;
24298c2ecf20Sopenharmony_ci
24308c2ecf20Sopenharmony_ci		fs_gen = get_generation(inode->i_sb);
24318c2ecf20Sopenharmony_ci		copy_item_head(&tmp_ih, ih);
24328c2ecf20Sopenharmony_ci
24338c2ecf20Sopenharmony_ci		if (!trans_running) {
24348c2ecf20Sopenharmony_ci			/* vs-3050 is gone, no need to drop the path */
24358c2ecf20Sopenharmony_ci			retval = journal_begin(&th, inode->i_sb, jbegin_count);
24368c2ecf20Sopenharmony_ci			if (retval)
24378c2ecf20Sopenharmony_ci				goto out;
24388c2ecf20Sopenharmony_ci			reiserfs_update_inode_transaction(inode);
24398c2ecf20Sopenharmony_ci			trans_running = 1;
24408c2ecf20Sopenharmony_ci			if (fs_changed(fs_gen, inode->i_sb)
24418c2ecf20Sopenharmony_ci			    && item_moved(&tmp_ih, &path)) {
24428c2ecf20Sopenharmony_ci				reiserfs_restore_prepared_buffer(inode->i_sb,
24438c2ecf20Sopenharmony_ci								 bh);
24448c2ecf20Sopenharmony_ci				goto research;
24458c2ecf20Sopenharmony_ci			}
24468c2ecf20Sopenharmony_ci		}
24478c2ecf20Sopenharmony_ci
24488c2ecf20Sopenharmony_ci		reiserfs_prepare_for_journal(inode->i_sb, bh, 1);
24498c2ecf20Sopenharmony_ci
24508c2ecf20Sopenharmony_ci		if (fs_changed(fs_gen, inode->i_sb)
24518c2ecf20Sopenharmony_ci		    && item_moved(&tmp_ih, &path)) {
24528c2ecf20Sopenharmony_ci			reiserfs_restore_prepared_buffer(inode->i_sb, bh);
24538c2ecf20Sopenharmony_ci			goto research;
24548c2ecf20Sopenharmony_ci		}
24558c2ecf20Sopenharmony_ci
24568c2ecf20Sopenharmony_ci		memcpy(ih_item_body(bh, ih) + pos_in_item, p + bytes_copied,
24578c2ecf20Sopenharmony_ci		       copy_size);
24588c2ecf20Sopenharmony_ci
24598c2ecf20Sopenharmony_ci		journal_mark_dirty(&th, bh);
24608c2ecf20Sopenharmony_ci		bytes_copied += copy_size;
24618c2ecf20Sopenharmony_ci		set_block_dev_mapped(bh_result, 0, inode);
24628c2ecf20Sopenharmony_ci
24638c2ecf20Sopenharmony_ci		/* are there still bytes left? */
24648c2ecf20Sopenharmony_ci		if (bytes_copied < bh_result->b_size &&
24658c2ecf20Sopenharmony_ci		    (byte_offset + bytes_copied) < inode->i_size) {
24668c2ecf20Sopenharmony_ci			set_cpu_key_k_offset(&key,
24678c2ecf20Sopenharmony_ci					     cpu_key_k_offset(&key) +
24688c2ecf20Sopenharmony_ci					     copy_size);
24698c2ecf20Sopenharmony_ci			goto research;
24708c2ecf20Sopenharmony_ci		}
24718c2ecf20Sopenharmony_ci	} else {
24728c2ecf20Sopenharmony_ci		reiserfs_warning(inode->i_sb, "clm-6003",
24738c2ecf20Sopenharmony_ci				 "bad item inode %lu", inode->i_ino);
24748c2ecf20Sopenharmony_ci		retval = -EIO;
24758c2ecf20Sopenharmony_ci		goto out;
24768c2ecf20Sopenharmony_ci	}
24778c2ecf20Sopenharmony_ci	retval = 0;
24788c2ecf20Sopenharmony_ci
24798c2ecf20Sopenharmony_ciout:
24808c2ecf20Sopenharmony_ci	pathrelse(&path);
24818c2ecf20Sopenharmony_ci	if (trans_running) {
24828c2ecf20Sopenharmony_ci		int err = journal_end(&th);
24838c2ecf20Sopenharmony_ci		if (err)
24848c2ecf20Sopenharmony_ci			retval = err;
24858c2ecf20Sopenharmony_ci		trans_running = 0;
24868c2ecf20Sopenharmony_ci	}
24878c2ecf20Sopenharmony_ci	reiserfs_write_unlock(inode->i_sb);
24888c2ecf20Sopenharmony_ci
24898c2ecf20Sopenharmony_ci	/* this is where we fill in holes in the file. */
24908c2ecf20Sopenharmony_ci	if (use_get_block) {
24918c2ecf20Sopenharmony_ci		retval = reiserfs_get_block(inode, block, bh_result,
24928c2ecf20Sopenharmony_ci					    GET_BLOCK_CREATE | GET_BLOCK_NO_IMUX
24938c2ecf20Sopenharmony_ci					    | GET_BLOCK_NO_DANGLE);
24948c2ecf20Sopenharmony_ci		if (!retval) {
24958c2ecf20Sopenharmony_ci			if (!buffer_mapped(bh_result)
24968c2ecf20Sopenharmony_ci			    || bh_result->b_blocknr == 0) {
24978c2ecf20Sopenharmony_ci				/* get_block failed to find a mapped unformatted node. */
24988c2ecf20Sopenharmony_ci				use_get_block = 0;
24998c2ecf20Sopenharmony_ci				goto start_over;
25008c2ecf20Sopenharmony_ci			}
25018c2ecf20Sopenharmony_ci		}
25028c2ecf20Sopenharmony_ci	}
25038c2ecf20Sopenharmony_ci	kunmap(bh_result->b_page);
25048c2ecf20Sopenharmony_ci
25058c2ecf20Sopenharmony_ci	if (!retval && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
25068c2ecf20Sopenharmony_ci		/*
25078c2ecf20Sopenharmony_ci		 * we've copied data from the page into the direct item, so the
25088c2ecf20Sopenharmony_ci		 * buffer in the page is now clean, mark it to reflect that.
25098c2ecf20Sopenharmony_ci		 */
25108c2ecf20Sopenharmony_ci		lock_buffer(bh_result);
25118c2ecf20Sopenharmony_ci		clear_buffer_dirty(bh_result);
25128c2ecf20Sopenharmony_ci		unlock_buffer(bh_result);
25138c2ecf20Sopenharmony_ci	}
25148c2ecf20Sopenharmony_ci	return retval;
25158c2ecf20Sopenharmony_ci}
25168c2ecf20Sopenharmony_ci
25178c2ecf20Sopenharmony_ci/*
25188c2ecf20Sopenharmony_ci * mason@suse.com: updated in 2.5.54 to follow the same general io
25198c2ecf20Sopenharmony_ci * start/recovery path as __block_write_full_page, along with special
25208c2ecf20Sopenharmony_ci * code to handle reiserfs tails.
25218c2ecf20Sopenharmony_ci */
25228c2ecf20Sopenharmony_cistatic int reiserfs_write_full_page(struct page *page,
25238c2ecf20Sopenharmony_ci				    struct writeback_control *wbc)
25248c2ecf20Sopenharmony_ci{
25258c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
25268c2ecf20Sopenharmony_ci	unsigned long end_index = inode->i_size >> PAGE_SHIFT;
25278c2ecf20Sopenharmony_ci	int error = 0;
25288c2ecf20Sopenharmony_ci	unsigned long block;
25298c2ecf20Sopenharmony_ci	sector_t last_block;
25308c2ecf20Sopenharmony_ci	struct buffer_head *head, *bh;
25318c2ecf20Sopenharmony_ci	int partial = 0;
25328c2ecf20Sopenharmony_ci	int nr = 0;
25338c2ecf20Sopenharmony_ci	int checked = PageChecked(page);
25348c2ecf20Sopenharmony_ci	struct reiserfs_transaction_handle th;
25358c2ecf20Sopenharmony_ci	struct super_block *s = inode->i_sb;
25368c2ecf20Sopenharmony_ci	int bh_per_page = PAGE_SIZE / s->s_blocksize;
25378c2ecf20Sopenharmony_ci	th.t_trans_id = 0;
25388c2ecf20Sopenharmony_ci
25398c2ecf20Sopenharmony_ci	/* no logging allowed when nonblocking or from PF_MEMALLOC */
25408c2ecf20Sopenharmony_ci	if (checked && (current->flags & PF_MEMALLOC)) {
25418c2ecf20Sopenharmony_ci		redirty_page_for_writepage(wbc, page);
25428c2ecf20Sopenharmony_ci		unlock_page(page);
25438c2ecf20Sopenharmony_ci		return 0;
25448c2ecf20Sopenharmony_ci	}
25458c2ecf20Sopenharmony_ci
25468c2ecf20Sopenharmony_ci	/*
25478c2ecf20Sopenharmony_ci	 * The page dirty bit is cleared before writepage is called, which
25488c2ecf20Sopenharmony_ci	 * means we have to tell create_empty_buffers to make dirty buffers
25498c2ecf20Sopenharmony_ci	 * The page really should be up to date at this point, so tossing
25508c2ecf20Sopenharmony_ci	 * in the BH_Uptodate is just a sanity check.
25518c2ecf20Sopenharmony_ci	 */
25528c2ecf20Sopenharmony_ci	if (!page_has_buffers(page)) {
25538c2ecf20Sopenharmony_ci		create_empty_buffers(page, s->s_blocksize,
25548c2ecf20Sopenharmony_ci				     (1 << BH_Dirty) | (1 << BH_Uptodate));
25558c2ecf20Sopenharmony_ci	}
25568c2ecf20Sopenharmony_ci	head = page_buffers(page);
25578c2ecf20Sopenharmony_ci
25588c2ecf20Sopenharmony_ci	/*
25598c2ecf20Sopenharmony_ci	 * last page in the file, zero out any contents past the
25608c2ecf20Sopenharmony_ci	 * last byte in the file
25618c2ecf20Sopenharmony_ci	 */
25628c2ecf20Sopenharmony_ci	if (page->index >= end_index) {
25638c2ecf20Sopenharmony_ci		unsigned last_offset;
25648c2ecf20Sopenharmony_ci
25658c2ecf20Sopenharmony_ci		last_offset = inode->i_size & (PAGE_SIZE - 1);
25668c2ecf20Sopenharmony_ci		/* no file contents in this page */
25678c2ecf20Sopenharmony_ci		if (page->index >= end_index + 1 || !last_offset) {
25688c2ecf20Sopenharmony_ci			unlock_page(page);
25698c2ecf20Sopenharmony_ci			return 0;
25708c2ecf20Sopenharmony_ci		}
25718c2ecf20Sopenharmony_ci		zero_user_segment(page, last_offset, PAGE_SIZE);
25728c2ecf20Sopenharmony_ci	}
25738c2ecf20Sopenharmony_ci	bh = head;
25748c2ecf20Sopenharmony_ci	block = page->index << (PAGE_SHIFT - s->s_blocksize_bits);
25758c2ecf20Sopenharmony_ci	last_block = (i_size_read(inode) - 1) >> inode->i_blkbits;
25768c2ecf20Sopenharmony_ci	/* first map all the buffers, logging any direct items we find */
25778c2ecf20Sopenharmony_ci	do {
25788c2ecf20Sopenharmony_ci		if (block > last_block) {
25798c2ecf20Sopenharmony_ci			/*
25808c2ecf20Sopenharmony_ci			 * This can happen when the block size is less than
25818c2ecf20Sopenharmony_ci			 * the page size.  The corresponding bytes in the page
25828c2ecf20Sopenharmony_ci			 * were zero filled above
25838c2ecf20Sopenharmony_ci			 */
25848c2ecf20Sopenharmony_ci			clear_buffer_dirty(bh);
25858c2ecf20Sopenharmony_ci			set_buffer_uptodate(bh);
25868c2ecf20Sopenharmony_ci		} else if ((checked || buffer_dirty(bh)) &&
25878c2ecf20Sopenharmony_ci		           (!buffer_mapped(bh) || (buffer_mapped(bh)
25888c2ecf20Sopenharmony_ci						       && bh->b_blocknr ==
25898c2ecf20Sopenharmony_ci						       0))) {
25908c2ecf20Sopenharmony_ci			/*
25918c2ecf20Sopenharmony_ci			 * not mapped yet, or it points to a direct item, search
25928c2ecf20Sopenharmony_ci			 * the btree for the mapping info, and log any direct
25938c2ecf20Sopenharmony_ci			 * items found
25948c2ecf20Sopenharmony_ci			 */
25958c2ecf20Sopenharmony_ci			if ((error = map_block_for_writepage(inode, bh, block))) {
25968c2ecf20Sopenharmony_ci				goto fail;
25978c2ecf20Sopenharmony_ci			}
25988c2ecf20Sopenharmony_ci		}
25998c2ecf20Sopenharmony_ci		bh = bh->b_this_page;
26008c2ecf20Sopenharmony_ci		block++;
26018c2ecf20Sopenharmony_ci	} while (bh != head);
26028c2ecf20Sopenharmony_ci
26038c2ecf20Sopenharmony_ci	/*
26048c2ecf20Sopenharmony_ci	 * we start the transaction after map_block_for_writepage,
26058c2ecf20Sopenharmony_ci	 * because it can create holes in the file (an unbounded operation).
26068c2ecf20Sopenharmony_ci	 * starting it here, we can make a reliable estimate for how many
26078c2ecf20Sopenharmony_ci	 * blocks we're going to log
26088c2ecf20Sopenharmony_ci	 */
26098c2ecf20Sopenharmony_ci	if (checked) {
26108c2ecf20Sopenharmony_ci		ClearPageChecked(page);
26118c2ecf20Sopenharmony_ci		reiserfs_write_lock(s);
26128c2ecf20Sopenharmony_ci		error = journal_begin(&th, s, bh_per_page + 1);
26138c2ecf20Sopenharmony_ci		if (error) {
26148c2ecf20Sopenharmony_ci			reiserfs_write_unlock(s);
26158c2ecf20Sopenharmony_ci			goto fail;
26168c2ecf20Sopenharmony_ci		}
26178c2ecf20Sopenharmony_ci		reiserfs_update_inode_transaction(inode);
26188c2ecf20Sopenharmony_ci	}
26198c2ecf20Sopenharmony_ci	/* now go through and lock any dirty buffers on the page */
26208c2ecf20Sopenharmony_ci	do {
26218c2ecf20Sopenharmony_ci		get_bh(bh);
26228c2ecf20Sopenharmony_ci		if (!buffer_mapped(bh))
26238c2ecf20Sopenharmony_ci			continue;
26248c2ecf20Sopenharmony_ci		if (buffer_mapped(bh) && bh->b_blocknr == 0)
26258c2ecf20Sopenharmony_ci			continue;
26268c2ecf20Sopenharmony_ci
26278c2ecf20Sopenharmony_ci		if (checked) {
26288c2ecf20Sopenharmony_ci			reiserfs_prepare_for_journal(s, bh, 1);
26298c2ecf20Sopenharmony_ci			journal_mark_dirty(&th, bh);
26308c2ecf20Sopenharmony_ci			continue;
26318c2ecf20Sopenharmony_ci		}
26328c2ecf20Sopenharmony_ci		/*
26338c2ecf20Sopenharmony_ci		 * from this point on, we know the buffer is mapped to a
26348c2ecf20Sopenharmony_ci		 * real block and not a direct item
26358c2ecf20Sopenharmony_ci		 */
26368c2ecf20Sopenharmony_ci		if (wbc->sync_mode != WB_SYNC_NONE) {
26378c2ecf20Sopenharmony_ci			lock_buffer(bh);
26388c2ecf20Sopenharmony_ci		} else {
26398c2ecf20Sopenharmony_ci			if (!trylock_buffer(bh)) {
26408c2ecf20Sopenharmony_ci				redirty_page_for_writepage(wbc, page);
26418c2ecf20Sopenharmony_ci				continue;
26428c2ecf20Sopenharmony_ci			}
26438c2ecf20Sopenharmony_ci		}
26448c2ecf20Sopenharmony_ci		if (test_clear_buffer_dirty(bh)) {
26458c2ecf20Sopenharmony_ci			mark_buffer_async_write(bh);
26468c2ecf20Sopenharmony_ci		} else {
26478c2ecf20Sopenharmony_ci			unlock_buffer(bh);
26488c2ecf20Sopenharmony_ci		}
26498c2ecf20Sopenharmony_ci	} while ((bh = bh->b_this_page) != head);
26508c2ecf20Sopenharmony_ci
26518c2ecf20Sopenharmony_ci	if (checked) {
26528c2ecf20Sopenharmony_ci		error = journal_end(&th);
26538c2ecf20Sopenharmony_ci		reiserfs_write_unlock(s);
26548c2ecf20Sopenharmony_ci		if (error)
26558c2ecf20Sopenharmony_ci			goto fail;
26568c2ecf20Sopenharmony_ci	}
26578c2ecf20Sopenharmony_ci	BUG_ON(PageWriteback(page));
26588c2ecf20Sopenharmony_ci	set_page_writeback(page);
26598c2ecf20Sopenharmony_ci	unlock_page(page);
26608c2ecf20Sopenharmony_ci
26618c2ecf20Sopenharmony_ci	/*
26628c2ecf20Sopenharmony_ci	 * since any buffer might be the only dirty buffer on the page,
26638c2ecf20Sopenharmony_ci	 * the first submit_bh can bring the page out of writeback.
26648c2ecf20Sopenharmony_ci	 * be careful with the buffers.
26658c2ecf20Sopenharmony_ci	 */
26668c2ecf20Sopenharmony_ci	do {
26678c2ecf20Sopenharmony_ci		struct buffer_head *next = bh->b_this_page;
26688c2ecf20Sopenharmony_ci		if (buffer_async_write(bh)) {
26698c2ecf20Sopenharmony_ci			submit_bh(REQ_OP_WRITE, 0, bh);
26708c2ecf20Sopenharmony_ci			nr++;
26718c2ecf20Sopenharmony_ci		}
26728c2ecf20Sopenharmony_ci		put_bh(bh);
26738c2ecf20Sopenharmony_ci		bh = next;
26748c2ecf20Sopenharmony_ci	} while (bh != head);
26758c2ecf20Sopenharmony_ci
26768c2ecf20Sopenharmony_ci	error = 0;
26778c2ecf20Sopenharmony_cidone:
26788c2ecf20Sopenharmony_ci	if (nr == 0) {
26798c2ecf20Sopenharmony_ci		/*
26808c2ecf20Sopenharmony_ci		 * if this page only had a direct item, it is very possible for
26818c2ecf20Sopenharmony_ci		 * no io to be required without there being an error.  Or,
26828c2ecf20Sopenharmony_ci		 * someone else could have locked them and sent them down the
26838c2ecf20Sopenharmony_ci		 * pipe without locking the page
26848c2ecf20Sopenharmony_ci		 */
26858c2ecf20Sopenharmony_ci		bh = head;
26868c2ecf20Sopenharmony_ci		do {
26878c2ecf20Sopenharmony_ci			if (!buffer_uptodate(bh)) {
26888c2ecf20Sopenharmony_ci				partial = 1;
26898c2ecf20Sopenharmony_ci				break;
26908c2ecf20Sopenharmony_ci			}
26918c2ecf20Sopenharmony_ci			bh = bh->b_this_page;
26928c2ecf20Sopenharmony_ci		} while (bh != head);
26938c2ecf20Sopenharmony_ci		if (!partial)
26948c2ecf20Sopenharmony_ci			SetPageUptodate(page);
26958c2ecf20Sopenharmony_ci		end_page_writeback(page);
26968c2ecf20Sopenharmony_ci	}
26978c2ecf20Sopenharmony_ci	return error;
26988c2ecf20Sopenharmony_ci
26998c2ecf20Sopenharmony_cifail:
27008c2ecf20Sopenharmony_ci	/*
27018c2ecf20Sopenharmony_ci	 * catches various errors, we need to make sure any valid dirty blocks
27028c2ecf20Sopenharmony_ci	 * get to the media.  The page is currently locked and not marked for
27038c2ecf20Sopenharmony_ci	 * writeback
27048c2ecf20Sopenharmony_ci	 */
27058c2ecf20Sopenharmony_ci	ClearPageUptodate(page);
27068c2ecf20Sopenharmony_ci	bh = head;
27078c2ecf20Sopenharmony_ci	do {
27088c2ecf20Sopenharmony_ci		get_bh(bh);
27098c2ecf20Sopenharmony_ci		if (buffer_mapped(bh) && buffer_dirty(bh) && bh->b_blocknr) {
27108c2ecf20Sopenharmony_ci			lock_buffer(bh);
27118c2ecf20Sopenharmony_ci			mark_buffer_async_write(bh);
27128c2ecf20Sopenharmony_ci		} else {
27138c2ecf20Sopenharmony_ci			/*
27148c2ecf20Sopenharmony_ci			 * clear any dirty bits that might have come from
27158c2ecf20Sopenharmony_ci			 * getting attached to a dirty page
27168c2ecf20Sopenharmony_ci			 */
27178c2ecf20Sopenharmony_ci			clear_buffer_dirty(bh);
27188c2ecf20Sopenharmony_ci		}
27198c2ecf20Sopenharmony_ci		bh = bh->b_this_page;
27208c2ecf20Sopenharmony_ci	} while (bh != head);
27218c2ecf20Sopenharmony_ci	SetPageError(page);
27228c2ecf20Sopenharmony_ci	BUG_ON(PageWriteback(page));
27238c2ecf20Sopenharmony_ci	set_page_writeback(page);
27248c2ecf20Sopenharmony_ci	unlock_page(page);
27258c2ecf20Sopenharmony_ci	do {
27268c2ecf20Sopenharmony_ci		struct buffer_head *next = bh->b_this_page;
27278c2ecf20Sopenharmony_ci		if (buffer_async_write(bh)) {
27288c2ecf20Sopenharmony_ci			clear_buffer_dirty(bh);
27298c2ecf20Sopenharmony_ci			submit_bh(REQ_OP_WRITE, 0, bh);
27308c2ecf20Sopenharmony_ci			nr++;
27318c2ecf20Sopenharmony_ci		}
27328c2ecf20Sopenharmony_ci		put_bh(bh);
27338c2ecf20Sopenharmony_ci		bh = next;
27348c2ecf20Sopenharmony_ci	} while (bh != head);
27358c2ecf20Sopenharmony_ci	goto done;
27368c2ecf20Sopenharmony_ci}
27378c2ecf20Sopenharmony_ci
27388c2ecf20Sopenharmony_cistatic int reiserfs_readpage(struct file *f, struct page *page)
27398c2ecf20Sopenharmony_ci{
27408c2ecf20Sopenharmony_ci	return block_read_full_page(page, reiserfs_get_block);
27418c2ecf20Sopenharmony_ci}
27428c2ecf20Sopenharmony_ci
27438c2ecf20Sopenharmony_cistatic int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
27448c2ecf20Sopenharmony_ci{
27458c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
27468c2ecf20Sopenharmony_ci	reiserfs_wait_on_write_block(inode->i_sb);
27478c2ecf20Sopenharmony_ci	return reiserfs_write_full_page(page, wbc);
27488c2ecf20Sopenharmony_ci}
27498c2ecf20Sopenharmony_ci
27508c2ecf20Sopenharmony_cistatic void reiserfs_truncate_failed_write(struct inode *inode)
27518c2ecf20Sopenharmony_ci{
27528c2ecf20Sopenharmony_ci	truncate_inode_pages(inode->i_mapping, inode->i_size);
27538c2ecf20Sopenharmony_ci	reiserfs_truncate_file(inode, 0);
27548c2ecf20Sopenharmony_ci}
27558c2ecf20Sopenharmony_ci
27568c2ecf20Sopenharmony_cistatic int reiserfs_write_begin(struct file *file,
27578c2ecf20Sopenharmony_ci				struct address_space *mapping,
27588c2ecf20Sopenharmony_ci				loff_t pos, unsigned len, unsigned flags,
27598c2ecf20Sopenharmony_ci				struct page **pagep, void **fsdata)
27608c2ecf20Sopenharmony_ci{
27618c2ecf20Sopenharmony_ci	struct inode *inode;
27628c2ecf20Sopenharmony_ci	struct page *page;
27638c2ecf20Sopenharmony_ci	pgoff_t index;
27648c2ecf20Sopenharmony_ci	int ret;
27658c2ecf20Sopenharmony_ci	int old_ref = 0;
27668c2ecf20Sopenharmony_ci
27678c2ecf20Sopenharmony_ci 	inode = mapping->host;
27688c2ecf20Sopenharmony_ci	*fsdata = NULL;
27698c2ecf20Sopenharmony_ci 	if (flags & AOP_FLAG_CONT_EXPAND &&
27708c2ecf20Sopenharmony_ci 	    (pos & (inode->i_sb->s_blocksize - 1)) == 0) {
27718c2ecf20Sopenharmony_ci 		pos ++;
27728c2ecf20Sopenharmony_ci		*fsdata = (void *)(unsigned long)flags;
27738c2ecf20Sopenharmony_ci	}
27748c2ecf20Sopenharmony_ci
27758c2ecf20Sopenharmony_ci	index = pos >> PAGE_SHIFT;
27768c2ecf20Sopenharmony_ci	page = grab_cache_page_write_begin(mapping, index, flags);
27778c2ecf20Sopenharmony_ci	if (!page)
27788c2ecf20Sopenharmony_ci		return -ENOMEM;
27798c2ecf20Sopenharmony_ci	*pagep = page;
27808c2ecf20Sopenharmony_ci
27818c2ecf20Sopenharmony_ci	reiserfs_wait_on_write_block(inode->i_sb);
27828c2ecf20Sopenharmony_ci	fix_tail_page_for_writing(page);
27838c2ecf20Sopenharmony_ci	if (reiserfs_transaction_running(inode->i_sb)) {
27848c2ecf20Sopenharmony_ci		struct reiserfs_transaction_handle *th;
27858c2ecf20Sopenharmony_ci		th = (struct reiserfs_transaction_handle *)current->
27868c2ecf20Sopenharmony_ci		    journal_info;
27878c2ecf20Sopenharmony_ci		BUG_ON(!th->t_refcount);
27888c2ecf20Sopenharmony_ci		BUG_ON(!th->t_trans_id);
27898c2ecf20Sopenharmony_ci		old_ref = th->t_refcount;
27908c2ecf20Sopenharmony_ci		th->t_refcount++;
27918c2ecf20Sopenharmony_ci	}
27928c2ecf20Sopenharmony_ci	ret = __block_write_begin(page, pos, len, reiserfs_get_block);
27938c2ecf20Sopenharmony_ci	if (ret && reiserfs_transaction_running(inode->i_sb)) {
27948c2ecf20Sopenharmony_ci		struct reiserfs_transaction_handle *th = current->journal_info;
27958c2ecf20Sopenharmony_ci		/*
27968c2ecf20Sopenharmony_ci		 * this gets a little ugly.  If reiserfs_get_block returned an
27978c2ecf20Sopenharmony_ci		 * error and left a transacstion running, we've got to close
27988c2ecf20Sopenharmony_ci		 * it, and we've got to free handle if it was a persistent
27998c2ecf20Sopenharmony_ci		 * transaction.
28008c2ecf20Sopenharmony_ci		 *
28018c2ecf20Sopenharmony_ci		 * But, if we had nested into an existing transaction, we need
28028c2ecf20Sopenharmony_ci		 * to just drop the ref count on the handle.
28038c2ecf20Sopenharmony_ci		 *
28048c2ecf20Sopenharmony_ci		 * If old_ref == 0, the transaction is from reiserfs_get_block,
28058c2ecf20Sopenharmony_ci		 * and it was a persistent trans.  Otherwise, it was nested
28068c2ecf20Sopenharmony_ci		 * above.
28078c2ecf20Sopenharmony_ci		 */
28088c2ecf20Sopenharmony_ci		if (th->t_refcount > old_ref) {
28098c2ecf20Sopenharmony_ci			if (old_ref)
28108c2ecf20Sopenharmony_ci				th->t_refcount--;
28118c2ecf20Sopenharmony_ci			else {
28128c2ecf20Sopenharmony_ci				int err;
28138c2ecf20Sopenharmony_ci				reiserfs_write_lock(inode->i_sb);
28148c2ecf20Sopenharmony_ci				err = reiserfs_end_persistent_transaction(th);
28158c2ecf20Sopenharmony_ci				reiserfs_write_unlock(inode->i_sb);
28168c2ecf20Sopenharmony_ci				if (err)
28178c2ecf20Sopenharmony_ci					ret = err;
28188c2ecf20Sopenharmony_ci			}
28198c2ecf20Sopenharmony_ci		}
28208c2ecf20Sopenharmony_ci	}
28218c2ecf20Sopenharmony_ci	if (ret) {
28228c2ecf20Sopenharmony_ci		unlock_page(page);
28238c2ecf20Sopenharmony_ci		put_page(page);
28248c2ecf20Sopenharmony_ci		/* Truncate allocated blocks */
28258c2ecf20Sopenharmony_ci		reiserfs_truncate_failed_write(inode);
28268c2ecf20Sopenharmony_ci	}
28278c2ecf20Sopenharmony_ci	return ret;
28288c2ecf20Sopenharmony_ci}
28298c2ecf20Sopenharmony_ci
28308c2ecf20Sopenharmony_ciint __reiserfs_write_begin(struct page *page, unsigned from, unsigned len)
28318c2ecf20Sopenharmony_ci{
28328c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
28338c2ecf20Sopenharmony_ci	int ret;
28348c2ecf20Sopenharmony_ci	int old_ref = 0;
28358c2ecf20Sopenharmony_ci	int depth;
28368c2ecf20Sopenharmony_ci
28378c2ecf20Sopenharmony_ci	depth = reiserfs_write_unlock_nested(inode->i_sb);
28388c2ecf20Sopenharmony_ci	reiserfs_wait_on_write_block(inode->i_sb);
28398c2ecf20Sopenharmony_ci	reiserfs_write_lock_nested(inode->i_sb, depth);
28408c2ecf20Sopenharmony_ci
28418c2ecf20Sopenharmony_ci	fix_tail_page_for_writing(page);
28428c2ecf20Sopenharmony_ci	if (reiserfs_transaction_running(inode->i_sb)) {
28438c2ecf20Sopenharmony_ci		struct reiserfs_transaction_handle *th;
28448c2ecf20Sopenharmony_ci		th = (struct reiserfs_transaction_handle *)current->
28458c2ecf20Sopenharmony_ci		    journal_info;
28468c2ecf20Sopenharmony_ci		BUG_ON(!th->t_refcount);
28478c2ecf20Sopenharmony_ci		BUG_ON(!th->t_trans_id);
28488c2ecf20Sopenharmony_ci		old_ref = th->t_refcount;
28498c2ecf20Sopenharmony_ci		th->t_refcount++;
28508c2ecf20Sopenharmony_ci	}
28518c2ecf20Sopenharmony_ci
28528c2ecf20Sopenharmony_ci	ret = __block_write_begin(page, from, len, reiserfs_get_block);
28538c2ecf20Sopenharmony_ci	if (ret && reiserfs_transaction_running(inode->i_sb)) {
28548c2ecf20Sopenharmony_ci		struct reiserfs_transaction_handle *th = current->journal_info;
28558c2ecf20Sopenharmony_ci		/*
28568c2ecf20Sopenharmony_ci		 * this gets a little ugly.  If reiserfs_get_block returned an
28578c2ecf20Sopenharmony_ci		 * error and left a transacstion running, we've got to close
28588c2ecf20Sopenharmony_ci		 * it, and we've got to free handle if it was a persistent
28598c2ecf20Sopenharmony_ci		 * transaction.
28608c2ecf20Sopenharmony_ci		 *
28618c2ecf20Sopenharmony_ci		 * But, if we had nested into an existing transaction, we need
28628c2ecf20Sopenharmony_ci		 * to just drop the ref count on the handle.
28638c2ecf20Sopenharmony_ci		 *
28648c2ecf20Sopenharmony_ci		 * If old_ref == 0, the transaction is from reiserfs_get_block,
28658c2ecf20Sopenharmony_ci		 * and it was a persistent trans.  Otherwise, it was nested
28668c2ecf20Sopenharmony_ci		 * above.
28678c2ecf20Sopenharmony_ci		 */
28688c2ecf20Sopenharmony_ci		if (th->t_refcount > old_ref) {
28698c2ecf20Sopenharmony_ci			if (old_ref)
28708c2ecf20Sopenharmony_ci				th->t_refcount--;
28718c2ecf20Sopenharmony_ci			else {
28728c2ecf20Sopenharmony_ci				int err;
28738c2ecf20Sopenharmony_ci				reiserfs_write_lock(inode->i_sb);
28748c2ecf20Sopenharmony_ci				err = reiserfs_end_persistent_transaction(th);
28758c2ecf20Sopenharmony_ci				reiserfs_write_unlock(inode->i_sb);
28768c2ecf20Sopenharmony_ci				if (err)
28778c2ecf20Sopenharmony_ci					ret = err;
28788c2ecf20Sopenharmony_ci			}
28798c2ecf20Sopenharmony_ci		}
28808c2ecf20Sopenharmony_ci	}
28818c2ecf20Sopenharmony_ci	return ret;
28828c2ecf20Sopenharmony_ci
28838c2ecf20Sopenharmony_ci}
28848c2ecf20Sopenharmony_ci
28858c2ecf20Sopenharmony_cistatic sector_t reiserfs_aop_bmap(struct address_space *as, sector_t block)
28868c2ecf20Sopenharmony_ci{
28878c2ecf20Sopenharmony_ci	return generic_block_bmap(as, block, reiserfs_bmap);
28888c2ecf20Sopenharmony_ci}
28898c2ecf20Sopenharmony_ci
28908c2ecf20Sopenharmony_cistatic int reiserfs_write_end(struct file *file, struct address_space *mapping,
28918c2ecf20Sopenharmony_ci			      loff_t pos, unsigned len, unsigned copied,
28928c2ecf20Sopenharmony_ci			      struct page *page, void *fsdata)
28938c2ecf20Sopenharmony_ci{
28948c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
28958c2ecf20Sopenharmony_ci	int ret = 0;
28968c2ecf20Sopenharmony_ci	int update_sd = 0;
28978c2ecf20Sopenharmony_ci	struct reiserfs_transaction_handle *th;
28988c2ecf20Sopenharmony_ci	unsigned start;
28998c2ecf20Sopenharmony_ci	bool locked = false;
29008c2ecf20Sopenharmony_ci
29018c2ecf20Sopenharmony_ci	if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND)
29028c2ecf20Sopenharmony_ci		pos ++;
29038c2ecf20Sopenharmony_ci
29048c2ecf20Sopenharmony_ci	reiserfs_wait_on_write_block(inode->i_sb);
29058c2ecf20Sopenharmony_ci	if (reiserfs_transaction_running(inode->i_sb))
29068c2ecf20Sopenharmony_ci		th = current->journal_info;
29078c2ecf20Sopenharmony_ci	else
29088c2ecf20Sopenharmony_ci		th = NULL;
29098c2ecf20Sopenharmony_ci
29108c2ecf20Sopenharmony_ci	start = pos & (PAGE_SIZE - 1);
29118c2ecf20Sopenharmony_ci	if (unlikely(copied < len)) {
29128c2ecf20Sopenharmony_ci		if (!PageUptodate(page))
29138c2ecf20Sopenharmony_ci			copied = 0;
29148c2ecf20Sopenharmony_ci
29158c2ecf20Sopenharmony_ci		page_zero_new_buffers(page, start + copied, start + len);
29168c2ecf20Sopenharmony_ci	}
29178c2ecf20Sopenharmony_ci	flush_dcache_page(page);
29188c2ecf20Sopenharmony_ci
29198c2ecf20Sopenharmony_ci	reiserfs_commit_page(inode, page, start, start + copied);
29208c2ecf20Sopenharmony_ci
29218c2ecf20Sopenharmony_ci	/*
29228c2ecf20Sopenharmony_ci	 * generic_commit_write does this for us, but does not update the
29238c2ecf20Sopenharmony_ci	 * transaction tracking stuff when the size changes.  So, we have
29248c2ecf20Sopenharmony_ci	 * to do the i_size updates here.
29258c2ecf20Sopenharmony_ci	 */
29268c2ecf20Sopenharmony_ci	if (pos + copied > inode->i_size) {
29278c2ecf20Sopenharmony_ci		struct reiserfs_transaction_handle myth;
29288c2ecf20Sopenharmony_ci		reiserfs_write_lock(inode->i_sb);
29298c2ecf20Sopenharmony_ci		locked = true;
29308c2ecf20Sopenharmony_ci		/*
29318c2ecf20Sopenharmony_ci		 * If the file have grown beyond the border where it
29328c2ecf20Sopenharmony_ci		 * can have a tail, unmark it as needing a tail
29338c2ecf20Sopenharmony_ci		 * packing
29348c2ecf20Sopenharmony_ci		 */
29358c2ecf20Sopenharmony_ci		if ((have_large_tails(inode->i_sb)
29368c2ecf20Sopenharmony_ci		     && inode->i_size > i_block_size(inode) * 4)
29378c2ecf20Sopenharmony_ci		    || (have_small_tails(inode->i_sb)
29388c2ecf20Sopenharmony_ci			&& inode->i_size > i_block_size(inode)))
29398c2ecf20Sopenharmony_ci			REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
29408c2ecf20Sopenharmony_ci
29418c2ecf20Sopenharmony_ci		ret = journal_begin(&myth, inode->i_sb, 1);
29428c2ecf20Sopenharmony_ci		if (ret)
29438c2ecf20Sopenharmony_ci			goto journal_error;
29448c2ecf20Sopenharmony_ci
29458c2ecf20Sopenharmony_ci		reiserfs_update_inode_transaction(inode);
29468c2ecf20Sopenharmony_ci		inode->i_size = pos + copied;
29478c2ecf20Sopenharmony_ci		/*
29488c2ecf20Sopenharmony_ci		 * this will just nest into our transaction.  It's important
29498c2ecf20Sopenharmony_ci		 * to use mark_inode_dirty so the inode gets pushed around on
29508c2ecf20Sopenharmony_ci		 * the dirty lists, and so that O_SYNC works as expected
29518c2ecf20Sopenharmony_ci		 */
29528c2ecf20Sopenharmony_ci		mark_inode_dirty(inode);
29538c2ecf20Sopenharmony_ci		reiserfs_update_sd(&myth, inode);
29548c2ecf20Sopenharmony_ci		update_sd = 1;
29558c2ecf20Sopenharmony_ci		ret = journal_end(&myth);
29568c2ecf20Sopenharmony_ci		if (ret)
29578c2ecf20Sopenharmony_ci			goto journal_error;
29588c2ecf20Sopenharmony_ci	}
29598c2ecf20Sopenharmony_ci	if (th) {
29608c2ecf20Sopenharmony_ci		if (!locked) {
29618c2ecf20Sopenharmony_ci			reiserfs_write_lock(inode->i_sb);
29628c2ecf20Sopenharmony_ci			locked = true;
29638c2ecf20Sopenharmony_ci		}
29648c2ecf20Sopenharmony_ci		if (!update_sd)
29658c2ecf20Sopenharmony_ci			mark_inode_dirty(inode);
29668c2ecf20Sopenharmony_ci		ret = reiserfs_end_persistent_transaction(th);
29678c2ecf20Sopenharmony_ci		if (ret)
29688c2ecf20Sopenharmony_ci			goto out;
29698c2ecf20Sopenharmony_ci	}
29708c2ecf20Sopenharmony_ci
29718c2ecf20Sopenharmony_ciout:
29728c2ecf20Sopenharmony_ci	if (locked)
29738c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
29748c2ecf20Sopenharmony_ci	unlock_page(page);
29758c2ecf20Sopenharmony_ci	put_page(page);
29768c2ecf20Sopenharmony_ci
29778c2ecf20Sopenharmony_ci	if (pos + len > inode->i_size)
29788c2ecf20Sopenharmony_ci		reiserfs_truncate_failed_write(inode);
29798c2ecf20Sopenharmony_ci
29808c2ecf20Sopenharmony_ci	return ret == 0 ? copied : ret;
29818c2ecf20Sopenharmony_ci
29828c2ecf20Sopenharmony_cijournal_error:
29838c2ecf20Sopenharmony_ci	reiserfs_write_unlock(inode->i_sb);
29848c2ecf20Sopenharmony_ci	locked = false;
29858c2ecf20Sopenharmony_ci	if (th) {
29868c2ecf20Sopenharmony_ci		if (!update_sd)
29878c2ecf20Sopenharmony_ci			reiserfs_update_sd(th, inode);
29888c2ecf20Sopenharmony_ci		ret = reiserfs_end_persistent_transaction(th);
29898c2ecf20Sopenharmony_ci	}
29908c2ecf20Sopenharmony_ci	goto out;
29918c2ecf20Sopenharmony_ci}
29928c2ecf20Sopenharmony_ci
29938c2ecf20Sopenharmony_ciint reiserfs_commit_write(struct file *f, struct page *page,
29948c2ecf20Sopenharmony_ci			  unsigned from, unsigned to)
29958c2ecf20Sopenharmony_ci{
29968c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
29978c2ecf20Sopenharmony_ci	loff_t pos = ((loff_t) page->index << PAGE_SHIFT) + to;
29988c2ecf20Sopenharmony_ci	int ret = 0;
29998c2ecf20Sopenharmony_ci	int update_sd = 0;
30008c2ecf20Sopenharmony_ci	struct reiserfs_transaction_handle *th = NULL;
30018c2ecf20Sopenharmony_ci	int depth;
30028c2ecf20Sopenharmony_ci
30038c2ecf20Sopenharmony_ci	depth = reiserfs_write_unlock_nested(inode->i_sb);
30048c2ecf20Sopenharmony_ci	reiserfs_wait_on_write_block(inode->i_sb);
30058c2ecf20Sopenharmony_ci	reiserfs_write_lock_nested(inode->i_sb, depth);
30068c2ecf20Sopenharmony_ci
30078c2ecf20Sopenharmony_ci	if (reiserfs_transaction_running(inode->i_sb)) {
30088c2ecf20Sopenharmony_ci		th = current->journal_info;
30098c2ecf20Sopenharmony_ci	}
30108c2ecf20Sopenharmony_ci	reiserfs_commit_page(inode, page, from, to);
30118c2ecf20Sopenharmony_ci
30128c2ecf20Sopenharmony_ci	/*
30138c2ecf20Sopenharmony_ci	 * generic_commit_write does this for us, but does not update the
30148c2ecf20Sopenharmony_ci	 * transaction tracking stuff when the size changes.  So, we have
30158c2ecf20Sopenharmony_ci	 * to do the i_size updates here.
30168c2ecf20Sopenharmony_ci	 */
30178c2ecf20Sopenharmony_ci	if (pos > inode->i_size) {
30188c2ecf20Sopenharmony_ci		struct reiserfs_transaction_handle myth;
30198c2ecf20Sopenharmony_ci		/*
30208c2ecf20Sopenharmony_ci		 * If the file have grown beyond the border where it
30218c2ecf20Sopenharmony_ci		 * can have a tail, unmark it as needing a tail
30228c2ecf20Sopenharmony_ci		 * packing
30238c2ecf20Sopenharmony_ci		 */
30248c2ecf20Sopenharmony_ci		if ((have_large_tails(inode->i_sb)
30258c2ecf20Sopenharmony_ci		     && inode->i_size > i_block_size(inode) * 4)
30268c2ecf20Sopenharmony_ci		    || (have_small_tails(inode->i_sb)
30278c2ecf20Sopenharmony_ci			&& inode->i_size > i_block_size(inode)))
30288c2ecf20Sopenharmony_ci			REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
30298c2ecf20Sopenharmony_ci
30308c2ecf20Sopenharmony_ci		ret = journal_begin(&myth, inode->i_sb, 1);
30318c2ecf20Sopenharmony_ci		if (ret)
30328c2ecf20Sopenharmony_ci			goto journal_error;
30338c2ecf20Sopenharmony_ci
30348c2ecf20Sopenharmony_ci		reiserfs_update_inode_transaction(inode);
30358c2ecf20Sopenharmony_ci		inode->i_size = pos;
30368c2ecf20Sopenharmony_ci		/*
30378c2ecf20Sopenharmony_ci		 * this will just nest into our transaction.  It's important
30388c2ecf20Sopenharmony_ci		 * to use mark_inode_dirty so the inode gets pushed around
30398c2ecf20Sopenharmony_ci		 * on the dirty lists, and so that O_SYNC works as expected
30408c2ecf20Sopenharmony_ci		 */
30418c2ecf20Sopenharmony_ci		mark_inode_dirty(inode);
30428c2ecf20Sopenharmony_ci		reiserfs_update_sd(&myth, inode);
30438c2ecf20Sopenharmony_ci		update_sd = 1;
30448c2ecf20Sopenharmony_ci		ret = journal_end(&myth);
30458c2ecf20Sopenharmony_ci		if (ret)
30468c2ecf20Sopenharmony_ci			goto journal_error;
30478c2ecf20Sopenharmony_ci	}
30488c2ecf20Sopenharmony_ci	if (th) {
30498c2ecf20Sopenharmony_ci		if (!update_sd)
30508c2ecf20Sopenharmony_ci			mark_inode_dirty(inode);
30518c2ecf20Sopenharmony_ci		ret = reiserfs_end_persistent_transaction(th);
30528c2ecf20Sopenharmony_ci		if (ret)
30538c2ecf20Sopenharmony_ci			goto out;
30548c2ecf20Sopenharmony_ci	}
30558c2ecf20Sopenharmony_ci
30568c2ecf20Sopenharmony_ciout:
30578c2ecf20Sopenharmony_ci	return ret;
30588c2ecf20Sopenharmony_ci
30598c2ecf20Sopenharmony_cijournal_error:
30608c2ecf20Sopenharmony_ci	if (th) {
30618c2ecf20Sopenharmony_ci		if (!update_sd)
30628c2ecf20Sopenharmony_ci			reiserfs_update_sd(th, inode);
30638c2ecf20Sopenharmony_ci		ret = reiserfs_end_persistent_transaction(th);
30648c2ecf20Sopenharmony_ci	}
30658c2ecf20Sopenharmony_ci
30668c2ecf20Sopenharmony_ci	return ret;
30678c2ecf20Sopenharmony_ci}
30688c2ecf20Sopenharmony_ci
30698c2ecf20Sopenharmony_civoid sd_attrs_to_i_attrs(__u16 sd_attrs, struct inode *inode)
30708c2ecf20Sopenharmony_ci{
30718c2ecf20Sopenharmony_ci	if (reiserfs_attrs(inode->i_sb)) {
30728c2ecf20Sopenharmony_ci		if (sd_attrs & REISERFS_SYNC_FL)
30738c2ecf20Sopenharmony_ci			inode->i_flags |= S_SYNC;
30748c2ecf20Sopenharmony_ci		else
30758c2ecf20Sopenharmony_ci			inode->i_flags &= ~S_SYNC;
30768c2ecf20Sopenharmony_ci		if (sd_attrs & REISERFS_IMMUTABLE_FL)
30778c2ecf20Sopenharmony_ci			inode->i_flags |= S_IMMUTABLE;
30788c2ecf20Sopenharmony_ci		else
30798c2ecf20Sopenharmony_ci			inode->i_flags &= ~S_IMMUTABLE;
30808c2ecf20Sopenharmony_ci		if (sd_attrs & REISERFS_APPEND_FL)
30818c2ecf20Sopenharmony_ci			inode->i_flags |= S_APPEND;
30828c2ecf20Sopenharmony_ci		else
30838c2ecf20Sopenharmony_ci			inode->i_flags &= ~S_APPEND;
30848c2ecf20Sopenharmony_ci		if (sd_attrs & REISERFS_NOATIME_FL)
30858c2ecf20Sopenharmony_ci			inode->i_flags |= S_NOATIME;
30868c2ecf20Sopenharmony_ci		else
30878c2ecf20Sopenharmony_ci			inode->i_flags &= ~S_NOATIME;
30888c2ecf20Sopenharmony_ci		if (sd_attrs & REISERFS_NOTAIL_FL)
30898c2ecf20Sopenharmony_ci			REISERFS_I(inode)->i_flags |= i_nopack_mask;
30908c2ecf20Sopenharmony_ci		else
30918c2ecf20Sopenharmony_ci			REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
30928c2ecf20Sopenharmony_ci	}
30938c2ecf20Sopenharmony_ci}
30948c2ecf20Sopenharmony_ci
30958c2ecf20Sopenharmony_ci/*
30968c2ecf20Sopenharmony_ci * decide if this buffer needs to stay around for data logging or ordered
30978c2ecf20Sopenharmony_ci * write purposes
30988c2ecf20Sopenharmony_ci */
30998c2ecf20Sopenharmony_cistatic int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
31008c2ecf20Sopenharmony_ci{
31018c2ecf20Sopenharmony_ci	int ret = 1;
31028c2ecf20Sopenharmony_ci	struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
31038c2ecf20Sopenharmony_ci
31048c2ecf20Sopenharmony_ci	lock_buffer(bh);
31058c2ecf20Sopenharmony_ci	spin_lock(&j->j_dirty_buffers_lock);
31068c2ecf20Sopenharmony_ci	if (!buffer_mapped(bh)) {
31078c2ecf20Sopenharmony_ci		goto free_jh;
31088c2ecf20Sopenharmony_ci	}
31098c2ecf20Sopenharmony_ci	/*
31108c2ecf20Sopenharmony_ci	 * the page is locked, and the only places that log a data buffer
31118c2ecf20Sopenharmony_ci	 * also lock the page.
31128c2ecf20Sopenharmony_ci	 */
31138c2ecf20Sopenharmony_ci	if (reiserfs_file_data_log(inode)) {
31148c2ecf20Sopenharmony_ci		/*
31158c2ecf20Sopenharmony_ci		 * very conservative, leave the buffer pinned if
31168c2ecf20Sopenharmony_ci		 * anyone might need it.
31178c2ecf20Sopenharmony_ci		 */
31188c2ecf20Sopenharmony_ci		if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
31198c2ecf20Sopenharmony_ci			ret = 0;
31208c2ecf20Sopenharmony_ci		}
31218c2ecf20Sopenharmony_ci	} else  if (buffer_dirty(bh)) {
31228c2ecf20Sopenharmony_ci		struct reiserfs_journal_list *jl;
31238c2ecf20Sopenharmony_ci		struct reiserfs_jh *jh = bh->b_private;
31248c2ecf20Sopenharmony_ci
31258c2ecf20Sopenharmony_ci		/*
31268c2ecf20Sopenharmony_ci		 * why is this safe?
31278c2ecf20Sopenharmony_ci		 * reiserfs_setattr updates i_size in the on disk
31288c2ecf20Sopenharmony_ci		 * stat data before allowing vmtruncate to be called.
31298c2ecf20Sopenharmony_ci		 *
31308c2ecf20Sopenharmony_ci		 * If buffer was put onto the ordered list for this
31318c2ecf20Sopenharmony_ci		 * transaction, we know for sure either this transaction
31328c2ecf20Sopenharmony_ci		 * or an older one already has updated i_size on disk,
31338c2ecf20Sopenharmony_ci		 * and this ordered data won't be referenced in the file
31348c2ecf20Sopenharmony_ci		 * if we crash.
31358c2ecf20Sopenharmony_ci		 *
31368c2ecf20Sopenharmony_ci		 * if the buffer was put onto the ordered list for an older
31378c2ecf20Sopenharmony_ci		 * transaction, we need to leave it around
31388c2ecf20Sopenharmony_ci		 */
31398c2ecf20Sopenharmony_ci		if (jh && (jl = jh->jl)
31408c2ecf20Sopenharmony_ci		    && jl != SB_JOURNAL(inode->i_sb)->j_current_jl)
31418c2ecf20Sopenharmony_ci			ret = 0;
31428c2ecf20Sopenharmony_ci	}
31438c2ecf20Sopenharmony_cifree_jh:
31448c2ecf20Sopenharmony_ci	if (ret && bh->b_private) {
31458c2ecf20Sopenharmony_ci		reiserfs_free_jh(bh);
31468c2ecf20Sopenharmony_ci	}
31478c2ecf20Sopenharmony_ci	spin_unlock(&j->j_dirty_buffers_lock);
31488c2ecf20Sopenharmony_ci	unlock_buffer(bh);
31498c2ecf20Sopenharmony_ci	return ret;
31508c2ecf20Sopenharmony_ci}
31518c2ecf20Sopenharmony_ci
31528c2ecf20Sopenharmony_ci/* clm -- taken from fs/buffer.c:block_invalidate_page */
31538c2ecf20Sopenharmony_cistatic void reiserfs_invalidatepage(struct page *page, unsigned int offset,
31548c2ecf20Sopenharmony_ci				    unsigned int length)
31558c2ecf20Sopenharmony_ci{
31568c2ecf20Sopenharmony_ci	struct buffer_head *head, *bh, *next;
31578c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
31588c2ecf20Sopenharmony_ci	unsigned int curr_off = 0;
31598c2ecf20Sopenharmony_ci	unsigned int stop = offset + length;
31608c2ecf20Sopenharmony_ci	int partial_page = (offset || length < PAGE_SIZE);
31618c2ecf20Sopenharmony_ci	int ret = 1;
31628c2ecf20Sopenharmony_ci
31638c2ecf20Sopenharmony_ci	BUG_ON(!PageLocked(page));
31648c2ecf20Sopenharmony_ci
31658c2ecf20Sopenharmony_ci	if (!partial_page)
31668c2ecf20Sopenharmony_ci		ClearPageChecked(page);
31678c2ecf20Sopenharmony_ci
31688c2ecf20Sopenharmony_ci	if (!page_has_buffers(page))
31698c2ecf20Sopenharmony_ci		goto out;
31708c2ecf20Sopenharmony_ci
31718c2ecf20Sopenharmony_ci	head = page_buffers(page);
31728c2ecf20Sopenharmony_ci	bh = head;
31738c2ecf20Sopenharmony_ci	do {
31748c2ecf20Sopenharmony_ci		unsigned int next_off = curr_off + bh->b_size;
31758c2ecf20Sopenharmony_ci		next = bh->b_this_page;
31768c2ecf20Sopenharmony_ci
31778c2ecf20Sopenharmony_ci		if (next_off > stop)
31788c2ecf20Sopenharmony_ci			goto out;
31798c2ecf20Sopenharmony_ci
31808c2ecf20Sopenharmony_ci		/*
31818c2ecf20Sopenharmony_ci		 * is this block fully invalidated?
31828c2ecf20Sopenharmony_ci		 */
31838c2ecf20Sopenharmony_ci		if (offset <= curr_off) {
31848c2ecf20Sopenharmony_ci			if (invalidatepage_can_drop(inode, bh))
31858c2ecf20Sopenharmony_ci				reiserfs_unmap_buffer(bh);
31868c2ecf20Sopenharmony_ci			else
31878c2ecf20Sopenharmony_ci				ret = 0;
31888c2ecf20Sopenharmony_ci		}
31898c2ecf20Sopenharmony_ci		curr_off = next_off;
31908c2ecf20Sopenharmony_ci		bh = next;
31918c2ecf20Sopenharmony_ci	} while (bh != head);
31928c2ecf20Sopenharmony_ci
31938c2ecf20Sopenharmony_ci	/*
31948c2ecf20Sopenharmony_ci	 * We release buffers only if the entire page is being invalidated.
31958c2ecf20Sopenharmony_ci	 * The get_block cached value has been unconditionally invalidated,
31968c2ecf20Sopenharmony_ci	 * so real IO is not possible anymore.
31978c2ecf20Sopenharmony_ci	 */
31988c2ecf20Sopenharmony_ci	if (!partial_page && ret) {
31998c2ecf20Sopenharmony_ci		ret = try_to_release_page(page, 0);
32008c2ecf20Sopenharmony_ci		/* maybe should BUG_ON(!ret); - neilb */
32018c2ecf20Sopenharmony_ci	}
32028c2ecf20Sopenharmony_ciout:
32038c2ecf20Sopenharmony_ci	return;
32048c2ecf20Sopenharmony_ci}
32058c2ecf20Sopenharmony_ci
32068c2ecf20Sopenharmony_cistatic int reiserfs_set_page_dirty(struct page *page)
32078c2ecf20Sopenharmony_ci{
32088c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
32098c2ecf20Sopenharmony_ci	if (reiserfs_file_data_log(inode)) {
32108c2ecf20Sopenharmony_ci		SetPageChecked(page);
32118c2ecf20Sopenharmony_ci		return __set_page_dirty_nobuffers(page);
32128c2ecf20Sopenharmony_ci	}
32138c2ecf20Sopenharmony_ci	return __set_page_dirty_buffers(page);
32148c2ecf20Sopenharmony_ci}
32158c2ecf20Sopenharmony_ci
32168c2ecf20Sopenharmony_ci/*
32178c2ecf20Sopenharmony_ci * Returns 1 if the page's buffers were dropped.  The page is locked.
32188c2ecf20Sopenharmony_ci *
32198c2ecf20Sopenharmony_ci * Takes j_dirty_buffers_lock to protect the b_assoc_buffers list_heads
32208c2ecf20Sopenharmony_ci * in the buffers at page_buffers(page).
32218c2ecf20Sopenharmony_ci *
32228c2ecf20Sopenharmony_ci * even in -o notail mode, we can't be sure an old mount without -o notail
32238c2ecf20Sopenharmony_ci * didn't create files with tails.
32248c2ecf20Sopenharmony_ci */
32258c2ecf20Sopenharmony_cistatic int reiserfs_releasepage(struct page *page, gfp_t unused_gfp_flags)
32268c2ecf20Sopenharmony_ci{
32278c2ecf20Sopenharmony_ci	struct inode *inode = page->mapping->host;
32288c2ecf20Sopenharmony_ci	struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
32298c2ecf20Sopenharmony_ci	struct buffer_head *head;
32308c2ecf20Sopenharmony_ci	struct buffer_head *bh;
32318c2ecf20Sopenharmony_ci	int ret = 1;
32328c2ecf20Sopenharmony_ci
32338c2ecf20Sopenharmony_ci	WARN_ON(PageChecked(page));
32348c2ecf20Sopenharmony_ci	spin_lock(&j->j_dirty_buffers_lock);
32358c2ecf20Sopenharmony_ci	head = page_buffers(page);
32368c2ecf20Sopenharmony_ci	bh = head;
32378c2ecf20Sopenharmony_ci	do {
32388c2ecf20Sopenharmony_ci		if (bh->b_private) {
32398c2ecf20Sopenharmony_ci			if (!buffer_dirty(bh) && !buffer_locked(bh)) {
32408c2ecf20Sopenharmony_ci				reiserfs_free_jh(bh);
32418c2ecf20Sopenharmony_ci			} else {
32428c2ecf20Sopenharmony_ci				ret = 0;
32438c2ecf20Sopenharmony_ci				break;
32448c2ecf20Sopenharmony_ci			}
32458c2ecf20Sopenharmony_ci		}
32468c2ecf20Sopenharmony_ci		bh = bh->b_this_page;
32478c2ecf20Sopenharmony_ci	} while (bh != head);
32488c2ecf20Sopenharmony_ci	if (ret)
32498c2ecf20Sopenharmony_ci		ret = try_to_free_buffers(page);
32508c2ecf20Sopenharmony_ci	spin_unlock(&j->j_dirty_buffers_lock);
32518c2ecf20Sopenharmony_ci	return ret;
32528c2ecf20Sopenharmony_ci}
32538c2ecf20Sopenharmony_ci
32548c2ecf20Sopenharmony_ci/*
32558c2ecf20Sopenharmony_ci * We thank Mingming Cao for helping us understand in great detail what
32568c2ecf20Sopenharmony_ci * to do in this section of the code.
32578c2ecf20Sopenharmony_ci */
32588c2ecf20Sopenharmony_cistatic ssize_t reiserfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
32598c2ecf20Sopenharmony_ci{
32608c2ecf20Sopenharmony_ci	struct file *file = iocb->ki_filp;
32618c2ecf20Sopenharmony_ci	struct inode *inode = file->f_mapping->host;
32628c2ecf20Sopenharmony_ci	size_t count = iov_iter_count(iter);
32638c2ecf20Sopenharmony_ci	ssize_t ret;
32648c2ecf20Sopenharmony_ci
32658c2ecf20Sopenharmony_ci	ret = blockdev_direct_IO(iocb, inode, iter,
32668c2ecf20Sopenharmony_ci				 reiserfs_get_blocks_direct_io);
32678c2ecf20Sopenharmony_ci
32688c2ecf20Sopenharmony_ci	/*
32698c2ecf20Sopenharmony_ci	 * In case of error extending write may have instantiated a few
32708c2ecf20Sopenharmony_ci	 * blocks outside i_size. Trim these off again.
32718c2ecf20Sopenharmony_ci	 */
32728c2ecf20Sopenharmony_ci	if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) {
32738c2ecf20Sopenharmony_ci		loff_t isize = i_size_read(inode);
32748c2ecf20Sopenharmony_ci		loff_t end = iocb->ki_pos + count;
32758c2ecf20Sopenharmony_ci
32768c2ecf20Sopenharmony_ci		if ((end > isize) && inode_newsize_ok(inode, isize) == 0) {
32778c2ecf20Sopenharmony_ci			truncate_setsize(inode, isize);
32788c2ecf20Sopenharmony_ci			reiserfs_vfs_truncate_file(inode);
32798c2ecf20Sopenharmony_ci		}
32808c2ecf20Sopenharmony_ci	}
32818c2ecf20Sopenharmony_ci
32828c2ecf20Sopenharmony_ci	return ret;
32838c2ecf20Sopenharmony_ci}
32848c2ecf20Sopenharmony_ci
32858c2ecf20Sopenharmony_ciint reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
32868c2ecf20Sopenharmony_ci{
32878c2ecf20Sopenharmony_ci	struct inode *inode = d_inode(dentry);
32888c2ecf20Sopenharmony_ci	unsigned int ia_valid;
32898c2ecf20Sopenharmony_ci	int error;
32908c2ecf20Sopenharmony_ci
32918c2ecf20Sopenharmony_ci	error = setattr_prepare(dentry, attr);
32928c2ecf20Sopenharmony_ci	if (error)
32938c2ecf20Sopenharmony_ci		return error;
32948c2ecf20Sopenharmony_ci
32958c2ecf20Sopenharmony_ci	/* must be turned off for recursive notify_change calls */
32968c2ecf20Sopenharmony_ci	ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
32978c2ecf20Sopenharmony_ci
32988c2ecf20Sopenharmony_ci	if (is_quota_modification(inode, attr)) {
32998c2ecf20Sopenharmony_ci		error = dquot_initialize(inode);
33008c2ecf20Sopenharmony_ci		if (error)
33018c2ecf20Sopenharmony_ci			return error;
33028c2ecf20Sopenharmony_ci	}
33038c2ecf20Sopenharmony_ci	reiserfs_write_lock(inode->i_sb);
33048c2ecf20Sopenharmony_ci	if (attr->ia_valid & ATTR_SIZE) {
33058c2ecf20Sopenharmony_ci		/*
33068c2ecf20Sopenharmony_ci		 * version 2 items will be caught by the s_maxbytes check
33078c2ecf20Sopenharmony_ci		 * done for us in vmtruncate
33088c2ecf20Sopenharmony_ci		 */
33098c2ecf20Sopenharmony_ci		if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
33108c2ecf20Sopenharmony_ci		    attr->ia_size > MAX_NON_LFS) {
33118c2ecf20Sopenharmony_ci			reiserfs_write_unlock(inode->i_sb);
33128c2ecf20Sopenharmony_ci			error = -EFBIG;
33138c2ecf20Sopenharmony_ci			goto out;
33148c2ecf20Sopenharmony_ci		}
33158c2ecf20Sopenharmony_ci
33168c2ecf20Sopenharmony_ci		inode_dio_wait(inode);
33178c2ecf20Sopenharmony_ci
33188c2ecf20Sopenharmony_ci		/* fill in hole pointers in the expanding truncate case. */
33198c2ecf20Sopenharmony_ci		if (attr->ia_size > inode->i_size) {
33208c2ecf20Sopenharmony_ci			error = generic_cont_expand_simple(inode, attr->ia_size);
33218c2ecf20Sopenharmony_ci			if (REISERFS_I(inode)->i_prealloc_count > 0) {
33228c2ecf20Sopenharmony_ci				int err;
33238c2ecf20Sopenharmony_ci				struct reiserfs_transaction_handle th;
33248c2ecf20Sopenharmony_ci				/* we're changing at most 2 bitmaps, inode + super */
33258c2ecf20Sopenharmony_ci				err = journal_begin(&th, inode->i_sb, 4);
33268c2ecf20Sopenharmony_ci				if (!err) {
33278c2ecf20Sopenharmony_ci					reiserfs_discard_prealloc(&th, inode);
33288c2ecf20Sopenharmony_ci					err = journal_end(&th);
33298c2ecf20Sopenharmony_ci				}
33308c2ecf20Sopenharmony_ci				if (err)
33318c2ecf20Sopenharmony_ci					error = err;
33328c2ecf20Sopenharmony_ci			}
33338c2ecf20Sopenharmony_ci			if (error) {
33348c2ecf20Sopenharmony_ci				reiserfs_write_unlock(inode->i_sb);
33358c2ecf20Sopenharmony_ci				goto out;
33368c2ecf20Sopenharmony_ci			}
33378c2ecf20Sopenharmony_ci			/*
33388c2ecf20Sopenharmony_ci			 * file size is changed, ctime and mtime are
33398c2ecf20Sopenharmony_ci			 * to be updated
33408c2ecf20Sopenharmony_ci			 */
33418c2ecf20Sopenharmony_ci			attr->ia_valid |= (ATTR_MTIME | ATTR_CTIME);
33428c2ecf20Sopenharmony_ci		}
33438c2ecf20Sopenharmony_ci	}
33448c2ecf20Sopenharmony_ci	reiserfs_write_unlock(inode->i_sb);
33458c2ecf20Sopenharmony_ci
33468c2ecf20Sopenharmony_ci	if ((((attr->ia_valid & ATTR_UID) && (from_kuid(&init_user_ns, attr->ia_uid) & ~0xffff)) ||
33478c2ecf20Sopenharmony_ci	     ((attr->ia_valid & ATTR_GID) && (from_kgid(&init_user_ns, attr->ia_gid) & ~0xffff))) &&
33488c2ecf20Sopenharmony_ci	    (get_inode_sd_version(inode) == STAT_DATA_V1)) {
33498c2ecf20Sopenharmony_ci		/* stat data of format v3.5 has 16 bit uid and gid */
33508c2ecf20Sopenharmony_ci		error = -EINVAL;
33518c2ecf20Sopenharmony_ci		goto out;
33528c2ecf20Sopenharmony_ci	}
33538c2ecf20Sopenharmony_ci
33548c2ecf20Sopenharmony_ci	if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
33558c2ecf20Sopenharmony_ci	    (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
33568c2ecf20Sopenharmony_ci		struct reiserfs_transaction_handle th;
33578c2ecf20Sopenharmony_ci		int jbegin_count =
33588c2ecf20Sopenharmony_ci		    2 *
33598c2ecf20Sopenharmony_ci		    (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) +
33608c2ecf20Sopenharmony_ci		     REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) +
33618c2ecf20Sopenharmony_ci		    2;
33628c2ecf20Sopenharmony_ci
33638c2ecf20Sopenharmony_ci		error = reiserfs_chown_xattrs(inode, attr);
33648c2ecf20Sopenharmony_ci
33658c2ecf20Sopenharmony_ci		if (error)
33668c2ecf20Sopenharmony_ci			return error;
33678c2ecf20Sopenharmony_ci
33688c2ecf20Sopenharmony_ci		/*
33698c2ecf20Sopenharmony_ci		 * (user+group)*(old+new) structure - we count quota
33708c2ecf20Sopenharmony_ci		 * info and , inode write (sb, inode)
33718c2ecf20Sopenharmony_ci		 */
33728c2ecf20Sopenharmony_ci		reiserfs_write_lock(inode->i_sb);
33738c2ecf20Sopenharmony_ci		error = journal_begin(&th, inode->i_sb, jbegin_count);
33748c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
33758c2ecf20Sopenharmony_ci		if (error)
33768c2ecf20Sopenharmony_ci			goto out;
33778c2ecf20Sopenharmony_ci		error = dquot_transfer(inode, attr);
33788c2ecf20Sopenharmony_ci		reiserfs_write_lock(inode->i_sb);
33798c2ecf20Sopenharmony_ci		if (error) {
33808c2ecf20Sopenharmony_ci			journal_end(&th);
33818c2ecf20Sopenharmony_ci			reiserfs_write_unlock(inode->i_sb);
33828c2ecf20Sopenharmony_ci			goto out;
33838c2ecf20Sopenharmony_ci		}
33848c2ecf20Sopenharmony_ci
33858c2ecf20Sopenharmony_ci		/*
33868c2ecf20Sopenharmony_ci		 * Update corresponding info in inode so that everything
33878c2ecf20Sopenharmony_ci		 * is in one transaction
33888c2ecf20Sopenharmony_ci		 */
33898c2ecf20Sopenharmony_ci		if (attr->ia_valid & ATTR_UID)
33908c2ecf20Sopenharmony_ci			inode->i_uid = attr->ia_uid;
33918c2ecf20Sopenharmony_ci		if (attr->ia_valid & ATTR_GID)
33928c2ecf20Sopenharmony_ci			inode->i_gid = attr->ia_gid;
33938c2ecf20Sopenharmony_ci		mark_inode_dirty(inode);
33948c2ecf20Sopenharmony_ci		error = journal_end(&th);
33958c2ecf20Sopenharmony_ci		reiserfs_write_unlock(inode->i_sb);
33968c2ecf20Sopenharmony_ci		if (error)
33978c2ecf20Sopenharmony_ci			goto out;
33988c2ecf20Sopenharmony_ci	}
33998c2ecf20Sopenharmony_ci
34008c2ecf20Sopenharmony_ci	if ((attr->ia_valid & ATTR_SIZE) &&
34018c2ecf20Sopenharmony_ci	    attr->ia_size != i_size_read(inode)) {
34028c2ecf20Sopenharmony_ci		error = inode_newsize_ok(inode, attr->ia_size);
34038c2ecf20Sopenharmony_ci		if (!error) {
34048c2ecf20Sopenharmony_ci			/*
34058c2ecf20Sopenharmony_ci			 * Could race against reiserfs_file_release
34068c2ecf20Sopenharmony_ci			 * if called from NFS, so take tailpack mutex.
34078c2ecf20Sopenharmony_ci			 */
34088c2ecf20Sopenharmony_ci			mutex_lock(&REISERFS_I(inode)->tailpack);
34098c2ecf20Sopenharmony_ci			truncate_setsize(inode, attr->ia_size);
34108c2ecf20Sopenharmony_ci			reiserfs_truncate_file(inode, 1);
34118c2ecf20Sopenharmony_ci			mutex_unlock(&REISERFS_I(inode)->tailpack);
34128c2ecf20Sopenharmony_ci		}
34138c2ecf20Sopenharmony_ci	}
34148c2ecf20Sopenharmony_ci
34158c2ecf20Sopenharmony_ci	if (!error) {
34168c2ecf20Sopenharmony_ci		setattr_copy(inode, attr);
34178c2ecf20Sopenharmony_ci		mark_inode_dirty(inode);
34188c2ecf20Sopenharmony_ci	}
34198c2ecf20Sopenharmony_ci
34208c2ecf20Sopenharmony_ci	if (!error && reiserfs_posixacl(inode->i_sb)) {
34218c2ecf20Sopenharmony_ci		if (attr->ia_valid & ATTR_MODE)
34228c2ecf20Sopenharmony_ci			error = reiserfs_acl_chmod(inode);
34238c2ecf20Sopenharmony_ci	}
34248c2ecf20Sopenharmony_ci
34258c2ecf20Sopenharmony_ciout:
34268c2ecf20Sopenharmony_ci	return error;
34278c2ecf20Sopenharmony_ci}
34288c2ecf20Sopenharmony_ci
34298c2ecf20Sopenharmony_ciconst struct address_space_operations reiserfs_address_space_operations = {
34308c2ecf20Sopenharmony_ci	.writepage = reiserfs_writepage,
34318c2ecf20Sopenharmony_ci	.readpage = reiserfs_readpage,
34328c2ecf20Sopenharmony_ci	.readahead = reiserfs_readahead,
34338c2ecf20Sopenharmony_ci	.releasepage = reiserfs_releasepage,
34348c2ecf20Sopenharmony_ci	.invalidatepage = reiserfs_invalidatepage,
34358c2ecf20Sopenharmony_ci	.write_begin = reiserfs_write_begin,
34368c2ecf20Sopenharmony_ci	.write_end = reiserfs_write_end,
34378c2ecf20Sopenharmony_ci	.bmap = reiserfs_aop_bmap,
34388c2ecf20Sopenharmony_ci	.direct_IO = reiserfs_direct_IO,
34398c2ecf20Sopenharmony_ci	.set_page_dirty = reiserfs_set_page_dirty,
34408c2ecf20Sopenharmony_ci};
3441