162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * namei.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Create and rename file, directory, symlinks
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci *  Portions of this code from linux/fs/ext3/dir.c
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci *  Copyright (C) 1992, 1993, 1994, 1995
1262306a36Sopenharmony_ci *  Remy Card (card@masi.ibp.fr)
1362306a36Sopenharmony_ci *  Laboratoire MASI - Institut Blaise pascal
1462306a36Sopenharmony_ci *  Universite Pierre et Marie Curie (Paris VI)
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci *   from
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci *   linux/fs/minix/dir.c
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci *   Copyright (C) 1991, 1992 Linux Torvalds
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include <linux/fs.h>
2462306a36Sopenharmony_ci#include <linux/types.h>
2562306a36Sopenharmony_ci#include <linux/slab.h>
2662306a36Sopenharmony_ci#include <linux/highmem.h>
2762306a36Sopenharmony_ci#include <linux/quotaops.h>
2862306a36Sopenharmony_ci#include <linux/iversion.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include <cluster/masklog.h>
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci#include "ocfs2.h"
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#include "alloc.h"
3562306a36Sopenharmony_ci#include "dcache.h"
3662306a36Sopenharmony_ci#include "dir.h"
3762306a36Sopenharmony_ci#include "dlmglue.h"
3862306a36Sopenharmony_ci#include "extent_map.h"
3962306a36Sopenharmony_ci#include "file.h"
4062306a36Sopenharmony_ci#include "inode.h"
4162306a36Sopenharmony_ci#include "journal.h"
4262306a36Sopenharmony_ci#include "namei.h"
4362306a36Sopenharmony_ci#include "suballoc.h"
4462306a36Sopenharmony_ci#include "super.h"
4562306a36Sopenharmony_ci#include "symlink.h"
4662306a36Sopenharmony_ci#include "sysfile.h"
4762306a36Sopenharmony_ci#include "uptodate.h"
4862306a36Sopenharmony_ci#include "xattr.h"
4962306a36Sopenharmony_ci#include "acl.h"
5062306a36Sopenharmony_ci#include "ocfs2_trace.h"
5162306a36Sopenharmony_ci#include "ioctl.h"
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci#include "buffer_head_io.h"
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic int ocfs2_mknod_locked(struct ocfs2_super *osb,
5662306a36Sopenharmony_ci			      struct inode *dir,
5762306a36Sopenharmony_ci			      struct inode *inode,
5862306a36Sopenharmony_ci			      dev_t dev,
5962306a36Sopenharmony_ci			      struct buffer_head **new_fe_bh,
6062306a36Sopenharmony_ci			      struct buffer_head *parent_fe_bh,
6162306a36Sopenharmony_ci			      handle_t *handle,
6262306a36Sopenharmony_ci			      struct ocfs2_alloc_context *inode_ac);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cistatic int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
6562306a36Sopenharmony_ci				    struct inode **ret_orphan_dir,
6662306a36Sopenharmony_ci				    u64 blkno,
6762306a36Sopenharmony_ci				    char *name,
6862306a36Sopenharmony_ci				    struct ocfs2_dir_lookup_result *lookup,
6962306a36Sopenharmony_ci				    bool dio);
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic int ocfs2_orphan_add(struct ocfs2_super *osb,
7262306a36Sopenharmony_ci			    handle_t *handle,
7362306a36Sopenharmony_ci			    struct inode *inode,
7462306a36Sopenharmony_ci			    struct buffer_head *fe_bh,
7562306a36Sopenharmony_ci			    char *name,
7662306a36Sopenharmony_ci			    struct ocfs2_dir_lookup_result *lookup,
7762306a36Sopenharmony_ci			    struct inode *orphan_dir_inode,
7862306a36Sopenharmony_ci			    bool dio);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cistatic int ocfs2_create_symlink_data(struct ocfs2_super *osb,
8162306a36Sopenharmony_ci				     handle_t *handle,
8262306a36Sopenharmony_ci				     struct inode *inode,
8362306a36Sopenharmony_ci				     const char *symname);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_cistatic int ocfs2_double_lock(struct ocfs2_super *osb,
8662306a36Sopenharmony_ci			     struct buffer_head **bh1,
8762306a36Sopenharmony_ci			     struct inode *inode1,
8862306a36Sopenharmony_ci			     struct buffer_head **bh2,
8962306a36Sopenharmony_ci			     struct inode *inode2,
9062306a36Sopenharmony_ci			     int rename);
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2);
9362306a36Sopenharmony_ci/* An orphan dir name is an 8 byte value, printed as a hex string */
9462306a36Sopenharmony_ci#define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_cistatic struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
9762306a36Sopenharmony_ci				   unsigned int flags)
9862306a36Sopenharmony_ci{
9962306a36Sopenharmony_ci	int status;
10062306a36Sopenharmony_ci	u64 blkno;
10162306a36Sopenharmony_ci	struct inode *inode = NULL;
10262306a36Sopenharmony_ci	struct dentry *ret;
10362306a36Sopenharmony_ci	struct ocfs2_inode_info *oi;
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	trace_ocfs2_lookup(dir, dentry, dentry->d_name.len,
10662306a36Sopenharmony_ci			   dentry->d_name.name,
10762306a36Sopenharmony_ci			   (unsigned long long)OCFS2_I(dir)->ip_blkno, 0);
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	if (dentry->d_name.len > OCFS2_MAX_FILENAME_LEN) {
11062306a36Sopenharmony_ci		ret = ERR_PTR(-ENAMETOOLONG);
11162306a36Sopenharmony_ci		goto bail;
11262306a36Sopenharmony_ci	}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	status = ocfs2_inode_lock_nested(dir, NULL, 0, OI_LS_PARENT);
11562306a36Sopenharmony_ci	if (status < 0) {
11662306a36Sopenharmony_ci		if (status != -ENOENT)
11762306a36Sopenharmony_ci			mlog_errno(status);
11862306a36Sopenharmony_ci		ret = ERR_PTR(status);
11962306a36Sopenharmony_ci		goto bail;
12062306a36Sopenharmony_ci	}
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	status = ocfs2_lookup_ino_from_name(dir, dentry->d_name.name,
12362306a36Sopenharmony_ci					    dentry->d_name.len, &blkno);
12462306a36Sopenharmony_ci	if (status < 0)
12562306a36Sopenharmony_ci		goto bail_add;
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0);
12862306a36Sopenharmony_ci	if (IS_ERR(inode)) {
12962306a36Sopenharmony_ci		ret = ERR_PTR(-EACCES);
13062306a36Sopenharmony_ci		goto bail_unlock;
13162306a36Sopenharmony_ci	}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	oi = OCFS2_I(inode);
13462306a36Sopenharmony_ci	/* Clear any orphaned state... If we were able to look up the
13562306a36Sopenharmony_ci	 * inode from a directory, it certainly can't be orphaned. We
13662306a36Sopenharmony_ci	 * might have the bad state from a node which intended to
13762306a36Sopenharmony_ci	 * orphan this inode but crashed before it could commit the
13862306a36Sopenharmony_ci	 * unlink. */
13962306a36Sopenharmony_ci	spin_lock(&oi->ip_lock);
14062306a36Sopenharmony_ci	oi->ip_flags &= ~OCFS2_INODE_MAYBE_ORPHANED;
14162306a36Sopenharmony_ci	spin_unlock(&oi->ip_lock);
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cibail_add:
14462306a36Sopenharmony_ci	ret = d_splice_alias(inode, dentry);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	if (inode) {
14762306a36Sopenharmony_ci		/*
14862306a36Sopenharmony_ci		 * If d_splice_alias() finds a DCACHE_DISCONNECTED
14962306a36Sopenharmony_ci		 * dentry, it will d_move() it on top of ourse. The
15062306a36Sopenharmony_ci		 * return value will indicate this however, so in
15162306a36Sopenharmony_ci		 * those cases, we switch them around for the locking
15262306a36Sopenharmony_ci		 * code.
15362306a36Sopenharmony_ci		 *
15462306a36Sopenharmony_ci		 * NOTE: This dentry already has ->d_op set from
15562306a36Sopenharmony_ci		 * ocfs2_get_parent() and ocfs2_get_dentry()
15662306a36Sopenharmony_ci		 */
15762306a36Sopenharmony_ci		if (!IS_ERR_OR_NULL(ret))
15862306a36Sopenharmony_ci			dentry = ret;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci		status = ocfs2_dentry_attach_lock(dentry, inode,
16162306a36Sopenharmony_ci						  OCFS2_I(dir)->ip_blkno);
16262306a36Sopenharmony_ci		if (status) {
16362306a36Sopenharmony_ci			mlog_errno(status);
16462306a36Sopenharmony_ci			ret = ERR_PTR(status);
16562306a36Sopenharmony_ci			goto bail_unlock;
16662306a36Sopenharmony_ci		}
16762306a36Sopenharmony_ci	} else
16862306a36Sopenharmony_ci		ocfs2_dentry_attach_gen(dentry);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_cibail_unlock:
17162306a36Sopenharmony_ci	/* Don't drop the cluster lock until *after* the d_add --
17262306a36Sopenharmony_ci	 * unlink on another node will message us to remove that
17362306a36Sopenharmony_ci	 * dentry under this lock so otherwise we can race this with
17462306a36Sopenharmony_ci	 * the downconvert thread and have a stale dentry. */
17562306a36Sopenharmony_ci	ocfs2_inode_unlock(dir, 0);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_cibail:
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	trace_ocfs2_lookup_ret(ret);
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	return ret;
18262306a36Sopenharmony_ci}
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_cistatic struct inode *ocfs2_get_init_inode(struct inode *dir, umode_t mode)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	struct inode *inode;
18762306a36Sopenharmony_ci	int status;
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci	inode = new_inode(dir->i_sb);
19062306a36Sopenharmony_ci	if (!inode) {
19162306a36Sopenharmony_ci		mlog(ML_ERROR, "new_inode failed!\n");
19262306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
19362306a36Sopenharmony_ci	}
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	/* populate as many fields early on as possible - many of
19662306a36Sopenharmony_ci	 * these are used by the support functions here and in
19762306a36Sopenharmony_ci	 * callers. */
19862306a36Sopenharmony_ci	if (S_ISDIR(mode))
19962306a36Sopenharmony_ci		set_nlink(inode, 2);
20062306a36Sopenharmony_ci	mode = mode_strip_sgid(&nop_mnt_idmap, dir, mode);
20162306a36Sopenharmony_ci	inode_init_owner(&nop_mnt_idmap, inode, dir, mode);
20262306a36Sopenharmony_ci	status = dquot_initialize(inode);
20362306a36Sopenharmony_ci	if (status)
20462306a36Sopenharmony_ci		return ERR_PTR(status);
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	return inode;
20762306a36Sopenharmony_ci}
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_cistatic void ocfs2_cleanup_add_entry_failure(struct ocfs2_super *osb,
21062306a36Sopenharmony_ci		struct dentry *dentry, struct inode *inode)
21162306a36Sopenharmony_ci{
21262306a36Sopenharmony_ci	struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
21562306a36Sopenharmony_ci	ocfs2_lock_res_free(&dl->dl_lockres);
21662306a36Sopenharmony_ci	BUG_ON(dl->dl_count != 1);
21762306a36Sopenharmony_ci	spin_lock(&dentry_attach_lock);
21862306a36Sopenharmony_ci	dentry->d_fsdata = NULL;
21962306a36Sopenharmony_ci	spin_unlock(&dentry_attach_lock);
22062306a36Sopenharmony_ci	kfree(dl);
22162306a36Sopenharmony_ci	iput(inode);
22262306a36Sopenharmony_ci}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_cistatic int ocfs2_mknod(struct mnt_idmap *idmap,
22562306a36Sopenharmony_ci		       struct inode *dir,
22662306a36Sopenharmony_ci		       struct dentry *dentry,
22762306a36Sopenharmony_ci		       umode_t mode,
22862306a36Sopenharmony_ci		       dev_t dev)
22962306a36Sopenharmony_ci{
23062306a36Sopenharmony_ci	int status = 0;
23162306a36Sopenharmony_ci	struct buffer_head *parent_fe_bh = NULL;
23262306a36Sopenharmony_ci	handle_t *handle = NULL;
23362306a36Sopenharmony_ci	struct ocfs2_super *osb;
23462306a36Sopenharmony_ci	struct ocfs2_dinode *dirfe;
23562306a36Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
23662306a36Sopenharmony_ci	struct buffer_head *new_fe_bh = NULL;
23762306a36Sopenharmony_ci	struct inode *inode = NULL;
23862306a36Sopenharmony_ci	struct ocfs2_alloc_context *inode_ac = NULL;
23962306a36Sopenharmony_ci	struct ocfs2_alloc_context *data_ac = NULL;
24062306a36Sopenharmony_ci	struct ocfs2_alloc_context *meta_ac = NULL;
24162306a36Sopenharmony_ci	int want_clusters = 0;
24262306a36Sopenharmony_ci	int want_meta = 0;
24362306a36Sopenharmony_ci	int xattr_credits = 0;
24462306a36Sopenharmony_ci	struct ocfs2_security_xattr_info si = {
24562306a36Sopenharmony_ci		.name = NULL,
24662306a36Sopenharmony_ci		.enable = 1,
24762306a36Sopenharmony_ci	};
24862306a36Sopenharmony_ci	int did_quota_inode = 0;
24962306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
25062306a36Sopenharmony_ci	sigset_t oldset;
25162306a36Sopenharmony_ci	int did_block_signals = 0;
25262306a36Sopenharmony_ci	struct ocfs2_dentry_lock *dl = NULL;
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci	trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name,
25562306a36Sopenharmony_ci			  (unsigned long long)OCFS2_I(dir)->ip_blkno,
25662306a36Sopenharmony_ci			  (unsigned long)dev, mode);
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	status = dquot_initialize(dir);
25962306a36Sopenharmony_ci	if (status) {
26062306a36Sopenharmony_ci		mlog_errno(status);
26162306a36Sopenharmony_ci		return status;
26262306a36Sopenharmony_ci	}
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	/* get our super block */
26562306a36Sopenharmony_ci	osb = OCFS2_SB(dir->i_sb);
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	status = ocfs2_inode_lock(dir, &parent_fe_bh, 1);
26862306a36Sopenharmony_ci	if (status < 0) {
26962306a36Sopenharmony_ci		if (status != -ENOENT)
27062306a36Sopenharmony_ci			mlog_errno(status);
27162306a36Sopenharmony_ci		return status;
27262306a36Sopenharmony_ci	}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	if (S_ISDIR(mode) && (dir->i_nlink >= ocfs2_link_max(osb))) {
27562306a36Sopenharmony_ci		status = -EMLINK;
27662306a36Sopenharmony_ci		goto leave;
27762306a36Sopenharmony_ci	}
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
28062306a36Sopenharmony_ci	if (!ocfs2_read_links_count(dirfe)) {
28162306a36Sopenharmony_ci		/* can't make a file in a deleted directory. */
28262306a36Sopenharmony_ci		status = -ENOENT;
28362306a36Sopenharmony_ci		goto leave;
28462306a36Sopenharmony_ci	}
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
28762306a36Sopenharmony_ci					   dentry->d_name.len);
28862306a36Sopenharmony_ci	if (status)
28962306a36Sopenharmony_ci		goto leave;
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	/* get a spot inside the dir. */
29262306a36Sopenharmony_ci	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
29362306a36Sopenharmony_ci					      dentry->d_name.name,
29462306a36Sopenharmony_ci					      dentry->d_name.len, &lookup);
29562306a36Sopenharmony_ci	if (status < 0) {
29662306a36Sopenharmony_ci		mlog_errno(status);
29762306a36Sopenharmony_ci		goto leave;
29862306a36Sopenharmony_ci	}
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	/* reserve an inode spot */
30162306a36Sopenharmony_ci	status = ocfs2_reserve_new_inode(osb, &inode_ac);
30262306a36Sopenharmony_ci	if (status < 0) {
30362306a36Sopenharmony_ci		if (status != -ENOSPC)
30462306a36Sopenharmony_ci			mlog_errno(status);
30562306a36Sopenharmony_ci		goto leave;
30662306a36Sopenharmony_ci	}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci	inode = ocfs2_get_init_inode(dir, mode);
30962306a36Sopenharmony_ci	if (IS_ERR(inode)) {
31062306a36Sopenharmony_ci		status = PTR_ERR(inode);
31162306a36Sopenharmony_ci		inode = NULL;
31262306a36Sopenharmony_ci		mlog_errno(status);
31362306a36Sopenharmony_ci		goto leave;
31462306a36Sopenharmony_ci	}
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	/* get security xattr */
31762306a36Sopenharmony_ci	status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);
31862306a36Sopenharmony_ci	if (status) {
31962306a36Sopenharmony_ci		if (status == -EOPNOTSUPP)
32062306a36Sopenharmony_ci			si.enable = 0;
32162306a36Sopenharmony_ci		else {
32262306a36Sopenharmony_ci			mlog_errno(status);
32362306a36Sopenharmony_ci			goto leave;
32462306a36Sopenharmony_ci		}
32562306a36Sopenharmony_ci	}
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	/* calculate meta data/clusters for setting security and acl xattr */
32862306a36Sopenharmony_ci	status = ocfs2_calc_xattr_init(dir, parent_fe_bh, mode,
32962306a36Sopenharmony_ci				       &si, &want_clusters,
33062306a36Sopenharmony_ci				       &xattr_credits, &want_meta);
33162306a36Sopenharmony_ci	if (status < 0) {
33262306a36Sopenharmony_ci		mlog_errno(status);
33362306a36Sopenharmony_ci		goto leave;
33462306a36Sopenharmony_ci	}
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	/* Reserve a cluster if creating an extent based directory. */
33762306a36Sopenharmony_ci	if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
33862306a36Sopenharmony_ci		want_clusters += 1;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci		/* Dir indexing requires extra space as well */
34162306a36Sopenharmony_ci		if (ocfs2_supports_indexed_dirs(osb))
34262306a36Sopenharmony_ci			want_meta++;
34362306a36Sopenharmony_ci	}
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	status = ocfs2_reserve_new_metadata_blocks(osb, want_meta, &meta_ac);
34662306a36Sopenharmony_ci	if (status < 0) {
34762306a36Sopenharmony_ci		if (status != -ENOSPC)
34862306a36Sopenharmony_ci			mlog_errno(status);
34962306a36Sopenharmony_ci		goto leave;
35062306a36Sopenharmony_ci	}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac);
35362306a36Sopenharmony_ci	if (status < 0) {
35462306a36Sopenharmony_ci		if (status != -ENOSPC)
35562306a36Sopenharmony_ci			mlog_errno(status);
35662306a36Sopenharmony_ci		goto leave;
35762306a36Sopenharmony_ci	}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
36062306a36Sopenharmony_ci							    S_ISDIR(mode),
36162306a36Sopenharmony_ci							    xattr_credits));
36262306a36Sopenharmony_ci	if (IS_ERR(handle)) {
36362306a36Sopenharmony_ci		status = PTR_ERR(handle);
36462306a36Sopenharmony_ci		handle = NULL;
36562306a36Sopenharmony_ci		mlog_errno(status);
36662306a36Sopenharmony_ci		goto leave;
36762306a36Sopenharmony_ci	}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	/* Starting to change things, restart is no longer possible. */
37062306a36Sopenharmony_ci	ocfs2_block_signals(&oldset);
37162306a36Sopenharmony_ci	did_block_signals = 1;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	status = dquot_alloc_inode(inode);
37462306a36Sopenharmony_ci	if (status)
37562306a36Sopenharmony_ci		goto leave;
37662306a36Sopenharmony_ci	did_quota_inode = 1;
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci	/* do the real work now. */
37962306a36Sopenharmony_ci	status = ocfs2_mknod_locked(osb, dir, inode, dev,
38062306a36Sopenharmony_ci				    &new_fe_bh, parent_fe_bh, handle,
38162306a36Sopenharmony_ci				    inode_ac);
38262306a36Sopenharmony_ci	if (status < 0) {
38362306a36Sopenharmony_ci		mlog_errno(status);
38462306a36Sopenharmony_ci		goto leave;
38562306a36Sopenharmony_ci	}
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	fe = (struct ocfs2_dinode *) new_fe_bh->b_data;
38862306a36Sopenharmony_ci	if (S_ISDIR(mode)) {
38962306a36Sopenharmony_ci		status = ocfs2_fill_new_dir(osb, handle, dir, inode,
39062306a36Sopenharmony_ci					    new_fe_bh, data_ac, meta_ac);
39162306a36Sopenharmony_ci		if (status < 0) {
39262306a36Sopenharmony_ci			mlog_errno(status);
39362306a36Sopenharmony_ci			goto leave;
39462306a36Sopenharmony_ci		}
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci		status = ocfs2_journal_access_di(handle, INODE_CACHE(dir),
39762306a36Sopenharmony_ci						 parent_fe_bh,
39862306a36Sopenharmony_ci						 OCFS2_JOURNAL_ACCESS_WRITE);
39962306a36Sopenharmony_ci		if (status < 0) {
40062306a36Sopenharmony_ci			mlog_errno(status);
40162306a36Sopenharmony_ci			goto leave;
40262306a36Sopenharmony_ci		}
40362306a36Sopenharmony_ci		ocfs2_add_links_count(dirfe, 1);
40462306a36Sopenharmony_ci		ocfs2_journal_dirty(handle, parent_fe_bh);
40562306a36Sopenharmony_ci		inc_nlink(dir);
40662306a36Sopenharmony_ci	}
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci	status = ocfs2_init_acl(handle, inode, dir, new_fe_bh, parent_fe_bh,
40962306a36Sopenharmony_ci			 meta_ac, data_ac);
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	if (status < 0) {
41262306a36Sopenharmony_ci		mlog_errno(status);
41362306a36Sopenharmony_ci		goto roll_back;
41462306a36Sopenharmony_ci	}
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	if (si.enable) {
41762306a36Sopenharmony_ci		status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si,
41862306a36Sopenharmony_ci						 meta_ac, data_ac);
41962306a36Sopenharmony_ci		if (status < 0) {
42062306a36Sopenharmony_ci			mlog_errno(status);
42162306a36Sopenharmony_ci			goto roll_back;
42262306a36Sopenharmony_ci		}
42362306a36Sopenharmony_ci	}
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	/*
42662306a36Sopenharmony_ci	 * Do this before adding the entry to the directory. We add
42762306a36Sopenharmony_ci	 * also set d_op after success so that ->d_iput() will cleanup
42862306a36Sopenharmony_ci	 * the dentry lock even if ocfs2_add_entry() fails below.
42962306a36Sopenharmony_ci	 */
43062306a36Sopenharmony_ci	status = ocfs2_dentry_attach_lock(dentry, inode,
43162306a36Sopenharmony_ci					  OCFS2_I(dir)->ip_blkno);
43262306a36Sopenharmony_ci	if (status) {
43362306a36Sopenharmony_ci		mlog_errno(status);
43462306a36Sopenharmony_ci		goto roll_back;
43562306a36Sopenharmony_ci	}
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci	dl = dentry->d_fsdata;
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci	status = ocfs2_add_entry(handle, dentry, inode,
44062306a36Sopenharmony_ci				 OCFS2_I(inode)->ip_blkno, parent_fe_bh,
44162306a36Sopenharmony_ci				 &lookup);
44262306a36Sopenharmony_ci	if (status < 0) {
44362306a36Sopenharmony_ci		mlog_errno(status);
44462306a36Sopenharmony_ci		goto roll_back;
44562306a36Sopenharmony_ci	}
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci	insert_inode_hash(inode);
44862306a36Sopenharmony_ci	d_instantiate(dentry, inode);
44962306a36Sopenharmony_ci	status = 0;
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ciroll_back:
45262306a36Sopenharmony_ci	if (status < 0 && S_ISDIR(mode)) {
45362306a36Sopenharmony_ci		ocfs2_add_links_count(dirfe, -1);
45462306a36Sopenharmony_ci		drop_nlink(dir);
45562306a36Sopenharmony_ci	}
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_cileave:
45862306a36Sopenharmony_ci	if (status < 0 && did_quota_inode)
45962306a36Sopenharmony_ci		dquot_free_inode(inode);
46062306a36Sopenharmony_ci	if (handle) {
46162306a36Sopenharmony_ci		if (status < 0 && fe)
46262306a36Sopenharmony_ci			ocfs2_set_links_count(fe, 0);
46362306a36Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
46462306a36Sopenharmony_ci	}
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
46762306a36Sopenharmony_ci	if (did_block_signals)
46862306a36Sopenharmony_ci		ocfs2_unblock_signals(&oldset);
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci	brelse(new_fe_bh);
47162306a36Sopenharmony_ci	brelse(parent_fe_bh);
47262306a36Sopenharmony_ci	kfree(si.value);
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	if (inode_ac)
47762306a36Sopenharmony_ci		ocfs2_free_alloc_context(inode_ac);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	if (data_ac)
48062306a36Sopenharmony_ci		ocfs2_free_alloc_context(data_ac);
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci	if (meta_ac)
48362306a36Sopenharmony_ci		ocfs2_free_alloc_context(meta_ac);
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	/*
48662306a36Sopenharmony_ci	 * We should call iput after the i_rwsem of the bitmap been
48762306a36Sopenharmony_ci	 * unlocked in ocfs2_free_alloc_context, or the
48862306a36Sopenharmony_ci	 * ocfs2_delete_inode will mutex_lock again.
48962306a36Sopenharmony_ci	 */
49062306a36Sopenharmony_ci	if ((status < 0) && inode) {
49162306a36Sopenharmony_ci		if (dl)
49262306a36Sopenharmony_ci			ocfs2_cleanup_add_entry_failure(osb, dentry, inode);
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
49562306a36Sopenharmony_ci		clear_nlink(inode);
49662306a36Sopenharmony_ci		iput(inode);
49762306a36Sopenharmony_ci	}
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	if (status)
50062306a36Sopenharmony_ci		mlog_errno(status);
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	return status;
50362306a36Sopenharmony_ci}
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_cistatic int __ocfs2_mknod_locked(struct inode *dir,
50662306a36Sopenharmony_ci				struct inode *inode,
50762306a36Sopenharmony_ci				dev_t dev,
50862306a36Sopenharmony_ci				struct buffer_head **new_fe_bh,
50962306a36Sopenharmony_ci				struct buffer_head *parent_fe_bh,
51062306a36Sopenharmony_ci				handle_t *handle,
51162306a36Sopenharmony_ci				struct ocfs2_alloc_context *inode_ac,
51262306a36Sopenharmony_ci				u64 fe_blkno, u64 suballoc_loc, u16 suballoc_bit)
51362306a36Sopenharmony_ci{
51462306a36Sopenharmony_ci	int status = 0;
51562306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
51662306a36Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
51762306a36Sopenharmony_ci	struct ocfs2_extent_list *fel;
51862306a36Sopenharmony_ci	u16 feat;
51962306a36Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
52062306a36Sopenharmony_ci	struct timespec64 ts;
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	*new_fe_bh = NULL;
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	/* populate as many fields early on as possible - many of
52562306a36Sopenharmony_ci	 * these are used by the support functions here and in
52662306a36Sopenharmony_ci	 * callers. */
52762306a36Sopenharmony_ci	inode->i_ino = ino_from_blkno(osb->sb, fe_blkno);
52862306a36Sopenharmony_ci	oi->ip_blkno = fe_blkno;
52962306a36Sopenharmony_ci	spin_lock(&osb->osb_lock);
53062306a36Sopenharmony_ci	inode->i_generation = osb->s_next_generation++;
53162306a36Sopenharmony_ci	spin_unlock(&osb->osb_lock);
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	*new_fe_bh = sb_getblk(osb->sb, fe_blkno);
53462306a36Sopenharmony_ci	if (!*new_fe_bh) {
53562306a36Sopenharmony_ci		status = -ENOMEM;
53662306a36Sopenharmony_ci		mlog_errno(status);
53762306a36Sopenharmony_ci		goto leave;
53862306a36Sopenharmony_ci	}
53962306a36Sopenharmony_ci	ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), *new_fe_bh);
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(inode),
54262306a36Sopenharmony_ci					 *new_fe_bh,
54362306a36Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_CREATE);
54462306a36Sopenharmony_ci	if (status < 0) {
54562306a36Sopenharmony_ci		mlog_errno(status);
54662306a36Sopenharmony_ci		goto leave;
54762306a36Sopenharmony_ci	}
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	fe = (struct ocfs2_dinode *) (*new_fe_bh)->b_data;
55062306a36Sopenharmony_ci	memset(fe, 0, osb->sb->s_blocksize);
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci	fe->i_generation = cpu_to_le32(inode->i_generation);
55362306a36Sopenharmony_ci	fe->i_fs_generation = cpu_to_le32(osb->fs_generation);
55462306a36Sopenharmony_ci	fe->i_blkno = cpu_to_le64(fe_blkno);
55562306a36Sopenharmony_ci	fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
55662306a36Sopenharmony_ci	fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
55762306a36Sopenharmony_ci	fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
55862306a36Sopenharmony_ci	fe->i_uid = cpu_to_le32(i_uid_read(inode));
55962306a36Sopenharmony_ci	fe->i_gid = cpu_to_le32(i_gid_read(inode));
56062306a36Sopenharmony_ci	fe->i_mode = cpu_to_le16(inode->i_mode);
56162306a36Sopenharmony_ci	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
56262306a36Sopenharmony_ci		fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci	ocfs2_set_links_count(fe, inode->i_nlink);
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ci	fe->i_last_eb_blk = 0;
56762306a36Sopenharmony_ci	strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE);
56862306a36Sopenharmony_ci	fe->i_flags |= cpu_to_le32(OCFS2_VALID_FL);
56962306a36Sopenharmony_ci	ktime_get_real_ts64(&ts);
57062306a36Sopenharmony_ci	fe->i_atime = fe->i_ctime = fe->i_mtime =
57162306a36Sopenharmony_ci		cpu_to_le64(ts.tv_sec);
57262306a36Sopenharmony_ci	fe->i_mtime_nsec = fe->i_ctime_nsec = fe->i_atime_nsec =
57362306a36Sopenharmony_ci		cpu_to_le32(ts.tv_nsec);
57462306a36Sopenharmony_ci	fe->i_dtime = 0;
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	/*
57762306a36Sopenharmony_ci	 * If supported, directories start with inline data. If inline
57862306a36Sopenharmony_ci	 * isn't supported, but indexing is, we start them as indexed.
57962306a36Sopenharmony_ci	 */
58062306a36Sopenharmony_ci	feat = le16_to_cpu(fe->i_dyn_features);
58162306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) {
58262306a36Sopenharmony_ci		fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL);
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci		fe->id2.i_data.id_count = cpu_to_le16(
58562306a36Sopenharmony_ci				ocfs2_max_inline_data_with_xattr(osb->sb, fe));
58662306a36Sopenharmony_ci	} else {
58762306a36Sopenharmony_ci		fel = &fe->id2.i_list;
58862306a36Sopenharmony_ci		fel->l_tree_depth = 0;
58962306a36Sopenharmony_ci		fel->l_next_free_rec = 0;
59062306a36Sopenharmony_ci		fel->l_count = cpu_to_le16(ocfs2_extent_recs_per_inode(osb->sb));
59162306a36Sopenharmony_ci	}
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci	ocfs2_journal_dirty(handle, *new_fe_bh);
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	ocfs2_populate_inode(inode, fe, 1);
59662306a36Sopenharmony_ci	ocfs2_ci_set_new(osb, INODE_CACHE(inode));
59762306a36Sopenharmony_ci	if (!ocfs2_mount_local(osb)) {
59862306a36Sopenharmony_ci		status = ocfs2_create_new_inode_locks(inode);
59962306a36Sopenharmony_ci		if (status < 0)
60062306a36Sopenharmony_ci			mlog_errno(status);
60162306a36Sopenharmony_ci	}
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	ocfs2_update_inode_fsync_trans(handle, inode, 1);
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_cileave:
60662306a36Sopenharmony_ci	if (status < 0) {
60762306a36Sopenharmony_ci		if (*new_fe_bh) {
60862306a36Sopenharmony_ci			brelse(*new_fe_bh);
60962306a36Sopenharmony_ci			*new_fe_bh = NULL;
61062306a36Sopenharmony_ci		}
61162306a36Sopenharmony_ci	}
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci	if (status)
61462306a36Sopenharmony_ci		mlog_errno(status);
61562306a36Sopenharmony_ci	return status;
61662306a36Sopenharmony_ci}
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_cistatic int ocfs2_mknod_locked(struct ocfs2_super *osb,
61962306a36Sopenharmony_ci			      struct inode *dir,
62062306a36Sopenharmony_ci			      struct inode *inode,
62162306a36Sopenharmony_ci			      dev_t dev,
62262306a36Sopenharmony_ci			      struct buffer_head **new_fe_bh,
62362306a36Sopenharmony_ci			      struct buffer_head *parent_fe_bh,
62462306a36Sopenharmony_ci			      handle_t *handle,
62562306a36Sopenharmony_ci			      struct ocfs2_alloc_context *inode_ac)
62662306a36Sopenharmony_ci{
62762306a36Sopenharmony_ci	int status = 0;
62862306a36Sopenharmony_ci	u64 suballoc_loc, fe_blkno = 0;
62962306a36Sopenharmony_ci	u16 suballoc_bit;
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	*new_fe_bh = NULL;
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci	status = ocfs2_claim_new_inode(handle, dir, parent_fe_bh,
63462306a36Sopenharmony_ci				       inode_ac, &suballoc_loc,
63562306a36Sopenharmony_ci				       &suballoc_bit, &fe_blkno);
63662306a36Sopenharmony_ci	if (status < 0) {
63762306a36Sopenharmony_ci		mlog_errno(status);
63862306a36Sopenharmony_ci		return status;
63962306a36Sopenharmony_ci	}
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh,
64262306a36Sopenharmony_ci				    parent_fe_bh, handle, inode_ac,
64362306a36Sopenharmony_ci				    fe_blkno, suballoc_loc, suballoc_bit);
64462306a36Sopenharmony_ci}
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_cistatic int ocfs2_mkdir(struct mnt_idmap *idmap,
64762306a36Sopenharmony_ci		       struct inode *dir,
64862306a36Sopenharmony_ci		       struct dentry *dentry,
64962306a36Sopenharmony_ci		       umode_t mode)
65062306a36Sopenharmony_ci{
65162306a36Sopenharmony_ci	int ret;
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci	trace_ocfs2_mkdir(dir, dentry, dentry->d_name.len, dentry->d_name.name,
65462306a36Sopenharmony_ci			  OCFS2_I(dir)->ip_blkno, mode);
65562306a36Sopenharmony_ci	ret = ocfs2_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFDIR, 0);
65662306a36Sopenharmony_ci	if (ret)
65762306a36Sopenharmony_ci		mlog_errno(ret);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	return ret;
66062306a36Sopenharmony_ci}
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_cistatic int ocfs2_create(struct mnt_idmap *idmap,
66362306a36Sopenharmony_ci			struct inode *dir,
66462306a36Sopenharmony_ci			struct dentry *dentry,
66562306a36Sopenharmony_ci			umode_t mode,
66662306a36Sopenharmony_ci			bool excl)
66762306a36Sopenharmony_ci{
66862306a36Sopenharmony_ci	int ret;
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	trace_ocfs2_create(dir, dentry, dentry->d_name.len, dentry->d_name.name,
67162306a36Sopenharmony_ci			   (unsigned long long)OCFS2_I(dir)->ip_blkno, mode);
67262306a36Sopenharmony_ci	ret = ocfs2_mknod(&nop_mnt_idmap, dir, dentry, mode | S_IFREG, 0);
67362306a36Sopenharmony_ci	if (ret)
67462306a36Sopenharmony_ci		mlog_errno(ret);
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	return ret;
67762306a36Sopenharmony_ci}
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_cistatic int ocfs2_link(struct dentry *old_dentry,
68062306a36Sopenharmony_ci		      struct inode *dir,
68162306a36Sopenharmony_ci		      struct dentry *dentry)
68262306a36Sopenharmony_ci{
68362306a36Sopenharmony_ci	handle_t *handle;
68462306a36Sopenharmony_ci	struct inode *inode = d_inode(old_dentry);
68562306a36Sopenharmony_ci	struct inode *old_dir = d_inode(old_dentry->d_parent);
68662306a36Sopenharmony_ci	int err;
68762306a36Sopenharmony_ci	struct buffer_head *fe_bh = NULL;
68862306a36Sopenharmony_ci	struct buffer_head *old_dir_bh = NULL;
68962306a36Sopenharmony_ci	struct buffer_head *parent_fe_bh = NULL;
69062306a36Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
69162306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
69262306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
69362306a36Sopenharmony_ci	sigset_t oldset;
69462306a36Sopenharmony_ci	u64 old_de_ino;
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno,
69762306a36Sopenharmony_ci			 old_dentry->d_name.len, old_dentry->d_name.name,
69862306a36Sopenharmony_ci			 dentry->d_name.len, dentry->d_name.name);
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
70162306a36Sopenharmony_ci		return -EPERM;
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci	err = dquot_initialize(dir);
70462306a36Sopenharmony_ci	if (err) {
70562306a36Sopenharmony_ci		mlog_errno(err);
70662306a36Sopenharmony_ci		return err;
70762306a36Sopenharmony_ci	}
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	err = ocfs2_double_lock(osb, &old_dir_bh, old_dir,
71062306a36Sopenharmony_ci			&parent_fe_bh, dir, 0);
71162306a36Sopenharmony_ci	if (err < 0) {
71262306a36Sopenharmony_ci		if (err != -ENOENT)
71362306a36Sopenharmony_ci			mlog_errno(err);
71462306a36Sopenharmony_ci		return err;
71562306a36Sopenharmony_ci	}
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	/* make sure both dirs have bhs
71862306a36Sopenharmony_ci	 * get an extra ref on old_dir_bh if old==new */
71962306a36Sopenharmony_ci	if (!parent_fe_bh) {
72062306a36Sopenharmony_ci		if (old_dir_bh) {
72162306a36Sopenharmony_ci			parent_fe_bh = old_dir_bh;
72262306a36Sopenharmony_ci			get_bh(parent_fe_bh);
72362306a36Sopenharmony_ci		} else {
72462306a36Sopenharmony_ci			mlog(ML_ERROR, "%s: no old_dir_bh!\n", osb->uuid_str);
72562306a36Sopenharmony_ci			err = -EIO;
72662306a36Sopenharmony_ci			goto out;
72762306a36Sopenharmony_ci		}
72862306a36Sopenharmony_ci	}
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	if (!dir->i_nlink) {
73162306a36Sopenharmony_ci		err = -ENOENT;
73262306a36Sopenharmony_ci		goto out;
73362306a36Sopenharmony_ci	}
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_ci	err = ocfs2_lookup_ino_from_name(old_dir, old_dentry->d_name.name,
73662306a36Sopenharmony_ci			old_dentry->d_name.len, &old_de_ino);
73762306a36Sopenharmony_ci	if (err) {
73862306a36Sopenharmony_ci		err = -ENOENT;
73962306a36Sopenharmony_ci		goto out;
74062306a36Sopenharmony_ci	}
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci	/*
74362306a36Sopenharmony_ci	 * Check whether another node removed the source inode while we
74462306a36Sopenharmony_ci	 * were in the vfs.
74562306a36Sopenharmony_ci	 */
74662306a36Sopenharmony_ci	if (old_de_ino != OCFS2_I(inode)->ip_blkno) {
74762306a36Sopenharmony_ci		err = -ENOENT;
74862306a36Sopenharmony_ci		goto out;
74962306a36Sopenharmony_ci	}
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ci	err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
75262306a36Sopenharmony_ci					dentry->d_name.len);
75362306a36Sopenharmony_ci	if (err)
75462306a36Sopenharmony_ci		goto out;
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci	err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
75762306a36Sopenharmony_ci					   dentry->d_name.name,
75862306a36Sopenharmony_ci					   dentry->d_name.len, &lookup);
75962306a36Sopenharmony_ci	if (err < 0) {
76062306a36Sopenharmony_ci		mlog_errno(err);
76162306a36Sopenharmony_ci		goto out;
76262306a36Sopenharmony_ci	}
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	err = ocfs2_inode_lock(inode, &fe_bh, 1);
76562306a36Sopenharmony_ci	if (err < 0) {
76662306a36Sopenharmony_ci		if (err != -ENOENT)
76762306a36Sopenharmony_ci			mlog_errno(err);
76862306a36Sopenharmony_ci		goto out;
76962306a36Sopenharmony_ci	}
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci	fe = (struct ocfs2_dinode *) fe_bh->b_data;
77262306a36Sopenharmony_ci	if (ocfs2_read_links_count(fe) >= ocfs2_link_max(osb)) {
77362306a36Sopenharmony_ci		err = -EMLINK;
77462306a36Sopenharmony_ci		goto out_unlock_inode;
77562306a36Sopenharmony_ci	}
77662306a36Sopenharmony_ci
77762306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_link_credits(osb->sb));
77862306a36Sopenharmony_ci	if (IS_ERR(handle)) {
77962306a36Sopenharmony_ci		err = PTR_ERR(handle);
78062306a36Sopenharmony_ci		handle = NULL;
78162306a36Sopenharmony_ci		mlog_errno(err);
78262306a36Sopenharmony_ci		goto out_unlock_inode;
78362306a36Sopenharmony_ci	}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	/* Starting to change things, restart is no longer possible. */
78662306a36Sopenharmony_ci	ocfs2_block_signals(&oldset);
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_ci	err = ocfs2_journal_access_di(handle, INODE_CACHE(inode), fe_bh,
78962306a36Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
79062306a36Sopenharmony_ci	if (err < 0) {
79162306a36Sopenharmony_ci		mlog_errno(err);
79262306a36Sopenharmony_ci		goto out_commit;
79362306a36Sopenharmony_ci	}
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci	inc_nlink(inode);
79662306a36Sopenharmony_ci	inode_set_ctime_current(inode);
79762306a36Sopenharmony_ci	ocfs2_set_links_count(fe, inode->i_nlink);
79862306a36Sopenharmony_ci	fe->i_ctime = cpu_to_le64(inode_get_ctime(inode).tv_sec);
79962306a36Sopenharmony_ci	fe->i_ctime_nsec = cpu_to_le32(inode_get_ctime(inode).tv_nsec);
80062306a36Sopenharmony_ci	ocfs2_journal_dirty(handle, fe_bh);
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	err = ocfs2_add_entry(handle, dentry, inode,
80362306a36Sopenharmony_ci			      OCFS2_I(inode)->ip_blkno,
80462306a36Sopenharmony_ci			      parent_fe_bh, &lookup);
80562306a36Sopenharmony_ci	if (err) {
80662306a36Sopenharmony_ci		ocfs2_add_links_count(fe, -1);
80762306a36Sopenharmony_ci		drop_nlink(inode);
80862306a36Sopenharmony_ci		mlog_errno(err);
80962306a36Sopenharmony_ci		goto out_commit;
81062306a36Sopenharmony_ci	}
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
81362306a36Sopenharmony_ci	if (err) {
81462306a36Sopenharmony_ci		mlog_errno(err);
81562306a36Sopenharmony_ci		goto out_commit;
81662306a36Sopenharmony_ci	}
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	ihold(inode);
81962306a36Sopenharmony_ci	d_instantiate(dentry, inode);
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ciout_commit:
82262306a36Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
82362306a36Sopenharmony_ci	ocfs2_unblock_signals(&oldset);
82462306a36Sopenharmony_ciout_unlock_inode:
82562306a36Sopenharmony_ci	ocfs2_inode_unlock(inode, 1);
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ciout:
82862306a36Sopenharmony_ci	ocfs2_double_unlock(old_dir, dir);
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	brelse(fe_bh);
83162306a36Sopenharmony_ci	brelse(parent_fe_bh);
83262306a36Sopenharmony_ci	brelse(old_dir_bh);
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci	if (err)
83762306a36Sopenharmony_ci		mlog_errno(err);
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ci	return err;
84062306a36Sopenharmony_ci}
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci/*
84362306a36Sopenharmony_ci * Takes and drops an exclusive lock on the given dentry. This will
84462306a36Sopenharmony_ci * force other nodes to drop it.
84562306a36Sopenharmony_ci */
84662306a36Sopenharmony_cistatic int ocfs2_remote_dentry_delete(struct dentry *dentry)
84762306a36Sopenharmony_ci{
84862306a36Sopenharmony_ci	int ret;
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_ci	ret = ocfs2_dentry_lock(dentry, 1);
85162306a36Sopenharmony_ci	if (ret)
85262306a36Sopenharmony_ci		mlog_errno(ret);
85362306a36Sopenharmony_ci	else
85462306a36Sopenharmony_ci		ocfs2_dentry_unlock(dentry, 1);
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci	return ret;
85762306a36Sopenharmony_ci}
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_cistatic inline int ocfs2_inode_is_unlinkable(struct inode *inode)
86062306a36Sopenharmony_ci{
86162306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode)) {
86262306a36Sopenharmony_ci		if (inode->i_nlink == 2)
86362306a36Sopenharmony_ci			return 1;
86462306a36Sopenharmony_ci		return 0;
86562306a36Sopenharmony_ci	}
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ci	if (inode->i_nlink == 1)
86862306a36Sopenharmony_ci		return 1;
86962306a36Sopenharmony_ci	return 0;
87062306a36Sopenharmony_ci}
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_cistatic int ocfs2_unlink(struct inode *dir,
87362306a36Sopenharmony_ci			struct dentry *dentry)
87462306a36Sopenharmony_ci{
87562306a36Sopenharmony_ci	int status;
87662306a36Sopenharmony_ci	int child_locked = 0;
87762306a36Sopenharmony_ci	bool is_unlinkable = false;
87862306a36Sopenharmony_ci	struct inode *inode = d_inode(dentry);
87962306a36Sopenharmony_ci	struct inode *orphan_dir = NULL;
88062306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
88162306a36Sopenharmony_ci	u64 blkno;
88262306a36Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
88362306a36Sopenharmony_ci	struct buffer_head *fe_bh = NULL;
88462306a36Sopenharmony_ci	struct buffer_head *parent_node_bh = NULL;
88562306a36Sopenharmony_ci	handle_t *handle = NULL;
88662306a36Sopenharmony_ci	char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
88762306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
88862306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
88962306a36Sopenharmony_ci
89062306a36Sopenharmony_ci	trace_ocfs2_unlink(dir, dentry, dentry->d_name.len,
89162306a36Sopenharmony_ci			   dentry->d_name.name,
89262306a36Sopenharmony_ci			   (unsigned long long)OCFS2_I(dir)->ip_blkno,
89362306a36Sopenharmony_ci			   (unsigned long long)OCFS2_I(inode)->ip_blkno);
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci	status = dquot_initialize(dir);
89662306a36Sopenharmony_ci	if (status) {
89762306a36Sopenharmony_ci		mlog_errno(status);
89862306a36Sopenharmony_ci		return status;
89962306a36Sopenharmony_ci	}
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci	BUG_ON(d_inode(dentry->d_parent) != dir);
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	if (inode == osb->root_inode)
90462306a36Sopenharmony_ci		return -EPERM;
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_ci	status = ocfs2_inode_lock_nested(dir, &parent_node_bh, 1,
90762306a36Sopenharmony_ci					 OI_LS_PARENT);
90862306a36Sopenharmony_ci	if (status < 0) {
90962306a36Sopenharmony_ci		if (status != -ENOENT)
91062306a36Sopenharmony_ci			mlog_errno(status);
91162306a36Sopenharmony_ci		return status;
91262306a36Sopenharmony_ci	}
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci	status = ocfs2_find_files_on_disk(dentry->d_name.name,
91562306a36Sopenharmony_ci					  dentry->d_name.len, &blkno, dir,
91662306a36Sopenharmony_ci					  &lookup);
91762306a36Sopenharmony_ci	if (status < 0) {
91862306a36Sopenharmony_ci		if (status != -ENOENT)
91962306a36Sopenharmony_ci			mlog_errno(status);
92062306a36Sopenharmony_ci		goto leave;
92162306a36Sopenharmony_ci	}
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci	if (OCFS2_I(inode)->ip_blkno != blkno) {
92462306a36Sopenharmony_ci		status = -ENOENT;
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci		trace_ocfs2_unlink_noent(
92762306a36Sopenharmony_ci				(unsigned long long)OCFS2_I(inode)->ip_blkno,
92862306a36Sopenharmony_ci				(unsigned long long)blkno,
92962306a36Sopenharmony_ci				OCFS2_I(inode)->ip_flags);
93062306a36Sopenharmony_ci		goto leave;
93162306a36Sopenharmony_ci	}
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ci	status = ocfs2_inode_lock(inode, &fe_bh, 1);
93462306a36Sopenharmony_ci	if (status < 0) {
93562306a36Sopenharmony_ci		if (status != -ENOENT)
93662306a36Sopenharmony_ci			mlog_errno(status);
93762306a36Sopenharmony_ci		goto leave;
93862306a36Sopenharmony_ci	}
93962306a36Sopenharmony_ci	child_locked = 1;
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode)) {
94262306a36Sopenharmony_ci		if (inode->i_nlink != 2 || !ocfs2_empty_dir(inode)) {
94362306a36Sopenharmony_ci			status = -ENOTEMPTY;
94462306a36Sopenharmony_ci			goto leave;
94562306a36Sopenharmony_ci		}
94662306a36Sopenharmony_ci	}
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_ci	status = ocfs2_remote_dentry_delete(dentry);
94962306a36Sopenharmony_ci	if (status < 0) {
95062306a36Sopenharmony_ci		/* This remote delete should succeed under all normal
95162306a36Sopenharmony_ci		 * circumstances. */
95262306a36Sopenharmony_ci		mlog_errno(status);
95362306a36Sopenharmony_ci		goto leave;
95462306a36Sopenharmony_ci	}
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	if (ocfs2_inode_is_unlinkable(inode)) {
95762306a36Sopenharmony_ci		status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
95862306a36Sopenharmony_ci						  OCFS2_I(inode)->ip_blkno,
95962306a36Sopenharmony_ci						  orphan_name, &orphan_insert,
96062306a36Sopenharmony_ci						  false);
96162306a36Sopenharmony_ci		if (status < 0) {
96262306a36Sopenharmony_ci			mlog_errno(status);
96362306a36Sopenharmony_ci			goto leave;
96462306a36Sopenharmony_ci		}
96562306a36Sopenharmony_ci		is_unlinkable = true;
96662306a36Sopenharmony_ci	}
96762306a36Sopenharmony_ci
96862306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_unlink_credits(osb->sb));
96962306a36Sopenharmony_ci	if (IS_ERR(handle)) {
97062306a36Sopenharmony_ci		status = PTR_ERR(handle);
97162306a36Sopenharmony_ci		handle = NULL;
97262306a36Sopenharmony_ci		mlog_errno(status);
97362306a36Sopenharmony_ci		goto leave;
97462306a36Sopenharmony_ci	}
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(inode), fe_bh,
97762306a36Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
97862306a36Sopenharmony_ci	if (status < 0) {
97962306a36Sopenharmony_ci		mlog_errno(status);
98062306a36Sopenharmony_ci		goto leave;
98162306a36Sopenharmony_ci	}
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci	fe = (struct ocfs2_dinode *) fe_bh->b_data;
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci	/* delete the name from the parent dir */
98662306a36Sopenharmony_ci	status = ocfs2_delete_entry(handle, dir, &lookup);
98762306a36Sopenharmony_ci	if (status < 0) {
98862306a36Sopenharmony_ci		mlog_errno(status);
98962306a36Sopenharmony_ci		goto leave;
99062306a36Sopenharmony_ci	}
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
99362306a36Sopenharmony_ci		drop_nlink(inode);
99462306a36Sopenharmony_ci	drop_nlink(inode);
99562306a36Sopenharmony_ci	ocfs2_set_links_count(fe, inode->i_nlink);
99662306a36Sopenharmony_ci	ocfs2_journal_dirty(handle, fe_bh);
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci	dir->i_mtime = inode_set_ctime_current(dir);
99962306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
100062306a36Sopenharmony_ci		drop_nlink(dir);
100162306a36Sopenharmony_ci
100262306a36Sopenharmony_ci	status = ocfs2_mark_inode_dirty(handle, dir, parent_node_bh);
100362306a36Sopenharmony_ci	if (status < 0) {
100462306a36Sopenharmony_ci		mlog_errno(status);
100562306a36Sopenharmony_ci		if (S_ISDIR(inode->i_mode))
100662306a36Sopenharmony_ci			inc_nlink(dir);
100762306a36Sopenharmony_ci		goto leave;
100862306a36Sopenharmony_ci	}
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci	if (is_unlinkable) {
101162306a36Sopenharmony_ci		status = ocfs2_orphan_add(osb, handle, inode, fe_bh,
101262306a36Sopenharmony_ci				orphan_name, &orphan_insert, orphan_dir, false);
101362306a36Sopenharmony_ci		if (status < 0)
101462306a36Sopenharmony_ci			mlog_errno(status);
101562306a36Sopenharmony_ci	}
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_cileave:
101862306a36Sopenharmony_ci	if (handle)
101962306a36Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_ci	if (orphan_dir) {
102262306a36Sopenharmony_ci		/* This was locked for us in ocfs2_prepare_orphan_dir() */
102362306a36Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir, 1);
102462306a36Sopenharmony_ci		inode_unlock(orphan_dir);
102562306a36Sopenharmony_ci		iput(orphan_dir);
102662306a36Sopenharmony_ci	}
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_ci	if (child_locked)
102962306a36Sopenharmony_ci		ocfs2_inode_unlock(inode, 1);
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci	brelse(fe_bh);
103462306a36Sopenharmony_ci	brelse(parent_node_bh);
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&orphan_insert);
103762306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
103862306a36Sopenharmony_ci
103962306a36Sopenharmony_ci	if (status && (status != -ENOTEMPTY) && (status != -ENOENT))
104062306a36Sopenharmony_ci		mlog_errno(status);
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_ci	return status;
104362306a36Sopenharmony_ci}
104462306a36Sopenharmony_ci
104562306a36Sopenharmony_cistatic int ocfs2_check_if_ancestor(struct ocfs2_super *osb,
104662306a36Sopenharmony_ci		u64 src_inode_no, u64 dest_inode_no)
104762306a36Sopenharmony_ci{
104862306a36Sopenharmony_ci	int ret = 0, i = 0;
104962306a36Sopenharmony_ci	u64 parent_inode_no = 0;
105062306a36Sopenharmony_ci	u64 child_inode_no = src_inode_no;
105162306a36Sopenharmony_ci	struct inode *child_inode;
105262306a36Sopenharmony_ci
105362306a36Sopenharmony_ci#define MAX_LOOKUP_TIMES 32
105462306a36Sopenharmony_ci	while (1) {
105562306a36Sopenharmony_ci		child_inode = ocfs2_iget(osb, child_inode_no, 0, 0);
105662306a36Sopenharmony_ci		if (IS_ERR(child_inode)) {
105762306a36Sopenharmony_ci			ret = PTR_ERR(child_inode);
105862306a36Sopenharmony_ci			break;
105962306a36Sopenharmony_ci		}
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci		ret = ocfs2_inode_lock(child_inode, NULL, 0);
106262306a36Sopenharmony_ci		if (ret < 0) {
106362306a36Sopenharmony_ci			iput(child_inode);
106462306a36Sopenharmony_ci			if (ret != -ENOENT)
106562306a36Sopenharmony_ci				mlog_errno(ret);
106662306a36Sopenharmony_ci			break;
106762306a36Sopenharmony_ci		}
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_ci		ret = ocfs2_lookup_ino_from_name(child_inode, "..", 2,
107062306a36Sopenharmony_ci				&parent_inode_no);
107162306a36Sopenharmony_ci		ocfs2_inode_unlock(child_inode, 0);
107262306a36Sopenharmony_ci		iput(child_inode);
107362306a36Sopenharmony_ci		if (ret < 0) {
107462306a36Sopenharmony_ci			ret = -ENOENT;
107562306a36Sopenharmony_ci			break;
107662306a36Sopenharmony_ci		}
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_ci		if (parent_inode_no == dest_inode_no) {
107962306a36Sopenharmony_ci			ret = 1;
108062306a36Sopenharmony_ci			break;
108162306a36Sopenharmony_ci		}
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_ci		if (parent_inode_no == osb->root_inode->i_ino) {
108462306a36Sopenharmony_ci			ret = 0;
108562306a36Sopenharmony_ci			break;
108662306a36Sopenharmony_ci		}
108762306a36Sopenharmony_ci
108862306a36Sopenharmony_ci		child_inode_no = parent_inode_no;
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci		if (++i >= MAX_LOOKUP_TIMES) {
109162306a36Sopenharmony_ci			mlog_ratelimited(ML_NOTICE, "max lookup times reached, "
109262306a36Sopenharmony_ci					"filesystem may have nested directories, "
109362306a36Sopenharmony_ci					"src inode: %llu, dest inode: %llu.\n",
109462306a36Sopenharmony_ci					(unsigned long long)src_inode_no,
109562306a36Sopenharmony_ci					(unsigned long long)dest_inode_no);
109662306a36Sopenharmony_ci			ret = 0;
109762306a36Sopenharmony_ci			break;
109862306a36Sopenharmony_ci		}
109962306a36Sopenharmony_ci	}
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ci	return ret;
110262306a36Sopenharmony_ci}
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_ci/*
110562306a36Sopenharmony_ci * The only place this should be used is rename and link!
110662306a36Sopenharmony_ci * if they have the same id, then the 1st one is the only one locked.
110762306a36Sopenharmony_ci */
110862306a36Sopenharmony_cistatic int ocfs2_double_lock(struct ocfs2_super *osb,
110962306a36Sopenharmony_ci			     struct buffer_head **bh1,
111062306a36Sopenharmony_ci			     struct inode *inode1,
111162306a36Sopenharmony_ci			     struct buffer_head **bh2,
111262306a36Sopenharmony_ci			     struct inode *inode2,
111362306a36Sopenharmony_ci			     int rename)
111462306a36Sopenharmony_ci{
111562306a36Sopenharmony_ci	int status;
111662306a36Sopenharmony_ci	int inode1_is_ancestor, inode2_is_ancestor;
111762306a36Sopenharmony_ci	struct ocfs2_inode_info *oi1 = OCFS2_I(inode1);
111862306a36Sopenharmony_ci	struct ocfs2_inode_info *oi2 = OCFS2_I(inode2);
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	trace_ocfs2_double_lock((unsigned long long)oi1->ip_blkno,
112162306a36Sopenharmony_ci				(unsigned long long)oi2->ip_blkno);
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_ci	if (*bh1)
112462306a36Sopenharmony_ci		*bh1 = NULL;
112562306a36Sopenharmony_ci	if (*bh2)
112662306a36Sopenharmony_ci		*bh2 = NULL;
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci	/* we always want to lock the one with the lower lockid first.
112962306a36Sopenharmony_ci	 * and if they are nested, we lock ancestor first */
113062306a36Sopenharmony_ci	if (oi1->ip_blkno != oi2->ip_blkno) {
113162306a36Sopenharmony_ci		inode1_is_ancestor = ocfs2_check_if_ancestor(osb, oi2->ip_blkno,
113262306a36Sopenharmony_ci				oi1->ip_blkno);
113362306a36Sopenharmony_ci		if (inode1_is_ancestor < 0) {
113462306a36Sopenharmony_ci			status = inode1_is_ancestor;
113562306a36Sopenharmony_ci			goto bail;
113662306a36Sopenharmony_ci		}
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ci		inode2_is_ancestor = ocfs2_check_if_ancestor(osb, oi1->ip_blkno,
113962306a36Sopenharmony_ci				oi2->ip_blkno);
114062306a36Sopenharmony_ci		if (inode2_is_ancestor < 0) {
114162306a36Sopenharmony_ci			status = inode2_is_ancestor;
114262306a36Sopenharmony_ci			goto bail;
114362306a36Sopenharmony_ci		}
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_ci		if ((inode1_is_ancestor == 1) ||
114662306a36Sopenharmony_ci				(oi1->ip_blkno < oi2->ip_blkno &&
114762306a36Sopenharmony_ci				inode2_is_ancestor == 0)) {
114862306a36Sopenharmony_ci			/* switch id1 and id2 around */
114962306a36Sopenharmony_ci			swap(bh2, bh1);
115062306a36Sopenharmony_ci			swap(inode2, inode1);
115162306a36Sopenharmony_ci		}
115262306a36Sopenharmony_ci		/* lock id2 */
115362306a36Sopenharmony_ci		status = ocfs2_inode_lock_nested(inode2, bh2, 1,
115462306a36Sopenharmony_ci				rename == 1 ? OI_LS_RENAME1 : OI_LS_PARENT);
115562306a36Sopenharmony_ci		if (status < 0) {
115662306a36Sopenharmony_ci			if (status != -ENOENT)
115762306a36Sopenharmony_ci				mlog_errno(status);
115862306a36Sopenharmony_ci			goto bail;
115962306a36Sopenharmony_ci		}
116062306a36Sopenharmony_ci	}
116162306a36Sopenharmony_ci
116262306a36Sopenharmony_ci	/* lock id1 */
116362306a36Sopenharmony_ci	status = ocfs2_inode_lock_nested(inode1, bh1, 1,
116462306a36Sopenharmony_ci			rename == 1 ?  OI_LS_RENAME2 : OI_LS_PARENT);
116562306a36Sopenharmony_ci	if (status < 0) {
116662306a36Sopenharmony_ci		/*
116762306a36Sopenharmony_ci		 * An error return must mean that no cluster locks
116862306a36Sopenharmony_ci		 * were held on function exit.
116962306a36Sopenharmony_ci		 */
117062306a36Sopenharmony_ci		if (oi1->ip_blkno != oi2->ip_blkno) {
117162306a36Sopenharmony_ci			ocfs2_inode_unlock(inode2, 1);
117262306a36Sopenharmony_ci			brelse(*bh2);
117362306a36Sopenharmony_ci			*bh2 = NULL;
117462306a36Sopenharmony_ci		}
117562306a36Sopenharmony_ci
117662306a36Sopenharmony_ci		if (status != -ENOENT)
117762306a36Sopenharmony_ci			mlog_errno(status);
117862306a36Sopenharmony_ci	}
117962306a36Sopenharmony_ci
118062306a36Sopenharmony_ci	trace_ocfs2_double_lock_end(
118162306a36Sopenharmony_ci			(unsigned long long)oi1->ip_blkno,
118262306a36Sopenharmony_ci			(unsigned long long)oi2->ip_blkno);
118362306a36Sopenharmony_ci
118462306a36Sopenharmony_cibail:
118562306a36Sopenharmony_ci	if (status)
118662306a36Sopenharmony_ci		mlog_errno(status);
118762306a36Sopenharmony_ci	return status;
118862306a36Sopenharmony_ci}
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_cistatic void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2)
119162306a36Sopenharmony_ci{
119262306a36Sopenharmony_ci	ocfs2_inode_unlock(inode1, 1);
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	if (inode1 != inode2)
119562306a36Sopenharmony_ci		ocfs2_inode_unlock(inode2, 1);
119662306a36Sopenharmony_ci}
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_cistatic int ocfs2_rename(struct mnt_idmap *idmap,
119962306a36Sopenharmony_ci			struct inode *old_dir,
120062306a36Sopenharmony_ci			struct dentry *old_dentry,
120162306a36Sopenharmony_ci			struct inode *new_dir,
120262306a36Sopenharmony_ci			struct dentry *new_dentry,
120362306a36Sopenharmony_ci			unsigned int flags)
120462306a36Sopenharmony_ci{
120562306a36Sopenharmony_ci	int status = 0, rename_lock = 0, parents_locked = 0, target_exists = 0;
120662306a36Sopenharmony_ci	int old_child_locked = 0, new_child_locked = 0, update_dot_dot = 0;
120762306a36Sopenharmony_ci	struct inode *old_inode = d_inode(old_dentry);
120862306a36Sopenharmony_ci	struct inode *new_inode = d_inode(new_dentry);
120962306a36Sopenharmony_ci	struct inode *orphan_dir = NULL;
121062306a36Sopenharmony_ci	struct ocfs2_dinode *newfe = NULL;
121162306a36Sopenharmony_ci	char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
121262306a36Sopenharmony_ci	struct buffer_head *newfe_bh = NULL;
121362306a36Sopenharmony_ci	struct buffer_head *old_inode_bh = NULL;
121462306a36Sopenharmony_ci	struct ocfs2_super *osb = NULL;
121562306a36Sopenharmony_ci	u64 newfe_blkno, old_de_ino;
121662306a36Sopenharmony_ci	handle_t *handle = NULL;
121762306a36Sopenharmony_ci	struct buffer_head *old_dir_bh = NULL;
121862306a36Sopenharmony_ci	struct buffer_head *new_dir_bh = NULL;
121962306a36Sopenharmony_ci	u32 old_dir_nlink = old_dir->i_nlink;
122062306a36Sopenharmony_ci	struct ocfs2_dinode *old_di;
122162306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result old_inode_dot_dot_res = { NULL, };
122262306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result target_lookup_res = { NULL, };
122362306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result old_entry_lookup = { NULL, };
122462306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
122562306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result target_insert = { NULL, };
122662306a36Sopenharmony_ci	bool should_add_orphan = false;
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ci	if (flags)
122962306a36Sopenharmony_ci		return -EINVAL;
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ci	/* At some point it might be nice to break this function up a
123262306a36Sopenharmony_ci	 * bit. */
123362306a36Sopenharmony_ci
123462306a36Sopenharmony_ci	trace_ocfs2_rename(old_dir, old_dentry, new_dir, new_dentry,
123562306a36Sopenharmony_ci			   old_dentry->d_name.len, old_dentry->d_name.name,
123662306a36Sopenharmony_ci			   new_dentry->d_name.len, new_dentry->d_name.name);
123762306a36Sopenharmony_ci
123862306a36Sopenharmony_ci	status = dquot_initialize(old_dir);
123962306a36Sopenharmony_ci	if (status) {
124062306a36Sopenharmony_ci		mlog_errno(status);
124162306a36Sopenharmony_ci		goto bail;
124262306a36Sopenharmony_ci	}
124362306a36Sopenharmony_ci	status = dquot_initialize(new_dir);
124462306a36Sopenharmony_ci	if (status) {
124562306a36Sopenharmony_ci		mlog_errno(status);
124662306a36Sopenharmony_ci		goto bail;
124762306a36Sopenharmony_ci	}
124862306a36Sopenharmony_ci
124962306a36Sopenharmony_ci	osb = OCFS2_SB(old_dir->i_sb);
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_ci	if (new_inode) {
125262306a36Sopenharmony_ci		if (!igrab(new_inode))
125362306a36Sopenharmony_ci			BUG();
125462306a36Sopenharmony_ci	}
125562306a36Sopenharmony_ci
125662306a36Sopenharmony_ci	/* Assume a directory hierarchy thusly:
125762306a36Sopenharmony_ci	 * a/b/c
125862306a36Sopenharmony_ci	 * a/d
125962306a36Sopenharmony_ci	 * a,b,c, and d are all directories.
126062306a36Sopenharmony_ci	 *
126162306a36Sopenharmony_ci	 * from cwd of 'a' on both nodes:
126262306a36Sopenharmony_ci	 * node1: mv b/c d
126362306a36Sopenharmony_ci	 * node2: mv d   b/c
126462306a36Sopenharmony_ci	 *
126562306a36Sopenharmony_ci	 * And that's why, just like the VFS, we need a file system
126662306a36Sopenharmony_ci	 * rename lock. */
126762306a36Sopenharmony_ci	if (old_dir != new_dir && S_ISDIR(old_inode->i_mode)) {
126862306a36Sopenharmony_ci		status = ocfs2_rename_lock(osb);
126962306a36Sopenharmony_ci		if (status < 0) {
127062306a36Sopenharmony_ci			mlog_errno(status);
127162306a36Sopenharmony_ci			goto bail;
127262306a36Sopenharmony_ci		}
127362306a36Sopenharmony_ci		rename_lock = 1;
127462306a36Sopenharmony_ci
127562306a36Sopenharmony_ci		/* here we cannot guarantee the inodes haven't just been
127662306a36Sopenharmony_ci		 * changed, so check if they are nested again */
127762306a36Sopenharmony_ci		status = ocfs2_check_if_ancestor(osb, new_dir->i_ino,
127862306a36Sopenharmony_ci				old_inode->i_ino);
127962306a36Sopenharmony_ci		if (status < 0) {
128062306a36Sopenharmony_ci			mlog_errno(status);
128162306a36Sopenharmony_ci			goto bail;
128262306a36Sopenharmony_ci		} else if (status == 1) {
128362306a36Sopenharmony_ci			status = -EPERM;
128462306a36Sopenharmony_ci			trace_ocfs2_rename_not_permitted(
128562306a36Sopenharmony_ci					(unsigned long long)old_inode->i_ino,
128662306a36Sopenharmony_ci					(unsigned long long)new_dir->i_ino);
128762306a36Sopenharmony_ci			goto bail;
128862306a36Sopenharmony_ci		}
128962306a36Sopenharmony_ci	}
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	/* if old and new are the same, this'll just do one lock. */
129262306a36Sopenharmony_ci	status = ocfs2_double_lock(osb, &old_dir_bh, old_dir,
129362306a36Sopenharmony_ci				   &new_dir_bh, new_dir, 1);
129462306a36Sopenharmony_ci	if (status < 0) {
129562306a36Sopenharmony_ci		mlog_errno(status);
129662306a36Sopenharmony_ci		goto bail;
129762306a36Sopenharmony_ci	}
129862306a36Sopenharmony_ci	parents_locked = 1;
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci	if (!new_dir->i_nlink) {
130162306a36Sopenharmony_ci		status = -EACCES;
130262306a36Sopenharmony_ci		goto bail;
130362306a36Sopenharmony_ci	}
130462306a36Sopenharmony_ci
130562306a36Sopenharmony_ci	/* make sure both dirs have bhs
130662306a36Sopenharmony_ci	 * get an extra ref on old_dir_bh if old==new */
130762306a36Sopenharmony_ci	if (!new_dir_bh) {
130862306a36Sopenharmony_ci		if (old_dir_bh) {
130962306a36Sopenharmony_ci			new_dir_bh = old_dir_bh;
131062306a36Sopenharmony_ci			get_bh(new_dir_bh);
131162306a36Sopenharmony_ci		} else {
131262306a36Sopenharmony_ci			mlog(ML_ERROR, "no old_dir_bh!\n");
131362306a36Sopenharmony_ci			status = -EIO;
131462306a36Sopenharmony_ci			goto bail;
131562306a36Sopenharmony_ci		}
131662306a36Sopenharmony_ci	}
131762306a36Sopenharmony_ci
131862306a36Sopenharmony_ci	/*
131962306a36Sopenharmony_ci	 * Aside from allowing a meta data update, the locking here
132062306a36Sopenharmony_ci	 * also ensures that the downconvert thread on other nodes
132162306a36Sopenharmony_ci	 * won't have to concurrently downconvert the inode and the
132262306a36Sopenharmony_ci	 * dentry locks.
132362306a36Sopenharmony_ci	 */
132462306a36Sopenharmony_ci	status = ocfs2_inode_lock_nested(old_inode, &old_inode_bh, 1,
132562306a36Sopenharmony_ci					 OI_LS_PARENT);
132662306a36Sopenharmony_ci	if (status < 0) {
132762306a36Sopenharmony_ci		if (status != -ENOENT)
132862306a36Sopenharmony_ci			mlog_errno(status);
132962306a36Sopenharmony_ci		goto bail;
133062306a36Sopenharmony_ci	}
133162306a36Sopenharmony_ci	old_child_locked = 1;
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci	status = ocfs2_remote_dentry_delete(old_dentry);
133462306a36Sopenharmony_ci	if (status < 0) {
133562306a36Sopenharmony_ci		mlog_errno(status);
133662306a36Sopenharmony_ci		goto bail;
133762306a36Sopenharmony_ci	}
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ci	if (S_ISDIR(old_inode->i_mode)) {
134062306a36Sopenharmony_ci		u64 old_inode_parent;
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_ci		update_dot_dot = 1;
134362306a36Sopenharmony_ci		status = ocfs2_find_files_on_disk("..", 2, &old_inode_parent,
134462306a36Sopenharmony_ci						  old_inode,
134562306a36Sopenharmony_ci						  &old_inode_dot_dot_res);
134662306a36Sopenharmony_ci		if (status) {
134762306a36Sopenharmony_ci			status = -EIO;
134862306a36Sopenharmony_ci			goto bail;
134962306a36Sopenharmony_ci		}
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci		if (old_inode_parent != OCFS2_I(old_dir)->ip_blkno) {
135262306a36Sopenharmony_ci			status = -EIO;
135362306a36Sopenharmony_ci			goto bail;
135462306a36Sopenharmony_ci		}
135562306a36Sopenharmony_ci
135662306a36Sopenharmony_ci		if (!new_inode && new_dir != old_dir &&
135762306a36Sopenharmony_ci		    new_dir->i_nlink >= ocfs2_link_max(osb)) {
135862306a36Sopenharmony_ci			status = -EMLINK;
135962306a36Sopenharmony_ci			goto bail;
136062306a36Sopenharmony_ci		}
136162306a36Sopenharmony_ci	}
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci	status = ocfs2_lookup_ino_from_name(old_dir, old_dentry->d_name.name,
136462306a36Sopenharmony_ci					    old_dentry->d_name.len,
136562306a36Sopenharmony_ci					    &old_de_ino);
136662306a36Sopenharmony_ci	if (status) {
136762306a36Sopenharmony_ci		status = -ENOENT;
136862306a36Sopenharmony_ci		goto bail;
136962306a36Sopenharmony_ci	}
137062306a36Sopenharmony_ci
137162306a36Sopenharmony_ci	/*
137262306a36Sopenharmony_ci	 *  Check for inode number is _not_ due to possible IO errors.
137362306a36Sopenharmony_ci	 *  We might rmdir the source, keep it as pwd of some process
137462306a36Sopenharmony_ci	 *  and merrily kill the link to whatever was created under the
137562306a36Sopenharmony_ci	 *  same name. Goodbye sticky bit ;-<
137662306a36Sopenharmony_ci	 */
137762306a36Sopenharmony_ci	if (old_de_ino != OCFS2_I(old_inode)->ip_blkno) {
137862306a36Sopenharmony_ci		status = -ENOENT;
137962306a36Sopenharmony_ci		goto bail;
138062306a36Sopenharmony_ci	}
138162306a36Sopenharmony_ci
138262306a36Sopenharmony_ci	/* check if the target already exists (in which case we need
138362306a36Sopenharmony_ci	 * to delete it */
138462306a36Sopenharmony_ci	status = ocfs2_find_files_on_disk(new_dentry->d_name.name,
138562306a36Sopenharmony_ci					  new_dentry->d_name.len,
138662306a36Sopenharmony_ci					  &newfe_blkno, new_dir,
138762306a36Sopenharmony_ci					  &target_lookup_res);
138862306a36Sopenharmony_ci	/* The only error we allow here is -ENOENT because the new
138962306a36Sopenharmony_ci	 * file not existing is perfectly valid. */
139062306a36Sopenharmony_ci	if ((status < 0) && (status != -ENOENT)) {
139162306a36Sopenharmony_ci		/* If we cannot find the file specified we should just */
139262306a36Sopenharmony_ci		/* return the error... */
139362306a36Sopenharmony_ci		mlog_errno(status);
139462306a36Sopenharmony_ci		goto bail;
139562306a36Sopenharmony_ci	}
139662306a36Sopenharmony_ci	if (status == 0)
139762306a36Sopenharmony_ci		target_exists = 1;
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_ci	if (!target_exists && new_inode) {
140062306a36Sopenharmony_ci		/*
140162306a36Sopenharmony_ci		 * Target was unlinked by another node while we were
140262306a36Sopenharmony_ci		 * waiting to get to ocfs2_rename(). There isn't
140362306a36Sopenharmony_ci		 * anything we can do here to help the situation, so
140462306a36Sopenharmony_ci		 * bubble up the appropriate error.
140562306a36Sopenharmony_ci		 */
140662306a36Sopenharmony_ci		status = -ENOENT;
140762306a36Sopenharmony_ci		goto bail;
140862306a36Sopenharmony_ci	}
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci	/* In case we need to overwrite an existing file, we blow it
141162306a36Sopenharmony_ci	 * away first */
141262306a36Sopenharmony_ci	if (target_exists) {
141362306a36Sopenharmony_ci		/* VFS didn't think there existed an inode here, but
141462306a36Sopenharmony_ci		 * someone else in the cluster must have raced our
141562306a36Sopenharmony_ci		 * rename to create one. Today we error cleanly, in
141662306a36Sopenharmony_ci		 * the future we should consider calling iget to build
141762306a36Sopenharmony_ci		 * a new struct inode for this entry. */
141862306a36Sopenharmony_ci		if (!new_inode) {
141962306a36Sopenharmony_ci			status = -EACCES;
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci			trace_ocfs2_rename_target_exists(new_dentry->d_name.len,
142262306a36Sopenharmony_ci						new_dentry->d_name.name);
142362306a36Sopenharmony_ci			goto bail;
142462306a36Sopenharmony_ci		}
142562306a36Sopenharmony_ci
142662306a36Sopenharmony_ci		if (OCFS2_I(new_inode)->ip_blkno != newfe_blkno) {
142762306a36Sopenharmony_ci			status = -EACCES;
142862306a36Sopenharmony_ci
142962306a36Sopenharmony_ci			trace_ocfs2_rename_disagree(
143062306a36Sopenharmony_ci			     (unsigned long long)OCFS2_I(new_inode)->ip_blkno,
143162306a36Sopenharmony_ci			     (unsigned long long)newfe_blkno,
143262306a36Sopenharmony_ci			     OCFS2_I(new_inode)->ip_flags);
143362306a36Sopenharmony_ci			goto bail;
143462306a36Sopenharmony_ci		}
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci		status = ocfs2_inode_lock(new_inode, &newfe_bh, 1);
143762306a36Sopenharmony_ci		if (status < 0) {
143862306a36Sopenharmony_ci			if (status != -ENOENT)
143962306a36Sopenharmony_ci				mlog_errno(status);
144062306a36Sopenharmony_ci			goto bail;
144162306a36Sopenharmony_ci		}
144262306a36Sopenharmony_ci		new_child_locked = 1;
144362306a36Sopenharmony_ci
144462306a36Sopenharmony_ci		status = ocfs2_remote_dentry_delete(new_dentry);
144562306a36Sopenharmony_ci		if (status < 0) {
144662306a36Sopenharmony_ci			mlog_errno(status);
144762306a36Sopenharmony_ci			goto bail;
144862306a36Sopenharmony_ci		}
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci		newfe = (struct ocfs2_dinode *) newfe_bh->b_data;
145162306a36Sopenharmony_ci
145262306a36Sopenharmony_ci		trace_ocfs2_rename_over_existing(
145362306a36Sopenharmony_ci		     (unsigned long long)newfe_blkno, newfe_bh, newfe_bh ?
145462306a36Sopenharmony_ci		     (unsigned long long)newfe_bh->b_blocknr : 0ULL);
145562306a36Sopenharmony_ci
145662306a36Sopenharmony_ci		if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) {
145762306a36Sopenharmony_ci			status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
145862306a36Sopenharmony_ci						OCFS2_I(new_inode)->ip_blkno,
145962306a36Sopenharmony_ci						orphan_name, &orphan_insert,
146062306a36Sopenharmony_ci						false);
146162306a36Sopenharmony_ci			if (status < 0) {
146262306a36Sopenharmony_ci				mlog_errno(status);
146362306a36Sopenharmony_ci				goto bail;
146462306a36Sopenharmony_ci			}
146562306a36Sopenharmony_ci			should_add_orphan = true;
146662306a36Sopenharmony_ci		}
146762306a36Sopenharmony_ci	} else {
146862306a36Sopenharmony_ci		BUG_ON(d_inode(new_dentry->d_parent) != new_dir);
146962306a36Sopenharmony_ci
147062306a36Sopenharmony_ci		status = ocfs2_check_dir_for_entry(new_dir,
147162306a36Sopenharmony_ci						   new_dentry->d_name.name,
147262306a36Sopenharmony_ci						   new_dentry->d_name.len);
147362306a36Sopenharmony_ci		if (status)
147462306a36Sopenharmony_ci			goto bail;
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_ci		status = ocfs2_prepare_dir_for_insert(osb, new_dir, new_dir_bh,
147762306a36Sopenharmony_ci						      new_dentry->d_name.name,
147862306a36Sopenharmony_ci						      new_dentry->d_name.len,
147962306a36Sopenharmony_ci						      &target_insert);
148062306a36Sopenharmony_ci		if (status < 0) {
148162306a36Sopenharmony_ci			mlog_errno(status);
148262306a36Sopenharmony_ci			goto bail;
148362306a36Sopenharmony_ci		}
148462306a36Sopenharmony_ci	}
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_rename_credits(osb->sb));
148762306a36Sopenharmony_ci	if (IS_ERR(handle)) {
148862306a36Sopenharmony_ci		status = PTR_ERR(handle);
148962306a36Sopenharmony_ci		handle = NULL;
149062306a36Sopenharmony_ci		mlog_errno(status);
149162306a36Sopenharmony_ci		goto bail;
149262306a36Sopenharmony_ci	}
149362306a36Sopenharmony_ci
149462306a36Sopenharmony_ci	if (target_exists) {
149562306a36Sopenharmony_ci		if (S_ISDIR(new_inode->i_mode)) {
149662306a36Sopenharmony_ci			if (new_inode->i_nlink != 2 ||
149762306a36Sopenharmony_ci			    !ocfs2_empty_dir(new_inode)) {
149862306a36Sopenharmony_ci				status = -ENOTEMPTY;
149962306a36Sopenharmony_ci				goto bail;
150062306a36Sopenharmony_ci			}
150162306a36Sopenharmony_ci		}
150262306a36Sopenharmony_ci		status = ocfs2_journal_access_di(handle, INODE_CACHE(new_inode),
150362306a36Sopenharmony_ci						 newfe_bh,
150462306a36Sopenharmony_ci						 OCFS2_JOURNAL_ACCESS_WRITE);
150562306a36Sopenharmony_ci		if (status < 0) {
150662306a36Sopenharmony_ci			mlog_errno(status);
150762306a36Sopenharmony_ci			goto bail;
150862306a36Sopenharmony_ci		}
150962306a36Sopenharmony_ci
151062306a36Sopenharmony_ci		/* change the dirent to point to the correct inode */
151162306a36Sopenharmony_ci		status = ocfs2_update_entry(new_dir, handle, &target_lookup_res,
151262306a36Sopenharmony_ci					    old_inode);
151362306a36Sopenharmony_ci		if (status < 0) {
151462306a36Sopenharmony_ci			mlog_errno(status);
151562306a36Sopenharmony_ci			goto bail;
151662306a36Sopenharmony_ci		}
151762306a36Sopenharmony_ci		inode_inc_iversion(new_dir);
151862306a36Sopenharmony_ci
151962306a36Sopenharmony_ci		if (S_ISDIR(new_inode->i_mode))
152062306a36Sopenharmony_ci			ocfs2_set_links_count(newfe, 0);
152162306a36Sopenharmony_ci		else
152262306a36Sopenharmony_ci			ocfs2_add_links_count(newfe, -1);
152362306a36Sopenharmony_ci		ocfs2_journal_dirty(handle, newfe_bh);
152462306a36Sopenharmony_ci		if (should_add_orphan) {
152562306a36Sopenharmony_ci			status = ocfs2_orphan_add(osb, handle, new_inode,
152662306a36Sopenharmony_ci					newfe_bh, orphan_name,
152762306a36Sopenharmony_ci					&orphan_insert, orphan_dir, false);
152862306a36Sopenharmony_ci			if (status < 0) {
152962306a36Sopenharmony_ci				mlog_errno(status);
153062306a36Sopenharmony_ci				goto bail;
153162306a36Sopenharmony_ci			}
153262306a36Sopenharmony_ci		}
153362306a36Sopenharmony_ci	} else {
153462306a36Sopenharmony_ci		/* if the name was not found in new_dir, add it now */
153562306a36Sopenharmony_ci		status = ocfs2_add_entry(handle, new_dentry, old_inode,
153662306a36Sopenharmony_ci					 OCFS2_I(old_inode)->ip_blkno,
153762306a36Sopenharmony_ci					 new_dir_bh, &target_insert);
153862306a36Sopenharmony_ci		if (status < 0) {
153962306a36Sopenharmony_ci			mlog_errno(status);
154062306a36Sopenharmony_ci			goto bail;
154162306a36Sopenharmony_ci		}
154262306a36Sopenharmony_ci	}
154362306a36Sopenharmony_ci
154462306a36Sopenharmony_ci	inode_set_ctime_current(old_inode);
154562306a36Sopenharmony_ci	mark_inode_dirty(old_inode);
154662306a36Sopenharmony_ci
154762306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(old_inode),
154862306a36Sopenharmony_ci					 old_inode_bh,
154962306a36Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
155062306a36Sopenharmony_ci	if (status >= 0) {
155162306a36Sopenharmony_ci		old_di = (struct ocfs2_dinode *) old_inode_bh->b_data;
155262306a36Sopenharmony_ci
155362306a36Sopenharmony_ci		old_di->i_ctime = cpu_to_le64(inode_get_ctime(old_inode).tv_sec);
155462306a36Sopenharmony_ci		old_di->i_ctime_nsec = cpu_to_le32(inode_get_ctime(old_inode).tv_nsec);
155562306a36Sopenharmony_ci		ocfs2_journal_dirty(handle, old_inode_bh);
155662306a36Sopenharmony_ci	} else
155762306a36Sopenharmony_ci		mlog_errno(status);
155862306a36Sopenharmony_ci
155962306a36Sopenharmony_ci	/*
156062306a36Sopenharmony_ci	 * Now that the name has been added to new_dir, remove the old name.
156162306a36Sopenharmony_ci	 *
156262306a36Sopenharmony_ci	 * We don't keep any directory entry context around until now
156362306a36Sopenharmony_ci	 * because the insert might have changed the type of directory
156462306a36Sopenharmony_ci	 * we're dealing with.
156562306a36Sopenharmony_ci	 */
156662306a36Sopenharmony_ci	status = ocfs2_find_entry(old_dentry->d_name.name,
156762306a36Sopenharmony_ci				  old_dentry->d_name.len, old_dir,
156862306a36Sopenharmony_ci				  &old_entry_lookup);
156962306a36Sopenharmony_ci	if (status) {
157062306a36Sopenharmony_ci		if (!is_journal_aborted(osb->journal->j_journal)) {
157162306a36Sopenharmony_ci			ocfs2_error(osb->sb, "new entry %.*s is added, but old entry %.*s "
157262306a36Sopenharmony_ci					"is not deleted.",
157362306a36Sopenharmony_ci					new_dentry->d_name.len, new_dentry->d_name.name,
157462306a36Sopenharmony_ci					old_dentry->d_name.len, old_dentry->d_name.name);
157562306a36Sopenharmony_ci		}
157662306a36Sopenharmony_ci		goto bail;
157762306a36Sopenharmony_ci	}
157862306a36Sopenharmony_ci
157962306a36Sopenharmony_ci	status = ocfs2_delete_entry(handle, old_dir, &old_entry_lookup);
158062306a36Sopenharmony_ci	if (status < 0) {
158162306a36Sopenharmony_ci		mlog_errno(status);
158262306a36Sopenharmony_ci		if (!is_journal_aborted(osb->journal->j_journal)) {
158362306a36Sopenharmony_ci			ocfs2_error(osb->sb, "new entry %.*s is added, but old entry %.*s "
158462306a36Sopenharmony_ci					"is not deleted.",
158562306a36Sopenharmony_ci					new_dentry->d_name.len, new_dentry->d_name.name,
158662306a36Sopenharmony_ci					old_dentry->d_name.len, old_dentry->d_name.name);
158762306a36Sopenharmony_ci		}
158862306a36Sopenharmony_ci		goto bail;
158962306a36Sopenharmony_ci	}
159062306a36Sopenharmony_ci
159162306a36Sopenharmony_ci	if (new_inode) {
159262306a36Sopenharmony_ci		drop_nlink(new_inode);
159362306a36Sopenharmony_ci		inode_set_ctime_current(new_inode);
159462306a36Sopenharmony_ci	}
159562306a36Sopenharmony_ci	old_dir->i_mtime = inode_set_ctime_current(old_dir);
159662306a36Sopenharmony_ci
159762306a36Sopenharmony_ci	if (update_dot_dot) {
159862306a36Sopenharmony_ci		status = ocfs2_update_entry(old_inode, handle,
159962306a36Sopenharmony_ci					    &old_inode_dot_dot_res, new_dir);
160062306a36Sopenharmony_ci		drop_nlink(old_dir);
160162306a36Sopenharmony_ci		if (new_inode) {
160262306a36Sopenharmony_ci			drop_nlink(new_inode);
160362306a36Sopenharmony_ci		} else {
160462306a36Sopenharmony_ci			inc_nlink(new_dir);
160562306a36Sopenharmony_ci			mark_inode_dirty(new_dir);
160662306a36Sopenharmony_ci		}
160762306a36Sopenharmony_ci	}
160862306a36Sopenharmony_ci	mark_inode_dirty(old_dir);
160962306a36Sopenharmony_ci	ocfs2_mark_inode_dirty(handle, old_dir, old_dir_bh);
161062306a36Sopenharmony_ci	if (new_inode) {
161162306a36Sopenharmony_ci		mark_inode_dirty(new_inode);
161262306a36Sopenharmony_ci		ocfs2_mark_inode_dirty(handle, new_inode, newfe_bh);
161362306a36Sopenharmony_ci	}
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci	if (old_dir != new_dir) {
161662306a36Sopenharmony_ci		/* Keep the same times on both directories.*/
161762306a36Sopenharmony_ci		new_dir->i_mtime = inode_set_ctime_to_ts(new_dir,
161862306a36Sopenharmony_ci							 inode_get_ctime(old_dir));
161962306a36Sopenharmony_ci
162062306a36Sopenharmony_ci		/*
162162306a36Sopenharmony_ci		 * This will also pick up the i_nlink change from the
162262306a36Sopenharmony_ci		 * block above.
162362306a36Sopenharmony_ci		 */
162462306a36Sopenharmony_ci		ocfs2_mark_inode_dirty(handle, new_dir, new_dir_bh);
162562306a36Sopenharmony_ci	}
162662306a36Sopenharmony_ci
162762306a36Sopenharmony_ci	if (old_dir_nlink != old_dir->i_nlink) {
162862306a36Sopenharmony_ci		if (!old_dir_bh) {
162962306a36Sopenharmony_ci			mlog(ML_ERROR, "need to change nlink for old dir "
163062306a36Sopenharmony_ci			     "%llu from %d to %d but bh is NULL!\n",
163162306a36Sopenharmony_ci			     (unsigned long long)OCFS2_I(old_dir)->ip_blkno,
163262306a36Sopenharmony_ci			     (int)old_dir_nlink, old_dir->i_nlink);
163362306a36Sopenharmony_ci		} else {
163462306a36Sopenharmony_ci			struct ocfs2_dinode *fe;
163562306a36Sopenharmony_ci			status = ocfs2_journal_access_di(handle,
163662306a36Sopenharmony_ci							 INODE_CACHE(old_dir),
163762306a36Sopenharmony_ci							 old_dir_bh,
163862306a36Sopenharmony_ci							 OCFS2_JOURNAL_ACCESS_WRITE);
163962306a36Sopenharmony_ci			fe = (struct ocfs2_dinode *) old_dir_bh->b_data;
164062306a36Sopenharmony_ci			ocfs2_set_links_count(fe, old_dir->i_nlink);
164162306a36Sopenharmony_ci			ocfs2_journal_dirty(handle, old_dir_bh);
164262306a36Sopenharmony_ci		}
164362306a36Sopenharmony_ci	}
164462306a36Sopenharmony_ci	ocfs2_dentry_move(old_dentry, new_dentry, old_dir, new_dir);
164562306a36Sopenharmony_ci	status = 0;
164662306a36Sopenharmony_cibail:
164762306a36Sopenharmony_ci	if (handle)
164862306a36Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
164962306a36Sopenharmony_ci
165062306a36Sopenharmony_ci	if (orphan_dir) {
165162306a36Sopenharmony_ci		/* This was locked for us in ocfs2_prepare_orphan_dir() */
165262306a36Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir, 1);
165362306a36Sopenharmony_ci		inode_unlock(orphan_dir);
165462306a36Sopenharmony_ci		iput(orphan_dir);
165562306a36Sopenharmony_ci	}
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ci	if (new_child_locked)
165862306a36Sopenharmony_ci		ocfs2_inode_unlock(new_inode, 1);
165962306a36Sopenharmony_ci
166062306a36Sopenharmony_ci	if (old_child_locked)
166162306a36Sopenharmony_ci		ocfs2_inode_unlock(old_inode, 1);
166262306a36Sopenharmony_ci
166362306a36Sopenharmony_ci	if (parents_locked)
166462306a36Sopenharmony_ci		ocfs2_double_unlock(old_dir, new_dir);
166562306a36Sopenharmony_ci
166662306a36Sopenharmony_ci	if (rename_lock)
166762306a36Sopenharmony_ci		ocfs2_rename_unlock(osb);
166862306a36Sopenharmony_ci
166962306a36Sopenharmony_ci	if (new_inode)
167062306a36Sopenharmony_ci		sync_mapping_buffers(old_inode->i_mapping);
167162306a36Sopenharmony_ci
167262306a36Sopenharmony_ci	iput(new_inode);
167362306a36Sopenharmony_ci
167462306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&target_lookup_res);
167562306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&old_entry_lookup);
167662306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&old_inode_dot_dot_res);
167762306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&orphan_insert);
167862306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&target_insert);
167962306a36Sopenharmony_ci
168062306a36Sopenharmony_ci	brelse(newfe_bh);
168162306a36Sopenharmony_ci	brelse(old_inode_bh);
168262306a36Sopenharmony_ci	brelse(old_dir_bh);
168362306a36Sopenharmony_ci	brelse(new_dir_bh);
168462306a36Sopenharmony_ci
168562306a36Sopenharmony_ci	if (status)
168662306a36Sopenharmony_ci		mlog_errno(status);
168762306a36Sopenharmony_ci
168862306a36Sopenharmony_ci	return status;
168962306a36Sopenharmony_ci}
169062306a36Sopenharmony_ci
169162306a36Sopenharmony_ci/*
169262306a36Sopenharmony_ci * we expect i_size = strlen(symname). Copy symname into the file
169362306a36Sopenharmony_ci * data, including the null terminator.
169462306a36Sopenharmony_ci */
169562306a36Sopenharmony_cistatic int ocfs2_create_symlink_data(struct ocfs2_super *osb,
169662306a36Sopenharmony_ci				     handle_t *handle,
169762306a36Sopenharmony_ci				     struct inode *inode,
169862306a36Sopenharmony_ci				     const char *symname)
169962306a36Sopenharmony_ci{
170062306a36Sopenharmony_ci	struct buffer_head **bhs = NULL;
170162306a36Sopenharmony_ci	const char *c;
170262306a36Sopenharmony_ci	struct super_block *sb = osb->sb;
170362306a36Sopenharmony_ci	u64 p_blkno, p_blocks;
170462306a36Sopenharmony_ci	int virtual, blocks, status, i, bytes_left;
170562306a36Sopenharmony_ci
170662306a36Sopenharmony_ci	bytes_left = i_size_read(inode) + 1;
170762306a36Sopenharmony_ci	/* we can't trust i_blocks because we're actually going to
170862306a36Sopenharmony_ci	 * write i_size + 1 bytes. */
170962306a36Sopenharmony_ci	blocks = (bytes_left + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
171062306a36Sopenharmony_ci
171162306a36Sopenharmony_ci	trace_ocfs2_create_symlink_data((unsigned long long)inode->i_blocks,
171262306a36Sopenharmony_ci					i_size_read(inode), blocks);
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ci	/* Sanity check -- make sure we're going to fit. */
171562306a36Sopenharmony_ci	if (bytes_left >
171662306a36Sopenharmony_ci	    ocfs2_clusters_to_bytes(sb, OCFS2_I(inode)->ip_clusters)) {
171762306a36Sopenharmony_ci		status = -EIO;
171862306a36Sopenharmony_ci		mlog_errno(status);
171962306a36Sopenharmony_ci		goto bail;
172062306a36Sopenharmony_ci	}
172162306a36Sopenharmony_ci
172262306a36Sopenharmony_ci	bhs = kcalloc(blocks, sizeof(struct buffer_head *), GFP_KERNEL);
172362306a36Sopenharmony_ci	if (!bhs) {
172462306a36Sopenharmony_ci		status = -ENOMEM;
172562306a36Sopenharmony_ci		mlog_errno(status);
172662306a36Sopenharmony_ci		goto bail;
172762306a36Sopenharmony_ci	}
172862306a36Sopenharmony_ci
172962306a36Sopenharmony_ci	status = ocfs2_extent_map_get_blocks(inode, 0, &p_blkno, &p_blocks,
173062306a36Sopenharmony_ci					     NULL);
173162306a36Sopenharmony_ci	if (status < 0) {
173262306a36Sopenharmony_ci		mlog_errno(status);
173362306a36Sopenharmony_ci		goto bail;
173462306a36Sopenharmony_ci	}
173562306a36Sopenharmony_ci
173662306a36Sopenharmony_ci	/* links can never be larger than one cluster so we know this
173762306a36Sopenharmony_ci	 * is all going to be contiguous, but do a sanity check
173862306a36Sopenharmony_ci	 * anyway. */
173962306a36Sopenharmony_ci	if ((p_blocks << sb->s_blocksize_bits) < bytes_left) {
174062306a36Sopenharmony_ci		status = -EIO;
174162306a36Sopenharmony_ci		mlog_errno(status);
174262306a36Sopenharmony_ci		goto bail;
174362306a36Sopenharmony_ci	}
174462306a36Sopenharmony_ci
174562306a36Sopenharmony_ci	virtual = 0;
174662306a36Sopenharmony_ci	while(bytes_left > 0) {
174762306a36Sopenharmony_ci		c = &symname[virtual * sb->s_blocksize];
174862306a36Sopenharmony_ci
174962306a36Sopenharmony_ci		bhs[virtual] = sb_getblk(sb, p_blkno);
175062306a36Sopenharmony_ci		if (!bhs[virtual]) {
175162306a36Sopenharmony_ci			status = -ENOMEM;
175262306a36Sopenharmony_ci			mlog_errno(status);
175362306a36Sopenharmony_ci			goto bail;
175462306a36Sopenharmony_ci		}
175562306a36Sopenharmony_ci		ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode),
175662306a36Sopenharmony_ci					      bhs[virtual]);
175762306a36Sopenharmony_ci
175862306a36Sopenharmony_ci		status = ocfs2_journal_access(handle, INODE_CACHE(inode),
175962306a36Sopenharmony_ci					      bhs[virtual],
176062306a36Sopenharmony_ci					      OCFS2_JOURNAL_ACCESS_CREATE);
176162306a36Sopenharmony_ci		if (status < 0) {
176262306a36Sopenharmony_ci			mlog_errno(status);
176362306a36Sopenharmony_ci			goto bail;
176462306a36Sopenharmony_ci		}
176562306a36Sopenharmony_ci
176662306a36Sopenharmony_ci		memset(bhs[virtual]->b_data, 0, sb->s_blocksize);
176762306a36Sopenharmony_ci
176862306a36Sopenharmony_ci		memcpy(bhs[virtual]->b_data, c,
176962306a36Sopenharmony_ci		       (bytes_left > sb->s_blocksize) ? sb->s_blocksize :
177062306a36Sopenharmony_ci		       bytes_left);
177162306a36Sopenharmony_ci
177262306a36Sopenharmony_ci		ocfs2_journal_dirty(handle, bhs[virtual]);
177362306a36Sopenharmony_ci
177462306a36Sopenharmony_ci		virtual++;
177562306a36Sopenharmony_ci		p_blkno++;
177662306a36Sopenharmony_ci		bytes_left -= sb->s_blocksize;
177762306a36Sopenharmony_ci	}
177862306a36Sopenharmony_ci
177962306a36Sopenharmony_ci	status = 0;
178062306a36Sopenharmony_cibail:
178162306a36Sopenharmony_ci
178262306a36Sopenharmony_ci	if (bhs) {
178362306a36Sopenharmony_ci		for(i = 0; i < blocks; i++)
178462306a36Sopenharmony_ci			brelse(bhs[i]);
178562306a36Sopenharmony_ci		kfree(bhs);
178662306a36Sopenharmony_ci	}
178762306a36Sopenharmony_ci
178862306a36Sopenharmony_ci	if (status)
178962306a36Sopenharmony_ci		mlog_errno(status);
179062306a36Sopenharmony_ci	return status;
179162306a36Sopenharmony_ci}
179262306a36Sopenharmony_ci
179362306a36Sopenharmony_cistatic int ocfs2_symlink(struct mnt_idmap *idmap,
179462306a36Sopenharmony_ci			 struct inode *dir,
179562306a36Sopenharmony_ci			 struct dentry *dentry,
179662306a36Sopenharmony_ci			 const char *symname)
179762306a36Sopenharmony_ci{
179862306a36Sopenharmony_ci	int status, l, credits;
179962306a36Sopenharmony_ci	u64 newsize;
180062306a36Sopenharmony_ci	struct ocfs2_super *osb = NULL;
180162306a36Sopenharmony_ci	struct inode *inode = NULL;
180262306a36Sopenharmony_ci	struct super_block *sb;
180362306a36Sopenharmony_ci	struct buffer_head *new_fe_bh = NULL;
180462306a36Sopenharmony_ci	struct buffer_head *parent_fe_bh = NULL;
180562306a36Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
180662306a36Sopenharmony_ci	struct ocfs2_dinode *dirfe;
180762306a36Sopenharmony_ci	handle_t *handle = NULL;
180862306a36Sopenharmony_ci	struct ocfs2_alloc_context *inode_ac = NULL;
180962306a36Sopenharmony_ci	struct ocfs2_alloc_context *data_ac = NULL;
181062306a36Sopenharmony_ci	struct ocfs2_alloc_context *xattr_ac = NULL;
181162306a36Sopenharmony_ci	int want_clusters = 0;
181262306a36Sopenharmony_ci	int xattr_credits = 0;
181362306a36Sopenharmony_ci	struct ocfs2_security_xattr_info si = {
181462306a36Sopenharmony_ci		.name = NULL,
181562306a36Sopenharmony_ci		.enable = 1,
181662306a36Sopenharmony_ci	};
181762306a36Sopenharmony_ci	int did_quota = 0, did_quota_inode = 0;
181862306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
181962306a36Sopenharmony_ci	sigset_t oldset;
182062306a36Sopenharmony_ci	int did_block_signals = 0;
182162306a36Sopenharmony_ci	struct ocfs2_dentry_lock *dl = NULL;
182262306a36Sopenharmony_ci
182362306a36Sopenharmony_ci	trace_ocfs2_symlink_begin(dir, dentry, symname,
182462306a36Sopenharmony_ci				  dentry->d_name.len, dentry->d_name.name);
182562306a36Sopenharmony_ci
182662306a36Sopenharmony_ci	status = dquot_initialize(dir);
182762306a36Sopenharmony_ci	if (status) {
182862306a36Sopenharmony_ci		mlog_errno(status);
182962306a36Sopenharmony_ci		goto bail;
183062306a36Sopenharmony_ci	}
183162306a36Sopenharmony_ci
183262306a36Sopenharmony_ci	sb = dir->i_sb;
183362306a36Sopenharmony_ci	osb = OCFS2_SB(sb);
183462306a36Sopenharmony_ci
183562306a36Sopenharmony_ci	l = strlen(symname) + 1;
183662306a36Sopenharmony_ci
183762306a36Sopenharmony_ci	credits = ocfs2_calc_symlink_credits(sb);
183862306a36Sopenharmony_ci
183962306a36Sopenharmony_ci	/* lock the parent directory */
184062306a36Sopenharmony_ci	status = ocfs2_inode_lock(dir, &parent_fe_bh, 1);
184162306a36Sopenharmony_ci	if (status < 0) {
184262306a36Sopenharmony_ci		if (status != -ENOENT)
184362306a36Sopenharmony_ci			mlog_errno(status);
184462306a36Sopenharmony_ci		return status;
184562306a36Sopenharmony_ci	}
184662306a36Sopenharmony_ci
184762306a36Sopenharmony_ci	dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
184862306a36Sopenharmony_ci	if (!ocfs2_read_links_count(dirfe)) {
184962306a36Sopenharmony_ci		/* can't make a file in a deleted directory. */
185062306a36Sopenharmony_ci		status = -ENOENT;
185162306a36Sopenharmony_ci		goto bail;
185262306a36Sopenharmony_ci	}
185362306a36Sopenharmony_ci
185462306a36Sopenharmony_ci	status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
185562306a36Sopenharmony_ci					   dentry->d_name.len);
185662306a36Sopenharmony_ci	if (status)
185762306a36Sopenharmony_ci		goto bail;
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_ci	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
186062306a36Sopenharmony_ci					      dentry->d_name.name,
186162306a36Sopenharmony_ci					      dentry->d_name.len, &lookup);
186262306a36Sopenharmony_ci	if (status < 0) {
186362306a36Sopenharmony_ci		mlog_errno(status);
186462306a36Sopenharmony_ci		goto bail;
186562306a36Sopenharmony_ci	}
186662306a36Sopenharmony_ci
186762306a36Sopenharmony_ci	status = ocfs2_reserve_new_inode(osb, &inode_ac);
186862306a36Sopenharmony_ci	if (status < 0) {
186962306a36Sopenharmony_ci		if (status != -ENOSPC)
187062306a36Sopenharmony_ci			mlog_errno(status);
187162306a36Sopenharmony_ci		goto bail;
187262306a36Sopenharmony_ci	}
187362306a36Sopenharmony_ci
187462306a36Sopenharmony_ci	inode = ocfs2_get_init_inode(dir, S_IFLNK | S_IRWXUGO);
187562306a36Sopenharmony_ci	if (IS_ERR(inode)) {
187662306a36Sopenharmony_ci		status = PTR_ERR(inode);
187762306a36Sopenharmony_ci		inode = NULL;
187862306a36Sopenharmony_ci		mlog_errno(status);
187962306a36Sopenharmony_ci		goto bail;
188062306a36Sopenharmony_ci	}
188162306a36Sopenharmony_ci
188262306a36Sopenharmony_ci	/* get security xattr */
188362306a36Sopenharmony_ci	status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);
188462306a36Sopenharmony_ci	if (status) {
188562306a36Sopenharmony_ci		if (status == -EOPNOTSUPP)
188662306a36Sopenharmony_ci			si.enable = 0;
188762306a36Sopenharmony_ci		else {
188862306a36Sopenharmony_ci			mlog_errno(status);
188962306a36Sopenharmony_ci			goto bail;
189062306a36Sopenharmony_ci		}
189162306a36Sopenharmony_ci	}
189262306a36Sopenharmony_ci
189362306a36Sopenharmony_ci	/* calculate meta data/clusters for setting security xattr */
189462306a36Sopenharmony_ci	if (si.enable) {
189562306a36Sopenharmony_ci		status = ocfs2_calc_security_init(dir, &si, &want_clusters,
189662306a36Sopenharmony_ci						  &xattr_credits, &xattr_ac);
189762306a36Sopenharmony_ci		if (status < 0) {
189862306a36Sopenharmony_ci			mlog_errno(status);
189962306a36Sopenharmony_ci			goto bail;
190062306a36Sopenharmony_ci		}
190162306a36Sopenharmony_ci	}
190262306a36Sopenharmony_ci
190362306a36Sopenharmony_ci	/* don't reserve bitmap space for fast symlinks. */
190462306a36Sopenharmony_ci	if (l > ocfs2_fast_symlink_chars(sb))
190562306a36Sopenharmony_ci		want_clusters += 1;
190662306a36Sopenharmony_ci
190762306a36Sopenharmony_ci	status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac);
190862306a36Sopenharmony_ci	if (status < 0) {
190962306a36Sopenharmony_ci		if (status != -ENOSPC)
191062306a36Sopenharmony_ci			mlog_errno(status);
191162306a36Sopenharmony_ci		goto bail;
191262306a36Sopenharmony_ci	}
191362306a36Sopenharmony_ci
191462306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb, credits + xattr_credits);
191562306a36Sopenharmony_ci	if (IS_ERR(handle)) {
191662306a36Sopenharmony_ci		status = PTR_ERR(handle);
191762306a36Sopenharmony_ci		handle = NULL;
191862306a36Sopenharmony_ci		mlog_errno(status);
191962306a36Sopenharmony_ci		goto bail;
192062306a36Sopenharmony_ci	}
192162306a36Sopenharmony_ci
192262306a36Sopenharmony_ci	/* Starting to change things, restart is no longer possible. */
192362306a36Sopenharmony_ci	ocfs2_block_signals(&oldset);
192462306a36Sopenharmony_ci	did_block_signals = 1;
192562306a36Sopenharmony_ci
192662306a36Sopenharmony_ci	status = dquot_alloc_inode(inode);
192762306a36Sopenharmony_ci	if (status)
192862306a36Sopenharmony_ci		goto bail;
192962306a36Sopenharmony_ci	did_quota_inode = 1;
193062306a36Sopenharmony_ci
193162306a36Sopenharmony_ci	trace_ocfs2_symlink_create(dir, dentry, dentry->d_name.len,
193262306a36Sopenharmony_ci				   dentry->d_name.name,
193362306a36Sopenharmony_ci				   (unsigned long long)OCFS2_I(dir)->ip_blkno,
193462306a36Sopenharmony_ci				   inode->i_mode);
193562306a36Sopenharmony_ci
193662306a36Sopenharmony_ci	status = ocfs2_mknod_locked(osb, dir, inode,
193762306a36Sopenharmony_ci				    0, &new_fe_bh, parent_fe_bh, handle,
193862306a36Sopenharmony_ci				    inode_ac);
193962306a36Sopenharmony_ci	if (status < 0) {
194062306a36Sopenharmony_ci		mlog_errno(status);
194162306a36Sopenharmony_ci		goto bail;
194262306a36Sopenharmony_ci	}
194362306a36Sopenharmony_ci
194462306a36Sopenharmony_ci	fe = (struct ocfs2_dinode *) new_fe_bh->b_data;
194562306a36Sopenharmony_ci	inode->i_rdev = 0;
194662306a36Sopenharmony_ci	newsize = l - 1;
194762306a36Sopenharmony_ci	inode->i_op = &ocfs2_symlink_inode_operations;
194862306a36Sopenharmony_ci	inode_nohighmem(inode);
194962306a36Sopenharmony_ci	if (l > ocfs2_fast_symlink_chars(sb)) {
195062306a36Sopenharmony_ci		u32 offset = 0;
195162306a36Sopenharmony_ci
195262306a36Sopenharmony_ci		status = dquot_alloc_space_nodirty(inode,
195362306a36Sopenharmony_ci		    ocfs2_clusters_to_bytes(osb->sb, 1));
195462306a36Sopenharmony_ci		if (status)
195562306a36Sopenharmony_ci			goto bail;
195662306a36Sopenharmony_ci		did_quota = 1;
195762306a36Sopenharmony_ci		inode->i_mapping->a_ops = &ocfs2_aops;
195862306a36Sopenharmony_ci		status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0,
195962306a36Sopenharmony_ci					      new_fe_bh,
196062306a36Sopenharmony_ci					      handle, data_ac, NULL,
196162306a36Sopenharmony_ci					      NULL);
196262306a36Sopenharmony_ci		if (status < 0) {
196362306a36Sopenharmony_ci			if (status != -ENOSPC && status != -EINTR) {
196462306a36Sopenharmony_ci				mlog(ML_ERROR,
196562306a36Sopenharmony_ci				     "Failed to extend file to %llu\n",
196662306a36Sopenharmony_ci				     (unsigned long long)newsize);
196762306a36Sopenharmony_ci				mlog_errno(status);
196862306a36Sopenharmony_ci				status = -ENOSPC;
196962306a36Sopenharmony_ci			}
197062306a36Sopenharmony_ci			goto bail;
197162306a36Sopenharmony_ci		}
197262306a36Sopenharmony_ci		i_size_write(inode, newsize);
197362306a36Sopenharmony_ci		inode->i_blocks = ocfs2_inode_sector_count(inode);
197462306a36Sopenharmony_ci	} else {
197562306a36Sopenharmony_ci		inode->i_mapping->a_ops = &ocfs2_fast_symlink_aops;
197662306a36Sopenharmony_ci		memcpy((char *) fe->id2.i_symlink, symname, l);
197762306a36Sopenharmony_ci		i_size_write(inode, newsize);
197862306a36Sopenharmony_ci		inode->i_blocks = 0;
197962306a36Sopenharmony_ci	}
198062306a36Sopenharmony_ci
198162306a36Sopenharmony_ci	status = ocfs2_mark_inode_dirty(handle, inode, new_fe_bh);
198262306a36Sopenharmony_ci	if (status < 0) {
198362306a36Sopenharmony_ci		mlog_errno(status);
198462306a36Sopenharmony_ci		goto bail;
198562306a36Sopenharmony_ci	}
198662306a36Sopenharmony_ci
198762306a36Sopenharmony_ci	if (!ocfs2_inode_is_fast_symlink(inode)) {
198862306a36Sopenharmony_ci		status = ocfs2_create_symlink_data(osb, handle, inode,
198962306a36Sopenharmony_ci						   symname);
199062306a36Sopenharmony_ci		if (status < 0) {
199162306a36Sopenharmony_ci			mlog_errno(status);
199262306a36Sopenharmony_ci			goto bail;
199362306a36Sopenharmony_ci		}
199462306a36Sopenharmony_ci	}
199562306a36Sopenharmony_ci
199662306a36Sopenharmony_ci	if (si.enable) {
199762306a36Sopenharmony_ci		status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si,
199862306a36Sopenharmony_ci						 xattr_ac, data_ac);
199962306a36Sopenharmony_ci		if (status < 0) {
200062306a36Sopenharmony_ci			mlog_errno(status);
200162306a36Sopenharmony_ci			goto bail;
200262306a36Sopenharmony_ci		}
200362306a36Sopenharmony_ci	}
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_ci	/*
200662306a36Sopenharmony_ci	 * Do this before adding the entry to the directory. We add
200762306a36Sopenharmony_ci	 * also set d_op after success so that ->d_iput() will cleanup
200862306a36Sopenharmony_ci	 * the dentry lock even if ocfs2_add_entry() fails below.
200962306a36Sopenharmony_ci	 */
201062306a36Sopenharmony_ci	status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
201162306a36Sopenharmony_ci	if (status) {
201262306a36Sopenharmony_ci		mlog_errno(status);
201362306a36Sopenharmony_ci		goto bail;
201462306a36Sopenharmony_ci	}
201562306a36Sopenharmony_ci
201662306a36Sopenharmony_ci	dl = dentry->d_fsdata;
201762306a36Sopenharmony_ci
201862306a36Sopenharmony_ci	status = ocfs2_add_entry(handle, dentry, inode,
201962306a36Sopenharmony_ci				 le64_to_cpu(fe->i_blkno), parent_fe_bh,
202062306a36Sopenharmony_ci				 &lookup);
202162306a36Sopenharmony_ci	if (status < 0) {
202262306a36Sopenharmony_ci		mlog_errno(status);
202362306a36Sopenharmony_ci		goto bail;
202462306a36Sopenharmony_ci	}
202562306a36Sopenharmony_ci
202662306a36Sopenharmony_ci	insert_inode_hash(inode);
202762306a36Sopenharmony_ci	d_instantiate(dentry, inode);
202862306a36Sopenharmony_cibail:
202962306a36Sopenharmony_ci	if (status < 0 && did_quota)
203062306a36Sopenharmony_ci		dquot_free_space_nodirty(inode,
203162306a36Sopenharmony_ci					ocfs2_clusters_to_bytes(osb->sb, 1));
203262306a36Sopenharmony_ci	if (status < 0 && did_quota_inode)
203362306a36Sopenharmony_ci		dquot_free_inode(inode);
203462306a36Sopenharmony_ci	if (handle) {
203562306a36Sopenharmony_ci		if (status < 0 && fe)
203662306a36Sopenharmony_ci			ocfs2_set_links_count(fe, 0);
203762306a36Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
203862306a36Sopenharmony_ci	}
203962306a36Sopenharmony_ci
204062306a36Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
204162306a36Sopenharmony_ci	if (did_block_signals)
204262306a36Sopenharmony_ci		ocfs2_unblock_signals(&oldset);
204362306a36Sopenharmony_ci
204462306a36Sopenharmony_ci	brelse(new_fe_bh);
204562306a36Sopenharmony_ci	brelse(parent_fe_bh);
204662306a36Sopenharmony_ci	kfree(si.value);
204762306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
204862306a36Sopenharmony_ci	if (inode_ac)
204962306a36Sopenharmony_ci		ocfs2_free_alloc_context(inode_ac);
205062306a36Sopenharmony_ci	if (data_ac)
205162306a36Sopenharmony_ci		ocfs2_free_alloc_context(data_ac);
205262306a36Sopenharmony_ci	if (xattr_ac)
205362306a36Sopenharmony_ci		ocfs2_free_alloc_context(xattr_ac);
205462306a36Sopenharmony_ci	if ((status < 0) && inode) {
205562306a36Sopenharmony_ci		if (dl)
205662306a36Sopenharmony_ci			ocfs2_cleanup_add_entry_failure(osb, dentry, inode);
205762306a36Sopenharmony_ci
205862306a36Sopenharmony_ci		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
205962306a36Sopenharmony_ci		clear_nlink(inode);
206062306a36Sopenharmony_ci		iput(inode);
206162306a36Sopenharmony_ci	}
206262306a36Sopenharmony_ci
206362306a36Sopenharmony_ci	if (status)
206462306a36Sopenharmony_ci		mlog_errno(status);
206562306a36Sopenharmony_ci
206662306a36Sopenharmony_ci	return status;
206762306a36Sopenharmony_ci}
206862306a36Sopenharmony_ci
206962306a36Sopenharmony_cistatic int ocfs2_blkno_stringify(u64 blkno, char *name)
207062306a36Sopenharmony_ci{
207162306a36Sopenharmony_ci	int status, namelen;
207262306a36Sopenharmony_ci
207362306a36Sopenharmony_ci	namelen = snprintf(name, OCFS2_ORPHAN_NAMELEN + 1, "%016llx",
207462306a36Sopenharmony_ci			   (long long)blkno);
207562306a36Sopenharmony_ci	if (namelen <= 0) {
207662306a36Sopenharmony_ci		if (namelen)
207762306a36Sopenharmony_ci			status = namelen;
207862306a36Sopenharmony_ci		else
207962306a36Sopenharmony_ci			status = -EINVAL;
208062306a36Sopenharmony_ci		mlog_errno(status);
208162306a36Sopenharmony_ci		goto bail;
208262306a36Sopenharmony_ci	}
208362306a36Sopenharmony_ci	if (namelen != OCFS2_ORPHAN_NAMELEN) {
208462306a36Sopenharmony_ci		status = -EINVAL;
208562306a36Sopenharmony_ci		mlog_errno(status);
208662306a36Sopenharmony_ci		goto bail;
208762306a36Sopenharmony_ci	}
208862306a36Sopenharmony_ci
208962306a36Sopenharmony_ci	trace_ocfs2_blkno_stringify(blkno, name, namelen);
209062306a36Sopenharmony_ci
209162306a36Sopenharmony_ci	status = 0;
209262306a36Sopenharmony_cibail:
209362306a36Sopenharmony_ci	if (status < 0)
209462306a36Sopenharmony_ci		mlog_errno(status);
209562306a36Sopenharmony_ci	return status;
209662306a36Sopenharmony_ci}
209762306a36Sopenharmony_ci
209862306a36Sopenharmony_cistatic int ocfs2_lookup_lock_orphan_dir(struct ocfs2_super *osb,
209962306a36Sopenharmony_ci					struct inode **ret_orphan_dir,
210062306a36Sopenharmony_ci					struct buffer_head **ret_orphan_dir_bh)
210162306a36Sopenharmony_ci{
210262306a36Sopenharmony_ci	struct inode *orphan_dir_inode;
210362306a36Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
210462306a36Sopenharmony_ci	int ret = 0;
210562306a36Sopenharmony_ci
210662306a36Sopenharmony_ci	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
210762306a36Sopenharmony_ci						       ORPHAN_DIR_SYSTEM_INODE,
210862306a36Sopenharmony_ci						       osb->slot_num);
210962306a36Sopenharmony_ci	if (!orphan_dir_inode) {
211062306a36Sopenharmony_ci		ret = -ENOENT;
211162306a36Sopenharmony_ci		mlog_errno(ret);
211262306a36Sopenharmony_ci		return ret;
211362306a36Sopenharmony_ci	}
211462306a36Sopenharmony_ci
211562306a36Sopenharmony_ci	inode_lock(orphan_dir_inode);
211662306a36Sopenharmony_ci
211762306a36Sopenharmony_ci	ret = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
211862306a36Sopenharmony_ci	if (ret < 0) {
211962306a36Sopenharmony_ci		inode_unlock(orphan_dir_inode);
212062306a36Sopenharmony_ci		iput(orphan_dir_inode);
212162306a36Sopenharmony_ci
212262306a36Sopenharmony_ci		mlog_errno(ret);
212362306a36Sopenharmony_ci		return ret;
212462306a36Sopenharmony_ci	}
212562306a36Sopenharmony_ci
212662306a36Sopenharmony_ci	*ret_orphan_dir = orphan_dir_inode;
212762306a36Sopenharmony_ci	*ret_orphan_dir_bh = orphan_dir_bh;
212862306a36Sopenharmony_ci
212962306a36Sopenharmony_ci	return 0;
213062306a36Sopenharmony_ci}
213162306a36Sopenharmony_ci
213262306a36Sopenharmony_cistatic int __ocfs2_prepare_orphan_dir(struct inode *orphan_dir_inode,
213362306a36Sopenharmony_ci				      struct buffer_head *orphan_dir_bh,
213462306a36Sopenharmony_ci				      u64 blkno,
213562306a36Sopenharmony_ci				      char *name,
213662306a36Sopenharmony_ci				      struct ocfs2_dir_lookup_result *lookup,
213762306a36Sopenharmony_ci				      bool dio)
213862306a36Sopenharmony_ci{
213962306a36Sopenharmony_ci	int ret;
214062306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(orphan_dir_inode->i_sb);
214162306a36Sopenharmony_ci	int namelen = dio ?
214262306a36Sopenharmony_ci			(OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN) :
214362306a36Sopenharmony_ci			OCFS2_ORPHAN_NAMELEN;
214462306a36Sopenharmony_ci
214562306a36Sopenharmony_ci	if (dio) {
214662306a36Sopenharmony_ci		ret = snprintf(name, OCFS2_DIO_ORPHAN_PREFIX_LEN + 1, "%s",
214762306a36Sopenharmony_ci				OCFS2_DIO_ORPHAN_PREFIX);
214862306a36Sopenharmony_ci		if (ret != OCFS2_DIO_ORPHAN_PREFIX_LEN) {
214962306a36Sopenharmony_ci			ret = -EINVAL;
215062306a36Sopenharmony_ci			mlog_errno(ret);
215162306a36Sopenharmony_ci			return ret;
215262306a36Sopenharmony_ci		}
215362306a36Sopenharmony_ci
215462306a36Sopenharmony_ci		ret = ocfs2_blkno_stringify(blkno,
215562306a36Sopenharmony_ci				name + OCFS2_DIO_ORPHAN_PREFIX_LEN);
215662306a36Sopenharmony_ci	} else
215762306a36Sopenharmony_ci		ret = ocfs2_blkno_stringify(blkno, name);
215862306a36Sopenharmony_ci	if (ret < 0) {
215962306a36Sopenharmony_ci		mlog_errno(ret);
216062306a36Sopenharmony_ci		return ret;
216162306a36Sopenharmony_ci	}
216262306a36Sopenharmony_ci
216362306a36Sopenharmony_ci	ret = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode,
216462306a36Sopenharmony_ci					   orphan_dir_bh, name,
216562306a36Sopenharmony_ci					   namelen, lookup);
216662306a36Sopenharmony_ci	if (ret < 0) {
216762306a36Sopenharmony_ci		mlog_errno(ret);
216862306a36Sopenharmony_ci		return ret;
216962306a36Sopenharmony_ci	}
217062306a36Sopenharmony_ci
217162306a36Sopenharmony_ci	return 0;
217262306a36Sopenharmony_ci}
217362306a36Sopenharmony_ci
217462306a36Sopenharmony_ci/**
217562306a36Sopenharmony_ci * ocfs2_prepare_orphan_dir() - Prepare an orphan directory for
217662306a36Sopenharmony_ci * insertion of an orphan.
217762306a36Sopenharmony_ci * @osb: ocfs2 file system
217862306a36Sopenharmony_ci * @ret_orphan_dir: Orphan dir inode - returned locked!
217962306a36Sopenharmony_ci * @blkno: Actual block number of the inode to be inserted into orphan dir.
218062306a36Sopenharmony_ci * @lookup: dir lookup result, to be passed back into functions like
218162306a36Sopenharmony_ci *          ocfs2_orphan_add
218262306a36Sopenharmony_ci *
218362306a36Sopenharmony_ci * Returns zero on success and the ret_orphan_dir, name and lookup
218462306a36Sopenharmony_ci * fields will be populated.
218562306a36Sopenharmony_ci *
218662306a36Sopenharmony_ci * Returns non-zero on failure.
218762306a36Sopenharmony_ci */
218862306a36Sopenharmony_cistatic int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
218962306a36Sopenharmony_ci				    struct inode **ret_orphan_dir,
219062306a36Sopenharmony_ci				    u64 blkno,
219162306a36Sopenharmony_ci				    char *name,
219262306a36Sopenharmony_ci				    struct ocfs2_dir_lookup_result *lookup,
219362306a36Sopenharmony_ci				    bool dio)
219462306a36Sopenharmony_ci{
219562306a36Sopenharmony_ci	struct inode *orphan_dir_inode = NULL;
219662306a36Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
219762306a36Sopenharmony_ci	int ret = 0;
219862306a36Sopenharmony_ci
219962306a36Sopenharmony_ci	ret = ocfs2_lookup_lock_orphan_dir(osb, &orphan_dir_inode,
220062306a36Sopenharmony_ci					   &orphan_dir_bh);
220162306a36Sopenharmony_ci	if (ret < 0) {
220262306a36Sopenharmony_ci		mlog_errno(ret);
220362306a36Sopenharmony_ci		return ret;
220462306a36Sopenharmony_ci	}
220562306a36Sopenharmony_ci
220662306a36Sopenharmony_ci	ret = __ocfs2_prepare_orphan_dir(orphan_dir_inode, orphan_dir_bh,
220762306a36Sopenharmony_ci					 blkno, name, lookup, dio);
220862306a36Sopenharmony_ci	if (ret < 0) {
220962306a36Sopenharmony_ci		mlog_errno(ret);
221062306a36Sopenharmony_ci		goto out;
221162306a36Sopenharmony_ci	}
221262306a36Sopenharmony_ci
221362306a36Sopenharmony_ci	*ret_orphan_dir = orphan_dir_inode;
221462306a36Sopenharmony_ci
221562306a36Sopenharmony_ciout:
221662306a36Sopenharmony_ci	brelse(orphan_dir_bh);
221762306a36Sopenharmony_ci
221862306a36Sopenharmony_ci	if (ret) {
221962306a36Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir_inode, 1);
222062306a36Sopenharmony_ci		inode_unlock(orphan_dir_inode);
222162306a36Sopenharmony_ci		iput(orphan_dir_inode);
222262306a36Sopenharmony_ci	}
222362306a36Sopenharmony_ci
222462306a36Sopenharmony_ci	if (ret)
222562306a36Sopenharmony_ci		mlog_errno(ret);
222662306a36Sopenharmony_ci	return ret;
222762306a36Sopenharmony_ci}
222862306a36Sopenharmony_ci
222962306a36Sopenharmony_cistatic int ocfs2_orphan_add(struct ocfs2_super *osb,
223062306a36Sopenharmony_ci			    handle_t *handle,
223162306a36Sopenharmony_ci			    struct inode *inode,
223262306a36Sopenharmony_ci			    struct buffer_head *fe_bh,
223362306a36Sopenharmony_ci			    char *name,
223462306a36Sopenharmony_ci			    struct ocfs2_dir_lookup_result *lookup,
223562306a36Sopenharmony_ci			    struct inode *orphan_dir_inode,
223662306a36Sopenharmony_ci			    bool dio)
223762306a36Sopenharmony_ci{
223862306a36Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
223962306a36Sopenharmony_ci	int status = 0;
224062306a36Sopenharmony_ci	struct ocfs2_dinode *orphan_fe;
224162306a36Sopenharmony_ci	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
224262306a36Sopenharmony_ci	int namelen = dio ?
224362306a36Sopenharmony_ci			(OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN) :
224462306a36Sopenharmony_ci			OCFS2_ORPHAN_NAMELEN;
224562306a36Sopenharmony_ci
224662306a36Sopenharmony_ci	trace_ocfs2_orphan_add_begin(
224762306a36Sopenharmony_ci				(unsigned long long)OCFS2_I(inode)->ip_blkno);
224862306a36Sopenharmony_ci
224962306a36Sopenharmony_ci	status = ocfs2_read_inode_block(orphan_dir_inode, &orphan_dir_bh);
225062306a36Sopenharmony_ci	if (status < 0) {
225162306a36Sopenharmony_ci		mlog_errno(status);
225262306a36Sopenharmony_ci		goto leave;
225362306a36Sopenharmony_ci	}
225462306a36Sopenharmony_ci
225562306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle,
225662306a36Sopenharmony_ci					 INODE_CACHE(orphan_dir_inode),
225762306a36Sopenharmony_ci					 orphan_dir_bh,
225862306a36Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
225962306a36Sopenharmony_ci	if (status < 0) {
226062306a36Sopenharmony_ci		mlog_errno(status);
226162306a36Sopenharmony_ci		goto leave;
226262306a36Sopenharmony_ci	}
226362306a36Sopenharmony_ci
226462306a36Sopenharmony_ci	/*
226562306a36Sopenharmony_ci	 * We're going to journal the change of i_flags and i_orphaned_slot.
226662306a36Sopenharmony_ci	 * It's safe anyway, though some callers may duplicate the journaling.
226762306a36Sopenharmony_ci	 * Journaling within the func just make the logic look more
226862306a36Sopenharmony_ci	 * straightforward.
226962306a36Sopenharmony_ci	 */
227062306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle,
227162306a36Sopenharmony_ci					 INODE_CACHE(inode),
227262306a36Sopenharmony_ci					 fe_bh,
227362306a36Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
227462306a36Sopenharmony_ci	if (status < 0) {
227562306a36Sopenharmony_ci		mlog_errno(status);
227662306a36Sopenharmony_ci		goto leave;
227762306a36Sopenharmony_ci	}
227862306a36Sopenharmony_ci
227962306a36Sopenharmony_ci	/* we're a cluster, and nlink can change on disk from
228062306a36Sopenharmony_ci	 * underneath us... */
228162306a36Sopenharmony_ci	orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
228262306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
228362306a36Sopenharmony_ci		ocfs2_add_links_count(orphan_fe, 1);
228462306a36Sopenharmony_ci	set_nlink(orphan_dir_inode, ocfs2_read_links_count(orphan_fe));
228562306a36Sopenharmony_ci	ocfs2_journal_dirty(handle, orphan_dir_bh);
228662306a36Sopenharmony_ci
228762306a36Sopenharmony_ci	status = __ocfs2_add_entry(handle, orphan_dir_inode, name,
228862306a36Sopenharmony_ci				   namelen, inode,
228962306a36Sopenharmony_ci				   OCFS2_I(inode)->ip_blkno,
229062306a36Sopenharmony_ci				   orphan_dir_bh, lookup);
229162306a36Sopenharmony_ci	if (status < 0) {
229262306a36Sopenharmony_ci		mlog_errno(status);
229362306a36Sopenharmony_ci		goto rollback;
229462306a36Sopenharmony_ci	}
229562306a36Sopenharmony_ci
229662306a36Sopenharmony_ci	if (dio) {
229762306a36Sopenharmony_ci		/* Update flag OCFS2_DIO_ORPHANED_FL and record the orphan
229862306a36Sopenharmony_ci		 * slot.
229962306a36Sopenharmony_ci		 */
230062306a36Sopenharmony_ci		fe->i_flags |= cpu_to_le32(OCFS2_DIO_ORPHANED_FL);
230162306a36Sopenharmony_ci		fe->i_dio_orphaned_slot = cpu_to_le16(osb->slot_num);
230262306a36Sopenharmony_ci	} else {
230362306a36Sopenharmony_ci		fe->i_flags |= cpu_to_le32(OCFS2_ORPHANED_FL);
230462306a36Sopenharmony_ci		OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR;
230562306a36Sopenharmony_ci
230662306a36Sopenharmony_ci		/* Record which orphan dir our inode now resides
230762306a36Sopenharmony_ci		 * in. delete_inode will use this to determine which orphan
230862306a36Sopenharmony_ci		 * dir to lock. */
230962306a36Sopenharmony_ci		fe->i_orphaned_slot = cpu_to_le16(osb->slot_num);
231062306a36Sopenharmony_ci	}
231162306a36Sopenharmony_ci
231262306a36Sopenharmony_ci	ocfs2_journal_dirty(handle, fe_bh);
231362306a36Sopenharmony_ci
231462306a36Sopenharmony_ci	trace_ocfs2_orphan_add_end((unsigned long long)OCFS2_I(inode)->ip_blkno,
231562306a36Sopenharmony_ci				   osb->slot_num);
231662306a36Sopenharmony_ci
231762306a36Sopenharmony_cirollback:
231862306a36Sopenharmony_ci	if (status < 0) {
231962306a36Sopenharmony_ci		if (S_ISDIR(inode->i_mode))
232062306a36Sopenharmony_ci			ocfs2_add_links_count(orphan_fe, -1);
232162306a36Sopenharmony_ci		set_nlink(orphan_dir_inode, ocfs2_read_links_count(orphan_fe));
232262306a36Sopenharmony_ci	}
232362306a36Sopenharmony_ci
232462306a36Sopenharmony_cileave:
232562306a36Sopenharmony_ci	brelse(orphan_dir_bh);
232662306a36Sopenharmony_ci
232762306a36Sopenharmony_ci	return status;
232862306a36Sopenharmony_ci}
232962306a36Sopenharmony_ci
233062306a36Sopenharmony_ci/* unlike orphan_add, we expect the orphan dir to already be locked here. */
233162306a36Sopenharmony_ciint ocfs2_orphan_del(struct ocfs2_super *osb,
233262306a36Sopenharmony_ci		     handle_t *handle,
233362306a36Sopenharmony_ci		     struct inode *orphan_dir_inode,
233462306a36Sopenharmony_ci		     struct inode *inode,
233562306a36Sopenharmony_ci		     struct buffer_head *orphan_dir_bh,
233662306a36Sopenharmony_ci		     bool dio)
233762306a36Sopenharmony_ci{
233862306a36Sopenharmony_ci	char name[OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN + 1];
233962306a36Sopenharmony_ci	struct ocfs2_dinode *orphan_fe;
234062306a36Sopenharmony_ci	int status = 0;
234162306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
234262306a36Sopenharmony_ci
234362306a36Sopenharmony_ci	if (dio) {
234462306a36Sopenharmony_ci		status = snprintf(name, OCFS2_DIO_ORPHAN_PREFIX_LEN + 1, "%s",
234562306a36Sopenharmony_ci				OCFS2_DIO_ORPHAN_PREFIX);
234662306a36Sopenharmony_ci		if (status != OCFS2_DIO_ORPHAN_PREFIX_LEN) {
234762306a36Sopenharmony_ci			status = -EINVAL;
234862306a36Sopenharmony_ci			mlog_errno(status);
234962306a36Sopenharmony_ci			return status;
235062306a36Sopenharmony_ci		}
235162306a36Sopenharmony_ci
235262306a36Sopenharmony_ci		status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno,
235362306a36Sopenharmony_ci				name + OCFS2_DIO_ORPHAN_PREFIX_LEN);
235462306a36Sopenharmony_ci	} else
235562306a36Sopenharmony_ci		status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
235662306a36Sopenharmony_ci	if (status < 0) {
235762306a36Sopenharmony_ci		mlog_errno(status);
235862306a36Sopenharmony_ci		goto leave;
235962306a36Sopenharmony_ci	}
236062306a36Sopenharmony_ci
236162306a36Sopenharmony_ci	trace_ocfs2_orphan_del(
236262306a36Sopenharmony_ci	     (unsigned long long)OCFS2_I(orphan_dir_inode)->ip_blkno,
236362306a36Sopenharmony_ci	     name, strlen(name));
236462306a36Sopenharmony_ci
236562306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle,
236662306a36Sopenharmony_ci					 INODE_CACHE(orphan_dir_inode),
236762306a36Sopenharmony_ci					 orphan_dir_bh,
236862306a36Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
236962306a36Sopenharmony_ci	if (status < 0) {
237062306a36Sopenharmony_ci		mlog_errno(status);
237162306a36Sopenharmony_ci		goto leave;
237262306a36Sopenharmony_ci	}
237362306a36Sopenharmony_ci
237462306a36Sopenharmony_ci	/* find it's spot in the orphan directory */
237562306a36Sopenharmony_ci	status = ocfs2_find_entry(name, strlen(name), orphan_dir_inode,
237662306a36Sopenharmony_ci				  &lookup);
237762306a36Sopenharmony_ci	if (status) {
237862306a36Sopenharmony_ci		mlog_errno(status);
237962306a36Sopenharmony_ci		goto leave;
238062306a36Sopenharmony_ci	}
238162306a36Sopenharmony_ci
238262306a36Sopenharmony_ci	/* remove it from the orphan directory */
238362306a36Sopenharmony_ci	status = ocfs2_delete_entry(handle, orphan_dir_inode, &lookup);
238462306a36Sopenharmony_ci	if (status < 0) {
238562306a36Sopenharmony_ci		mlog_errno(status);
238662306a36Sopenharmony_ci		goto leave;
238762306a36Sopenharmony_ci	}
238862306a36Sopenharmony_ci
238962306a36Sopenharmony_ci	/* do the i_nlink dance! :) */
239062306a36Sopenharmony_ci	orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
239162306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
239262306a36Sopenharmony_ci		ocfs2_add_links_count(orphan_fe, -1);
239362306a36Sopenharmony_ci	set_nlink(orphan_dir_inode, ocfs2_read_links_count(orphan_fe));
239462306a36Sopenharmony_ci	ocfs2_journal_dirty(handle, orphan_dir_bh);
239562306a36Sopenharmony_ci
239662306a36Sopenharmony_cileave:
239762306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
239862306a36Sopenharmony_ci
239962306a36Sopenharmony_ci	if (status)
240062306a36Sopenharmony_ci		mlog_errno(status);
240162306a36Sopenharmony_ci	return status;
240262306a36Sopenharmony_ci}
240362306a36Sopenharmony_ci
240462306a36Sopenharmony_ci/**
240562306a36Sopenharmony_ci * ocfs2_prep_new_orphaned_file() - Prepare the orphan dir to receive a newly
240662306a36Sopenharmony_ci * allocated file. This is different from the typical 'add to orphan dir'
240762306a36Sopenharmony_ci * operation in that the inode does not yet exist. This is a problem because
240862306a36Sopenharmony_ci * the orphan dir stringifies the inode block number to come up with it's
240962306a36Sopenharmony_ci * dirent. Obviously if the inode does not yet exist we have a chicken and egg
241062306a36Sopenharmony_ci * problem. This function works around it by calling deeper into the orphan
241162306a36Sopenharmony_ci * and suballoc code than other callers. Use this only by necessity.
241262306a36Sopenharmony_ci * @dir: The directory which this inode will ultimately wind up under - not the
241362306a36Sopenharmony_ci * orphan dir!
241462306a36Sopenharmony_ci * @dir_bh: buffer_head the @dir inode block
241562306a36Sopenharmony_ci * @orphan_name: string of length (CFS2_ORPHAN_NAMELEN + 1). Will be filled
241662306a36Sopenharmony_ci * with the string to be used for orphan dirent. Pass back to the orphan dir
241762306a36Sopenharmony_ci * code.
241862306a36Sopenharmony_ci * @ret_orphan_dir: orphan dir inode returned to be passed back into orphan
241962306a36Sopenharmony_ci * dir code.
242062306a36Sopenharmony_ci * @ret_di_blkno: block number where the new inode will be allocated.
242162306a36Sopenharmony_ci * @orphan_insert: Dir insert context to be passed back into orphan dir code.
242262306a36Sopenharmony_ci * @ret_inode_ac: Inode alloc context to be passed back to the allocator.
242362306a36Sopenharmony_ci *
242462306a36Sopenharmony_ci * Returns zero on success and the ret_orphan_dir, name and lookup
242562306a36Sopenharmony_ci * fields will be populated.
242662306a36Sopenharmony_ci *
242762306a36Sopenharmony_ci * Returns non-zero on failure.
242862306a36Sopenharmony_ci */
242962306a36Sopenharmony_cistatic int ocfs2_prep_new_orphaned_file(struct inode *dir,
243062306a36Sopenharmony_ci					struct buffer_head *dir_bh,
243162306a36Sopenharmony_ci					char *orphan_name,
243262306a36Sopenharmony_ci					struct inode **ret_orphan_dir,
243362306a36Sopenharmony_ci					u64 *ret_di_blkno,
243462306a36Sopenharmony_ci					struct ocfs2_dir_lookup_result *orphan_insert,
243562306a36Sopenharmony_ci					struct ocfs2_alloc_context **ret_inode_ac)
243662306a36Sopenharmony_ci{
243762306a36Sopenharmony_ci	int ret;
243862306a36Sopenharmony_ci	u64 di_blkno;
243962306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
244062306a36Sopenharmony_ci	struct inode *orphan_dir = NULL;
244162306a36Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
244262306a36Sopenharmony_ci	struct ocfs2_alloc_context *inode_ac = NULL;
244362306a36Sopenharmony_ci
244462306a36Sopenharmony_ci	ret = ocfs2_lookup_lock_orphan_dir(osb, &orphan_dir, &orphan_dir_bh);
244562306a36Sopenharmony_ci	if (ret < 0) {
244662306a36Sopenharmony_ci		mlog_errno(ret);
244762306a36Sopenharmony_ci		return ret;
244862306a36Sopenharmony_ci	}
244962306a36Sopenharmony_ci
245062306a36Sopenharmony_ci	/* reserve an inode spot */
245162306a36Sopenharmony_ci	ret = ocfs2_reserve_new_inode(osb, &inode_ac);
245262306a36Sopenharmony_ci	if (ret < 0) {
245362306a36Sopenharmony_ci		if (ret != -ENOSPC)
245462306a36Sopenharmony_ci			mlog_errno(ret);
245562306a36Sopenharmony_ci		goto out;
245662306a36Sopenharmony_ci	}
245762306a36Sopenharmony_ci
245862306a36Sopenharmony_ci	ret = ocfs2_find_new_inode_loc(dir, dir_bh, inode_ac,
245962306a36Sopenharmony_ci				       &di_blkno);
246062306a36Sopenharmony_ci	if (ret) {
246162306a36Sopenharmony_ci		mlog_errno(ret);
246262306a36Sopenharmony_ci		goto out;
246362306a36Sopenharmony_ci	}
246462306a36Sopenharmony_ci
246562306a36Sopenharmony_ci	ret = __ocfs2_prepare_orphan_dir(orphan_dir, orphan_dir_bh,
246662306a36Sopenharmony_ci					 di_blkno, orphan_name, orphan_insert,
246762306a36Sopenharmony_ci					 false);
246862306a36Sopenharmony_ci	if (ret < 0) {
246962306a36Sopenharmony_ci		mlog_errno(ret);
247062306a36Sopenharmony_ci		goto out;
247162306a36Sopenharmony_ci	}
247262306a36Sopenharmony_ci
247362306a36Sopenharmony_ciout:
247462306a36Sopenharmony_ci	if (ret == 0) {
247562306a36Sopenharmony_ci		*ret_orphan_dir = orphan_dir;
247662306a36Sopenharmony_ci		*ret_di_blkno = di_blkno;
247762306a36Sopenharmony_ci		*ret_inode_ac = inode_ac;
247862306a36Sopenharmony_ci		/*
247962306a36Sopenharmony_ci		 * orphan_name and orphan_insert are already up to
248062306a36Sopenharmony_ci		 * date via prepare_orphan_dir
248162306a36Sopenharmony_ci		 */
248262306a36Sopenharmony_ci	} else {
248362306a36Sopenharmony_ci		/* Unroll reserve_new_inode* */
248462306a36Sopenharmony_ci		if (inode_ac)
248562306a36Sopenharmony_ci			ocfs2_free_alloc_context(inode_ac);
248662306a36Sopenharmony_ci
248762306a36Sopenharmony_ci		/* Unroll orphan dir locking */
248862306a36Sopenharmony_ci		inode_unlock(orphan_dir);
248962306a36Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir, 1);
249062306a36Sopenharmony_ci		iput(orphan_dir);
249162306a36Sopenharmony_ci	}
249262306a36Sopenharmony_ci
249362306a36Sopenharmony_ci	brelse(orphan_dir_bh);
249462306a36Sopenharmony_ci
249562306a36Sopenharmony_ci	return ret;
249662306a36Sopenharmony_ci}
249762306a36Sopenharmony_ci
249862306a36Sopenharmony_ciint ocfs2_create_inode_in_orphan(struct inode *dir,
249962306a36Sopenharmony_ci				 int mode,
250062306a36Sopenharmony_ci				 struct inode **new_inode)
250162306a36Sopenharmony_ci{
250262306a36Sopenharmony_ci	int status, did_quota_inode = 0;
250362306a36Sopenharmony_ci	struct inode *inode = NULL;
250462306a36Sopenharmony_ci	struct inode *orphan_dir = NULL;
250562306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
250662306a36Sopenharmony_ci	handle_t *handle = NULL;
250762306a36Sopenharmony_ci	char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
250862306a36Sopenharmony_ci	struct buffer_head *parent_di_bh = NULL;
250962306a36Sopenharmony_ci	struct buffer_head *new_di_bh = NULL;
251062306a36Sopenharmony_ci	struct ocfs2_alloc_context *inode_ac = NULL;
251162306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
251262306a36Sopenharmony_ci	u64 di_blkno, suballoc_loc;
251362306a36Sopenharmony_ci	u16 suballoc_bit;
251462306a36Sopenharmony_ci
251562306a36Sopenharmony_ci	status = ocfs2_inode_lock(dir, &parent_di_bh, 1);
251662306a36Sopenharmony_ci	if (status < 0) {
251762306a36Sopenharmony_ci		if (status != -ENOENT)
251862306a36Sopenharmony_ci			mlog_errno(status);
251962306a36Sopenharmony_ci		return status;
252062306a36Sopenharmony_ci	}
252162306a36Sopenharmony_ci
252262306a36Sopenharmony_ci	status = ocfs2_prep_new_orphaned_file(dir, parent_di_bh,
252362306a36Sopenharmony_ci					      orphan_name, &orphan_dir,
252462306a36Sopenharmony_ci					      &di_blkno, &orphan_insert, &inode_ac);
252562306a36Sopenharmony_ci	if (status < 0) {
252662306a36Sopenharmony_ci		if (status != -ENOSPC)
252762306a36Sopenharmony_ci			mlog_errno(status);
252862306a36Sopenharmony_ci		goto leave;
252962306a36Sopenharmony_ci	}
253062306a36Sopenharmony_ci
253162306a36Sopenharmony_ci	inode = ocfs2_get_init_inode(dir, mode);
253262306a36Sopenharmony_ci	if (IS_ERR(inode)) {
253362306a36Sopenharmony_ci		status = PTR_ERR(inode);
253462306a36Sopenharmony_ci		inode = NULL;
253562306a36Sopenharmony_ci		mlog_errno(status);
253662306a36Sopenharmony_ci		goto leave;
253762306a36Sopenharmony_ci	}
253862306a36Sopenharmony_ci
253962306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb, 0, 0));
254062306a36Sopenharmony_ci	if (IS_ERR(handle)) {
254162306a36Sopenharmony_ci		status = PTR_ERR(handle);
254262306a36Sopenharmony_ci		handle = NULL;
254362306a36Sopenharmony_ci		mlog_errno(status);
254462306a36Sopenharmony_ci		goto leave;
254562306a36Sopenharmony_ci	}
254662306a36Sopenharmony_ci
254762306a36Sopenharmony_ci	status = dquot_alloc_inode(inode);
254862306a36Sopenharmony_ci	if (status)
254962306a36Sopenharmony_ci		goto leave;
255062306a36Sopenharmony_ci	did_quota_inode = 1;
255162306a36Sopenharmony_ci
255262306a36Sopenharmony_ci	status = ocfs2_claim_new_inode_at_loc(handle, dir, inode_ac,
255362306a36Sopenharmony_ci					      &suballoc_loc,
255462306a36Sopenharmony_ci					      &suballoc_bit, di_blkno);
255562306a36Sopenharmony_ci	if (status < 0) {
255662306a36Sopenharmony_ci		mlog_errno(status);
255762306a36Sopenharmony_ci		goto leave;
255862306a36Sopenharmony_ci	}
255962306a36Sopenharmony_ci
256062306a36Sopenharmony_ci	clear_nlink(inode);
256162306a36Sopenharmony_ci	/* do the real work now. */
256262306a36Sopenharmony_ci	status = __ocfs2_mknod_locked(dir, inode,
256362306a36Sopenharmony_ci				      0, &new_di_bh, parent_di_bh, handle,
256462306a36Sopenharmony_ci				      inode_ac, di_blkno, suballoc_loc,
256562306a36Sopenharmony_ci				      suballoc_bit);
256662306a36Sopenharmony_ci	if (status < 0) {
256762306a36Sopenharmony_ci		mlog_errno(status);
256862306a36Sopenharmony_ci		goto leave;
256962306a36Sopenharmony_ci	}
257062306a36Sopenharmony_ci
257162306a36Sopenharmony_ci	status = ocfs2_orphan_add(osb, handle, inode, new_di_bh, orphan_name,
257262306a36Sopenharmony_ci				  &orphan_insert, orphan_dir, false);
257362306a36Sopenharmony_ci	if (status < 0) {
257462306a36Sopenharmony_ci		mlog_errno(status);
257562306a36Sopenharmony_ci		goto leave;
257662306a36Sopenharmony_ci	}
257762306a36Sopenharmony_ci
257862306a36Sopenharmony_ci	/* get open lock so that only nodes can't remove it from orphan dir. */
257962306a36Sopenharmony_ci	status = ocfs2_open_lock(inode);
258062306a36Sopenharmony_ci	if (status < 0)
258162306a36Sopenharmony_ci		mlog_errno(status);
258262306a36Sopenharmony_ci
258362306a36Sopenharmony_ci	insert_inode_hash(inode);
258462306a36Sopenharmony_cileave:
258562306a36Sopenharmony_ci	if (status < 0 && did_quota_inode)
258662306a36Sopenharmony_ci		dquot_free_inode(inode);
258762306a36Sopenharmony_ci	if (handle)
258862306a36Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
258962306a36Sopenharmony_ci
259062306a36Sopenharmony_ci	if (orphan_dir) {
259162306a36Sopenharmony_ci		/* This was locked for us in ocfs2_prepare_orphan_dir() */
259262306a36Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir, 1);
259362306a36Sopenharmony_ci		inode_unlock(orphan_dir);
259462306a36Sopenharmony_ci		iput(orphan_dir);
259562306a36Sopenharmony_ci	}
259662306a36Sopenharmony_ci
259762306a36Sopenharmony_ci	if ((status < 0) && inode) {
259862306a36Sopenharmony_ci		clear_nlink(inode);
259962306a36Sopenharmony_ci		iput(inode);
260062306a36Sopenharmony_ci	}
260162306a36Sopenharmony_ci
260262306a36Sopenharmony_ci	if (inode_ac)
260362306a36Sopenharmony_ci		ocfs2_free_alloc_context(inode_ac);
260462306a36Sopenharmony_ci
260562306a36Sopenharmony_ci	brelse(new_di_bh);
260662306a36Sopenharmony_ci
260762306a36Sopenharmony_ci	if (!status)
260862306a36Sopenharmony_ci		*new_inode = inode;
260962306a36Sopenharmony_ci
261062306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&orphan_insert);
261162306a36Sopenharmony_ci
261262306a36Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
261362306a36Sopenharmony_ci	brelse(parent_di_bh);
261462306a36Sopenharmony_ci	return status;
261562306a36Sopenharmony_ci}
261662306a36Sopenharmony_ci
261762306a36Sopenharmony_ciint ocfs2_add_inode_to_orphan(struct ocfs2_super *osb,
261862306a36Sopenharmony_ci	struct inode *inode)
261962306a36Sopenharmony_ci{
262062306a36Sopenharmony_ci	char orphan_name[OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN + 1];
262162306a36Sopenharmony_ci	struct inode *orphan_dir_inode = NULL;
262262306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
262362306a36Sopenharmony_ci	struct buffer_head *di_bh = NULL;
262462306a36Sopenharmony_ci	int status = 0;
262562306a36Sopenharmony_ci	handle_t *handle = NULL;
262662306a36Sopenharmony_ci	struct ocfs2_dinode *di = NULL;
262762306a36Sopenharmony_ci
262862306a36Sopenharmony_ci	status = ocfs2_inode_lock(inode, &di_bh, 1);
262962306a36Sopenharmony_ci	if (status < 0) {
263062306a36Sopenharmony_ci		mlog_errno(status);
263162306a36Sopenharmony_ci		goto bail;
263262306a36Sopenharmony_ci	}
263362306a36Sopenharmony_ci
263462306a36Sopenharmony_ci	di = (struct ocfs2_dinode *) di_bh->b_data;
263562306a36Sopenharmony_ci	/*
263662306a36Sopenharmony_ci	 * Another append dio crashed?
263762306a36Sopenharmony_ci	 * If so, manually recover it first.
263862306a36Sopenharmony_ci	 */
263962306a36Sopenharmony_ci	if (unlikely(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL))) {
264062306a36Sopenharmony_ci		status = ocfs2_truncate_file(inode, di_bh, i_size_read(inode));
264162306a36Sopenharmony_ci		if (status < 0) {
264262306a36Sopenharmony_ci			if (status != -ENOSPC)
264362306a36Sopenharmony_ci				mlog_errno(status);
264462306a36Sopenharmony_ci			goto bail_unlock_inode;
264562306a36Sopenharmony_ci		}
264662306a36Sopenharmony_ci
264762306a36Sopenharmony_ci		status = ocfs2_del_inode_from_orphan(osb, inode, di_bh, 0, 0);
264862306a36Sopenharmony_ci		if (status < 0) {
264962306a36Sopenharmony_ci			mlog_errno(status);
265062306a36Sopenharmony_ci			goto bail_unlock_inode;
265162306a36Sopenharmony_ci		}
265262306a36Sopenharmony_ci	}
265362306a36Sopenharmony_ci
265462306a36Sopenharmony_ci	status = ocfs2_prepare_orphan_dir(osb, &orphan_dir_inode,
265562306a36Sopenharmony_ci			OCFS2_I(inode)->ip_blkno,
265662306a36Sopenharmony_ci			orphan_name,
265762306a36Sopenharmony_ci			&orphan_insert,
265862306a36Sopenharmony_ci			true);
265962306a36Sopenharmony_ci	if (status < 0) {
266062306a36Sopenharmony_ci		mlog_errno(status);
266162306a36Sopenharmony_ci		goto bail_unlock_inode;
266262306a36Sopenharmony_ci	}
266362306a36Sopenharmony_ci
266462306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb,
266562306a36Sopenharmony_ci			OCFS2_INODE_ADD_TO_ORPHAN_CREDITS);
266662306a36Sopenharmony_ci	if (IS_ERR(handle)) {
266762306a36Sopenharmony_ci		status = PTR_ERR(handle);
266862306a36Sopenharmony_ci		goto bail_unlock_orphan;
266962306a36Sopenharmony_ci	}
267062306a36Sopenharmony_ci
267162306a36Sopenharmony_ci	status = ocfs2_orphan_add(osb, handle, inode, di_bh, orphan_name,
267262306a36Sopenharmony_ci			&orphan_insert, orphan_dir_inode, true);
267362306a36Sopenharmony_ci	if (status)
267462306a36Sopenharmony_ci		mlog_errno(status);
267562306a36Sopenharmony_ci
267662306a36Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
267762306a36Sopenharmony_ci
267862306a36Sopenharmony_cibail_unlock_orphan:
267962306a36Sopenharmony_ci	ocfs2_inode_unlock(orphan_dir_inode, 1);
268062306a36Sopenharmony_ci	inode_unlock(orphan_dir_inode);
268162306a36Sopenharmony_ci	iput(orphan_dir_inode);
268262306a36Sopenharmony_ci
268362306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&orphan_insert);
268462306a36Sopenharmony_ci
268562306a36Sopenharmony_cibail_unlock_inode:
268662306a36Sopenharmony_ci	ocfs2_inode_unlock(inode, 1);
268762306a36Sopenharmony_ci	brelse(di_bh);
268862306a36Sopenharmony_ci
268962306a36Sopenharmony_cibail:
269062306a36Sopenharmony_ci	return status;
269162306a36Sopenharmony_ci}
269262306a36Sopenharmony_ci
269362306a36Sopenharmony_ciint ocfs2_del_inode_from_orphan(struct ocfs2_super *osb,
269462306a36Sopenharmony_ci		struct inode *inode, struct buffer_head *di_bh,
269562306a36Sopenharmony_ci		int update_isize, loff_t end)
269662306a36Sopenharmony_ci{
269762306a36Sopenharmony_ci	struct inode *orphan_dir_inode = NULL;
269862306a36Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
269962306a36Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
270062306a36Sopenharmony_ci	handle_t *handle = NULL;
270162306a36Sopenharmony_ci	int status = 0;
270262306a36Sopenharmony_ci
270362306a36Sopenharmony_ci	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
270462306a36Sopenharmony_ci			ORPHAN_DIR_SYSTEM_INODE,
270562306a36Sopenharmony_ci			le16_to_cpu(di->i_dio_orphaned_slot));
270662306a36Sopenharmony_ci	if (!orphan_dir_inode) {
270762306a36Sopenharmony_ci		status = -ENOENT;
270862306a36Sopenharmony_ci		mlog_errno(status);
270962306a36Sopenharmony_ci		goto bail;
271062306a36Sopenharmony_ci	}
271162306a36Sopenharmony_ci
271262306a36Sopenharmony_ci	inode_lock(orphan_dir_inode);
271362306a36Sopenharmony_ci	status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
271462306a36Sopenharmony_ci	if (status < 0) {
271562306a36Sopenharmony_ci		inode_unlock(orphan_dir_inode);
271662306a36Sopenharmony_ci		iput(orphan_dir_inode);
271762306a36Sopenharmony_ci		mlog_errno(status);
271862306a36Sopenharmony_ci		goto bail;
271962306a36Sopenharmony_ci	}
272062306a36Sopenharmony_ci
272162306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb,
272262306a36Sopenharmony_ci			OCFS2_INODE_DEL_FROM_ORPHAN_CREDITS);
272362306a36Sopenharmony_ci	if (IS_ERR(handle)) {
272462306a36Sopenharmony_ci		status = PTR_ERR(handle);
272562306a36Sopenharmony_ci		goto bail_unlock_orphan;
272662306a36Sopenharmony_ci	}
272762306a36Sopenharmony_ci
272862306a36Sopenharmony_ci	BUG_ON(!(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL)));
272962306a36Sopenharmony_ci
273062306a36Sopenharmony_ci	status = ocfs2_orphan_del(osb, handle, orphan_dir_inode,
273162306a36Sopenharmony_ci				inode, orphan_dir_bh, true);
273262306a36Sopenharmony_ci	if (status < 0) {
273362306a36Sopenharmony_ci		mlog_errno(status);
273462306a36Sopenharmony_ci		goto bail_commit;
273562306a36Sopenharmony_ci	}
273662306a36Sopenharmony_ci
273762306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle,
273862306a36Sopenharmony_ci			INODE_CACHE(inode),
273962306a36Sopenharmony_ci			di_bh,
274062306a36Sopenharmony_ci			OCFS2_JOURNAL_ACCESS_WRITE);
274162306a36Sopenharmony_ci	if (status < 0) {
274262306a36Sopenharmony_ci		mlog_errno(status);
274362306a36Sopenharmony_ci		goto bail_commit;
274462306a36Sopenharmony_ci	}
274562306a36Sopenharmony_ci
274662306a36Sopenharmony_ci	di->i_flags &= ~cpu_to_le32(OCFS2_DIO_ORPHANED_FL);
274762306a36Sopenharmony_ci	di->i_dio_orphaned_slot = 0;
274862306a36Sopenharmony_ci
274962306a36Sopenharmony_ci	if (update_isize) {
275062306a36Sopenharmony_ci		status = ocfs2_set_inode_size(handle, inode, di_bh, end);
275162306a36Sopenharmony_ci		if (status)
275262306a36Sopenharmony_ci			mlog_errno(status);
275362306a36Sopenharmony_ci	} else
275462306a36Sopenharmony_ci		ocfs2_journal_dirty(handle, di_bh);
275562306a36Sopenharmony_ci
275662306a36Sopenharmony_cibail_commit:
275762306a36Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
275862306a36Sopenharmony_ci
275962306a36Sopenharmony_cibail_unlock_orphan:
276062306a36Sopenharmony_ci	ocfs2_inode_unlock(orphan_dir_inode, 1);
276162306a36Sopenharmony_ci	inode_unlock(orphan_dir_inode);
276262306a36Sopenharmony_ci	brelse(orphan_dir_bh);
276362306a36Sopenharmony_ci	iput(orphan_dir_inode);
276462306a36Sopenharmony_ci
276562306a36Sopenharmony_cibail:
276662306a36Sopenharmony_ci	return status;
276762306a36Sopenharmony_ci}
276862306a36Sopenharmony_ci
276962306a36Sopenharmony_ciint ocfs2_mv_orphaned_inode_to_new(struct inode *dir,
277062306a36Sopenharmony_ci				   struct inode *inode,
277162306a36Sopenharmony_ci				   struct dentry *dentry)
277262306a36Sopenharmony_ci{
277362306a36Sopenharmony_ci	int status = 0;
277462306a36Sopenharmony_ci	struct buffer_head *parent_di_bh = NULL;
277562306a36Sopenharmony_ci	handle_t *handle = NULL;
277662306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
277762306a36Sopenharmony_ci	struct ocfs2_dinode *dir_di, *di;
277862306a36Sopenharmony_ci	struct inode *orphan_dir_inode = NULL;
277962306a36Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
278062306a36Sopenharmony_ci	struct buffer_head *di_bh = NULL;
278162306a36Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
278262306a36Sopenharmony_ci
278362306a36Sopenharmony_ci	trace_ocfs2_mv_orphaned_inode_to_new(dir, dentry,
278462306a36Sopenharmony_ci				dentry->d_name.len, dentry->d_name.name,
278562306a36Sopenharmony_ci				(unsigned long long)OCFS2_I(dir)->ip_blkno,
278662306a36Sopenharmony_ci				(unsigned long long)OCFS2_I(inode)->ip_blkno);
278762306a36Sopenharmony_ci
278862306a36Sopenharmony_ci	status = ocfs2_inode_lock(dir, &parent_di_bh, 1);
278962306a36Sopenharmony_ci	if (status < 0) {
279062306a36Sopenharmony_ci		if (status != -ENOENT)
279162306a36Sopenharmony_ci			mlog_errno(status);
279262306a36Sopenharmony_ci		return status;
279362306a36Sopenharmony_ci	}
279462306a36Sopenharmony_ci
279562306a36Sopenharmony_ci	dir_di = (struct ocfs2_dinode *) parent_di_bh->b_data;
279662306a36Sopenharmony_ci	if (!dir_di->i_links_count) {
279762306a36Sopenharmony_ci		/* can't make a file in a deleted directory. */
279862306a36Sopenharmony_ci		status = -ENOENT;
279962306a36Sopenharmony_ci		goto leave;
280062306a36Sopenharmony_ci	}
280162306a36Sopenharmony_ci
280262306a36Sopenharmony_ci	status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
280362306a36Sopenharmony_ci					   dentry->d_name.len);
280462306a36Sopenharmony_ci	if (status)
280562306a36Sopenharmony_ci		goto leave;
280662306a36Sopenharmony_ci
280762306a36Sopenharmony_ci	/* get a spot inside the dir. */
280862306a36Sopenharmony_ci	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_di_bh,
280962306a36Sopenharmony_ci					      dentry->d_name.name,
281062306a36Sopenharmony_ci					      dentry->d_name.len, &lookup);
281162306a36Sopenharmony_ci	if (status < 0) {
281262306a36Sopenharmony_ci		mlog_errno(status);
281362306a36Sopenharmony_ci		goto leave;
281462306a36Sopenharmony_ci	}
281562306a36Sopenharmony_ci
281662306a36Sopenharmony_ci	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
281762306a36Sopenharmony_ci						       ORPHAN_DIR_SYSTEM_INODE,
281862306a36Sopenharmony_ci						       osb->slot_num);
281962306a36Sopenharmony_ci	if (!orphan_dir_inode) {
282062306a36Sopenharmony_ci		status = -ENOENT;
282162306a36Sopenharmony_ci		mlog_errno(status);
282262306a36Sopenharmony_ci		goto leave;
282362306a36Sopenharmony_ci	}
282462306a36Sopenharmony_ci
282562306a36Sopenharmony_ci	inode_lock(orphan_dir_inode);
282662306a36Sopenharmony_ci
282762306a36Sopenharmony_ci	status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
282862306a36Sopenharmony_ci	if (status < 0) {
282962306a36Sopenharmony_ci		mlog_errno(status);
283062306a36Sopenharmony_ci		inode_unlock(orphan_dir_inode);
283162306a36Sopenharmony_ci		iput(orphan_dir_inode);
283262306a36Sopenharmony_ci		goto leave;
283362306a36Sopenharmony_ci	}
283462306a36Sopenharmony_ci
283562306a36Sopenharmony_ci	status = ocfs2_read_inode_block(inode, &di_bh);
283662306a36Sopenharmony_ci	if (status < 0) {
283762306a36Sopenharmony_ci		mlog_errno(status);
283862306a36Sopenharmony_ci		goto orphan_unlock;
283962306a36Sopenharmony_ci	}
284062306a36Sopenharmony_ci
284162306a36Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_rename_credits(osb->sb));
284262306a36Sopenharmony_ci	if (IS_ERR(handle)) {
284362306a36Sopenharmony_ci		status = PTR_ERR(handle);
284462306a36Sopenharmony_ci		handle = NULL;
284562306a36Sopenharmony_ci		mlog_errno(status);
284662306a36Sopenharmony_ci		goto orphan_unlock;
284762306a36Sopenharmony_ci	}
284862306a36Sopenharmony_ci
284962306a36Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(inode),
285062306a36Sopenharmony_ci					 di_bh, OCFS2_JOURNAL_ACCESS_WRITE);
285162306a36Sopenharmony_ci	if (status < 0) {
285262306a36Sopenharmony_ci		mlog_errno(status);
285362306a36Sopenharmony_ci		goto out_commit;
285462306a36Sopenharmony_ci	}
285562306a36Sopenharmony_ci
285662306a36Sopenharmony_ci	status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
285762306a36Sopenharmony_ci				  orphan_dir_bh, false);
285862306a36Sopenharmony_ci	if (status < 0) {
285962306a36Sopenharmony_ci		mlog_errno(status);
286062306a36Sopenharmony_ci		goto out_commit;
286162306a36Sopenharmony_ci	}
286262306a36Sopenharmony_ci
286362306a36Sopenharmony_ci	di = (struct ocfs2_dinode *)di_bh->b_data;
286462306a36Sopenharmony_ci	di->i_flags &= ~cpu_to_le32(OCFS2_ORPHANED_FL);
286562306a36Sopenharmony_ci	di->i_orphaned_slot = 0;
286662306a36Sopenharmony_ci	set_nlink(inode, 1);
286762306a36Sopenharmony_ci	ocfs2_set_links_count(di, inode->i_nlink);
286862306a36Sopenharmony_ci	ocfs2_update_inode_fsync_trans(handle, inode, 1);
286962306a36Sopenharmony_ci	ocfs2_journal_dirty(handle, di_bh);
287062306a36Sopenharmony_ci
287162306a36Sopenharmony_ci	status = ocfs2_add_entry(handle, dentry, inode,
287262306a36Sopenharmony_ci				 OCFS2_I(inode)->ip_blkno, parent_di_bh,
287362306a36Sopenharmony_ci				 &lookup);
287462306a36Sopenharmony_ci	if (status < 0) {
287562306a36Sopenharmony_ci		mlog_errno(status);
287662306a36Sopenharmony_ci		goto out_commit;
287762306a36Sopenharmony_ci	}
287862306a36Sopenharmony_ci
287962306a36Sopenharmony_ci	status = ocfs2_dentry_attach_lock(dentry, inode,
288062306a36Sopenharmony_ci					  OCFS2_I(dir)->ip_blkno);
288162306a36Sopenharmony_ci	if (status) {
288262306a36Sopenharmony_ci		mlog_errno(status);
288362306a36Sopenharmony_ci		goto out_commit;
288462306a36Sopenharmony_ci	}
288562306a36Sopenharmony_ci
288662306a36Sopenharmony_ci	d_instantiate(dentry, inode);
288762306a36Sopenharmony_ci	status = 0;
288862306a36Sopenharmony_ciout_commit:
288962306a36Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
289062306a36Sopenharmony_ciorphan_unlock:
289162306a36Sopenharmony_ci	ocfs2_inode_unlock(orphan_dir_inode, 1);
289262306a36Sopenharmony_ci	inode_unlock(orphan_dir_inode);
289362306a36Sopenharmony_ci	iput(orphan_dir_inode);
289462306a36Sopenharmony_cileave:
289562306a36Sopenharmony_ci
289662306a36Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
289762306a36Sopenharmony_ci
289862306a36Sopenharmony_ci	brelse(di_bh);
289962306a36Sopenharmony_ci	brelse(parent_di_bh);
290062306a36Sopenharmony_ci	brelse(orphan_dir_bh);
290162306a36Sopenharmony_ci
290262306a36Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
290362306a36Sopenharmony_ci
290462306a36Sopenharmony_ci	if (status)
290562306a36Sopenharmony_ci		mlog_errno(status);
290662306a36Sopenharmony_ci
290762306a36Sopenharmony_ci	return status;
290862306a36Sopenharmony_ci}
290962306a36Sopenharmony_ci
291062306a36Sopenharmony_ciconst struct inode_operations ocfs2_dir_iops = {
291162306a36Sopenharmony_ci	.create		= ocfs2_create,
291262306a36Sopenharmony_ci	.lookup		= ocfs2_lookup,
291362306a36Sopenharmony_ci	.link		= ocfs2_link,
291462306a36Sopenharmony_ci	.unlink		= ocfs2_unlink,
291562306a36Sopenharmony_ci	.rmdir		= ocfs2_unlink,
291662306a36Sopenharmony_ci	.symlink	= ocfs2_symlink,
291762306a36Sopenharmony_ci	.mkdir		= ocfs2_mkdir,
291862306a36Sopenharmony_ci	.mknod		= ocfs2_mknod,
291962306a36Sopenharmony_ci	.rename		= ocfs2_rename,
292062306a36Sopenharmony_ci	.setattr	= ocfs2_setattr,
292162306a36Sopenharmony_ci	.getattr	= ocfs2_getattr,
292262306a36Sopenharmony_ci	.permission	= ocfs2_permission,
292362306a36Sopenharmony_ci	.listxattr	= ocfs2_listxattr,
292462306a36Sopenharmony_ci	.fiemap         = ocfs2_fiemap,
292562306a36Sopenharmony_ci	.get_inode_acl	= ocfs2_iop_get_acl,
292662306a36Sopenharmony_ci	.set_acl	= ocfs2_iop_set_acl,
292762306a36Sopenharmony_ci	.fileattr_get	= ocfs2_fileattr_get,
292862306a36Sopenharmony_ci	.fileattr_set	= ocfs2_fileattr_set,
292962306a36Sopenharmony_ci};
2930