162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * inode.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * vfs' aops, fops, dops and iops
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/fs.h>
1162306a36Sopenharmony_ci#include <linux/types.h>
1262306a36Sopenharmony_ci#include <linux/highmem.h>
1362306a36Sopenharmony_ci#include <linux/pagemap.h>
1462306a36Sopenharmony_ci#include <linux/quotaops.h>
1562306a36Sopenharmony_ci#include <linux/iversion.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <asm/byteorder.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include <cluster/masklog.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#include "ocfs2.h"
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include "alloc.h"
2462306a36Sopenharmony_ci#include "dir.h"
2562306a36Sopenharmony_ci#include "blockcheck.h"
2662306a36Sopenharmony_ci#include "dlmglue.h"
2762306a36Sopenharmony_ci#include "extent_map.h"
2862306a36Sopenharmony_ci#include "file.h"
2962306a36Sopenharmony_ci#include "heartbeat.h"
3062306a36Sopenharmony_ci#include "inode.h"
3162306a36Sopenharmony_ci#include "journal.h"
3262306a36Sopenharmony_ci#include "namei.h"
3362306a36Sopenharmony_ci#include "suballoc.h"
3462306a36Sopenharmony_ci#include "super.h"
3562306a36Sopenharmony_ci#include "symlink.h"
3662306a36Sopenharmony_ci#include "sysfile.h"
3762306a36Sopenharmony_ci#include "uptodate.h"
3862306a36Sopenharmony_ci#include "xattr.h"
3962306a36Sopenharmony_ci#include "refcounttree.h"
4062306a36Sopenharmony_ci#include "ocfs2_trace.h"
4162306a36Sopenharmony_ci#include "filecheck.h"
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#include "buffer_head_io.h"
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistruct ocfs2_find_inode_args
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	u64		fi_blkno;
4862306a36Sopenharmony_ci	unsigned long	fi_ino;
4962306a36Sopenharmony_ci	unsigned int	fi_flags;
5062306a36Sopenharmony_ci	unsigned int	fi_sysfile_type;
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic struct lock_class_key ocfs2_sysfile_lock_key[NUM_SYSTEM_INODES];
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic int ocfs2_read_locked_inode(struct inode *inode,
5662306a36Sopenharmony_ci				   struct ocfs2_find_inode_args *args);
5762306a36Sopenharmony_cistatic int ocfs2_init_locked_inode(struct inode *inode, void *opaque);
5862306a36Sopenharmony_cistatic int ocfs2_find_actor(struct inode *inode, void *opaque);
5962306a36Sopenharmony_cistatic int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
6062306a36Sopenharmony_ci				    struct inode *inode,
6162306a36Sopenharmony_ci				    struct buffer_head *fe_bh);
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic int ocfs2_filecheck_read_inode_block_full(struct inode *inode,
6462306a36Sopenharmony_ci						 struct buffer_head **bh,
6562306a36Sopenharmony_ci						 int flags, int type);
6662306a36Sopenharmony_cistatic int ocfs2_filecheck_validate_inode_block(struct super_block *sb,
6762306a36Sopenharmony_ci						struct buffer_head *bh);
6862306a36Sopenharmony_cistatic int ocfs2_filecheck_repair_inode_block(struct super_block *sb,
6962306a36Sopenharmony_ci					      struct buffer_head *bh);
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_civoid ocfs2_set_inode_flags(struct inode *inode)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	unsigned int flags = OCFS2_I(inode)->ip_attr;
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	inode->i_flags &= ~(S_IMMUTABLE |
7662306a36Sopenharmony_ci		S_SYNC | S_APPEND | S_NOATIME | S_DIRSYNC);
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	if (flags & OCFS2_IMMUTABLE_FL)
7962306a36Sopenharmony_ci		inode->i_flags |= S_IMMUTABLE;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	if (flags & OCFS2_SYNC_FL)
8262306a36Sopenharmony_ci		inode->i_flags |= S_SYNC;
8362306a36Sopenharmony_ci	if (flags & OCFS2_APPEND_FL)
8462306a36Sopenharmony_ci		inode->i_flags |= S_APPEND;
8562306a36Sopenharmony_ci	if (flags & OCFS2_NOATIME_FL)
8662306a36Sopenharmony_ci		inode->i_flags |= S_NOATIME;
8762306a36Sopenharmony_ci	if (flags & OCFS2_DIRSYNC_FL)
8862306a36Sopenharmony_ci		inode->i_flags |= S_DIRSYNC;
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/* Propagate flags from i_flags to OCFS2_I(inode)->ip_attr */
9262306a36Sopenharmony_civoid ocfs2_get_inode_flags(struct ocfs2_inode_info *oi)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	unsigned int flags = oi->vfs_inode.i_flags;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci	oi->ip_attr &= ~(OCFS2_SYNC_FL|OCFS2_APPEND_FL|
9762306a36Sopenharmony_ci			OCFS2_IMMUTABLE_FL|OCFS2_NOATIME_FL|OCFS2_DIRSYNC_FL);
9862306a36Sopenharmony_ci	if (flags & S_SYNC)
9962306a36Sopenharmony_ci		oi->ip_attr |= OCFS2_SYNC_FL;
10062306a36Sopenharmony_ci	if (flags & S_APPEND)
10162306a36Sopenharmony_ci		oi->ip_attr |= OCFS2_APPEND_FL;
10262306a36Sopenharmony_ci	if (flags & S_IMMUTABLE)
10362306a36Sopenharmony_ci		oi->ip_attr |= OCFS2_IMMUTABLE_FL;
10462306a36Sopenharmony_ci	if (flags & S_NOATIME)
10562306a36Sopenharmony_ci		oi->ip_attr |= OCFS2_NOATIME_FL;
10662306a36Sopenharmony_ci	if (flags & S_DIRSYNC)
10762306a36Sopenharmony_ci		oi->ip_attr |= OCFS2_DIRSYNC_FL;
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cistruct inode *ocfs2_ilookup(struct super_block *sb, u64 blkno)
11162306a36Sopenharmony_ci{
11262306a36Sopenharmony_ci	struct ocfs2_find_inode_args args;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	args.fi_blkno = blkno;
11562306a36Sopenharmony_ci	args.fi_flags = 0;
11662306a36Sopenharmony_ci	args.fi_ino = ino_from_blkno(sb, blkno);
11762306a36Sopenharmony_ci	args.fi_sysfile_type = 0;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	return ilookup5(sb, blkno, ocfs2_find_actor, &args);
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_cistruct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags,
12262306a36Sopenharmony_ci			 int sysfile_type)
12362306a36Sopenharmony_ci{
12462306a36Sopenharmony_ci	int rc = -ESTALE;
12562306a36Sopenharmony_ci	struct inode *inode = NULL;
12662306a36Sopenharmony_ci	struct super_block *sb = osb->sb;
12762306a36Sopenharmony_ci	struct ocfs2_find_inode_args args;
12862306a36Sopenharmony_ci	journal_t *journal = osb->journal->j_journal;
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	trace_ocfs2_iget_begin((unsigned long long)blkno, flags,
13162306a36Sopenharmony_ci			       sysfile_type);
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	/* Ok. By now we've either got the offsets passed to us by the
13462306a36Sopenharmony_ci	 * caller, or we just pulled them off the bh. Lets do some
13562306a36Sopenharmony_ci	 * sanity checks to make sure they're OK. */
13662306a36Sopenharmony_ci	if (blkno == 0) {
13762306a36Sopenharmony_ci		inode = ERR_PTR(-EINVAL);
13862306a36Sopenharmony_ci		mlog_errno(PTR_ERR(inode));
13962306a36Sopenharmony_ci		goto bail;
14062306a36Sopenharmony_ci	}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	args.fi_blkno = blkno;
14362306a36Sopenharmony_ci	args.fi_flags = flags;
14462306a36Sopenharmony_ci	args.fi_ino = ino_from_blkno(sb, blkno);
14562306a36Sopenharmony_ci	args.fi_sysfile_type = sysfile_type;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	inode = iget5_locked(sb, args.fi_ino, ocfs2_find_actor,
14862306a36Sopenharmony_ci			     ocfs2_init_locked_inode, &args);
14962306a36Sopenharmony_ci	/* inode was *not* in the inode cache. 2.6.x requires
15062306a36Sopenharmony_ci	 * us to do our own read_inode call and unlock it
15162306a36Sopenharmony_ci	 * afterwards. */
15262306a36Sopenharmony_ci	if (inode == NULL) {
15362306a36Sopenharmony_ci		inode = ERR_PTR(-ENOMEM);
15462306a36Sopenharmony_ci		mlog_errno(PTR_ERR(inode));
15562306a36Sopenharmony_ci		goto bail;
15662306a36Sopenharmony_ci	}
15762306a36Sopenharmony_ci	trace_ocfs2_iget5_locked(inode->i_state);
15862306a36Sopenharmony_ci	if (inode->i_state & I_NEW) {
15962306a36Sopenharmony_ci		rc = ocfs2_read_locked_inode(inode, &args);
16062306a36Sopenharmony_ci		unlock_new_inode(inode);
16162306a36Sopenharmony_ci	}
16262306a36Sopenharmony_ci	if (is_bad_inode(inode)) {
16362306a36Sopenharmony_ci		iput(inode);
16462306a36Sopenharmony_ci		inode = ERR_PTR(rc);
16562306a36Sopenharmony_ci		goto bail;
16662306a36Sopenharmony_ci	}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci	/*
16962306a36Sopenharmony_ci	 * Set transaction id's of transactions that have to be committed
17062306a36Sopenharmony_ci	 * to finish f[data]sync. We set them to currently running transaction
17162306a36Sopenharmony_ci	 * as we cannot be sure that the inode or some of its metadata isn't
17262306a36Sopenharmony_ci	 * part of the transaction - the inode could have been reclaimed and
17362306a36Sopenharmony_ci	 * now it is reread from disk.
17462306a36Sopenharmony_ci	 */
17562306a36Sopenharmony_ci	if (journal) {
17662306a36Sopenharmony_ci		transaction_t *transaction;
17762306a36Sopenharmony_ci		tid_t tid;
17862306a36Sopenharmony_ci		struct ocfs2_inode_info *oi = OCFS2_I(inode);
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci		read_lock(&journal->j_state_lock);
18162306a36Sopenharmony_ci		if (journal->j_running_transaction)
18262306a36Sopenharmony_ci			transaction = journal->j_running_transaction;
18362306a36Sopenharmony_ci		else
18462306a36Sopenharmony_ci			transaction = journal->j_committing_transaction;
18562306a36Sopenharmony_ci		if (transaction)
18662306a36Sopenharmony_ci			tid = transaction->t_tid;
18762306a36Sopenharmony_ci		else
18862306a36Sopenharmony_ci			tid = journal->j_commit_sequence;
18962306a36Sopenharmony_ci		read_unlock(&journal->j_state_lock);
19062306a36Sopenharmony_ci		oi->i_sync_tid = tid;
19162306a36Sopenharmony_ci		oi->i_datasync_tid = tid;
19262306a36Sopenharmony_ci	}
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_cibail:
19562306a36Sopenharmony_ci	if (!IS_ERR(inode)) {
19662306a36Sopenharmony_ci		trace_ocfs2_iget_end(inode,
19762306a36Sopenharmony_ci			(unsigned long long)OCFS2_I(inode)->ip_blkno);
19862306a36Sopenharmony_ci	}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	return inode;
20162306a36Sopenharmony_ci}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci/*
20562306a36Sopenharmony_ci * here's how inodes get read from disk:
20662306a36Sopenharmony_ci * iget5_locked -> find_actor -> OCFS2_FIND_ACTOR
20762306a36Sopenharmony_ci * found? : return the in-memory inode
20862306a36Sopenharmony_ci * not found? : get_new_inode -> OCFS2_INIT_LOCKED_INODE
20962306a36Sopenharmony_ci */
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_cistatic int ocfs2_find_actor(struct inode *inode, void *opaque)
21262306a36Sopenharmony_ci{
21362306a36Sopenharmony_ci	struct ocfs2_find_inode_args *args = NULL;
21462306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
21562306a36Sopenharmony_ci	int ret = 0;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	args = opaque;
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	mlog_bug_on_msg(!inode, "No inode in find actor!\n");
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	trace_ocfs2_find_actor(inode, inode->i_ino, opaque, args->fi_blkno);
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	if (oi->ip_blkno != args->fi_blkno)
22462306a36Sopenharmony_ci		goto bail;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	ret = 1;
22762306a36Sopenharmony_cibail:
22862306a36Sopenharmony_ci	return ret;
22962306a36Sopenharmony_ci}
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci/*
23262306a36Sopenharmony_ci * initialize the new inode, but don't do anything that would cause
23362306a36Sopenharmony_ci * us to sleep.
23462306a36Sopenharmony_ci * return 0 on success, 1 on failure
23562306a36Sopenharmony_ci */
23662306a36Sopenharmony_cistatic int ocfs2_init_locked_inode(struct inode *inode, void *opaque)
23762306a36Sopenharmony_ci{
23862306a36Sopenharmony_ci	struct ocfs2_find_inode_args *args = opaque;
23962306a36Sopenharmony_ci	static struct lock_class_key ocfs2_quota_ip_alloc_sem_key,
24062306a36Sopenharmony_ci				     ocfs2_file_ip_alloc_sem_key;
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci	inode->i_ino = args->fi_ino;
24362306a36Sopenharmony_ci	OCFS2_I(inode)->ip_blkno = args->fi_blkno;
24462306a36Sopenharmony_ci	if (args->fi_sysfile_type != 0)
24562306a36Sopenharmony_ci		lockdep_set_class(&inode->i_rwsem,
24662306a36Sopenharmony_ci			&ocfs2_sysfile_lock_key[args->fi_sysfile_type]);
24762306a36Sopenharmony_ci	if (args->fi_sysfile_type == USER_QUOTA_SYSTEM_INODE ||
24862306a36Sopenharmony_ci	    args->fi_sysfile_type == GROUP_QUOTA_SYSTEM_INODE ||
24962306a36Sopenharmony_ci	    args->fi_sysfile_type == LOCAL_USER_QUOTA_SYSTEM_INODE ||
25062306a36Sopenharmony_ci	    args->fi_sysfile_type == LOCAL_GROUP_QUOTA_SYSTEM_INODE)
25162306a36Sopenharmony_ci		lockdep_set_class(&OCFS2_I(inode)->ip_alloc_sem,
25262306a36Sopenharmony_ci				  &ocfs2_quota_ip_alloc_sem_key);
25362306a36Sopenharmony_ci	else
25462306a36Sopenharmony_ci		lockdep_set_class(&OCFS2_I(inode)->ip_alloc_sem,
25562306a36Sopenharmony_ci				  &ocfs2_file_ip_alloc_sem_key);
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	return 0;
25862306a36Sopenharmony_ci}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_civoid ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
26162306a36Sopenharmony_ci			  int create_ino)
26262306a36Sopenharmony_ci{
26362306a36Sopenharmony_ci	struct super_block *sb;
26462306a36Sopenharmony_ci	struct ocfs2_super *osb;
26562306a36Sopenharmony_ci	int use_plocks = 1;
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	sb = inode->i_sb;
26862306a36Sopenharmony_ci	osb = OCFS2_SB(sb);
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	if ((osb->s_mount_opt & OCFS2_MOUNT_LOCALFLOCKS) ||
27162306a36Sopenharmony_ci	    ocfs2_mount_local(osb) || !ocfs2_stack_supports_plocks())
27262306a36Sopenharmony_ci		use_plocks = 0;
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	/*
27562306a36Sopenharmony_ci	 * These have all been checked by ocfs2_read_inode_block() or set
27662306a36Sopenharmony_ci	 * by ocfs2_mknod_locked(), so a failure is a code bug.
27762306a36Sopenharmony_ci	 */
27862306a36Sopenharmony_ci	BUG_ON(!OCFS2_IS_VALID_DINODE(fe));  /* This means that read_inode
27962306a36Sopenharmony_ci						cannot create a superblock
28062306a36Sopenharmony_ci						inode today.  change if
28162306a36Sopenharmony_ci						that is needed. */
28262306a36Sopenharmony_ci	BUG_ON(!(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL)));
28362306a36Sopenharmony_ci	BUG_ON(le32_to_cpu(fe->i_fs_generation) != osb->fs_generation);
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
28762306a36Sopenharmony_ci	OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
28862306a36Sopenharmony_ci	OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features);
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci	inode_set_iversion(inode, 1);
29162306a36Sopenharmony_ci	inode->i_generation = le32_to_cpu(fe->i_generation);
29262306a36Sopenharmony_ci	inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
29362306a36Sopenharmony_ci	inode->i_mode = le16_to_cpu(fe->i_mode);
29462306a36Sopenharmony_ci	i_uid_write(inode, le32_to_cpu(fe->i_uid));
29562306a36Sopenharmony_ci	i_gid_write(inode, le32_to_cpu(fe->i_gid));
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	/* Fast symlinks will have i_size but no allocated clusters. */
29862306a36Sopenharmony_ci	if (S_ISLNK(inode->i_mode) && !fe->i_clusters) {
29962306a36Sopenharmony_ci		inode->i_blocks = 0;
30062306a36Sopenharmony_ci		inode->i_mapping->a_ops = &ocfs2_fast_symlink_aops;
30162306a36Sopenharmony_ci	} else {
30262306a36Sopenharmony_ci		inode->i_blocks = ocfs2_inode_sector_count(inode);
30362306a36Sopenharmony_ci		inode->i_mapping->a_ops = &ocfs2_aops;
30462306a36Sopenharmony_ci	}
30562306a36Sopenharmony_ci	inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
30662306a36Sopenharmony_ci	inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
30762306a36Sopenharmony_ci	inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
30862306a36Sopenharmony_ci	inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec);
30962306a36Sopenharmony_ci	inode_set_ctime(inode, le64_to_cpu(fe->i_ctime),
31062306a36Sopenharmony_ci		        le32_to_cpu(fe->i_ctime_nsec));
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	if (OCFS2_I(inode)->ip_blkno != le64_to_cpu(fe->i_blkno))
31362306a36Sopenharmony_ci		mlog(ML_ERROR,
31462306a36Sopenharmony_ci		     "ip_blkno %llu != i_blkno %llu!\n",
31562306a36Sopenharmony_ci		     (unsigned long long)OCFS2_I(inode)->ip_blkno,
31662306a36Sopenharmony_ci		     (unsigned long long)le64_to_cpu(fe->i_blkno));
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	set_nlink(inode, ocfs2_read_links_count(fe));
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	trace_ocfs2_populate_inode(OCFS2_I(inode)->ip_blkno,
32162306a36Sopenharmony_ci				   le32_to_cpu(fe->i_flags));
32262306a36Sopenharmony_ci	if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) {
32362306a36Sopenharmony_ci		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE;
32462306a36Sopenharmony_ci		inode->i_flags |= S_NOQUOTA;
32562306a36Sopenharmony_ci	}
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	if (fe->i_flags & cpu_to_le32(OCFS2_LOCAL_ALLOC_FL)) {
32862306a36Sopenharmony_ci		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP;
32962306a36Sopenharmony_ci	} else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) {
33062306a36Sopenharmony_ci		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP;
33162306a36Sopenharmony_ci	} else if (fe->i_flags & cpu_to_le32(OCFS2_QUOTA_FL)) {
33262306a36Sopenharmony_ci		inode->i_flags |= S_NOQUOTA;
33362306a36Sopenharmony_ci	} else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) {
33462306a36Sopenharmony_ci		/* we can't actually hit this as read_inode can't
33562306a36Sopenharmony_ci		 * handle superblocks today ;-) */
33662306a36Sopenharmony_ci		BUG();
33762306a36Sopenharmony_ci	}
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	switch (inode->i_mode & S_IFMT) {
34062306a36Sopenharmony_ci	    case S_IFREG:
34162306a36Sopenharmony_ci		    if (use_plocks)
34262306a36Sopenharmony_ci			    inode->i_fop = &ocfs2_fops;
34362306a36Sopenharmony_ci		    else
34462306a36Sopenharmony_ci			    inode->i_fop = &ocfs2_fops_no_plocks;
34562306a36Sopenharmony_ci		    inode->i_op = &ocfs2_file_iops;
34662306a36Sopenharmony_ci		    i_size_write(inode, le64_to_cpu(fe->i_size));
34762306a36Sopenharmony_ci		    break;
34862306a36Sopenharmony_ci	    case S_IFDIR:
34962306a36Sopenharmony_ci		    inode->i_op = &ocfs2_dir_iops;
35062306a36Sopenharmony_ci		    if (use_plocks)
35162306a36Sopenharmony_ci			    inode->i_fop = &ocfs2_dops;
35262306a36Sopenharmony_ci		    else
35362306a36Sopenharmony_ci			    inode->i_fop = &ocfs2_dops_no_plocks;
35462306a36Sopenharmony_ci		    i_size_write(inode, le64_to_cpu(fe->i_size));
35562306a36Sopenharmony_ci		    OCFS2_I(inode)->ip_dir_lock_gen = 1;
35662306a36Sopenharmony_ci		    break;
35762306a36Sopenharmony_ci	    case S_IFLNK:
35862306a36Sopenharmony_ci		    inode->i_op = &ocfs2_symlink_inode_operations;
35962306a36Sopenharmony_ci		    inode_nohighmem(inode);
36062306a36Sopenharmony_ci		    i_size_write(inode, le64_to_cpu(fe->i_size));
36162306a36Sopenharmony_ci		    break;
36262306a36Sopenharmony_ci	    default:
36362306a36Sopenharmony_ci		    inode->i_op = &ocfs2_special_file_iops;
36462306a36Sopenharmony_ci		    init_special_inode(inode, inode->i_mode,
36562306a36Sopenharmony_ci				       inode->i_rdev);
36662306a36Sopenharmony_ci		    break;
36762306a36Sopenharmony_ci	}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	if (create_ino) {
37062306a36Sopenharmony_ci		inode->i_ino = ino_from_blkno(inode->i_sb,
37162306a36Sopenharmony_ci			       le64_to_cpu(fe->i_blkno));
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci		/*
37462306a36Sopenharmony_ci		 * If we ever want to create system files from kernel,
37562306a36Sopenharmony_ci		 * the generation argument to
37662306a36Sopenharmony_ci		 * ocfs2_inode_lock_res_init() will have to change.
37762306a36Sopenharmony_ci		 */
37862306a36Sopenharmony_ci		BUG_ON(le32_to_cpu(fe->i_flags) & OCFS2_SYSTEM_FL);
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci		ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_inode_lockres,
38162306a36Sopenharmony_ci					  OCFS2_LOCK_TYPE_META, 0, inode);
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci		ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_open_lockres,
38462306a36Sopenharmony_ci					  OCFS2_LOCK_TYPE_OPEN, 0, inode);
38562306a36Sopenharmony_ci	}
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_rw_lockres,
38862306a36Sopenharmony_ci				  OCFS2_LOCK_TYPE_RW, inode->i_generation,
38962306a36Sopenharmony_ci				  inode);
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	ocfs2_set_inode_flags(inode);
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	OCFS2_I(inode)->ip_last_used_slot = 0;
39462306a36Sopenharmony_ci	OCFS2_I(inode)->ip_last_used_group = 0;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
39762306a36Sopenharmony_ci		ocfs2_resv_set_type(&OCFS2_I(inode)->ip_la_data_resv,
39862306a36Sopenharmony_ci				    OCFS2_RESV_FLAG_DIR);
39962306a36Sopenharmony_ci}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_cistatic int ocfs2_read_locked_inode(struct inode *inode,
40262306a36Sopenharmony_ci				   struct ocfs2_find_inode_args *args)
40362306a36Sopenharmony_ci{
40462306a36Sopenharmony_ci	struct super_block *sb;
40562306a36Sopenharmony_ci	struct ocfs2_super *osb;
40662306a36Sopenharmony_ci	struct ocfs2_dinode *fe;
40762306a36Sopenharmony_ci	struct buffer_head *bh = NULL;
40862306a36Sopenharmony_ci	int status, can_lock, lock_level = 0;
40962306a36Sopenharmony_ci	u32 generation = 0;
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	status = -EINVAL;
41262306a36Sopenharmony_ci	sb = inode->i_sb;
41362306a36Sopenharmony_ci	osb = OCFS2_SB(sb);
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	/*
41662306a36Sopenharmony_ci	 * To improve performance of cold-cache inode stats, we take
41762306a36Sopenharmony_ci	 * the cluster lock here if possible.
41862306a36Sopenharmony_ci	 *
41962306a36Sopenharmony_ci	 * Generally, OCFS2 never trusts the contents of an inode
42062306a36Sopenharmony_ci	 * unless it's holding a cluster lock, so taking it here isn't
42162306a36Sopenharmony_ci	 * a correctness issue as much as it is a performance
42262306a36Sopenharmony_ci	 * improvement.
42362306a36Sopenharmony_ci	 *
42462306a36Sopenharmony_ci	 * There are three times when taking the lock is not a good idea:
42562306a36Sopenharmony_ci	 *
42662306a36Sopenharmony_ci	 * 1) During startup, before we have initialized the DLM.
42762306a36Sopenharmony_ci	 *
42862306a36Sopenharmony_ci	 * 2) If we are reading certain system files which never get
42962306a36Sopenharmony_ci	 *    cluster locks (local alloc, truncate log).
43062306a36Sopenharmony_ci	 *
43162306a36Sopenharmony_ci	 * 3) If the process doing the iget() is responsible for
43262306a36Sopenharmony_ci	 *    orphan dir recovery. We're holding the orphan dir lock and
43362306a36Sopenharmony_ci	 *    can get into a deadlock with another process on another
43462306a36Sopenharmony_ci	 *    node in ->delete_inode().
43562306a36Sopenharmony_ci	 *
43662306a36Sopenharmony_ci	 * #1 and #2 can be simply solved by never taking the lock
43762306a36Sopenharmony_ci	 * here for system files (which are the only type we read
43862306a36Sopenharmony_ci	 * during mount). It's a heavier approach, but our main
43962306a36Sopenharmony_ci	 * concern is user-accessible files anyway.
44062306a36Sopenharmony_ci	 *
44162306a36Sopenharmony_ci	 * #3 works itself out because we'll eventually take the
44262306a36Sopenharmony_ci	 * cluster lock before trusting anything anyway.
44362306a36Sopenharmony_ci	 */
44462306a36Sopenharmony_ci	can_lock = !(args->fi_flags & OCFS2_FI_FLAG_SYSFILE)
44562306a36Sopenharmony_ci		&& !(args->fi_flags & OCFS2_FI_FLAG_ORPHAN_RECOVERY)
44662306a36Sopenharmony_ci		&& !ocfs2_mount_local(osb);
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	trace_ocfs2_read_locked_inode(
44962306a36Sopenharmony_ci		(unsigned long long)OCFS2_I(inode)->ip_blkno, can_lock);
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci	/*
45262306a36Sopenharmony_ci	 * To maintain backwards compatibility with older versions of
45362306a36Sopenharmony_ci	 * ocfs2-tools, we still store the generation value for system
45462306a36Sopenharmony_ci	 * files. The only ones that actually matter to userspace are
45562306a36Sopenharmony_ci	 * the journals, but it's easier and inexpensive to just flag
45662306a36Sopenharmony_ci	 * all system files similarly.
45762306a36Sopenharmony_ci	 */
45862306a36Sopenharmony_ci	if (args->fi_flags & OCFS2_FI_FLAG_SYSFILE)
45962306a36Sopenharmony_ci		generation = osb->fs_generation;
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_inode_lockres,
46262306a36Sopenharmony_ci				  OCFS2_LOCK_TYPE_META,
46362306a36Sopenharmony_ci				  generation, inode);
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci	ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_open_lockres,
46662306a36Sopenharmony_ci				  OCFS2_LOCK_TYPE_OPEN,
46762306a36Sopenharmony_ci				  0, inode);
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	if (can_lock) {
47062306a36Sopenharmony_ci		status = ocfs2_open_lock(inode);
47162306a36Sopenharmony_ci		if (status) {
47262306a36Sopenharmony_ci			make_bad_inode(inode);
47362306a36Sopenharmony_ci			mlog_errno(status);
47462306a36Sopenharmony_ci			return status;
47562306a36Sopenharmony_ci		}
47662306a36Sopenharmony_ci		status = ocfs2_inode_lock(inode, NULL, lock_level);
47762306a36Sopenharmony_ci		if (status) {
47862306a36Sopenharmony_ci			make_bad_inode(inode);
47962306a36Sopenharmony_ci			mlog_errno(status);
48062306a36Sopenharmony_ci			return status;
48162306a36Sopenharmony_ci		}
48262306a36Sopenharmony_ci	}
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	if (args->fi_flags & OCFS2_FI_FLAG_ORPHAN_RECOVERY) {
48562306a36Sopenharmony_ci		status = ocfs2_try_open_lock(inode, 0);
48662306a36Sopenharmony_ci		if (status) {
48762306a36Sopenharmony_ci			make_bad_inode(inode);
48862306a36Sopenharmony_ci			return status;
48962306a36Sopenharmony_ci		}
49062306a36Sopenharmony_ci	}
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	if (can_lock) {
49362306a36Sopenharmony_ci		if (args->fi_flags & OCFS2_FI_FLAG_FILECHECK_CHK)
49462306a36Sopenharmony_ci			status = ocfs2_filecheck_read_inode_block_full(inode,
49562306a36Sopenharmony_ci						&bh, OCFS2_BH_IGNORE_CACHE, 0);
49662306a36Sopenharmony_ci		else if (args->fi_flags & OCFS2_FI_FLAG_FILECHECK_FIX)
49762306a36Sopenharmony_ci			status = ocfs2_filecheck_read_inode_block_full(inode,
49862306a36Sopenharmony_ci						&bh, OCFS2_BH_IGNORE_CACHE, 1);
49962306a36Sopenharmony_ci		else
50062306a36Sopenharmony_ci			status = ocfs2_read_inode_block_full(inode,
50162306a36Sopenharmony_ci						&bh, OCFS2_BH_IGNORE_CACHE);
50262306a36Sopenharmony_ci	} else {
50362306a36Sopenharmony_ci		status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh);
50462306a36Sopenharmony_ci		/*
50562306a36Sopenharmony_ci		 * If buffer is in jbd, then its checksum may not have been
50662306a36Sopenharmony_ci		 * computed as yet.
50762306a36Sopenharmony_ci		 */
50862306a36Sopenharmony_ci		if (!status && !buffer_jbd(bh)) {
50962306a36Sopenharmony_ci			if (args->fi_flags & OCFS2_FI_FLAG_FILECHECK_CHK)
51062306a36Sopenharmony_ci				status = ocfs2_filecheck_validate_inode_block(
51162306a36Sopenharmony_ci								osb->sb, bh);
51262306a36Sopenharmony_ci			else if (args->fi_flags & OCFS2_FI_FLAG_FILECHECK_FIX)
51362306a36Sopenharmony_ci				status = ocfs2_filecheck_repair_inode_block(
51462306a36Sopenharmony_ci								osb->sb, bh);
51562306a36Sopenharmony_ci			else
51662306a36Sopenharmony_ci				status = ocfs2_validate_inode_block(
51762306a36Sopenharmony_ci								osb->sb, bh);
51862306a36Sopenharmony_ci		}
51962306a36Sopenharmony_ci	}
52062306a36Sopenharmony_ci	if (status < 0) {
52162306a36Sopenharmony_ci		mlog_errno(status);
52262306a36Sopenharmony_ci		goto bail;
52362306a36Sopenharmony_ci	}
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci	status = -EINVAL;
52662306a36Sopenharmony_ci	fe = (struct ocfs2_dinode *) bh->b_data;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	/*
52962306a36Sopenharmony_ci	 * This is a code bug. Right now the caller needs to
53062306a36Sopenharmony_ci	 * understand whether it is asking for a system file inode or
53162306a36Sopenharmony_ci	 * not so the proper lock names can be built.
53262306a36Sopenharmony_ci	 */
53362306a36Sopenharmony_ci	mlog_bug_on_msg(!!(fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) !=
53462306a36Sopenharmony_ci			!!(args->fi_flags & OCFS2_FI_FLAG_SYSFILE),
53562306a36Sopenharmony_ci			"Inode %llu: system file state is ambiguous\n",
53662306a36Sopenharmony_ci			(unsigned long long)args->fi_blkno);
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	if (S_ISCHR(le16_to_cpu(fe->i_mode)) ||
53962306a36Sopenharmony_ci	    S_ISBLK(le16_to_cpu(fe->i_mode)))
54062306a36Sopenharmony_ci		inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci	ocfs2_populate_inode(inode, fe, 0);
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci	BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno));
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	if (buffer_dirty(bh) && !buffer_jbd(bh)) {
54762306a36Sopenharmony_ci		if (can_lock) {
54862306a36Sopenharmony_ci			ocfs2_inode_unlock(inode, lock_level);
54962306a36Sopenharmony_ci			lock_level = 1;
55062306a36Sopenharmony_ci			ocfs2_inode_lock(inode, NULL, lock_level);
55162306a36Sopenharmony_ci		}
55262306a36Sopenharmony_ci		status = ocfs2_write_block(osb, bh, INODE_CACHE(inode));
55362306a36Sopenharmony_ci		if (status < 0) {
55462306a36Sopenharmony_ci			mlog_errno(status);
55562306a36Sopenharmony_ci			goto bail;
55662306a36Sopenharmony_ci		}
55762306a36Sopenharmony_ci	}
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci	status = 0;
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_cibail:
56262306a36Sopenharmony_ci	if (can_lock)
56362306a36Sopenharmony_ci		ocfs2_inode_unlock(inode, lock_level);
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	if (status < 0)
56662306a36Sopenharmony_ci		make_bad_inode(inode);
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci	brelse(bh);
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci	return status;
57162306a36Sopenharmony_ci}
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_civoid ocfs2_sync_blockdev(struct super_block *sb)
57462306a36Sopenharmony_ci{
57562306a36Sopenharmony_ci	sync_blockdev(sb->s_bdev);
57662306a36Sopenharmony_ci}
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_cistatic int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
57962306a36Sopenharmony_ci				     struct inode *inode,
58062306a36Sopenharmony_ci				     struct buffer_head *fe_bh)
58162306a36Sopenharmony_ci{
58262306a36Sopenharmony_ci	int status = 0;
58362306a36Sopenharmony_ci	struct ocfs2_dinode *fe;
58462306a36Sopenharmony_ci	handle_t *handle = NULL;
58562306a36Sopenharmony_ci
58662306a36Sopenharmony_ci	fe = (struct ocfs2_dinode *) fe_bh->b_data;
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	/*
58962306a36Sopenharmony_ci	 * This check will also skip truncate of inodes with inline
59062306a36Sopenharmony_ci	 * data and fast symlinks.
59162306a36Sopenharmony_ci	 */
59262306a36Sopenharmony_ci	if (fe->i_clusters) {
59362306a36Sopenharmony_ci		if (ocfs2_should_order_data(inode))
59462306a36Sopenharmony_ci			ocfs2_begin_ordered_truncate(inode, 0);
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci		handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
59762306a36Sopenharmony_ci		if (IS_ERR(handle)) {
59862306a36Sopenharmony_ci			status = PTR_ERR(handle);
59962306a36Sopenharmony_ci			handle = NULL;
60062306a36Sopenharmony_ci			mlog_errno(status);
60162306a36Sopenharmony_ci			goto out;
60262306a36Sopenharmony_ci		}
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci		status = ocfs2_journal_access_di(handle, INODE_CACHE(inode),
60562306a36Sopenharmony_ci						 fe_bh,
60662306a36Sopenharmony_ci						 OCFS2_JOURNAL_ACCESS_WRITE);
60762306a36Sopenharmony_ci		if (status < 0) {
60862306a36Sopenharmony_ci			mlog_errno(status);
60962306a36Sopenharmony_ci			goto out;
61062306a36Sopenharmony_ci		}
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci		i_size_write(inode, 0);
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci		status = ocfs2_mark_inode_dirty(handle, inode, fe_bh);
61562306a36Sopenharmony_ci		if (status < 0) {
61662306a36Sopenharmony_ci			mlog_errno(status);
61762306a36Sopenharmony_ci			goto out;
61862306a36Sopenharmony_ci		}
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
62162306a36Sopenharmony_ci		handle = NULL;
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci		status = ocfs2_commit_truncate(osb, inode, fe_bh);
62462306a36Sopenharmony_ci		if (status < 0)
62562306a36Sopenharmony_ci			mlog_errno(status);
62662306a36Sopenharmony_ci	}
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ciout:
62962306a36Sopenharmony_ci	if (handle)
63062306a36Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
63162306a36Sopenharmony_ci	return status;
63262306a36Sopenharmony_ci}
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_cistatic int ocfs2_remove_inode(struct inode *inode,
63562306a36Sopenharmony_ci			      struct buffer_head *di_bh,
63662306a36Sopenharmony_ci			      struct inode *orphan_dir_inode,
63762306a36Sopenharmony_ci			      struct buffer_head *orphan_dir_bh)
63862306a36Sopenharmony_ci{
63962306a36Sopenharmony_ci	int status;
64062306a36Sopenharmony_ci	struct inode *inode_alloc_inode = NULL;
64162306a36Sopenharmony_ci	struct buffer_head *inode_alloc_bh = NULL;
64262306a36Sopenharmony_ci	handle_t *handle;
64362306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
64462306a36Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci	inode_alloc_inode =
64762306a36Sopenharmony_ci		ocfs2_get_system_file_inode(osb, INODE_ALLOC_SYSTEM_INODE,
64862306a36Sopenharmony_ci					    le16_to_cpu(di->i_suballoc_slot));
64962306a36Sopenharmony_ci	if (!inode_alloc_inode) {
65062306a36Sopenharmony_ci		status = -ENOENT;
65162306a36Sopenharmony_ci		mlog_errno(status);
65262306a36Sopenharmony_ci		goto bail;
65362306a36Sopenharmony_ci	}
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci	inode_lock(inode_alloc_inode);
65662306a36Sopenharmony_ci	status = ocfs2_inode_lock(inode_alloc_inode, &inode_alloc_bh, 1);
65762306a36Sopenharmony_ci	if (status < 0) {
65862306a36Sopenharmony_ci		inode_unlock(inode_alloc_inode);
65962306a36Sopenharmony_ci
66062306a36Sopenharmony_ci		mlog_errno(status);
66162306a36Sopenharmony_ci		goto bail;
66262306a36Sopenharmony_ci	}
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS +
66562306a36Sopenharmony_ci				   ocfs2_quota_trans_credits(inode->i_sb));
66662306a36Sopenharmony_ci	if (IS_ERR(handle)) {
66762306a36Sopenharmony_ci		status = PTR_ERR(handle);
66862306a36Sopenharmony_ci		mlog_errno(status);
66962306a36Sopenharmony_ci		goto bail_unlock;
67062306a36Sopenharmony_ci	}
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
67362306a36Sopenharmony_ci		status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
67462306a36Sopenharmony_ci					  orphan_dir_bh, false);
67562306a36Sopenharmony_ci		if (status < 0) {
67662306a36Sopenharmony_ci			mlog_errno(status);
67762306a36Sopenharmony_ci			goto bail_commit;
67862306a36Sopenharmony_ci		}
67962306a36Sopenharmony_ci	}
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_ci	/* set the inodes dtime */
68262306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh,
68362306a36Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
68462306a36Sopenharmony_ci	if (status < 0) {
68562306a36Sopenharmony_ci		mlog_errno(status);
68662306a36Sopenharmony_ci		goto bail_commit;
68762306a36Sopenharmony_ci	}
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_ci	di->i_dtime = cpu_to_le64(ktime_get_real_seconds());
69062306a36Sopenharmony_ci	di->i_flags &= cpu_to_le32(~(OCFS2_VALID_FL | OCFS2_ORPHANED_FL));
69162306a36Sopenharmony_ci	ocfs2_journal_dirty(handle, di_bh);
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci	ocfs2_remove_from_cache(INODE_CACHE(inode), di_bh);
69462306a36Sopenharmony_ci	dquot_free_inode(inode);
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	status = ocfs2_free_dinode(handle, inode_alloc_inode,
69762306a36Sopenharmony_ci				   inode_alloc_bh, di);
69862306a36Sopenharmony_ci	if (status < 0)
69962306a36Sopenharmony_ci		mlog_errno(status);
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_cibail_commit:
70262306a36Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
70362306a36Sopenharmony_cibail_unlock:
70462306a36Sopenharmony_ci	ocfs2_inode_unlock(inode_alloc_inode, 1);
70562306a36Sopenharmony_ci	inode_unlock(inode_alloc_inode);
70662306a36Sopenharmony_ci	brelse(inode_alloc_bh);
70762306a36Sopenharmony_cibail:
70862306a36Sopenharmony_ci	iput(inode_alloc_inode);
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	return status;
71162306a36Sopenharmony_ci}
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci/*
71462306a36Sopenharmony_ci * Serialize with orphan dir recovery. If the process doing
71562306a36Sopenharmony_ci * recovery on this orphan dir does an iget() with the dir
71662306a36Sopenharmony_ci * i_rwsem held, we'll deadlock here. Instead we detect this
71762306a36Sopenharmony_ci * and exit early - recovery will wipe this inode for us.
71862306a36Sopenharmony_ci */
71962306a36Sopenharmony_cistatic int ocfs2_check_orphan_recovery_state(struct ocfs2_super *osb,
72062306a36Sopenharmony_ci					     int slot)
72162306a36Sopenharmony_ci{
72262306a36Sopenharmony_ci	int ret = 0;
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	spin_lock(&osb->osb_lock);
72562306a36Sopenharmony_ci	if (ocfs2_node_map_test_bit(osb, &osb->osb_recovering_orphan_dirs, slot)) {
72662306a36Sopenharmony_ci		ret = -EDEADLK;
72762306a36Sopenharmony_ci		goto out;
72862306a36Sopenharmony_ci	}
72962306a36Sopenharmony_ci	/* This signals to the orphan recovery process that it should
73062306a36Sopenharmony_ci	 * wait for us to handle the wipe. */
73162306a36Sopenharmony_ci	osb->osb_orphan_wipes[slot]++;
73262306a36Sopenharmony_ciout:
73362306a36Sopenharmony_ci	spin_unlock(&osb->osb_lock);
73462306a36Sopenharmony_ci	trace_ocfs2_check_orphan_recovery_state(slot, ret);
73562306a36Sopenharmony_ci	return ret;
73662306a36Sopenharmony_ci}
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_cistatic void ocfs2_signal_wipe_completion(struct ocfs2_super *osb,
73962306a36Sopenharmony_ci					 int slot)
74062306a36Sopenharmony_ci{
74162306a36Sopenharmony_ci	spin_lock(&osb->osb_lock);
74262306a36Sopenharmony_ci	osb->osb_orphan_wipes[slot]--;
74362306a36Sopenharmony_ci	spin_unlock(&osb->osb_lock);
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci	wake_up(&osb->osb_wipe_event);
74662306a36Sopenharmony_ci}
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_cistatic int ocfs2_wipe_inode(struct inode *inode,
74962306a36Sopenharmony_ci			    struct buffer_head *di_bh)
75062306a36Sopenharmony_ci{
75162306a36Sopenharmony_ci	int status, orphaned_slot = -1;
75262306a36Sopenharmony_ci	struct inode *orphan_dir_inode = NULL;
75362306a36Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
75462306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
75562306a36Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci	if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
75862306a36Sopenharmony_ci		orphaned_slot = le16_to_cpu(di->i_orphaned_slot);
75962306a36Sopenharmony_ci
76062306a36Sopenharmony_ci		status = ocfs2_check_orphan_recovery_state(osb, orphaned_slot);
76162306a36Sopenharmony_ci		if (status)
76262306a36Sopenharmony_ci			return status;
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci		orphan_dir_inode = ocfs2_get_system_file_inode(osb,
76562306a36Sopenharmony_ci							       ORPHAN_DIR_SYSTEM_INODE,
76662306a36Sopenharmony_ci							       orphaned_slot);
76762306a36Sopenharmony_ci		if (!orphan_dir_inode) {
76862306a36Sopenharmony_ci			status = -ENOENT;
76962306a36Sopenharmony_ci			mlog_errno(status);
77062306a36Sopenharmony_ci			goto bail;
77162306a36Sopenharmony_ci		}
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ci		/* Lock the orphan dir. The lock will be held for the entire
77462306a36Sopenharmony_ci		 * delete_inode operation. We do this now to avoid races with
77562306a36Sopenharmony_ci		 * recovery completion on other nodes. */
77662306a36Sopenharmony_ci		inode_lock(orphan_dir_inode);
77762306a36Sopenharmony_ci		status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
77862306a36Sopenharmony_ci		if (status < 0) {
77962306a36Sopenharmony_ci			inode_unlock(orphan_dir_inode);
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci			mlog_errno(status);
78262306a36Sopenharmony_ci			goto bail;
78362306a36Sopenharmony_ci		}
78462306a36Sopenharmony_ci	}
78562306a36Sopenharmony_ci
78662306a36Sopenharmony_ci	/* we do this while holding the orphan dir lock because we
78762306a36Sopenharmony_ci	 * don't want recovery being run from another node to try an
78862306a36Sopenharmony_ci	 * inode delete underneath us -- this will result in two nodes
78962306a36Sopenharmony_ci	 * truncating the same file! */
79062306a36Sopenharmony_ci	status = ocfs2_truncate_for_delete(osb, inode, di_bh);
79162306a36Sopenharmony_ci	if (status < 0) {
79262306a36Sopenharmony_ci		mlog_errno(status);
79362306a36Sopenharmony_ci		goto bail_unlock_dir;
79462306a36Sopenharmony_ci	}
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	/* Remove any dir index tree */
79762306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode)) {
79862306a36Sopenharmony_ci		status = ocfs2_dx_dir_truncate(inode, di_bh);
79962306a36Sopenharmony_ci		if (status) {
80062306a36Sopenharmony_ci			mlog_errno(status);
80162306a36Sopenharmony_ci			goto bail_unlock_dir;
80262306a36Sopenharmony_ci		}
80362306a36Sopenharmony_ci	}
80462306a36Sopenharmony_ci
80562306a36Sopenharmony_ci	/*Free extended attribute resources associated with this inode.*/
80662306a36Sopenharmony_ci	status = ocfs2_xattr_remove(inode, di_bh);
80762306a36Sopenharmony_ci	if (status < 0) {
80862306a36Sopenharmony_ci		mlog_errno(status);
80962306a36Sopenharmony_ci		goto bail_unlock_dir;
81062306a36Sopenharmony_ci	}
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	status = ocfs2_remove_refcount_tree(inode, di_bh);
81362306a36Sopenharmony_ci	if (status < 0) {
81462306a36Sopenharmony_ci		mlog_errno(status);
81562306a36Sopenharmony_ci		goto bail_unlock_dir;
81662306a36Sopenharmony_ci	}
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	status = ocfs2_remove_inode(inode, di_bh, orphan_dir_inode,
81962306a36Sopenharmony_ci				    orphan_dir_bh);
82062306a36Sopenharmony_ci	if (status < 0)
82162306a36Sopenharmony_ci		mlog_errno(status);
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_cibail_unlock_dir:
82462306a36Sopenharmony_ci	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)
82562306a36Sopenharmony_ci		return status;
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci	ocfs2_inode_unlock(orphan_dir_inode, 1);
82862306a36Sopenharmony_ci	inode_unlock(orphan_dir_inode);
82962306a36Sopenharmony_ci	brelse(orphan_dir_bh);
83062306a36Sopenharmony_cibail:
83162306a36Sopenharmony_ci	iput(orphan_dir_inode);
83262306a36Sopenharmony_ci	ocfs2_signal_wipe_completion(osb, orphaned_slot);
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	return status;
83562306a36Sopenharmony_ci}
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci/* There is a series of simple checks that should be done before a
83862306a36Sopenharmony_ci * trylock is even considered. Encapsulate those in this function. */
83962306a36Sopenharmony_cistatic int ocfs2_inode_is_valid_to_delete(struct inode *inode)
84062306a36Sopenharmony_ci{
84162306a36Sopenharmony_ci	int ret = 0;
84262306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
84362306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_ci	trace_ocfs2_inode_is_valid_to_delete(current, osb->dc_task,
84662306a36Sopenharmony_ci					     (unsigned long long)oi->ip_blkno,
84762306a36Sopenharmony_ci					     oi->ip_flags);
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci	/* We shouldn't be getting here for the root directory
85062306a36Sopenharmony_ci	 * inode.. */
85162306a36Sopenharmony_ci	if (inode == osb->root_inode) {
85262306a36Sopenharmony_ci		mlog(ML_ERROR, "Skipping delete of root inode.\n");
85362306a36Sopenharmony_ci		goto bail;
85462306a36Sopenharmony_ci	}
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci	/*
85762306a36Sopenharmony_ci	 * If we're coming from downconvert_thread we can't go into our own
85862306a36Sopenharmony_ci	 * voting [hello, deadlock city!] so we cannot delete the inode. But
85962306a36Sopenharmony_ci	 * since we dropped last inode ref when downconverting dentry lock,
86062306a36Sopenharmony_ci	 * we cannot have the file open and thus the node doing unlink will
86162306a36Sopenharmony_ci	 * take care of deleting the inode.
86262306a36Sopenharmony_ci	 */
86362306a36Sopenharmony_ci	if (current == osb->dc_task)
86462306a36Sopenharmony_ci		goto bail;
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ci	spin_lock(&oi->ip_lock);
86762306a36Sopenharmony_ci	/* OCFS2 *never* deletes system files. This should technically
86862306a36Sopenharmony_ci	 * never get here as system file inodes should always have a
86962306a36Sopenharmony_ci	 * positive link count. */
87062306a36Sopenharmony_ci	if (oi->ip_flags & OCFS2_INODE_SYSTEM_FILE) {
87162306a36Sopenharmony_ci		mlog(ML_ERROR, "Skipping delete of system file %llu\n",
87262306a36Sopenharmony_ci		     (unsigned long long)oi->ip_blkno);
87362306a36Sopenharmony_ci		goto bail_unlock;
87462306a36Sopenharmony_ci	}
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci	ret = 1;
87762306a36Sopenharmony_cibail_unlock:
87862306a36Sopenharmony_ci	spin_unlock(&oi->ip_lock);
87962306a36Sopenharmony_cibail:
88062306a36Sopenharmony_ci	return ret;
88162306a36Sopenharmony_ci}
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci/* Query the cluster to determine whether we should wipe an inode from
88462306a36Sopenharmony_ci * disk or not.
88562306a36Sopenharmony_ci *
88662306a36Sopenharmony_ci * Requires the inode to have the cluster lock. */
88762306a36Sopenharmony_cistatic int ocfs2_query_inode_wipe(struct inode *inode,
88862306a36Sopenharmony_ci				  struct buffer_head *di_bh,
88962306a36Sopenharmony_ci				  int *wipe)
89062306a36Sopenharmony_ci{
89162306a36Sopenharmony_ci	int status = 0, reason = 0;
89262306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
89362306a36Sopenharmony_ci	struct ocfs2_dinode *di;
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci	*wipe = 0;
89662306a36Sopenharmony_ci
89762306a36Sopenharmony_ci	trace_ocfs2_query_inode_wipe_begin((unsigned long long)oi->ip_blkno,
89862306a36Sopenharmony_ci					   inode->i_nlink);
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci	/* While we were waiting for the cluster lock in
90162306a36Sopenharmony_ci	 * ocfs2_delete_inode, another node might have asked to delete
90262306a36Sopenharmony_ci	 * the inode. Recheck our flags to catch this. */
90362306a36Sopenharmony_ci	if (!ocfs2_inode_is_valid_to_delete(inode)) {
90462306a36Sopenharmony_ci		reason = 1;
90562306a36Sopenharmony_ci		goto bail;
90662306a36Sopenharmony_ci	}
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ci	/* Now that we have an up to date inode, we can double check
90962306a36Sopenharmony_ci	 * the link count. */
91062306a36Sopenharmony_ci	if (inode->i_nlink)
91162306a36Sopenharmony_ci		goto bail;
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci	/* Do some basic inode verification... */
91462306a36Sopenharmony_ci	di = (struct ocfs2_dinode *) di_bh->b_data;
91562306a36Sopenharmony_ci	if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL)) &&
91662306a36Sopenharmony_ci	    !(oi->ip_flags & OCFS2_INODE_SKIP_ORPHAN_DIR)) {
91762306a36Sopenharmony_ci		/*
91862306a36Sopenharmony_ci		 * Inodes in the orphan dir must have ORPHANED_FL.  The only
91962306a36Sopenharmony_ci		 * inodes that come back out of the orphan dir are reflink
92062306a36Sopenharmony_ci		 * targets. A reflink target may be moved out of the orphan
92162306a36Sopenharmony_ci		 * dir between the time we scan the directory and the time we
92262306a36Sopenharmony_ci		 * process it. This would lead to HAS_REFCOUNT_FL being set but
92362306a36Sopenharmony_ci		 * ORPHANED_FL not.
92462306a36Sopenharmony_ci		 */
92562306a36Sopenharmony_ci		if (di->i_dyn_features & cpu_to_le16(OCFS2_HAS_REFCOUNT_FL)) {
92662306a36Sopenharmony_ci			reason = 2;
92762306a36Sopenharmony_ci			goto bail;
92862306a36Sopenharmony_ci		}
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_ci		/* for lack of a better error? */
93162306a36Sopenharmony_ci		status = -EEXIST;
93262306a36Sopenharmony_ci		mlog(ML_ERROR,
93362306a36Sopenharmony_ci		     "Inode %llu (on-disk %llu) not orphaned! "
93462306a36Sopenharmony_ci		     "Disk flags  0x%x, inode flags 0x%x\n",
93562306a36Sopenharmony_ci		     (unsigned long long)oi->ip_blkno,
93662306a36Sopenharmony_ci		     (unsigned long long)le64_to_cpu(di->i_blkno),
93762306a36Sopenharmony_ci		     le32_to_cpu(di->i_flags), oi->ip_flags);
93862306a36Sopenharmony_ci		goto bail;
93962306a36Sopenharmony_ci	}
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci	/* has someone already deleted us?! baaad... */
94262306a36Sopenharmony_ci	if (di->i_dtime) {
94362306a36Sopenharmony_ci		status = -EEXIST;
94462306a36Sopenharmony_ci		mlog_errno(status);
94562306a36Sopenharmony_ci		goto bail;
94662306a36Sopenharmony_ci	}
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_ci	/*
94962306a36Sopenharmony_ci	 * This is how ocfs2 determines whether an inode is still live
95062306a36Sopenharmony_ci	 * within the cluster. Every node takes a shared read lock on
95162306a36Sopenharmony_ci	 * the inode open lock in ocfs2_read_locked_inode(). When we
95262306a36Sopenharmony_ci	 * get to ->delete_inode(), each node tries to convert it's
95362306a36Sopenharmony_ci	 * lock to an exclusive. Trylocks are serialized by the inode
95462306a36Sopenharmony_ci	 * meta data lock. If the upconvert succeeds, we know the inode
95562306a36Sopenharmony_ci	 * is no longer live and can be deleted.
95662306a36Sopenharmony_ci	 *
95762306a36Sopenharmony_ci	 * Though we call this with the meta data lock held, the
95862306a36Sopenharmony_ci	 * trylock keeps us from ABBA deadlock.
95962306a36Sopenharmony_ci	 */
96062306a36Sopenharmony_ci	status = ocfs2_try_open_lock(inode, 1);
96162306a36Sopenharmony_ci	if (status == -EAGAIN) {
96262306a36Sopenharmony_ci		status = 0;
96362306a36Sopenharmony_ci		reason = 3;
96462306a36Sopenharmony_ci		goto bail;
96562306a36Sopenharmony_ci	}
96662306a36Sopenharmony_ci	if (status < 0) {
96762306a36Sopenharmony_ci		mlog_errno(status);
96862306a36Sopenharmony_ci		goto bail;
96962306a36Sopenharmony_ci	}
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci	*wipe = 1;
97262306a36Sopenharmony_ci	trace_ocfs2_query_inode_wipe_succ(le16_to_cpu(di->i_orphaned_slot));
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_cibail:
97562306a36Sopenharmony_ci	trace_ocfs2_query_inode_wipe_end(status, reason);
97662306a36Sopenharmony_ci	return status;
97762306a36Sopenharmony_ci}
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci/* Support function for ocfs2_delete_inode. Will help us keep the
98062306a36Sopenharmony_ci * inode data in a consistent state for clear_inode. Always truncates
98162306a36Sopenharmony_ci * pages, optionally sync's them first. */
98262306a36Sopenharmony_cistatic void ocfs2_cleanup_delete_inode(struct inode *inode,
98362306a36Sopenharmony_ci				       int sync_data)
98462306a36Sopenharmony_ci{
98562306a36Sopenharmony_ci	trace_ocfs2_cleanup_delete_inode(
98662306a36Sopenharmony_ci		(unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data);
98762306a36Sopenharmony_ci	if (sync_data)
98862306a36Sopenharmony_ci		filemap_write_and_wait(inode->i_mapping);
98962306a36Sopenharmony_ci	truncate_inode_pages_final(&inode->i_data);
99062306a36Sopenharmony_ci}
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_cistatic void ocfs2_delete_inode(struct inode *inode)
99362306a36Sopenharmony_ci{
99462306a36Sopenharmony_ci	int wipe, status;
99562306a36Sopenharmony_ci	sigset_t oldset;
99662306a36Sopenharmony_ci	struct buffer_head *di_bh = NULL;
99762306a36Sopenharmony_ci	struct ocfs2_dinode *di = NULL;
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_ci	trace_ocfs2_delete_inode(inode->i_ino,
100062306a36Sopenharmony_ci				 (unsigned long long)OCFS2_I(inode)->ip_blkno,
100162306a36Sopenharmony_ci				 is_bad_inode(inode));
100262306a36Sopenharmony_ci
100362306a36Sopenharmony_ci	/* When we fail in read_inode() we mark inode as bad. The second test
100462306a36Sopenharmony_ci	 * catches the case when inode allocation fails before allocating
100562306a36Sopenharmony_ci	 * a block for inode. */
100662306a36Sopenharmony_ci	if (is_bad_inode(inode) || !OCFS2_I(inode)->ip_blkno)
100762306a36Sopenharmony_ci		goto bail;
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	if (!ocfs2_inode_is_valid_to_delete(inode)) {
101062306a36Sopenharmony_ci		/* It's probably not necessary to truncate_inode_pages
101162306a36Sopenharmony_ci		 * here but we do it for safety anyway (it will most
101262306a36Sopenharmony_ci		 * likely be a no-op anyway) */
101362306a36Sopenharmony_ci		ocfs2_cleanup_delete_inode(inode, 0);
101462306a36Sopenharmony_ci		goto bail;
101562306a36Sopenharmony_ci	}
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci	dquot_initialize(inode);
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_ci	/* We want to block signals in delete_inode as the lock and
102062306a36Sopenharmony_ci	 * messaging paths may return us -ERESTARTSYS. Which would
102162306a36Sopenharmony_ci	 * cause us to exit early, resulting in inodes being orphaned
102262306a36Sopenharmony_ci	 * forever. */
102362306a36Sopenharmony_ci	ocfs2_block_signals(&oldset);
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_ci	/*
102662306a36Sopenharmony_ci	 * Synchronize us against ocfs2_get_dentry. We take this in
102762306a36Sopenharmony_ci	 * shared mode so that all nodes can still concurrently
102862306a36Sopenharmony_ci	 * process deletes.
102962306a36Sopenharmony_ci	 */
103062306a36Sopenharmony_ci	status = ocfs2_nfs_sync_lock(OCFS2_SB(inode->i_sb), 0);
103162306a36Sopenharmony_ci	if (status < 0) {
103262306a36Sopenharmony_ci		mlog(ML_ERROR, "getting nfs sync lock(PR) failed %d\n", status);
103362306a36Sopenharmony_ci		ocfs2_cleanup_delete_inode(inode, 0);
103462306a36Sopenharmony_ci		goto bail_unblock;
103562306a36Sopenharmony_ci	}
103662306a36Sopenharmony_ci	/* Lock down the inode. This gives us an up to date view of
103762306a36Sopenharmony_ci	 * it's metadata (for verification), and allows us to
103862306a36Sopenharmony_ci	 * serialize delete_inode on multiple nodes.
103962306a36Sopenharmony_ci	 *
104062306a36Sopenharmony_ci	 * Even though we might be doing a truncate, we don't take the
104162306a36Sopenharmony_ci	 * allocation lock here as it won't be needed - nobody will
104262306a36Sopenharmony_ci	 * have the file open.
104362306a36Sopenharmony_ci	 */
104462306a36Sopenharmony_ci	status = ocfs2_inode_lock(inode, &di_bh, 1);
104562306a36Sopenharmony_ci	if (status < 0) {
104662306a36Sopenharmony_ci		if (status != -ENOENT)
104762306a36Sopenharmony_ci			mlog_errno(status);
104862306a36Sopenharmony_ci		ocfs2_cleanup_delete_inode(inode, 0);
104962306a36Sopenharmony_ci		goto bail_unlock_nfs_sync;
105062306a36Sopenharmony_ci	}
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ci	di = (struct ocfs2_dinode *)di_bh->b_data;
105362306a36Sopenharmony_ci	/* Skip inode deletion and wait for dio orphan entry recovered
105462306a36Sopenharmony_ci	 * first */
105562306a36Sopenharmony_ci	if (unlikely(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL))) {
105662306a36Sopenharmony_ci		ocfs2_cleanup_delete_inode(inode, 0);
105762306a36Sopenharmony_ci		goto bail_unlock_inode;
105862306a36Sopenharmony_ci	}
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_ci	/* Query the cluster. This will be the final decision made
106162306a36Sopenharmony_ci	 * before we go ahead and wipe the inode. */
106262306a36Sopenharmony_ci	status = ocfs2_query_inode_wipe(inode, di_bh, &wipe);
106362306a36Sopenharmony_ci	if (!wipe || status < 0) {
106462306a36Sopenharmony_ci		/* Error and remote inode busy both mean we won't be
106562306a36Sopenharmony_ci		 * removing the inode, so they take almost the same
106662306a36Sopenharmony_ci		 * path. */
106762306a36Sopenharmony_ci		if (status < 0)
106862306a36Sopenharmony_ci			mlog_errno(status);
106962306a36Sopenharmony_ci
107062306a36Sopenharmony_ci		/* Someone in the cluster has disallowed a wipe of
107162306a36Sopenharmony_ci		 * this inode, or it was never completely
107262306a36Sopenharmony_ci		 * orphaned. Write out the pages and exit now. */
107362306a36Sopenharmony_ci		ocfs2_cleanup_delete_inode(inode, 1);
107462306a36Sopenharmony_ci		goto bail_unlock_inode;
107562306a36Sopenharmony_ci	}
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_ci	ocfs2_cleanup_delete_inode(inode, 0);
107862306a36Sopenharmony_ci
107962306a36Sopenharmony_ci	status = ocfs2_wipe_inode(inode, di_bh);
108062306a36Sopenharmony_ci	if (status < 0) {
108162306a36Sopenharmony_ci		if (status != -EDEADLK)
108262306a36Sopenharmony_ci			mlog_errno(status);
108362306a36Sopenharmony_ci		goto bail_unlock_inode;
108462306a36Sopenharmony_ci	}
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ci	/*
108762306a36Sopenharmony_ci	 * Mark the inode as successfully deleted.
108862306a36Sopenharmony_ci	 *
108962306a36Sopenharmony_ci	 * This is important for ocfs2_clear_inode() as it will check
109062306a36Sopenharmony_ci	 * this flag and skip any checkpointing work
109162306a36Sopenharmony_ci	 *
109262306a36Sopenharmony_ci	 * ocfs2_stuff_meta_lvb() also uses this flag to invalidate
109362306a36Sopenharmony_ci	 * the LVB for other nodes.
109462306a36Sopenharmony_ci	 */
109562306a36Sopenharmony_ci	OCFS2_I(inode)->ip_flags |= OCFS2_INODE_DELETED;
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_cibail_unlock_inode:
109862306a36Sopenharmony_ci	ocfs2_inode_unlock(inode, 1);
109962306a36Sopenharmony_ci	brelse(di_bh);
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_cibail_unlock_nfs_sync:
110262306a36Sopenharmony_ci	ocfs2_nfs_sync_unlock(OCFS2_SB(inode->i_sb), 0);
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_cibail_unblock:
110562306a36Sopenharmony_ci	ocfs2_unblock_signals(&oldset);
110662306a36Sopenharmony_cibail:
110762306a36Sopenharmony_ci	return;
110862306a36Sopenharmony_ci}
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_cistatic void ocfs2_clear_inode(struct inode *inode)
111162306a36Sopenharmony_ci{
111262306a36Sopenharmony_ci	int status;
111362306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
111462306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_ci	clear_inode(inode);
111762306a36Sopenharmony_ci	trace_ocfs2_clear_inode((unsigned long long)oi->ip_blkno,
111862306a36Sopenharmony_ci				inode->i_nlink);
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	mlog_bug_on_msg(osb == NULL,
112162306a36Sopenharmony_ci			"Inode=%lu\n", inode->i_ino);
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_ci	dquot_drop(inode);
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	/* To preven remote deletes we hold open lock before, now it
112662306a36Sopenharmony_ci	 * is time to unlock PR and EX open locks. */
112762306a36Sopenharmony_ci	ocfs2_open_unlock(inode);
112862306a36Sopenharmony_ci
112962306a36Sopenharmony_ci	/* Do these before all the other work so that we don't bounce
113062306a36Sopenharmony_ci	 * the downconvert thread while waiting to destroy the locks. */
113162306a36Sopenharmony_ci	ocfs2_mark_lockres_freeing(osb, &oi->ip_rw_lockres);
113262306a36Sopenharmony_ci	ocfs2_mark_lockres_freeing(osb, &oi->ip_inode_lockres);
113362306a36Sopenharmony_ci	ocfs2_mark_lockres_freeing(osb, &oi->ip_open_lockres);
113462306a36Sopenharmony_ci
113562306a36Sopenharmony_ci	ocfs2_resv_discard(&osb->osb_la_resmap,
113662306a36Sopenharmony_ci			   &oi->ip_la_data_resv);
113762306a36Sopenharmony_ci	ocfs2_resv_init_once(&oi->ip_la_data_resv);
113862306a36Sopenharmony_ci
113962306a36Sopenharmony_ci	/* We very well may get a clear_inode before all an inodes
114062306a36Sopenharmony_ci	 * metadata has hit disk. Of course, we can't drop any cluster
114162306a36Sopenharmony_ci	 * locks until the journal has finished with it. The only
114262306a36Sopenharmony_ci	 * exception here are successfully wiped inodes - their
114362306a36Sopenharmony_ci	 * metadata can now be considered to be part of the system
114462306a36Sopenharmony_ci	 * inodes from which it came. */
114562306a36Sopenharmony_ci	if (!(oi->ip_flags & OCFS2_INODE_DELETED))
114662306a36Sopenharmony_ci		ocfs2_checkpoint_inode(inode);
114762306a36Sopenharmony_ci
114862306a36Sopenharmony_ci	mlog_bug_on_msg(!list_empty(&oi->ip_io_markers),
114962306a36Sopenharmony_ci			"Clear inode of %llu, inode has io markers\n",
115062306a36Sopenharmony_ci			(unsigned long long)oi->ip_blkno);
115162306a36Sopenharmony_ci	mlog_bug_on_msg(!list_empty(&oi->ip_unwritten_list),
115262306a36Sopenharmony_ci			"Clear inode of %llu, inode has unwritten extents\n",
115362306a36Sopenharmony_ci			(unsigned long long)oi->ip_blkno);
115462306a36Sopenharmony_ci
115562306a36Sopenharmony_ci	ocfs2_extent_map_trunc(inode, 0);
115662306a36Sopenharmony_ci
115762306a36Sopenharmony_ci	status = ocfs2_drop_inode_locks(inode);
115862306a36Sopenharmony_ci	if (status < 0)
115962306a36Sopenharmony_ci		mlog_errno(status);
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci	ocfs2_lock_res_free(&oi->ip_rw_lockres);
116262306a36Sopenharmony_ci	ocfs2_lock_res_free(&oi->ip_inode_lockres);
116362306a36Sopenharmony_ci	ocfs2_lock_res_free(&oi->ip_open_lockres);
116462306a36Sopenharmony_ci
116562306a36Sopenharmony_ci	ocfs2_metadata_cache_exit(INODE_CACHE(inode));
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_ci	mlog_bug_on_msg(INODE_CACHE(inode)->ci_num_cached,
116862306a36Sopenharmony_ci			"Clear inode of %llu, inode has %u cache items\n",
116962306a36Sopenharmony_ci			(unsigned long long)oi->ip_blkno,
117062306a36Sopenharmony_ci			INODE_CACHE(inode)->ci_num_cached);
117162306a36Sopenharmony_ci
117262306a36Sopenharmony_ci	mlog_bug_on_msg(!(INODE_CACHE(inode)->ci_flags & OCFS2_CACHE_FL_INLINE),
117362306a36Sopenharmony_ci			"Clear inode of %llu, inode has a bad flag\n",
117462306a36Sopenharmony_ci			(unsigned long long)oi->ip_blkno);
117562306a36Sopenharmony_ci
117662306a36Sopenharmony_ci	mlog_bug_on_msg(spin_is_locked(&oi->ip_lock),
117762306a36Sopenharmony_ci			"Clear inode of %llu, inode is locked\n",
117862306a36Sopenharmony_ci			(unsigned long long)oi->ip_blkno);
117962306a36Sopenharmony_ci
118062306a36Sopenharmony_ci	mlog_bug_on_msg(!mutex_trylock(&oi->ip_io_mutex),
118162306a36Sopenharmony_ci			"Clear inode of %llu, io_mutex is locked\n",
118262306a36Sopenharmony_ci			(unsigned long long)oi->ip_blkno);
118362306a36Sopenharmony_ci	mutex_unlock(&oi->ip_io_mutex);
118462306a36Sopenharmony_ci
118562306a36Sopenharmony_ci	/*
118662306a36Sopenharmony_ci	 * down_trylock() returns 0, down_write_trylock() returns 1
118762306a36Sopenharmony_ci	 * kernel 1, world 0
118862306a36Sopenharmony_ci	 */
118962306a36Sopenharmony_ci	mlog_bug_on_msg(!down_write_trylock(&oi->ip_alloc_sem),
119062306a36Sopenharmony_ci			"Clear inode of %llu, alloc_sem is locked\n",
119162306a36Sopenharmony_ci			(unsigned long long)oi->ip_blkno);
119262306a36Sopenharmony_ci	up_write(&oi->ip_alloc_sem);
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	mlog_bug_on_msg(oi->ip_open_count,
119562306a36Sopenharmony_ci			"Clear inode of %llu has open count %d\n",
119662306a36Sopenharmony_ci			(unsigned long long)oi->ip_blkno, oi->ip_open_count);
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci	/* Clear all other flags. */
119962306a36Sopenharmony_ci	oi->ip_flags = 0;
120062306a36Sopenharmony_ci	oi->ip_dir_start_lookup = 0;
120162306a36Sopenharmony_ci	oi->ip_blkno = 0ULL;
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci	/*
120462306a36Sopenharmony_ci	 * ip_jinode is used to track txns against this inode. We ensure that
120562306a36Sopenharmony_ci	 * the journal is flushed before journal shutdown. Thus it is safe to
120662306a36Sopenharmony_ci	 * have inodes get cleaned up after journal shutdown.
120762306a36Sopenharmony_ci	 */
120862306a36Sopenharmony_ci	jbd2_journal_release_jbd_inode(osb->journal->j_journal,
120962306a36Sopenharmony_ci				       &oi->ip_jinode);
121062306a36Sopenharmony_ci}
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_civoid ocfs2_evict_inode(struct inode *inode)
121362306a36Sopenharmony_ci{
121462306a36Sopenharmony_ci	if (!inode->i_nlink ||
121562306a36Sopenharmony_ci	    (OCFS2_I(inode)->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)) {
121662306a36Sopenharmony_ci		ocfs2_delete_inode(inode);
121762306a36Sopenharmony_ci	} else {
121862306a36Sopenharmony_ci		truncate_inode_pages_final(&inode->i_data);
121962306a36Sopenharmony_ci	}
122062306a36Sopenharmony_ci	ocfs2_clear_inode(inode);
122162306a36Sopenharmony_ci}
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci/* Called under inode_lock, with no more references on the
122462306a36Sopenharmony_ci * struct inode, so it's safe here to check the flags field
122562306a36Sopenharmony_ci * and to manipulate i_nlink without any other locks. */
122662306a36Sopenharmony_ciint ocfs2_drop_inode(struct inode *inode)
122762306a36Sopenharmony_ci{
122862306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
122962306a36Sopenharmony_ci
123062306a36Sopenharmony_ci	trace_ocfs2_drop_inode((unsigned long long)oi->ip_blkno,
123162306a36Sopenharmony_ci				inode->i_nlink, oi->ip_flags);
123262306a36Sopenharmony_ci
123362306a36Sopenharmony_ci	assert_spin_locked(&inode->i_lock);
123462306a36Sopenharmony_ci	inode->i_state |= I_WILL_FREE;
123562306a36Sopenharmony_ci	spin_unlock(&inode->i_lock);
123662306a36Sopenharmony_ci	write_inode_now(inode, 1);
123762306a36Sopenharmony_ci	spin_lock(&inode->i_lock);
123862306a36Sopenharmony_ci	WARN_ON(inode->i_state & I_NEW);
123962306a36Sopenharmony_ci	inode->i_state &= ~I_WILL_FREE;
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_ci	return 1;
124262306a36Sopenharmony_ci}
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci/*
124562306a36Sopenharmony_ci * This is called from our getattr.
124662306a36Sopenharmony_ci */
124762306a36Sopenharmony_ciint ocfs2_inode_revalidate(struct dentry *dentry)
124862306a36Sopenharmony_ci{
124962306a36Sopenharmony_ci	struct inode *inode = d_inode(dentry);
125062306a36Sopenharmony_ci	int status = 0;
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ci	trace_ocfs2_inode_revalidate(inode,
125362306a36Sopenharmony_ci		inode ? (unsigned long long)OCFS2_I(inode)->ip_blkno : 0ULL,
125462306a36Sopenharmony_ci		inode ? (unsigned long long)OCFS2_I(inode)->ip_flags : 0);
125562306a36Sopenharmony_ci
125662306a36Sopenharmony_ci	if (!inode) {
125762306a36Sopenharmony_ci		status = -ENOENT;
125862306a36Sopenharmony_ci		goto bail;
125962306a36Sopenharmony_ci	}
126062306a36Sopenharmony_ci
126162306a36Sopenharmony_ci	spin_lock(&OCFS2_I(inode)->ip_lock);
126262306a36Sopenharmony_ci	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
126362306a36Sopenharmony_ci		spin_unlock(&OCFS2_I(inode)->ip_lock);
126462306a36Sopenharmony_ci		status = -ENOENT;
126562306a36Sopenharmony_ci		goto bail;
126662306a36Sopenharmony_ci	}
126762306a36Sopenharmony_ci	spin_unlock(&OCFS2_I(inode)->ip_lock);
126862306a36Sopenharmony_ci
126962306a36Sopenharmony_ci	/* Let ocfs2_inode_lock do the work of updating our struct
127062306a36Sopenharmony_ci	 * inode for us. */
127162306a36Sopenharmony_ci	status = ocfs2_inode_lock(inode, NULL, 0);
127262306a36Sopenharmony_ci	if (status < 0) {
127362306a36Sopenharmony_ci		if (status != -ENOENT)
127462306a36Sopenharmony_ci			mlog_errno(status);
127562306a36Sopenharmony_ci		goto bail;
127662306a36Sopenharmony_ci	}
127762306a36Sopenharmony_ci	ocfs2_inode_unlock(inode, 0);
127862306a36Sopenharmony_cibail:
127962306a36Sopenharmony_ci	return status;
128062306a36Sopenharmony_ci}
128162306a36Sopenharmony_ci
128262306a36Sopenharmony_ci/*
128362306a36Sopenharmony_ci * Updates a disk inode from a
128462306a36Sopenharmony_ci * struct inode.
128562306a36Sopenharmony_ci * Only takes ip_lock.
128662306a36Sopenharmony_ci */
128762306a36Sopenharmony_ciint ocfs2_mark_inode_dirty(handle_t *handle,
128862306a36Sopenharmony_ci			   struct inode *inode,
128962306a36Sopenharmony_ci			   struct buffer_head *bh)
129062306a36Sopenharmony_ci{
129162306a36Sopenharmony_ci	int status;
129262306a36Sopenharmony_ci	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data;
129362306a36Sopenharmony_ci
129462306a36Sopenharmony_ci	trace_ocfs2_mark_inode_dirty((unsigned long long)OCFS2_I(inode)->ip_blkno);
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(inode), bh,
129762306a36Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
129862306a36Sopenharmony_ci	if (status < 0) {
129962306a36Sopenharmony_ci		mlog_errno(status);
130062306a36Sopenharmony_ci		goto leave;
130162306a36Sopenharmony_ci	}
130262306a36Sopenharmony_ci
130362306a36Sopenharmony_ci	spin_lock(&OCFS2_I(inode)->ip_lock);
130462306a36Sopenharmony_ci	fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);
130562306a36Sopenharmony_ci	ocfs2_get_inode_flags(OCFS2_I(inode));
130662306a36Sopenharmony_ci	fe->i_attr = cpu_to_le32(OCFS2_I(inode)->ip_attr);
130762306a36Sopenharmony_ci	fe->i_dyn_features = cpu_to_le16(OCFS2_I(inode)->ip_dyn_features);
130862306a36Sopenharmony_ci	spin_unlock(&OCFS2_I(inode)->ip_lock);
130962306a36Sopenharmony_ci
131062306a36Sopenharmony_ci	fe->i_size = cpu_to_le64(i_size_read(inode));
131162306a36Sopenharmony_ci	ocfs2_set_links_count(fe, inode->i_nlink);
131262306a36Sopenharmony_ci	fe->i_uid = cpu_to_le32(i_uid_read(inode));
131362306a36Sopenharmony_ci	fe->i_gid = cpu_to_le32(i_gid_read(inode));
131462306a36Sopenharmony_ci	fe->i_mode = cpu_to_le16(inode->i_mode);
131562306a36Sopenharmony_ci	fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
131662306a36Sopenharmony_ci	fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
131762306a36Sopenharmony_ci	fe->i_ctime = cpu_to_le64(inode_get_ctime(inode).tv_sec);
131862306a36Sopenharmony_ci	fe->i_ctime_nsec = cpu_to_le32(inode_get_ctime(inode).tv_nsec);
131962306a36Sopenharmony_ci	fe->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec);
132062306a36Sopenharmony_ci	fe->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_ci	ocfs2_journal_dirty(handle, bh);
132362306a36Sopenharmony_ci	ocfs2_update_inode_fsync_trans(handle, inode, 1);
132462306a36Sopenharmony_cileave:
132562306a36Sopenharmony_ci	return status;
132662306a36Sopenharmony_ci}
132762306a36Sopenharmony_ci
132862306a36Sopenharmony_ci/*
132962306a36Sopenharmony_ci *
133062306a36Sopenharmony_ci * Updates a struct inode from a disk inode.
133162306a36Sopenharmony_ci * does no i/o, only takes ip_lock.
133262306a36Sopenharmony_ci */
133362306a36Sopenharmony_civoid ocfs2_refresh_inode(struct inode *inode,
133462306a36Sopenharmony_ci			 struct ocfs2_dinode *fe)
133562306a36Sopenharmony_ci{
133662306a36Sopenharmony_ci	spin_lock(&OCFS2_I(inode)->ip_lock);
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_ci	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
133962306a36Sopenharmony_ci	OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
134062306a36Sopenharmony_ci	OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features);
134162306a36Sopenharmony_ci	ocfs2_set_inode_flags(inode);
134262306a36Sopenharmony_ci	i_size_write(inode, le64_to_cpu(fe->i_size));
134362306a36Sopenharmony_ci	set_nlink(inode, ocfs2_read_links_count(fe));
134462306a36Sopenharmony_ci	i_uid_write(inode, le32_to_cpu(fe->i_uid));
134562306a36Sopenharmony_ci	i_gid_write(inode, le32_to_cpu(fe->i_gid));
134662306a36Sopenharmony_ci	inode->i_mode = le16_to_cpu(fe->i_mode);
134762306a36Sopenharmony_ci	if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
134862306a36Sopenharmony_ci		inode->i_blocks = 0;
134962306a36Sopenharmony_ci	else
135062306a36Sopenharmony_ci		inode->i_blocks = ocfs2_inode_sector_count(inode);
135162306a36Sopenharmony_ci	inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
135262306a36Sopenharmony_ci	inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
135362306a36Sopenharmony_ci	inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
135462306a36Sopenharmony_ci	inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec);
135562306a36Sopenharmony_ci	inode_set_ctime(inode, le64_to_cpu(fe->i_ctime),
135662306a36Sopenharmony_ci			le32_to_cpu(fe->i_ctime_nsec));
135762306a36Sopenharmony_ci
135862306a36Sopenharmony_ci	spin_unlock(&OCFS2_I(inode)->ip_lock);
135962306a36Sopenharmony_ci}
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_ciint ocfs2_validate_inode_block(struct super_block *sb,
136262306a36Sopenharmony_ci			       struct buffer_head *bh)
136362306a36Sopenharmony_ci{
136462306a36Sopenharmony_ci	int rc;
136562306a36Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci	trace_ocfs2_validate_inode_block((unsigned long long)bh->b_blocknr);
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_ci	BUG_ON(!buffer_uptodate(bh));
137062306a36Sopenharmony_ci
137162306a36Sopenharmony_ci	/*
137262306a36Sopenharmony_ci	 * If the ecc fails, we return the error but otherwise
137362306a36Sopenharmony_ci	 * leave the filesystem running.  We know any error is
137462306a36Sopenharmony_ci	 * local to this block.
137562306a36Sopenharmony_ci	 */
137662306a36Sopenharmony_ci	rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &di->i_check);
137762306a36Sopenharmony_ci	if (rc) {
137862306a36Sopenharmony_ci		mlog(ML_ERROR, "Checksum failed for dinode %llu\n",
137962306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr);
138062306a36Sopenharmony_ci		goto bail;
138162306a36Sopenharmony_ci	}
138262306a36Sopenharmony_ci
138362306a36Sopenharmony_ci	/*
138462306a36Sopenharmony_ci	 * Errors after here are fatal.
138562306a36Sopenharmony_ci	 */
138662306a36Sopenharmony_ci
138762306a36Sopenharmony_ci	rc = -EINVAL;
138862306a36Sopenharmony_ci
138962306a36Sopenharmony_ci	if (!OCFS2_IS_VALID_DINODE(di)) {
139062306a36Sopenharmony_ci		rc = ocfs2_error(sb, "Invalid dinode #%llu: signature = %.*s\n",
139162306a36Sopenharmony_ci				 (unsigned long long)bh->b_blocknr, 7,
139262306a36Sopenharmony_ci				 di->i_signature);
139362306a36Sopenharmony_ci		goto bail;
139462306a36Sopenharmony_ci	}
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci	if (le64_to_cpu(di->i_blkno) != bh->b_blocknr) {
139762306a36Sopenharmony_ci		rc = ocfs2_error(sb, "Invalid dinode #%llu: i_blkno is %llu\n",
139862306a36Sopenharmony_ci				 (unsigned long long)bh->b_blocknr,
139962306a36Sopenharmony_ci				 (unsigned long long)le64_to_cpu(di->i_blkno));
140062306a36Sopenharmony_ci		goto bail;
140162306a36Sopenharmony_ci	}
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	if (!(di->i_flags & cpu_to_le32(OCFS2_VALID_FL))) {
140462306a36Sopenharmony_ci		rc = ocfs2_error(sb,
140562306a36Sopenharmony_ci				 "Invalid dinode #%llu: OCFS2_VALID_FL not set\n",
140662306a36Sopenharmony_ci				 (unsigned long long)bh->b_blocknr);
140762306a36Sopenharmony_ci		goto bail;
140862306a36Sopenharmony_ci	}
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci	if (le32_to_cpu(di->i_fs_generation) !=
141162306a36Sopenharmony_ci	    OCFS2_SB(sb)->fs_generation) {
141262306a36Sopenharmony_ci		rc = ocfs2_error(sb,
141362306a36Sopenharmony_ci				 "Invalid dinode #%llu: fs_generation is %u\n",
141462306a36Sopenharmony_ci				 (unsigned long long)bh->b_blocknr,
141562306a36Sopenharmony_ci				 le32_to_cpu(di->i_fs_generation));
141662306a36Sopenharmony_ci		goto bail;
141762306a36Sopenharmony_ci	}
141862306a36Sopenharmony_ci
141962306a36Sopenharmony_ci	rc = 0;
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_cibail:
142262306a36Sopenharmony_ci	return rc;
142362306a36Sopenharmony_ci}
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_cistatic int ocfs2_filecheck_validate_inode_block(struct super_block *sb,
142662306a36Sopenharmony_ci						struct buffer_head *bh)
142762306a36Sopenharmony_ci{
142862306a36Sopenharmony_ci	int rc = 0;
142962306a36Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
143062306a36Sopenharmony_ci
143162306a36Sopenharmony_ci	trace_ocfs2_filecheck_validate_inode_block(
143262306a36Sopenharmony_ci		(unsigned long long)bh->b_blocknr);
143362306a36Sopenharmony_ci
143462306a36Sopenharmony_ci	BUG_ON(!buffer_uptodate(bh));
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci	/*
143762306a36Sopenharmony_ci	 * Call ocfs2_validate_meta_ecc() first since it has ecc repair
143862306a36Sopenharmony_ci	 * function, but we should not return error immediately when ecc
143962306a36Sopenharmony_ci	 * validation fails, because the reason is quite likely the invalid
144062306a36Sopenharmony_ci	 * inode number inputed.
144162306a36Sopenharmony_ci	 */
144262306a36Sopenharmony_ci	rc = ocfs2_validate_meta_ecc(sb, bh->b_data, &di->i_check);
144362306a36Sopenharmony_ci	if (rc) {
144462306a36Sopenharmony_ci		mlog(ML_ERROR,
144562306a36Sopenharmony_ci		     "Filecheck: checksum failed for dinode %llu\n",
144662306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr);
144762306a36Sopenharmony_ci		rc = -OCFS2_FILECHECK_ERR_BLOCKECC;
144862306a36Sopenharmony_ci	}
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci	if (!OCFS2_IS_VALID_DINODE(di)) {
145162306a36Sopenharmony_ci		mlog(ML_ERROR,
145262306a36Sopenharmony_ci		     "Filecheck: invalid dinode #%llu: signature = %.*s\n",
145362306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr, 7, di->i_signature);
145462306a36Sopenharmony_ci		rc = -OCFS2_FILECHECK_ERR_INVALIDINO;
145562306a36Sopenharmony_ci		goto bail;
145662306a36Sopenharmony_ci	} else if (rc)
145762306a36Sopenharmony_ci		goto bail;
145862306a36Sopenharmony_ci
145962306a36Sopenharmony_ci	if (le64_to_cpu(di->i_blkno) != bh->b_blocknr) {
146062306a36Sopenharmony_ci		mlog(ML_ERROR,
146162306a36Sopenharmony_ci		     "Filecheck: invalid dinode #%llu: i_blkno is %llu\n",
146262306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr,
146362306a36Sopenharmony_ci		     (unsigned long long)le64_to_cpu(di->i_blkno));
146462306a36Sopenharmony_ci		rc = -OCFS2_FILECHECK_ERR_BLOCKNO;
146562306a36Sopenharmony_ci		goto bail;
146662306a36Sopenharmony_ci	}
146762306a36Sopenharmony_ci
146862306a36Sopenharmony_ci	if (!(di->i_flags & cpu_to_le32(OCFS2_VALID_FL))) {
146962306a36Sopenharmony_ci		mlog(ML_ERROR,
147062306a36Sopenharmony_ci		     "Filecheck: invalid dinode #%llu: OCFS2_VALID_FL "
147162306a36Sopenharmony_ci		     "not set\n",
147262306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr);
147362306a36Sopenharmony_ci		rc = -OCFS2_FILECHECK_ERR_VALIDFLAG;
147462306a36Sopenharmony_ci		goto bail;
147562306a36Sopenharmony_ci	}
147662306a36Sopenharmony_ci
147762306a36Sopenharmony_ci	if (le32_to_cpu(di->i_fs_generation) !=
147862306a36Sopenharmony_ci	    OCFS2_SB(sb)->fs_generation) {
147962306a36Sopenharmony_ci		mlog(ML_ERROR,
148062306a36Sopenharmony_ci		     "Filecheck: invalid dinode #%llu: fs_generation is %u\n",
148162306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr,
148262306a36Sopenharmony_ci		     le32_to_cpu(di->i_fs_generation));
148362306a36Sopenharmony_ci		rc = -OCFS2_FILECHECK_ERR_GENERATION;
148462306a36Sopenharmony_ci	}
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_cibail:
148762306a36Sopenharmony_ci	return rc;
148862306a36Sopenharmony_ci}
148962306a36Sopenharmony_ci
149062306a36Sopenharmony_cistatic int ocfs2_filecheck_repair_inode_block(struct super_block *sb,
149162306a36Sopenharmony_ci					      struct buffer_head *bh)
149262306a36Sopenharmony_ci{
149362306a36Sopenharmony_ci	int changed = 0;
149462306a36Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
149562306a36Sopenharmony_ci
149662306a36Sopenharmony_ci	if (!ocfs2_filecheck_validate_inode_block(sb, bh))
149762306a36Sopenharmony_ci		return 0;
149862306a36Sopenharmony_ci
149962306a36Sopenharmony_ci	trace_ocfs2_filecheck_repair_inode_block(
150062306a36Sopenharmony_ci		(unsigned long long)bh->b_blocknr);
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci	if (ocfs2_is_hard_readonly(OCFS2_SB(sb)) ||
150362306a36Sopenharmony_ci	    ocfs2_is_soft_readonly(OCFS2_SB(sb))) {
150462306a36Sopenharmony_ci		mlog(ML_ERROR,
150562306a36Sopenharmony_ci		     "Filecheck: cannot repair dinode #%llu "
150662306a36Sopenharmony_ci		     "on readonly filesystem\n",
150762306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr);
150862306a36Sopenharmony_ci		return -OCFS2_FILECHECK_ERR_READONLY;
150962306a36Sopenharmony_ci	}
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ci	if (buffer_jbd(bh)) {
151262306a36Sopenharmony_ci		mlog(ML_ERROR,
151362306a36Sopenharmony_ci		     "Filecheck: cannot repair dinode #%llu, "
151462306a36Sopenharmony_ci		     "its buffer is in jbd\n",
151562306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr);
151662306a36Sopenharmony_ci		return -OCFS2_FILECHECK_ERR_INJBD;
151762306a36Sopenharmony_ci	}
151862306a36Sopenharmony_ci
151962306a36Sopenharmony_ci	if (!OCFS2_IS_VALID_DINODE(di)) {
152062306a36Sopenharmony_ci		/* Cannot fix invalid inode block */
152162306a36Sopenharmony_ci		return -OCFS2_FILECHECK_ERR_INVALIDINO;
152262306a36Sopenharmony_ci	}
152362306a36Sopenharmony_ci
152462306a36Sopenharmony_ci	if (!(di->i_flags & cpu_to_le32(OCFS2_VALID_FL))) {
152562306a36Sopenharmony_ci		/* Cannot just add VALID_FL flag back as a fix,
152662306a36Sopenharmony_ci		 * need more things to check here.
152762306a36Sopenharmony_ci		 */
152862306a36Sopenharmony_ci		return -OCFS2_FILECHECK_ERR_VALIDFLAG;
152962306a36Sopenharmony_ci	}
153062306a36Sopenharmony_ci
153162306a36Sopenharmony_ci	if (le64_to_cpu(di->i_blkno) != bh->b_blocknr) {
153262306a36Sopenharmony_ci		di->i_blkno = cpu_to_le64(bh->b_blocknr);
153362306a36Sopenharmony_ci		changed = 1;
153462306a36Sopenharmony_ci		mlog(ML_ERROR,
153562306a36Sopenharmony_ci		     "Filecheck: reset dinode #%llu: i_blkno to %llu\n",
153662306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr,
153762306a36Sopenharmony_ci		     (unsigned long long)le64_to_cpu(di->i_blkno));
153862306a36Sopenharmony_ci	}
153962306a36Sopenharmony_ci
154062306a36Sopenharmony_ci	if (le32_to_cpu(di->i_fs_generation) !=
154162306a36Sopenharmony_ci	    OCFS2_SB(sb)->fs_generation) {
154262306a36Sopenharmony_ci		di->i_fs_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation);
154362306a36Sopenharmony_ci		changed = 1;
154462306a36Sopenharmony_ci		mlog(ML_ERROR,
154562306a36Sopenharmony_ci		     "Filecheck: reset dinode #%llu: fs_generation to %u\n",
154662306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr,
154762306a36Sopenharmony_ci		     le32_to_cpu(di->i_fs_generation));
154862306a36Sopenharmony_ci	}
154962306a36Sopenharmony_ci
155062306a36Sopenharmony_ci	if (changed || ocfs2_validate_meta_ecc(sb, bh->b_data, &di->i_check)) {
155162306a36Sopenharmony_ci		ocfs2_compute_meta_ecc(sb, bh->b_data, &di->i_check);
155262306a36Sopenharmony_ci		mark_buffer_dirty(bh);
155362306a36Sopenharmony_ci		mlog(ML_ERROR,
155462306a36Sopenharmony_ci		     "Filecheck: reset dinode #%llu: compute meta ecc\n",
155562306a36Sopenharmony_ci		     (unsigned long long)bh->b_blocknr);
155662306a36Sopenharmony_ci	}
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_ci	return 0;
155962306a36Sopenharmony_ci}
156062306a36Sopenharmony_ci
156162306a36Sopenharmony_cistatic int
156262306a36Sopenharmony_ciocfs2_filecheck_read_inode_block_full(struct inode *inode,
156362306a36Sopenharmony_ci				      struct buffer_head **bh,
156462306a36Sopenharmony_ci				      int flags, int type)
156562306a36Sopenharmony_ci{
156662306a36Sopenharmony_ci	int rc;
156762306a36Sopenharmony_ci	struct buffer_head *tmp = *bh;
156862306a36Sopenharmony_ci
156962306a36Sopenharmony_ci	if (!type) /* Check inode block */
157062306a36Sopenharmony_ci		rc = ocfs2_read_blocks(INODE_CACHE(inode),
157162306a36Sopenharmony_ci				OCFS2_I(inode)->ip_blkno,
157262306a36Sopenharmony_ci				1, &tmp, flags,
157362306a36Sopenharmony_ci				ocfs2_filecheck_validate_inode_block);
157462306a36Sopenharmony_ci	else /* Repair inode block */
157562306a36Sopenharmony_ci		rc = ocfs2_read_blocks(INODE_CACHE(inode),
157662306a36Sopenharmony_ci				OCFS2_I(inode)->ip_blkno,
157762306a36Sopenharmony_ci				1, &tmp, flags,
157862306a36Sopenharmony_ci				ocfs2_filecheck_repair_inode_block);
157962306a36Sopenharmony_ci
158062306a36Sopenharmony_ci	/* If ocfs2_read_blocks() got us a new bh, pass it up. */
158162306a36Sopenharmony_ci	if (!rc && !*bh)
158262306a36Sopenharmony_ci		*bh = tmp;
158362306a36Sopenharmony_ci
158462306a36Sopenharmony_ci	return rc;
158562306a36Sopenharmony_ci}
158662306a36Sopenharmony_ci
158762306a36Sopenharmony_ciint ocfs2_read_inode_block_full(struct inode *inode, struct buffer_head **bh,
158862306a36Sopenharmony_ci				int flags)
158962306a36Sopenharmony_ci{
159062306a36Sopenharmony_ci	int rc;
159162306a36Sopenharmony_ci	struct buffer_head *tmp = *bh;
159262306a36Sopenharmony_ci
159362306a36Sopenharmony_ci	rc = ocfs2_read_blocks(INODE_CACHE(inode), OCFS2_I(inode)->ip_blkno,
159462306a36Sopenharmony_ci			       1, &tmp, flags, ocfs2_validate_inode_block);
159562306a36Sopenharmony_ci
159662306a36Sopenharmony_ci	/* If ocfs2_read_blocks() got us a new bh, pass it up. */
159762306a36Sopenharmony_ci	if (!rc && !*bh)
159862306a36Sopenharmony_ci		*bh = tmp;
159962306a36Sopenharmony_ci
160062306a36Sopenharmony_ci	return rc;
160162306a36Sopenharmony_ci}
160262306a36Sopenharmony_ci
160362306a36Sopenharmony_ciint ocfs2_read_inode_block(struct inode *inode, struct buffer_head **bh)
160462306a36Sopenharmony_ci{
160562306a36Sopenharmony_ci	return ocfs2_read_inode_block_full(inode, bh, 0);
160662306a36Sopenharmony_ci}
160762306a36Sopenharmony_ci
160862306a36Sopenharmony_ci
160962306a36Sopenharmony_cistatic u64 ocfs2_inode_cache_owner(struct ocfs2_caching_info *ci)
161062306a36Sopenharmony_ci{
161162306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = cache_info_to_inode(ci);
161262306a36Sopenharmony_ci
161362306a36Sopenharmony_ci	return oi->ip_blkno;
161462306a36Sopenharmony_ci}
161562306a36Sopenharmony_ci
161662306a36Sopenharmony_cistatic struct super_block *ocfs2_inode_cache_get_super(struct ocfs2_caching_info *ci)
161762306a36Sopenharmony_ci{
161862306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = cache_info_to_inode(ci);
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ci	return oi->vfs_inode.i_sb;
162162306a36Sopenharmony_ci}
162262306a36Sopenharmony_ci
162362306a36Sopenharmony_cistatic void ocfs2_inode_cache_lock(struct ocfs2_caching_info *ci)
162462306a36Sopenharmony_ci{
162562306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = cache_info_to_inode(ci);
162662306a36Sopenharmony_ci
162762306a36Sopenharmony_ci	spin_lock(&oi->ip_lock);
162862306a36Sopenharmony_ci}
162962306a36Sopenharmony_ci
163062306a36Sopenharmony_cistatic void ocfs2_inode_cache_unlock(struct ocfs2_caching_info *ci)
163162306a36Sopenharmony_ci{
163262306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = cache_info_to_inode(ci);
163362306a36Sopenharmony_ci
163462306a36Sopenharmony_ci	spin_unlock(&oi->ip_lock);
163562306a36Sopenharmony_ci}
163662306a36Sopenharmony_ci
163762306a36Sopenharmony_cistatic void ocfs2_inode_cache_io_lock(struct ocfs2_caching_info *ci)
163862306a36Sopenharmony_ci{
163962306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = cache_info_to_inode(ci);
164062306a36Sopenharmony_ci
164162306a36Sopenharmony_ci	mutex_lock(&oi->ip_io_mutex);
164262306a36Sopenharmony_ci}
164362306a36Sopenharmony_ci
164462306a36Sopenharmony_cistatic void ocfs2_inode_cache_io_unlock(struct ocfs2_caching_info *ci)
164562306a36Sopenharmony_ci{
164662306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = cache_info_to_inode(ci);
164762306a36Sopenharmony_ci
164862306a36Sopenharmony_ci	mutex_unlock(&oi->ip_io_mutex);
164962306a36Sopenharmony_ci}
165062306a36Sopenharmony_ci
165162306a36Sopenharmony_ciconst struct ocfs2_caching_operations ocfs2_inode_caching_ops = {
165262306a36Sopenharmony_ci	.co_owner		= ocfs2_inode_cache_owner,
165362306a36Sopenharmony_ci	.co_get_super		= ocfs2_inode_cache_get_super,
165462306a36Sopenharmony_ci	.co_cache_lock		= ocfs2_inode_cache_lock,
165562306a36Sopenharmony_ci	.co_cache_unlock	= ocfs2_inode_cache_unlock,
165662306a36Sopenharmony_ci	.co_io_lock		= ocfs2_inode_cache_io_lock,
165762306a36Sopenharmony_ci	.co_io_unlock		= ocfs2_inode_cache_io_unlock,
165862306a36Sopenharmony_ci};
165962306a36Sopenharmony_ci
1660