18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/* -*- mode: c; c-basic-offset: 8; -*-
38c2ecf20Sopenharmony_ci * vim: noexpandtab sw=8 ts=8 sts=0:
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * namei.c
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Create and rename file, directory, symlinks
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci *  Portions of this code from linux/fs/ext3/dir.c
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci *  Copyright (C) 1992, 1993, 1994, 1995
148c2ecf20Sopenharmony_ci *  Remy Card (card@masi.ibp.fr)
158c2ecf20Sopenharmony_ci *  Laboratoire MASI - Institut Blaise pascal
168c2ecf20Sopenharmony_ci *  Universite Pierre et Marie Curie (Paris VI)
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci *   from
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci *   linux/fs/minix/dir.c
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci *   Copyright (C) 1991, 1992 Linux Torvalds
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#include <linux/fs.h>
268c2ecf20Sopenharmony_ci#include <linux/types.h>
278c2ecf20Sopenharmony_ci#include <linux/slab.h>
288c2ecf20Sopenharmony_ci#include <linux/highmem.h>
298c2ecf20Sopenharmony_ci#include <linux/quotaops.h>
308c2ecf20Sopenharmony_ci#include <linux/iversion.h>
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci#include <cluster/masklog.h>
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#include "ocfs2.h"
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#include "alloc.h"
378c2ecf20Sopenharmony_ci#include "dcache.h"
388c2ecf20Sopenharmony_ci#include "dir.h"
398c2ecf20Sopenharmony_ci#include "dlmglue.h"
408c2ecf20Sopenharmony_ci#include "extent_map.h"
418c2ecf20Sopenharmony_ci#include "file.h"
428c2ecf20Sopenharmony_ci#include "inode.h"
438c2ecf20Sopenharmony_ci#include "journal.h"
448c2ecf20Sopenharmony_ci#include "namei.h"
458c2ecf20Sopenharmony_ci#include "suballoc.h"
468c2ecf20Sopenharmony_ci#include "super.h"
478c2ecf20Sopenharmony_ci#include "symlink.h"
488c2ecf20Sopenharmony_ci#include "sysfile.h"
498c2ecf20Sopenharmony_ci#include "uptodate.h"
508c2ecf20Sopenharmony_ci#include "xattr.h"
518c2ecf20Sopenharmony_ci#include "acl.h"
528c2ecf20Sopenharmony_ci#include "ocfs2_trace.h"
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci#include "buffer_head_io.h"
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic int ocfs2_mknod_locked(struct ocfs2_super *osb,
578c2ecf20Sopenharmony_ci			      struct inode *dir,
588c2ecf20Sopenharmony_ci			      struct inode *inode,
598c2ecf20Sopenharmony_ci			      dev_t dev,
608c2ecf20Sopenharmony_ci			      struct buffer_head **new_fe_bh,
618c2ecf20Sopenharmony_ci			      struct buffer_head *parent_fe_bh,
628c2ecf20Sopenharmony_ci			      handle_t *handle,
638c2ecf20Sopenharmony_ci			      struct ocfs2_alloc_context *inode_ac);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistatic int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
668c2ecf20Sopenharmony_ci				    struct inode **ret_orphan_dir,
678c2ecf20Sopenharmony_ci				    u64 blkno,
688c2ecf20Sopenharmony_ci				    char *name,
698c2ecf20Sopenharmony_ci				    struct ocfs2_dir_lookup_result *lookup,
708c2ecf20Sopenharmony_ci				    bool dio);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistatic int ocfs2_orphan_add(struct ocfs2_super *osb,
738c2ecf20Sopenharmony_ci			    handle_t *handle,
748c2ecf20Sopenharmony_ci			    struct inode *inode,
758c2ecf20Sopenharmony_ci			    struct buffer_head *fe_bh,
768c2ecf20Sopenharmony_ci			    char *name,
778c2ecf20Sopenharmony_ci			    struct ocfs2_dir_lookup_result *lookup,
788c2ecf20Sopenharmony_ci			    struct inode *orphan_dir_inode,
798c2ecf20Sopenharmony_ci			    bool dio);
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistatic int ocfs2_create_symlink_data(struct ocfs2_super *osb,
828c2ecf20Sopenharmony_ci				     handle_t *handle,
838c2ecf20Sopenharmony_ci				     struct inode *inode,
848c2ecf20Sopenharmony_ci				     const char *symname);
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_cistatic int ocfs2_double_lock(struct ocfs2_super *osb,
878c2ecf20Sopenharmony_ci			     struct buffer_head **bh1,
888c2ecf20Sopenharmony_ci			     struct inode *inode1,
898c2ecf20Sopenharmony_ci			     struct buffer_head **bh2,
908c2ecf20Sopenharmony_ci			     struct inode *inode2,
918c2ecf20Sopenharmony_ci			     int rename);
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_cistatic void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2);
948c2ecf20Sopenharmony_ci/* An orphan dir name is an 8 byte value, printed as a hex string */
958c2ecf20Sopenharmony_ci#define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistatic struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
988c2ecf20Sopenharmony_ci				   unsigned int flags)
998c2ecf20Sopenharmony_ci{
1008c2ecf20Sopenharmony_ci	int status;
1018c2ecf20Sopenharmony_ci	u64 blkno;
1028c2ecf20Sopenharmony_ci	struct inode *inode = NULL;
1038c2ecf20Sopenharmony_ci	struct dentry *ret;
1048c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	trace_ocfs2_lookup(dir, dentry, dentry->d_name.len,
1078c2ecf20Sopenharmony_ci			   dentry->d_name.name,
1088c2ecf20Sopenharmony_ci			   (unsigned long long)OCFS2_I(dir)->ip_blkno, 0);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	if (dentry->d_name.len > OCFS2_MAX_FILENAME_LEN) {
1118c2ecf20Sopenharmony_ci		ret = ERR_PTR(-ENAMETOOLONG);
1128c2ecf20Sopenharmony_ci		goto bail;
1138c2ecf20Sopenharmony_ci	}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock_nested(dir, NULL, 0, OI_LS_PARENT);
1168c2ecf20Sopenharmony_ci	if (status < 0) {
1178c2ecf20Sopenharmony_ci		if (status != -ENOENT)
1188c2ecf20Sopenharmony_ci			mlog_errno(status);
1198c2ecf20Sopenharmony_ci		ret = ERR_PTR(status);
1208c2ecf20Sopenharmony_ci		goto bail;
1218c2ecf20Sopenharmony_ci	}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	status = ocfs2_lookup_ino_from_name(dir, dentry->d_name.name,
1248c2ecf20Sopenharmony_ci					    dentry->d_name.len, &blkno);
1258c2ecf20Sopenharmony_ci	if (status < 0)
1268c2ecf20Sopenharmony_ci		goto bail_add;
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0);
1298c2ecf20Sopenharmony_ci	if (IS_ERR(inode)) {
1308c2ecf20Sopenharmony_ci		ret = ERR_PTR(-EACCES);
1318c2ecf20Sopenharmony_ci		goto bail_unlock;
1328c2ecf20Sopenharmony_ci	}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	oi = OCFS2_I(inode);
1358c2ecf20Sopenharmony_ci	/* Clear any orphaned state... If we were able to look up the
1368c2ecf20Sopenharmony_ci	 * inode from a directory, it certainly can't be orphaned. We
1378c2ecf20Sopenharmony_ci	 * might have the bad state from a node which intended to
1388c2ecf20Sopenharmony_ci	 * orphan this inode but crashed before it could commit the
1398c2ecf20Sopenharmony_ci	 * unlink. */
1408c2ecf20Sopenharmony_ci	spin_lock(&oi->ip_lock);
1418c2ecf20Sopenharmony_ci	oi->ip_flags &= ~OCFS2_INODE_MAYBE_ORPHANED;
1428c2ecf20Sopenharmony_ci	spin_unlock(&oi->ip_lock);
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_cibail_add:
1458c2ecf20Sopenharmony_ci	ret = d_splice_alias(inode, dentry);
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	if (inode) {
1488c2ecf20Sopenharmony_ci		/*
1498c2ecf20Sopenharmony_ci		 * If d_splice_alias() finds a DCACHE_DISCONNECTED
1508c2ecf20Sopenharmony_ci		 * dentry, it will d_move() it on top of ourse. The
1518c2ecf20Sopenharmony_ci		 * return value will indicate this however, so in
1528c2ecf20Sopenharmony_ci		 * those cases, we switch them around for the locking
1538c2ecf20Sopenharmony_ci		 * code.
1548c2ecf20Sopenharmony_ci		 *
1558c2ecf20Sopenharmony_ci		 * NOTE: This dentry already has ->d_op set from
1568c2ecf20Sopenharmony_ci		 * ocfs2_get_parent() and ocfs2_get_dentry()
1578c2ecf20Sopenharmony_ci		 */
1588c2ecf20Sopenharmony_ci		if (!IS_ERR_OR_NULL(ret))
1598c2ecf20Sopenharmony_ci			dentry = ret;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci		status = ocfs2_dentry_attach_lock(dentry, inode,
1628c2ecf20Sopenharmony_ci						  OCFS2_I(dir)->ip_blkno);
1638c2ecf20Sopenharmony_ci		if (status) {
1648c2ecf20Sopenharmony_ci			mlog_errno(status);
1658c2ecf20Sopenharmony_ci			ret = ERR_PTR(status);
1668c2ecf20Sopenharmony_ci			goto bail_unlock;
1678c2ecf20Sopenharmony_ci		}
1688c2ecf20Sopenharmony_ci	} else
1698c2ecf20Sopenharmony_ci		ocfs2_dentry_attach_gen(dentry);
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_cibail_unlock:
1728c2ecf20Sopenharmony_ci	/* Don't drop the cluster lock until *after* the d_add --
1738c2ecf20Sopenharmony_ci	 * unlink on another node will message us to remove that
1748c2ecf20Sopenharmony_ci	 * dentry under this lock so otherwise we can race this with
1758c2ecf20Sopenharmony_ci	 * the downconvert thread and have a stale dentry. */
1768c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(dir, 0);
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_cibail:
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	trace_ocfs2_lookup_ret(ret);
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	return ret;
1838c2ecf20Sopenharmony_ci}
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_cistatic struct inode *ocfs2_get_init_inode(struct inode *dir, umode_t mode)
1868c2ecf20Sopenharmony_ci{
1878c2ecf20Sopenharmony_ci	struct inode *inode;
1888c2ecf20Sopenharmony_ci	int status;
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	inode = new_inode(dir->i_sb);
1918c2ecf20Sopenharmony_ci	if (!inode) {
1928c2ecf20Sopenharmony_ci		mlog(ML_ERROR, "new_inode failed!\n");
1938c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
1948c2ecf20Sopenharmony_ci	}
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	/* populate as many fields early on as possible - many of
1978c2ecf20Sopenharmony_ci	 * these are used by the support functions here and in
1988c2ecf20Sopenharmony_ci	 * callers. */
1998c2ecf20Sopenharmony_ci	if (S_ISDIR(mode))
2008c2ecf20Sopenharmony_ci		set_nlink(inode, 2);
2018c2ecf20Sopenharmony_ci	mode = mode_strip_sgid(dir, mode);
2028c2ecf20Sopenharmony_ci	inode_init_owner(inode, dir, mode);
2038c2ecf20Sopenharmony_ci	status = dquot_initialize(inode);
2048c2ecf20Sopenharmony_ci	if (status)
2058c2ecf20Sopenharmony_ci		return ERR_PTR(status);
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	return inode;
2088c2ecf20Sopenharmony_ci}
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_cistatic void ocfs2_cleanup_add_entry_failure(struct ocfs2_super *osb,
2118c2ecf20Sopenharmony_ci		struct dentry *dentry, struct inode *inode)
2128c2ecf20Sopenharmony_ci{
2138c2ecf20Sopenharmony_ci	struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	ocfs2_simple_drop_lockres(osb, &dl->dl_lockres);
2168c2ecf20Sopenharmony_ci	ocfs2_lock_res_free(&dl->dl_lockres);
2178c2ecf20Sopenharmony_ci	BUG_ON(dl->dl_count != 1);
2188c2ecf20Sopenharmony_ci	spin_lock(&dentry_attach_lock);
2198c2ecf20Sopenharmony_ci	dentry->d_fsdata = NULL;
2208c2ecf20Sopenharmony_ci	spin_unlock(&dentry_attach_lock);
2218c2ecf20Sopenharmony_ci	kfree(dl);
2228c2ecf20Sopenharmony_ci	iput(inode);
2238c2ecf20Sopenharmony_ci}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_cistatic int ocfs2_mknod(struct inode *dir,
2268c2ecf20Sopenharmony_ci		       struct dentry *dentry,
2278c2ecf20Sopenharmony_ci		       umode_t mode,
2288c2ecf20Sopenharmony_ci		       dev_t dev)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	int status = 0;
2318c2ecf20Sopenharmony_ci	struct buffer_head *parent_fe_bh = NULL;
2328c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
2338c2ecf20Sopenharmony_ci	struct ocfs2_super *osb;
2348c2ecf20Sopenharmony_ci	struct ocfs2_dinode *dirfe;
2358c2ecf20Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
2368c2ecf20Sopenharmony_ci	struct buffer_head *new_fe_bh = NULL;
2378c2ecf20Sopenharmony_ci	struct inode *inode = NULL;
2388c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *inode_ac = NULL;
2398c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *data_ac = NULL;
2408c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *meta_ac = NULL;
2418c2ecf20Sopenharmony_ci	int want_clusters = 0;
2428c2ecf20Sopenharmony_ci	int want_meta = 0;
2438c2ecf20Sopenharmony_ci	int xattr_credits = 0;
2448c2ecf20Sopenharmony_ci	struct ocfs2_security_xattr_info si = {
2458c2ecf20Sopenharmony_ci		.name = NULL,
2468c2ecf20Sopenharmony_ci		.enable = 1,
2478c2ecf20Sopenharmony_ci	};
2488c2ecf20Sopenharmony_ci	int did_quota_inode = 0;
2498c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
2508c2ecf20Sopenharmony_ci	sigset_t oldset;
2518c2ecf20Sopenharmony_ci	int did_block_signals = 0;
2528c2ecf20Sopenharmony_ci	struct ocfs2_dentry_lock *dl = NULL;
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci	trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name,
2558c2ecf20Sopenharmony_ci			  (unsigned long long)OCFS2_I(dir)->ip_blkno,
2568c2ecf20Sopenharmony_ci			  (unsigned long)dev, mode);
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	status = dquot_initialize(dir);
2598c2ecf20Sopenharmony_ci	if (status) {
2608c2ecf20Sopenharmony_ci		mlog_errno(status);
2618c2ecf20Sopenharmony_ci		return status;
2628c2ecf20Sopenharmony_ci	}
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	/* get our super block */
2658c2ecf20Sopenharmony_ci	osb = OCFS2_SB(dir->i_sb);
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock(dir, &parent_fe_bh, 1);
2688c2ecf20Sopenharmony_ci	if (status < 0) {
2698c2ecf20Sopenharmony_ci		if (status != -ENOENT)
2708c2ecf20Sopenharmony_ci			mlog_errno(status);
2718c2ecf20Sopenharmony_ci		return status;
2728c2ecf20Sopenharmony_ci	}
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	if (S_ISDIR(mode) && (dir->i_nlink >= ocfs2_link_max(osb))) {
2758c2ecf20Sopenharmony_ci		status = -EMLINK;
2768c2ecf20Sopenharmony_ci		goto leave;
2778c2ecf20Sopenharmony_ci	}
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
2808c2ecf20Sopenharmony_ci	if (!ocfs2_read_links_count(dirfe)) {
2818c2ecf20Sopenharmony_ci		/* can't make a file in a deleted directory. */
2828c2ecf20Sopenharmony_ci		status = -ENOENT;
2838c2ecf20Sopenharmony_ci		goto leave;
2848c2ecf20Sopenharmony_ci	}
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
2878c2ecf20Sopenharmony_ci					   dentry->d_name.len);
2888c2ecf20Sopenharmony_ci	if (status)
2898c2ecf20Sopenharmony_ci		goto leave;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	/* get a spot inside the dir. */
2928c2ecf20Sopenharmony_ci	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
2938c2ecf20Sopenharmony_ci					      dentry->d_name.name,
2948c2ecf20Sopenharmony_ci					      dentry->d_name.len, &lookup);
2958c2ecf20Sopenharmony_ci	if (status < 0) {
2968c2ecf20Sopenharmony_ci		mlog_errno(status);
2978c2ecf20Sopenharmony_ci		goto leave;
2988c2ecf20Sopenharmony_ci	}
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci	/* reserve an inode spot */
3018c2ecf20Sopenharmony_ci	status = ocfs2_reserve_new_inode(osb, &inode_ac);
3028c2ecf20Sopenharmony_ci	if (status < 0) {
3038c2ecf20Sopenharmony_ci		if (status != -ENOSPC)
3048c2ecf20Sopenharmony_ci			mlog_errno(status);
3058c2ecf20Sopenharmony_ci		goto leave;
3068c2ecf20Sopenharmony_ci	}
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci	inode = ocfs2_get_init_inode(dir, mode);
3098c2ecf20Sopenharmony_ci	if (IS_ERR(inode)) {
3108c2ecf20Sopenharmony_ci		status = PTR_ERR(inode);
3118c2ecf20Sopenharmony_ci		inode = NULL;
3128c2ecf20Sopenharmony_ci		mlog_errno(status);
3138c2ecf20Sopenharmony_ci		goto leave;
3148c2ecf20Sopenharmony_ci	}
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci	/* get security xattr */
3178c2ecf20Sopenharmony_ci	status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);
3188c2ecf20Sopenharmony_ci	if (status) {
3198c2ecf20Sopenharmony_ci		if (status == -EOPNOTSUPP)
3208c2ecf20Sopenharmony_ci			si.enable = 0;
3218c2ecf20Sopenharmony_ci		else {
3228c2ecf20Sopenharmony_ci			mlog_errno(status);
3238c2ecf20Sopenharmony_ci			goto leave;
3248c2ecf20Sopenharmony_ci		}
3258c2ecf20Sopenharmony_ci	}
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci	/* calculate meta data/clusters for setting security and acl xattr */
3288c2ecf20Sopenharmony_ci	status = ocfs2_calc_xattr_init(dir, parent_fe_bh, mode,
3298c2ecf20Sopenharmony_ci				       &si, &want_clusters,
3308c2ecf20Sopenharmony_ci				       &xattr_credits, &want_meta);
3318c2ecf20Sopenharmony_ci	if (status < 0) {
3328c2ecf20Sopenharmony_ci		mlog_errno(status);
3338c2ecf20Sopenharmony_ci		goto leave;
3348c2ecf20Sopenharmony_ci	}
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	/* Reserve a cluster if creating an extent based directory. */
3378c2ecf20Sopenharmony_ci	if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
3388c2ecf20Sopenharmony_ci		want_clusters += 1;
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci		/* Dir indexing requires extra space as well */
3418c2ecf20Sopenharmony_ci		if (ocfs2_supports_indexed_dirs(osb))
3428c2ecf20Sopenharmony_ci			want_meta++;
3438c2ecf20Sopenharmony_ci	}
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	status = ocfs2_reserve_new_metadata_blocks(osb, want_meta, &meta_ac);
3468c2ecf20Sopenharmony_ci	if (status < 0) {
3478c2ecf20Sopenharmony_ci		if (status != -ENOSPC)
3488c2ecf20Sopenharmony_ci			mlog_errno(status);
3498c2ecf20Sopenharmony_ci		goto leave;
3508c2ecf20Sopenharmony_ci	}
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci	status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac);
3538c2ecf20Sopenharmony_ci	if (status < 0) {
3548c2ecf20Sopenharmony_ci		if (status != -ENOSPC)
3558c2ecf20Sopenharmony_ci			mlog_errno(status);
3568c2ecf20Sopenharmony_ci		goto leave;
3578c2ecf20Sopenharmony_ci	}
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
3608c2ecf20Sopenharmony_ci							    S_ISDIR(mode),
3618c2ecf20Sopenharmony_ci							    xattr_credits));
3628c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
3638c2ecf20Sopenharmony_ci		status = PTR_ERR(handle);
3648c2ecf20Sopenharmony_ci		handle = NULL;
3658c2ecf20Sopenharmony_ci		mlog_errno(status);
3668c2ecf20Sopenharmony_ci		goto leave;
3678c2ecf20Sopenharmony_ci	}
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci	/* Starting to change things, restart is no longer possible. */
3708c2ecf20Sopenharmony_ci	ocfs2_block_signals(&oldset);
3718c2ecf20Sopenharmony_ci	did_block_signals = 1;
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	status = dquot_alloc_inode(inode);
3748c2ecf20Sopenharmony_ci	if (status)
3758c2ecf20Sopenharmony_ci		goto leave;
3768c2ecf20Sopenharmony_ci	did_quota_inode = 1;
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ci	/* do the real work now. */
3798c2ecf20Sopenharmony_ci	status = ocfs2_mknod_locked(osb, dir, inode, dev,
3808c2ecf20Sopenharmony_ci				    &new_fe_bh, parent_fe_bh, handle,
3818c2ecf20Sopenharmony_ci				    inode_ac);
3828c2ecf20Sopenharmony_ci	if (status < 0) {
3838c2ecf20Sopenharmony_ci		mlog_errno(status);
3848c2ecf20Sopenharmony_ci		goto leave;
3858c2ecf20Sopenharmony_ci	}
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci	fe = (struct ocfs2_dinode *) new_fe_bh->b_data;
3888c2ecf20Sopenharmony_ci	if (S_ISDIR(mode)) {
3898c2ecf20Sopenharmony_ci		status = ocfs2_fill_new_dir(osb, handle, dir, inode,
3908c2ecf20Sopenharmony_ci					    new_fe_bh, data_ac, meta_ac);
3918c2ecf20Sopenharmony_ci		if (status < 0) {
3928c2ecf20Sopenharmony_ci			mlog_errno(status);
3938c2ecf20Sopenharmony_ci			goto leave;
3948c2ecf20Sopenharmony_ci		}
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci		status = ocfs2_journal_access_di(handle, INODE_CACHE(dir),
3978c2ecf20Sopenharmony_ci						 parent_fe_bh,
3988c2ecf20Sopenharmony_ci						 OCFS2_JOURNAL_ACCESS_WRITE);
3998c2ecf20Sopenharmony_ci		if (status < 0) {
4008c2ecf20Sopenharmony_ci			mlog_errno(status);
4018c2ecf20Sopenharmony_ci			goto leave;
4028c2ecf20Sopenharmony_ci		}
4038c2ecf20Sopenharmony_ci		ocfs2_add_links_count(dirfe, 1);
4048c2ecf20Sopenharmony_ci		ocfs2_journal_dirty(handle, parent_fe_bh);
4058c2ecf20Sopenharmony_ci		inc_nlink(dir);
4068c2ecf20Sopenharmony_ci	}
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci	status = ocfs2_init_acl(handle, inode, dir, new_fe_bh, parent_fe_bh,
4098c2ecf20Sopenharmony_ci			 meta_ac, data_ac);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	if (status < 0) {
4128c2ecf20Sopenharmony_ci		mlog_errno(status);
4138c2ecf20Sopenharmony_ci		goto roll_back;
4148c2ecf20Sopenharmony_ci	}
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci	if (si.enable) {
4178c2ecf20Sopenharmony_ci		status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si,
4188c2ecf20Sopenharmony_ci						 meta_ac, data_ac);
4198c2ecf20Sopenharmony_ci		if (status < 0) {
4208c2ecf20Sopenharmony_ci			mlog_errno(status);
4218c2ecf20Sopenharmony_ci			goto roll_back;
4228c2ecf20Sopenharmony_ci		}
4238c2ecf20Sopenharmony_ci	}
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	/*
4268c2ecf20Sopenharmony_ci	 * Do this before adding the entry to the directory. We add
4278c2ecf20Sopenharmony_ci	 * also set d_op after success so that ->d_iput() will cleanup
4288c2ecf20Sopenharmony_ci	 * the dentry lock even if ocfs2_add_entry() fails below.
4298c2ecf20Sopenharmony_ci	 */
4308c2ecf20Sopenharmony_ci	status = ocfs2_dentry_attach_lock(dentry, inode,
4318c2ecf20Sopenharmony_ci					  OCFS2_I(dir)->ip_blkno);
4328c2ecf20Sopenharmony_ci	if (status) {
4338c2ecf20Sopenharmony_ci		mlog_errno(status);
4348c2ecf20Sopenharmony_ci		goto roll_back;
4358c2ecf20Sopenharmony_ci	}
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci	dl = dentry->d_fsdata;
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_ci	status = ocfs2_add_entry(handle, dentry, inode,
4408c2ecf20Sopenharmony_ci				 OCFS2_I(inode)->ip_blkno, parent_fe_bh,
4418c2ecf20Sopenharmony_ci				 &lookup);
4428c2ecf20Sopenharmony_ci	if (status < 0) {
4438c2ecf20Sopenharmony_ci		mlog_errno(status);
4448c2ecf20Sopenharmony_ci		goto roll_back;
4458c2ecf20Sopenharmony_ci	}
4468c2ecf20Sopenharmony_ci
4478c2ecf20Sopenharmony_ci	insert_inode_hash(inode);
4488c2ecf20Sopenharmony_ci	d_instantiate(dentry, inode);
4498c2ecf20Sopenharmony_ci	status = 0;
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ciroll_back:
4528c2ecf20Sopenharmony_ci	if (status < 0 && S_ISDIR(mode)) {
4538c2ecf20Sopenharmony_ci		ocfs2_add_links_count(dirfe, -1);
4548c2ecf20Sopenharmony_ci		drop_nlink(dir);
4558c2ecf20Sopenharmony_ci	}
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_cileave:
4588c2ecf20Sopenharmony_ci	if (status < 0 && did_quota_inode)
4598c2ecf20Sopenharmony_ci		dquot_free_inode(inode);
4608c2ecf20Sopenharmony_ci	if (handle) {
4618c2ecf20Sopenharmony_ci		if (status < 0 && fe)
4628c2ecf20Sopenharmony_ci			ocfs2_set_links_count(fe, 0);
4638c2ecf20Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
4648c2ecf20Sopenharmony_ci	}
4658c2ecf20Sopenharmony_ci
4668c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
4678c2ecf20Sopenharmony_ci	if (did_block_signals)
4688c2ecf20Sopenharmony_ci		ocfs2_unblock_signals(&oldset);
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	brelse(new_fe_bh);
4718c2ecf20Sopenharmony_ci	brelse(parent_fe_bh);
4728c2ecf20Sopenharmony_ci	kfree(si.value);
4738c2ecf20Sopenharmony_ci
4748c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci	if (inode_ac)
4778c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(inode_ac);
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci	if (data_ac)
4808c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(data_ac);
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_ci	if (meta_ac)
4838c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(meta_ac);
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci	/*
4868c2ecf20Sopenharmony_ci	 * We should call iput after the i_mutex of the bitmap been
4878c2ecf20Sopenharmony_ci	 * unlocked in ocfs2_free_alloc_context, or the
4888c2ecf20Sopenharmony_ci	 * ocfs2_delete_inode will mutex_lock again.
4898c2ecf20Sopenharmony_ci	 */
4908c2ecf20Sopenharmony_ci	if ((status < 0) && inode) {
4918c2ecf20Sopenharmony_ci		if (dl)
4928c2ecf20Sopenharmony_ci			ocfs2_cleanup_add_entry_failure(osb, dentry, inode);
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
4958c2ecf20Sopenharmony_ci		clear_nlink(inode);
4968c2ecf20Sopenharmony_ci		iput(inode);
4978c2ecf20Sopenharmony_ci	}
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci	if (status)
5008c2ecf20Sopenharmony_ci		mlog_errno(status);
5018c2ecf20Sopenharmony_ci
5028c2ecf20Sopenharmony_ci	return status;
5038c2ecf20Sopenharmony_ci}
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_cistatic int __ocfs2_mknod_locked(struct inode *dir,
5068c2ecf20Sopenharmony_ci				struct inode *inode,
5078c2ecf20Sopenharmony_ci				dev_t dev,
5088c2ecf20Sopenharmony_ci				struct buffer_head **new_fe_bh,
5098c2ecf20Sopenharmony_ci				struct buffer_head *parent_fe_bh,
5108c2ecf20Sopenharmony_ci				handle_t *handle,
5118c2ecf20Sopenharmony_ci				struct ocfs2_alloc_context *inode_ac,
5128c2ecf20Sopenharmony_ci				u64 fe_blkno, u64 suballoc_loc, u16 suballoc_bit)
5138c2ecf20Sopenharmony_ci{
5148c2ecf20Sopenharmony_ci	int status = 0;
5158c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
5168c2ecf20Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
5178c2ecf20Sopenharmony_ci	struct ocfs2_extent_list *fel;
5188c2ecf20Sopenharmony_ci	u16 feat;
5198c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi = OCFS2_I(inode);
5208c2ecf20Sopenharmony_ci	struct timespec64 ts;
5218c2ecf20Sopenharmony_ci
5228c2ecf20Sopenharmony_ci	*new_fe_bh = NULL;
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci	/* populate as many fields early on as possible - many of
5258c2ecf20Sopenharmony_ci	 * these are used by the support functions here and in
5268c2ecf20Sopenharmony_ci	 * callers. */
5278c2ecf20Sopenharmony_ci	inode->i_ino = ino_from_blkno(osb->sb, fe_blkno);
5288c2ecf20Sopenharmony_ci	oi->ip_blkno = fe_blkno;
5298c2ecf20Sopenharmony_ci	spin_lock(&osb->osb_lock);
5308c2ecf20Sopenharmony_ci	inode->i_generation = osb->s_next_generation++;
5318c2ecf20Sopenharmony_ci	spin_unlock(&osb->osb_lock);
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	*new_fe_bh = sb_getblk(osb->sb, fe_blkno);
5348c2ecf20Sopenharmony_ci	if (!*new_fe_bh) {
5358c2ecf20Sopenharmony_ci		status = -ENOMEM;
5368c2ecf20Sopenharmony_ci		mlog_errno(status);
5378c2ecf20Sopenharmony_ci		goto leave;
5388c2ecf20Sopenharmony_ci	}
5398c2ecf20Sopenharmony_ci	ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), *new_fe_bh);
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(inode),
5428c2ecf20Sopenharmony_ci					 *new_fe_bh,
5438c2ecf20Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_CREATE);
5448c2ecf20Sopenharmony_ci	if (status < 0) {
5458c2ecf20Sopenharmony_ci		mlog_errno(status);
5468c2ecf20Sopenharmony_ci		goto leave;
5478c2ecf20Sopenharmony_ci	}
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_ci	fe = (struct ocfs2_dinode *) (*new_fe_bh)->b_data;
5508c2ecf20Sopenharmony_ci	memset(fe, 0, osb->sb->s_blocksize);
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	fe->i_generation = cpu_to_le32(inode->i_generation);
5538c2ecf20Sopenharmony_ci	fe->i_fs_generation = cpu_to_le32(osb->fs_generation);
5548c2ecf20Sopenharmony_ci	fe->i_blkno = cpu_to_le64(fe_blkno);
5558c2ecf20Sopenharmony_ci	fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
5568c2ecf20Sopenharmony_ci	fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
5578c2ecf20Sopenharmony_ci	fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
5588c2ecf20Sopenharmony_ci	fe->i_uid = cpu_to_le32(i_uid_read(inode));
5598c2ecf20Sopenharmony_ci	fe->i_gid = cpu_to_le32(i_gid_read(inode));
5608c2ecf20Sopenharmony_ci	fe->i_mode = cpu_to_le16(inode->i_mode);
5618c2ecf20Sopenharmony_ci	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
5628c2ecf20Sopenharmony_ci		fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
5638c2ecf20Sopenharmony_ci
5648c2ecf20Sopenharmony_ci	ocfs2_set_links_count(fe, inode->i_nlink);
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci	fe->i_last_eb_blk = 0;
5678c2ecf20Sopenharmony_ci	strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE);
5688c2ecf20Sopenharmony_ci	fe->i_flags |= cpu_to_le32(OCFS2_VALID_FL);
5698c2ecf20Sopenharmony_ci	ktime_get_real_ts64(&ts);
5708c2ecf20Sopenharmony_ci	fe->i_atime = fe->i_ctime = fe->i_mtime =
5718c2ecf20Sopenharmony_ci		cpu_to_le64(ts.tv_sec);
5728c2ecf20Sopenharmony_ci	fe->i_mtime_nsec = fe->i_ctime_nsec = fe->i_atime_nsec =
5738c2ecf20Sopenharmony_ci		cpu_to_le32(ts.tv_nsec);
5748c2ecf20Sopenharmony_ci	fe->i_dtime = 0;
5758c2ecf20Sopenharmony_ci
5768c2ecf20Sopenharmony_ci	/*
5778c2ecf20Sopenharmony_ci	 * If supported, directories start with inline data. If inline
5788c2ecf20Sopenharmony_ci	 * isn't supported, but indexing is, we start them as indexed.
5798c2ecf20Sopenharmony_ci	 */
5808c2ecf20Sopenharmony_ci	feat = le16_to_cpu(fe->i_dyn_features);
5818c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) {
5828c2ecf20Sopenharmony_ci		fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL);
5838c2ecf20Sopenharmony_ci
5848c2ecf20Sopenharmony_ci		fe->id2.i_data.id_count = cpu_to_le16(
5858c2ecf20Sopenharmony_ci				ocfs2_max_inline_data_with_xattr(osb->sb, fe));
5868c2ecf20Sopenharmony_ci	} else {
5878c2ecf20Sopenharmony_ci		fel = &fe->id2.i_list;
5888c2ecf20Sopenharmony_ci		fel->l_tree_depth = 0;
5898c2ecf20Sopenharmony_ci		fel->l_next_free_rec = 0;
5908c2ecf20Sopenharmony_ci		fel->l_count = cpu_to_le16(ocfs2_extent_recs_per_inode(osb->sb));
5918c2ecf20Sopenharmony_ci	}
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, *new_fe_bh);
5948c2ecf20Sopenharmony_ci
5958c2ecf20Sopenharmony_ci	ocfs2_populate_inode(inode, fe, 1);
5968c2ecf20Sopenharmony_ci	ocfs2_ci_set_new(osb, INODE_CACHE(inode));
5978c2ecf20Sopenharmony_ci	if (!ocfs2_mount_local(osb)) {
5988c2ecf20Sopenharmony_ci		status = ocfs2_create_new_inode_locks(inode);
5998c2ecf20Sopenharmony_ci		if (status < 0)
6008c2ecf20Sopenharmony_ci			mlog_errno(status);
6018c2ecf20Sopenharmony_ci	}
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci	ocfs2_update_inode_fsync_trans(handle, inode, 1);
6048c2ecf20Sopenharmony_ci
6058c2ecf20Sopenharmony_cileave:
6068c2ecf20Sopenharmony_ci	if (status < 0) {
6078c2ecf20Sopenharmony_ci		if (*new_fe_bh) {
6088c2ecf20Sopenharmony_ci			brelse(*new_fe_bh);
6098c2ecf20Sopenharmony_ci			*new_fe_bh = NULL;
6108c2ecf20Sopenharmony_ci		}
6118c2ecf20Sopenharmony_ci	}
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_ci	if (status)
6148c2ecf20Sopenharmony_ci		mlog_errno(status);
6158c2ecf20Sopenharmony_ci	return status;
6168c2ecf20Sopenharmony_ci}
6178c2ecf20Sopenharmony_ci
6188c2ecf20Sopenharmony_cistatic int ocfs2_mknod_locked(struct ocfs2_super *osb,
6198c2ecf20Sopenharmony_ci			      struct inode *dir,
6208c2ecf20Sopenharmony_ci			      struct inode *inode,
6218c2ecf20Sopenharmony_ci			      dev_t dev,
6228c2ecf20Sopenharmony_ci			      struct buffer_head **new_fe_bh,
6238c2ecf20Sopenharmony_ci			      struct buffer_head *parent_fe_bh,
6248c2ecf20Sopenharmony_ci			      handle_t *handle,
6258c2ecf20Sopenharmony_ci			      struct ocfs2_alloc_context *inode_ac)
6268c2ecf20Sopenharmony_ci{
6278c2ecf20Sopenharmony_ci	int status = 0;
6288c2ecf20Sopenharmony_ci	u64 suballoc_loc, fe_blkno = 0;
6298c2ecf20Sopenharmony_ci	u16 suballoc_bit;
6308c2ecf20Sopenharmony_ci
6318c2ecf20Sopenharmony_ci	*new_fe_bh = NULL;
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci	status = ocfs2_claim_new_inode(handle, dir, parent_fe_bh,
6348c2ecf20Sopenharmony_ci				       inode_ac, &suballoc_loc,
6358c2ecf20Sopenharmony_ci				       &suballoc_bit, &fe_blkno);
6368c2ecf20Sopenharmony_ci	if (status < 0) {
6378c2ecf20Sopenharmony_ci		mlog_errno(status);
6388c2ecf20Sopenharmony_ci		return status;
6398c2ecf20Sopenharmony_ci	}
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci	return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh,
6428c2ecf20Sopenharmony_ci				    parent_fe_bh, handle, inode_ac,
6438c2ecf20Sopenharmony_ci				    fe_blkno, suballoc_loc, suballoc_bit);
6448c2ecf20Sopenharmony_ci}
6458c2ecf20Sopenharmony_ci
6468c2ecf20Sopenharmony_cistatic int ocfs2_mkdir(struct inode *dir,
6478c2ecf20Sopenharmony_ci		       struct dentry *dentry,
6488c2ecf20Sopenharmony_ci		       umode_t mode)
6498c2ecf20Sopenharmony_ci{
6508c2ecf20Sopenharmony_ci	int ret;
6518c2ecf20Sopenharmony_ci
6528c2ecf20Sopenharmony_ci	trace_ocfs2_mkdir(dir, dentry, dentry->d_name.len, dentry->d_name.name,
6538c2ecf20Sopenharmony_ci			  OCFS2_I(dir)->ip_blkno, mode);
6548c2ecf20Sopenharmony_ci	ret = ocfs2_mknod(dir, dentry, mode | S_IFDIR, 0);
6558c2ecf20Sopenharmony_ci	if (ret)
6568c2ecf20Sopenharmony_ci		mlog_errno(ret);
6578c2ecf20Sopenharmony_ci
6588c2ecf20Sopenharmony_ci	return ret;
6598c2ecf20Sopenharmony_ci}
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_cistatic int ocfs2_create(struct inode *dir,
6628c2ecf20Sopenharmony_ci			struct dentry *dentry,
6638c2ecf20Sopenharmony_ci			umode_t mode,
6648c2ecf20Sopenharmony_ci			bool excl)
6658c2ecf20Sopenharmony_ci{
6668c2ecf20Sopenharmony_ci	int ret;
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_ci	trace_ocfs2_create(dir, dentry, dentry->d_name.len, dentry->d_name.name,
6698c2ecf20Sopenharmony_ci			   (unsigned long long)OCFS2_I(dir)->ip_blkno, mode);
6708c2ecf20Sopenharmony_ci	ret = ocfs2_mknod(dir, dentry, mode | S_IFREG, 0);
6718c2ecf20Sopenharmony_ci	if (ret)
6728c2ecf20Sopenharmony_ci		mlog_errno(ret);
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_ci	return ret;
6758c2ecf20Sopenharmony_ci}
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_cistatic int ocfs2_link(struct dentry *old_dentry,
6788c2ecf20Sopenharmony_ci		      struct inode *dir,
6798c2ecf20Sopenharmony_ci		      struct dentry *dentry)
6808c2ecf20Sopenharmony_ci{
6818c2ecf20Sopenharmony_ci	handle_t *handle;
6828c2ecf20Sopenharmony_ci	struct inode *inode = d_inode(old_dentry);
6838c2ecf20Sopenharmony_ci	struct inode *old_dir = d_inode(old_dentry->d_parent);
6848c2ecf20Sopenharmony_ci	int err;
6858c2ecf20Sopenharmony_ci	struct buffer_head *fe_bh = NULL;
6868c2ecf20Sopenharmony_ci	struct buffer_head *old_dir_bh = NULL;
6878c2ecf20Sopenharmony_ci	struct buffer_head *parent_fe_bh = NULL;
6888c2ecf20Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
6898c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
6908c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
6918c2ecf20Sopenharmony_ci	sigset_t oldset;
6928c2ecf20Sopenharmony_ci	u64 old_de_ino;
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_ci	trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno,
6958c2ecf20Sopenharmony_ci			 old_dentry->d_name.len, old_dentry->d_name.name,
6968c2ecf20Sopenharmony_ci			 dentry->d_name.len, dentry->d_name.name);
6978c2ecf20Sopenharmony_ci
6988c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
6998c2ecf20Sopenharmony_ci		return -EPERM;
7008c2ecf20Sopenharmony_ci
7018c2ecf20Sopenharmony_ci	err = dquot_initialize(dir);
7028c2ecf20Sopenharmony_ci	if (err) {
7038c2ecf20Sopenharmony_ci		mlog_errno(err);
7048c2ecf20Sopenharmony_ci		return err;
7058c2ecf20Sopenharmony_ci	}
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci	err = ocfs2_double_lock(osb, &old_dir_bh, old_dir,
7088c2ecf20Sopenharmony_ci			&parent_fe_bh, dir, 0);
7098c2ecf20Sopenharmony_ci	if (err < 0) {
7108c2ecf20Sopenharmony_ci		if (err != -ENOENT)
7118c2ecf20Sopenharmony_ci			mlog_errno(err);
7128c2ecf20Sopenharmony_ci		return err;
7138c2ecf20Sopenharmony_ci	}
7148c2ecf20Sopenharmony_ci
7158c2ecf20Sopenharmony_ci	/* make sure both dirs have bhs
7168c2ecf20Sopenharmony_ci	 * get an extra ref on old_dir_bh if old==new */
7178c2ecf20Sopenharmony_ci	if (!parent_fe_bh) {
7188c2ecf20Sopenharmony_ci		if (old_dir_bh) {
7198c2ecf20Sopenharmony_ci			parent_fe_bh = old_dir_bh;
7208c2ecf20Sopenharmony_ci			get_bh(parent_fe_bh);
7218c2ecf20Sopenharmony_ci		} else {
7228c2ecf20Sopenharmony_ci			mlog(ML_ERROR, "%s: no old_dir_bh!\n", osb->uuid_str);
7238c2ecf20Sopenharmony_ci			err = -EIO;
7248c2ecf20Sopenharmony_ci			goto out;
7258c2ecf20Sopenharmony_ci		}
7268c2ecf20Sopenharmony_ci	}
7278c2ecf20Sopenharmony_ci
7288c2ecf20Sopenharmony_ci	if (!dir->i_nlink) {
7298c2ecf20Sopenharmony_ci		err = -ENOENT;
7308c2ecf20Sopenharmony_ci		goto out;
7318c2ecf20Sopenharmony_ci	}
7328c2ecf20Sopenharmony_ci
7338c2ecf20Sopenharmony_ci	err = ocfs2_lookup_ino_from_name(old_dir, old_dentry->d_name.name,
7348c2ecf20Sopenharmony_ci			old_dentry->d_name.len, &old_de_ino);
7358c2ecf20Sopenharmony_ci	if (err) {
7368c2ecf20Sopenharmony_ci		err = -ENOENT;
7378c2ecf20Sopenharmony_ci		goto out;
7388c2ecf20Sopenharmony_ci	}
7398c2ecf20Sopenharmony_ci
7408c2ecf20Sopenharmony_ci	/*
7418c2ecf20Sopenharmony_ci	 * Check whether another node removed the source inode while we
7428c2ecf20Sopenharmony_ci	 * were in the vfs.
7438c2ecf20Sopenharmony_ci	 */
7448c2ecf20Sopenharmony_ci	if (old_de_ino != OCFS2_I(inode)->ip_blkno) {
7458c2ecf20Sopenharmony_ci		err = -ENOENT;
7468c2ecf20Sopenharmony_ci		goto out;
7478c2ecf20Sopenharmony_ci	}
7488c2ecf20Sopenharmony_ci
7498c2ecf20Sopenharmony_ci	err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
7508c2ecf20Sopenharmony_ci					dentry->d_name.len);
7518c2ecf20Sopenharmony_ci	if (err)
7528c2ecf20Sopenharmony_ci		goto out;
7538c2ecf20Sopenharmony_ci
7548c2ecf20Sopenharmony_ci	err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
7558c2ecf20Sopenharmony_ci					   dentry->d_name.name,
7568c2ecf20Sopenharmony_ci					   dentry->d_name.len, &lookup);
7578c2ecf20Sopenharmony_ci	if (err < 0) {
7588c2ecf20Sopenharmony_ci		mlog_errno(err);
7598c2ecf20Sopenharmony_ci		goto out;
7608c2ecf20Sopenharmony_ci	}
7618c2ecf20Sopenharmony_ci
7628c2ecf20Sopenharmony_ci	err = ocfs2_inode_lock(inode, &fe_bh, 1);
7638c2ecf20Sopenharmony_ci	if (err < 0) {
7648c2ecf20Sopenharmony_ci		if (err != -ENOENT)
7658c2ecf20Sopenharmony_ci			mlog_errno(err);
7668c2ecf20Sopenharmony_ci		goto out;
7678c2ecf20Sopenharmony_ci	}
7688c2ecf20Sopenharmony_ci
7698c2ecf20Sopenharmony_ci	fe = (struct ocfs2_dinode *) fe_bh->b_data;
7708c2ecf20Sopenharmony_ci	if (ocfs2_read_links_count(fe) >= ocfs2_link_max(osb)) {
7718c2ecf20Sopenharmony_ci		err = -EMLINK;
7728c2ecf20Sopenharmony_ci		goto out_unlock_inode;
7738c2ecf20Sopenharmony_ci	}
7748c2ecf20Sopenharmony_ci
7758c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_link_credits(osb->sb));
7768c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
7778c2ecf20Sopenharmony_ci		err = PTR_ERR(handle);
7788c2ecf20Sopenharmony_ci		handle = NULL;
7798c2ecf20Sopenharmony_ci		mlog_errno(err);
7808c2ecf20Sopenharmony_ci		goto out_unlock_inode;
7818c2ecf20Sopenharmony_ci	}
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ci	/* Starting to change things, restart is no longer possible. */
7848c2ecf20Sopenharmony_ci	ocfs2_block_signals(&oldset);
7858c2ecf20Sopenharmony_ci
7868c2ecf20Sopenharmony_ci	err = ocfs2_journal_access_di(handle, INODE_CACHE(inode), fe_bh,
7878c2ecf20Sopenharmony_ci				      OCFS2_JOURNAL_ACCESS_WRITE);
7888c2ecf20Sopenharmony_ci	if (err < 0) {
7898c2ecf20Sopenharmony_ci		mlog_errno(err);
7908c2ecf20Sopenharmony_ci		goto out_commit;
7918c2ecf20Sopenharmony_ci	}
7928c2ecf20Sopenharmony_ci
7938c2ecf20Sopenharmony_ci	inc_nlink(inode);
7948c2ecf20Sopenharmony_ci	inode->i_ctime = current_time(inode);
7958c2ecf20Sopenharmony_ci	ocfs2_set_links_count(fe, inode->i_nlink);
7968c2ecf20Sopenharmony_ci	fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
7978c2ecf20Sopenharmony_ci	fe->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
7988c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, fe_bh);
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci	err = ocfs2_add_entry(handle, dentry, inode,
8018c2ecf20Sopenharmony_ci			      OCFS2_I(inode)->ip_blkno,
8028c2ecf20Sopenharmony_ci			      parent_fe_bh, &lookup);
8038c2ecf20Sopenharmony_ci	if (err) {
8048c2ecf20Sopenharmony_ci		ocfs2_add_links_count(fe, -1);
8058c2ecf20Sopenharmony_ci		drop_nlink(inode);
8068c2ecf20Sopenharmony_ci		mlog_errno(err);
8078c2ecf20Sopenharmony_ci		goto out_commit;
8088c2ecf20Sopenharmony_ci	}
8098c2ecf20Sopenharmony_ci
8108c2ecf20Sopenharmony_ci	err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
8118c2ecf20Sopenharmony_ci	if (err) {
8128c2ecf20Sopenharmony_ci		mlog_errno(err);
8138c2ecf20Sopenharmony_ci		goto out_commit;
8148c2ecf20Sopenharmony_ci	}
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci	ihold(inode);
8178c2ecf20Sopenharmony_ci	d_instantiate(dentry, inode);
8188c2ecf20Sopenharmony_ci
8198c2ecf20Sopenharmony_ciout_commit:
8208c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
8218c2ecf20Sopenharmony_ci	ocfs2_unblock_signals(&oldset);
8228c2ecf20Sopenharmony_ciout_unlock_inode:
8238c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(inode, 1);
8248c2ecf20Sopenharmony_ci
8258c2ecf20Sopenharmony_ciout:
8268c2ecf20Sopenharmony_ci	ocfs2_double_unlock(old_dir, dir);
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci	brelse(fe_bh);
8298c2ecf20Sopenharmony_ci	brelse(parent_fe_bh);
8308c2ecf20Sopenharmony_ci	brelse(old_dir_bh);
8318c2ecf20Sopenharmony_ci
8328c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
8338c2ecf20Sopenharmony_ci
8348c2ecf20Sopenharmony_ci	if (err)
8358c2ecf20Sopenharmony_ci		mlog_errno(err);
8368c2ecf20Sopenharmony_ci
8378c2ecf20Sopenharmony_ci	return err;
8388c2ecf20Sopenharmony_ci}
8398c2ecf20Sopenharmony_ci
8408c2ecf20Sopenharmony_ci/*
8418c2ecf20Sopenharmony_ci * Takes and drops an exclusive lock on the given dentry. This will
8428c2ecf20Sopenharmony_ci * force other nodes to drop it.
8438c2ecf20Sopenharmony_ci */
8448c2ecf20Sopenharmony_cistatic int ocfs2_remote_dentry_delete(struct dentry *dentry)
8458c2ecf20Sopenharmony_ci{
8468c2ecf20Sopenharmony_ci	int ret;
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_ci	ret = ocfs2_dentry_lock(dentry, 1);
8498c2ecf20Sopenharmony_ci	if (ret)
8508c2ecf20Sopenharmony_ci		mlog_errno(ret);
8518c2ecf20Sopenharmony_ci	else
8528c2ecf20Sopenharmony_ci		ocfs2_dentry_unlock(dentry, 1);
8538c2ecf20Sopenharmony_ci
8548c2ecf20Sopenharmony_ci	return ret;
8558c2ecf20Sopenharmony_ci}
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_cistatic inline int ocfs2_inode_is_unlinkable(struct inode *inode)
8588c2ecf20Sopenharmony_ci{
8598c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode)) {
8608c2ecf20Sopenharmony_ci		if (inode->i_nlink == 2)
8618c2ecf20Sopenharmony_ci			return 1;
8628c2ecf20Sopenharmony_ci		return 0;
8638c2ecf20Sopenharmony_ci	}
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	if (inode->i_nlink == 1)
8668c2ecf20Sopenharmony_ci		return 1;
8678c2ecf20Sopenharmony_ci	return 0;
8688c2ecf20Sopenharmony_ci}
8698c2ecf20Sopenharmony_ci
8708c2ecf20Sopenharmony_cistatic int ocfs2_unlink(struct inode *dir,
8718c2ecf20Sopenharmony_ci			struct dentry *dentry)
8728c2ecf20Sopenharmony_ci{
8738c2ecf20Sopenharmony_ci	int status;
8748c2ecf20Sopenharmony_ci	int child_locked = 0;
8758c2ecf20Sopenharmony_ci	bool is_unlinkable = false;
8768c2ecf20Sopenharmony_ci	struct inode *inode = d_inode(dentry);
8778c2ecf20Sopenharmony_ci	struct inode *orphan_dir = NULL;
8788c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
8798c2ecf20Sopenharmony_ci	u64 blkno;
8808c2ecf20Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
8818c2ecf20Sopenharmony_ci	struct buffer_head *fe_bh = NULL;
8828c2ecf20Sopenharmony_ci	struct buffer_head *parent_node_bh = NULL;
8838c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
8848c2ecf20Sopenharmony_ci	char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
8858c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
8868c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
8878c2ecf20Sopenharmony_ci
8888c2ecf20Sopenharmony_ci	trace_ocfs2_unlink(dir, dentry, dentry->d_name.len,
8898c2ecf20Sopenharmony_ci			   dentry->d_name.name,
8908c2ecf20Sopenharmony_ci			   (unsigned long long)OCFS2_I(dir)->ip_blkno,
8918c2ecf20Sopenharmony_ci			   (unsigned long long)OCFS2_I(inode)->ip_blkno);
8928c2ecf20Sopenharmony_ci
8938c2ecf20Sopenharmony_ci	status = dquot_initialize(dir);
8948c2ecf20Sopenharmony_ci	if (status) {
8958c2ecf20Sopenharmony_ci		mlog_errno(status);
8968c2ecf20Sopenharmony_ci		return status;
8978c2ecf20Sopenharmony_ci	}
8988c2ecf20Sopenharmony_ci
8998c2ecf20Sopenharmony_ci	BUG_ON(d_inode(dentry->d_parent) != dir);
9008c2ecf20Sopenharmony_ci
9018c2ecf20Sopenharmony_ci	if (inode == osb->root_inode)
9028c2ecf20Sopenharmony_ci		return -EPERM;
9038c2ecf20Sopenharmony_ci
9048c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock_nested(dir, &parent_node_bh, 1,
9058c2ecf20Sopenharmony_ci					 OI_LS_PARENT);
9068c2ecf20Sopenharmony_ci	if (status < 0) {
9078c2ecf20Sopenharmony_ci		if (status != -ENOENT)
9088c2ecf20Sopenharmony_ci			mlog_errno(status);
9098c2ecf20Sopenharmony_ci		return status;
9108c2ecf20Sopenharmony_ci	}
9118c2ecf20Sopenharmony_ci
9128c2ecf20Sopenharmony_ci	status = ocfs2_find_files_on_disk(dentry->d_name.name,
9138c2ecf20Sopenharmony_ci					  dentry->d_name.len, &blkno, dir,
9148c2ecf20Sopenharmony_ci					  &lookup);
9158c2ecf20Sopenharmony_ci	if (status < 0) {
9168c2ecf20Sopenharmony_ci		if (status != -ENOENT)
9178c2ecf20Sopenharmony_ci			mlog_errno(status);
9188c2ecf20Sopenharmony_ci		goto leave;
9198c2ecf20Sopenharmony_ci	}
9208c2ecf20Sopenharmony_ci
9218c2ecf20Sopenharmony_ci	if (OCFS2_I(inode)->ip_blkno != blkno) {
9228c2ecf20Sopenharmony_ci		status = -ENOENT;
9238c2ecf20Sopenharmony_ci
9248c2ecf20Sopenharmony_ci		trace_ocfs2_unlink_noent(
9258c2ecf20Sopenharmony_ci				(unsigned long long)OCFS2_I(inode)->ip_blkno,
9268c2ecf20Sopenharmony_ci				(unsigned long long)blkno,
9278c2ecf20Sopenharmony_ci				OCFS2_I(inode)->ip_flags);
9288c2ecf20Sopenharmony_ci		goto leave;
9298c2ecf20Sopenharmony_ci	}
9308c2ecf20Sopenharmony_ci
9318c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock(inode, &fe_bh, 1);
9328c2ecf20Sopenharmony_ci	if (status < 0) {
9338c2ecf20Sopenharmony_ci		if (status != -ENOENT)
9348c2ecf20Sopenharmony_ci			mlog_errno(status);
9358c2ecf20Sopenharmony_ci		goto leave;
9368c2ecf20Sopenharmony_ci	}
9378c2ecf20Sopenharmony_ci	child_locked = 1;
9388c2ecf20Sopenharmony_ci
9398c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode)) {
9408c2ecf20Sopenharmony_ci		if (inode->i_nlink != 2 || !ocfs2_empty_dir(inode)) {
9418c2ecf20Sopenharmony_ci			status = -ENOTEMPTY;
9428c2ecf20Sopenharmony_ci			goto leave;
9438c2ecf20Sopenharmony_ci		}
9448c2ecf20Sopenharmony_ci	}
9458c2ecf20Sopenharmony_ci
9468c2ecf20Sopenharmony_ci	status = ocfs2_remote_dentry_delete(dentry);
9478c2ecf20Sopenharmony_ci	if (status < 0) {
9488c2ecf20Sopenharmony_ci		/* This remote delete should succeed under all normal
9498c2ecf20Sopenharmony_ci		 * circumstances. */
9508c2ecf20Sopenharmony_ci		mlog_errno(status);
9518c2ecf20Sopenharmony_ci		goto leave;
9528c2ecf20Sopenharmony_ci	}
9538c2ecf20Sopenharmony_ci
9548c2ecf20Sopenharmony_ci	if (ocfs2_inode_is_unlinkable(inode)) {
9558c2ecf20Sopenharmony_ci		status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
9568c2ecf20Sopenharmony_ci						  OCFS2_I(inode)->ip_blkno,
9578c2ecf20Sopenharmony_ci						  orphan_name, &orphan_insert,
9588c2ecf20Sopenharmony_ci						  false);
9598c2ecf20Sopenharmony_ci		if (status < 0) {
9608c2ecf20Sopenharmony_ci			mlog_errno(status);
9618c2ecf20Sopenharmony_ci			goto leave;
9628c2ecf20Sopenharmony_ci		}
9638c2ecf20Sopenharmony_ci		is_unlinkable = true;
9648c2ecf20Sopenharmony_ci	}
9658c2ecf20Sopenharmony_ci
9668c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_unlink_credits(osb->sb));
9678c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
9688c2ecf20Sopenharmony_ci		status = PTR_ERR(handle);
9698c2ecf20Sopenharmony_ci		handle = NULL;
9708c2ecf20Sopenharmony_ci		mlog_errno(status);
9718c2ecf20Sopenharmony_ci		goto leave;
9728c2ecf20Sopenharmony_ci	}
9738c2ecf20Sopenharmony_ci
9748c2ecf20Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(inode), fe_bh,
9758c2ecf20Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
9768c2ecf20Sopenharmony_ci	if (status < 0) {
9778c2ecf20Sopenharmony_ci		mlog_errno(status);
9788c2ecf20Sopenharmony_ci		goto leave;
9798c2ecf20Sopenharmony_ci	}
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci	fe = (struct ocfs2_dinode *) fe_bh->b_data;
9828c2ecf20Sopenharmony_ci
9838c2ecf20Sopenharmony_ci	/* delete the name from the parent dir */
9848c2ecf20Sopenharmony_ci	status = ocfs2_delete_entry(handle, dir, &lookup);
9858c2ecf20Sopenharmony_ci	if (status < 0) {
9868c2ecf20Sopenharmony_ci		mlog_errno(status);
9878c2ecf20Sopenharmony_ci		goto leave;
9888c2ecf20Sopenharmony_ci	}
9898c2ecf20Sopenharmony_ci
9908c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
9918c2ecf20Sopenharmony_ci		drop_nlink(inode);
9928c2ecf20Sopenharmony_ci	drop_nlink(inode);
9938c2ecf20Sopenharmony_ci	ocfs2_set_links_count(fe, inode->i_nlink);
9948c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, fe_bh);
9958c2ecf20Sopenharmony_ci
9968c2ecf20Sopenharmony_ci	dir->i_ctime = dir->i_mtime = current_time(dir);
9978c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
9988c2ecf20Sopenharmony_ci		drop_nlink(dir);
9998c2ecf20Sopenharmony_ci
10008c2ecf20Sopenharmony_ci	status = ocfs2_mark_inode_dirty(handle, dir, parent_node_bh);
10018c2ecf20Sopenharmony_ci	if (status < 0) {
10028c2ecf20Sopenharmony_ci		mlog_errno(status);
10038c2ecf20Sopenharmony_ci		if (S_ISDIR(inode->i_mode))
10048c2ecf20Sopenharmony_ci			inc_nlink(dir);
10058c2ecf20Sopenharmony_ci		goto leave;
10068c2ecf20Sopenharmony_ci	}
10078c2ecf20Sopenharmony_ci
10088c2ecf20Sopenharmony_ci	if (is_unlinkable) {
10098c2ecf20Sopenharmony_ci		status = ocfs2_orphan_add(osb, handle, inode, fe_bh,
10108c2ecf20Sopenharmony_ci				orphan_name, &orphan_insert, orphan_dir, false);
10118c2ecf20Sopenharmony_ci		if (status < 0)
10128c2ecf20Sopenharmony_ci			mlog_errno(status);
10138c2ecf20Sopenharmony_ci	}
10148c2ecf20Sopenharmony_ci
10158c2ecf20Sopenharmony_cileave:
10168c2ecf20Sopenharmony_ci	if (handle)
10178c2ecf20Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
10188c2ecf20Sopenharmony_ci
10198c2ecf20Sopenharmony_ci	if (orphan_dir) {
10208c2ecf20Sopenharmony_ci		/* This was locked for us in ocfs2_prepare_orphan_dir() */
10218c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir, 1);
10228c2ecf20Sopenharmony_ci		inode_unlock(orphan_dir);
10238c2ecf20Sopenharmony_ci		iput(orphan_dir);
10248c2ecf20Sopenharmony_ci	}
10258c2ecf20Sopenharmony_ci
10268c2ecf20Sopenharmony_ci	if (child_locked)
10278c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(inode, 1);
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
10308c2ecf20Sopenharmony_ci
10318c2ecf20Sopenharmony_ci	brelse(fe_bh);
10328c2ecf20Sopenharmony_ci	brelse(parent_node_bh);
10338c2ecf20Sopenharmony_ci
10348c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&orphan_insert);
10358c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
10368c2ecf20Sopenharmony_ci
10378c2ecf20Sopenharmony_ci	if (status && (status != -ENOTEMPTY) && (status != -ENOENT))
10388c2ecf20Sopenharmony_ci		mlog_errno(status);
10398c2ecf20Sopenharmony_ci
10408c2ecf20Sopenharmony_ci	return status;
10418c2ecf20Sopenharmony_ci}
10428c2ecf20Sopenharmony_ci
10438c2ecf20Sopenharmony_cistatic int ocfs2_check_if_ancestor(struct ocfs2_super *osb,
10448c2ecf20Sopenharmony_ci		u64 src_inode_no, u64 dest_inode_no)
10458c2ecf20Sopenharmony_ci{
10468c2ecf20Sopenharmony_ci	int ret = 0, i = 0;
10478c2ecf20Sopenharmony_ci	u64 parent_inode_no = 0;
10488c2ecf20Sopenharmony_ci	u64 child_inode_no = src_inode_no;
10498c2ecf20Sopenharmony_ci	struct inode *child_inode;
10508c2ecf20Sopenharmony_ci
10518c2ecf20Sopenharmony_ci#define MAX_LOOKUP_TIMES 32
10528c2ecf20Sopenharmony_ci	while (1) {
10538c2ecf20Sopenharmony_ci		child_inode = ocfs2_iget(osb, child_inode_no, 0, 0);
10548c2ecf20Sopenharmony_ci		if (IS_ERR(child_inode)) {
10558c2ecf20Sopenharmony_ci			ret = PTR_ERR(child_inode);
10568c2ecf20Sopenharmony_ci			break;
10578c2ecf20Sopenharmony_ci		}
10588c2ecf20Sopenharmony_ci
10598c2ecf20Sopenharmony_ci		ret = ocfs2_inode_lock(child_inode, NULL, 0);
10608c2ecf20Sopenharmony_ci		if (ret < 0) {
10618c2ecf20Sopenharmony_ci			iput(child_inode);
10628c2ecf20Sopenharmony_ci			if (ret != -ENOENT)
10638c2ecf20Sopenharmony_ci				mlog_errno(ret);
10648c2ecf20Sopenharmony_ci			break;
10658c2ecf20Sopenharmony_ci		}
10668c2ecf20Sopenharmony_ci
10678c2ecf20Sopenharmony_ci		ret = ocfs2_lookup_ino_from_name(child_inode, "..", 2,
10688c2ecf20Sopenharmony_ci				&parent_inode_no);
10698c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(child_inode, 0);
10708c2ecf20Sopenharmony_ci		iput(child_inode);
10718c2ecf20Sopenharmony_ci		if (ret < 0) {
10728c2ecf20Sopenharmony_ci			ret = -ENOENT;
10738c2ecf20Sopenharmony_ci			break;
10748c2ecf20Sopenharmony_ci		}
10758c2ecf20Sopenharmony_ci
10768c2ecf20Sopenharmony_ci		if (parent_inode_no == dest_inode_no) {
10778c2ecf20Sopenharmony_ci			ret = 1;
10788c2ecf20Sopenharmony_ci			break;
10798c2ecf20Sopenharmony_ci		}
10808c2ecf20Sopenharmony_ci
10818c2ecf20Sopenharmony_ci		if (parent_inode_no == osb->root_inode->i_ino) {
10828c2ecf20Sopenharmony_ci			ret = 0;
10838c2ecf20Sopenharmony_ci			break;
10848c2ecf20Sopenharmony_ci		}
10858c2ecf20Sopenharmony_ci
10868c2ecf20Sopenharmony_ci		child_inode_no = parent_inode_no;
10878c2ecf20Sopenharmony_ci
10888c2ecf20Sopenharmony_ci		if (++i >= MAX_LOOKUP_TIMES) {
10898c2ecf20Sopenharmony_ci			mlog(ML_NOTICE, "max lookup times reached, filesystem "
10908c2ecf20Sopenharmony_ci					"may have nested directories, "
10918c2ecf20Sopenharmony_ci					"src inode: %llu, dest inode: %llu.\n",
10928c2ecf20Sopenharmony_ci					(unsigned long long)src_inode_no,
10938c2ecf20Sopenharmony_ci					(unsigned long long)dest_inode_no);
10948c2ecf20Sopenharmony_ci			ret = 0;
10958c2ecf20Sopenharmony_ci			break;
10968c2ecf20Sopenharmony_ci		}
10978c2ecf20Sopenharmony_ci	}
10988c2ecf20Sopenharmony_ci
10998c2ecf20Sopenharmony_ci	return ret;
11008c2ecf20Sopenharmony_ci}
11018c2ecf20Sopenharmony_ci
11028c2ecf20Sopenharmony_ci/*
11038c2ecf20Sopenharmony_ci * The only place this should be used is rename and link!
11048c2ecf20Sopenharmony_ci * if they have the same id, then the 1st one is the only one locked.
11058c2ecf20Sopenharmony_ci */
11068c2ecf20Sopenharmony_cistatic int ocfs2_double_lock(struct ocfs2_super *osb,
11078c2ecf20Sopenharmony_ci			     struct buffer_head **bh1,
11088c2ecf20Sopenharmony_ci			     struct inode *inode1,
11098c2ecf20Sopenharmony_ci			     struct buffer_head **bh2,
11108c2ecf20Sopenharmony_ci			     struct inode *inode2,
11118c2ecf20Sopenharmony_ci			     int rename)
11128c2ecf20Sopenharmony_ci{
11138c2ecf20Sopenharmony_ci	int status;
11148c2ecf20Sopenharmony_ci	int inode1_is_ancestor, inode2_is_ancestor;
11158c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi1 = OCFS2_I(inode1);
11168c2ecf20Sopenharmony_ci	struct ocfs2_inode_info *oi2 = OCFS2_I(inode2);
11178c2ecf20Sopenharmony_ci
11188c2ecf20Sopenharmony_ci	trace_ocfs2_double_lock((unsigned long long)oi1->ip_blkno,
11198c2ecf20Sopenharmony_ci				(unsigned long long)oi2->ip_blkno);
11208c2ecf20Sopenharmony_ci
11218c2ecf20Sopenharmony_ci	if (*bh1)
11228c2ecf20Sopenharmony_ci		*bh1 = NULL;
11238c2ecf20Sopenharmony_ci	if (*bh2)
11248c2ecf20Sopenharmony_ci		*bh2 = NULL;
11258c2ecf20Sopenharmony_ci
11268c2ecf20Sopenharmony_ci	/* we always want to lock the one with the lower lockid first.
11278c2ecf20Sopenharmony_ci	 * and if they are nested, we lock ancestor first */
11288c2ecf20Sopenharmony_ci	if (oi1->ip_blkno != oi2->ip_blkno) {
11298c2ecf20Sopenharmony_ci		inode1_is_ancestor = ocfs2_check_if_ancestor(osb, oi2->ip_blkno,
11308c2ecf20Sopenharmony_ci				oi1->ip_blkno);
11318c2ecf20Sopenharmony_ci		if (inode1_is_ancestor < 0) {
11328c2ecf20Sopenharmony_ci			status = inode1_is_ancestor;
11338c2ecf20Sopenharmony_ci			goto bail;
11348c2ecf20Sopenharmony_ci		}
11358c2ecf20Sopenharmony_ci
11368c2ecf20Sopenharmony_ci		inode2_is_ancestor = ocfs2_check_if_ancestor(osb, oi1->ip_blkno,
11378c2ecf20Sopenharmony_ci				oi2->ip_blkno);
11388c2ecf20Sopenharmony_ci		if (inode2_is_ancestor < 0) {
11398c2ecf20Sopenharmony_ci			status = inode2_is_ancestor;
11408c2ecf20Sopenharmony_ci			goto bail;
11418c2ecf20Sopenharmony_ci		}
11428c2ecf20Sopenharmony_ci
11438c2ecf20Sopenharmony_ci		if ((inode1_is_ancestor == 1) ||
11448c2ecf20Sopenharmony_ci				(oi1->ip_blkno < oi2->ip_blkno &&
11458c2ecf20Sopenharmony_ci				inode2_is_ancestor == 0)) {
11468c2ecf20Sopenharmony_ci			/* switch id1 and id2 around */
11478c2ecf20Sopenharmony_ci			swap(bh2, bh1);
11488c2ecf20Sopenharmony_ci			swap(inode2, inode1);
11498c2ecf20Sopenharmony_ci		}
11508c2ecf20Sopenharmony_ci		/* lock id2 */
11518c2ecf20Sopenharmony_ci		status = ocfs2_inode_lock_nested(inode2, bh2, 1,
11528c2ecf20Sopenharmony_ci				rename == 1 ? OI_LS_RENAME1 : OI_LS_PARENT);
11538c2ecf20Sopenharmony_ci		if (status < 0) {
11548c2ecf20Sopenharmony_ci			if (status != -ENOENT)
11558c2ecf20Sopenharmony_ci				mlog_errno(status);
11568c2ecf20Sopenharmony_ci			goto bail;
11578c2ecf20Sopenharmony_ci		}
11588c2ecf20Sopenharmony_ci	}
11598c2ecf20Sopenharmony_ci
11608c2ecf20Sopenharmony_ci	/* lock id1 */
11618c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock_nested(inode1, bh1, 1,
11628c2ecf20Sopenharmony_ci			rename == 1 ?  OI_LS_RENAME2 : OI_LS_PARENT);
11638c2ecf20Sopenharmony_ci	if (status < 0) {
11648c2ecf20Sopenharmony_ci		/*
11658c2ecf20Sopenharmony_ci		 * An error return must mean that no cluster locks
11668c2ecf20Sopenharmony_ci		 * were held on function exit.
11678c2ecf20Sopenharmony_ci		 */
11688c2ecf20Sopenharmony_ci		if (oi1->ip_blkno != oi2->ip_blkno) {
11698c2ecf20Sopenharmony_ci			ocfs2_inode_unlock(inode2, 1);
11708c2ecf20Sopenharmony_ci			brelse(*bh2);
11718c2ecf20Sopenharmony_ci			*bh2 = NULL;
11728c2ecf20Sopenharmony_ci		}
11738c2ecf20Sopenharmony_ci
11748c2ecf20Sopenharmony_ci		if (status != -ENOENT)
11758c2ecf20Sopenharmony_ci			mlog_errno(status);
11768c2ecf20Sopenharmony_ci	}
11778c2ecf20Sopenharmony_ci
11788c2ecf20Sopenharmony_ci	trace_ocfs2_double_lock_end(
11798c2ecf20Sopenharmony_ci			(unsigned long long)oi1->ip_blkno,
11808c2ecf20Sopenharmony_ci			(unsigned long long)oi2->ip_blkno);
11818c2ecf20Sopenharmony_ci
11828c2ecf20Sopenharmony_cibail:
11838c2ecf20Sopenharmony_ci	if (status)
11848c2ecf20Sopenharmony_ci		mlog_errno(status);
11858c2ecf20Sopenharmony_ci	return status;
11868c2ecf20Sopenharmony_ci}
11878c2ecf20Sopenharmony_ci
11888c2ecf20Sopenharmony_cistatic void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2)
11898c2ecf20Sopenharmony_ci{
11908c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(inode1, 1);
11918c2ecf20Sopenharmony_ci
11928c2ecf20Sopenharmony_ci	if (inode1 != inode2)
11938c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(inode2, 1);
11948c2ecf20Sopenharmony_ci}
11958c2ecf20Sopenharmony_ci
11968c2ecf20Sopenharmony_cistatic int ocfs2_rename(struct inode *old_dir,
11978c2ecf20Sopenharmony_ci			struct dentry *old_dentry,
11988c2ecf20Sopenharmony_ci			struct inode *new_dir,
11998c2ecf20Sopenharmony_ci			struct dentry *new_dentry,
12008c2ecf20Sopenharmony_ci			unsigned int flags)
12018c2ecf20Sopenharmony_ci{
12028c2ecf20Sopenharmony_ci	int status = 0, rename_lock = 0, parents_locked = 0, target_exists = 0;
12038c2ecf20Sopenharmony_ci	int old_child_locked = 0, new_child_locked = 0, update_dot_dot = 0;
12048c2ecf20Sopenharmony_ci	struct inode *old_inode = d_inode(old_dentry);
12058c2ecf20Sopenharmony_ci	struct inode *new_inode = d_inode(new_dentry);
12068c2ecf20Sopenharmony_ci	struct inode *orphan_dir = NULL;
12078c2ecf20Sopenharmony_ci	struct ocfs2_dinode *newfe = NULL;
12088c2ecf20Sopenharmony_ci	char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
12098c2ecf20Sopenharmony_ci	struct buffer_head *newfe_bh = NULL;
12108c2ecf20Sopenharmony_ci	struct buffer_head *old_inode_bh = NULL;
12118c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = NULL;
12128c2ecf20Sopenharmony_ci	u64 newfe_blkno, old_de_ino;
12138c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
12148c2ecf20Sopenharmony_ci	struct buffer_head *old_dir_bh = NULL;
12158c2ecf20Sopenharmony_ci	struct buffer_head *new_dir_bh = NULL;
12168c2ecf20Sopenharmony_ci	u32 old_dir_nlink = old_dir->i_nlink;
12178c2ecf20Sopenharmony_ci	struct ocfs2_dinode *old_di;
12188c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result old_inode_dot_dot_res = { NULL, };
12198c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result target_lookup_res = { NULL, };
12208c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result old_entry_lookup = { NULL, };
12218c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
12228c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result target_insert = { NULL, };
12238c2ecf20Sopenharmony_ci	bool should_add_orphan = false;
12248c2ecf20Sopenharmony_ci
12258c2ecf20Sopenharmony_ci	if (flags)
12268c2ecf20Sopenharmony_ci		return -EINVAL;
12278c2ecf20Sopenharmony_ci
12288c2ecf20Sopenharmony_ci	/* At some point it might be nice to break this function up a
12298c2ecf20Sopenharmony_ci	 * bit. */
12308c2ecf20Sopenharmony_ci
12318c2ecf20Sopenharmony_ci	trace_ocfs2_rename(old_dir, old_dentry, new_dir, new_dentry,
12328c2ecf20Sopenharmony_ci			   old_dentry->d_name.len, old_dentry->d_name.name,
12338c2ecf20Sopenharmony_ci			   new_dentry->d_name.len, new_dentry->d_name.name);
12348c2ecf20Sopenharmony_ci
12358c2ecf20Sopenharmony_ci	status = dquot_initialize(old_dir);
12368c2ecf20Sopenharmony_ci	if (status) {
12378c2ecf20Sopenharmony_ci		mlog_errno(status);
12388c2ecf20Sopenharmony_ci		goto bail;
12398c2ecf20Sopenharmony_ci	}
12408c2ecf20Sopenharmony_ci	status = dquot_initialize(new_dir);
12418c2ecf20Sopenharmony_ci	if (status) {
12428c2ecf20Sopenharmony_ci		mlog_errno(status);
12438c2ecf20Sopenharmony_ci		goto bail;
12448c2ecf20Sopenharmony_ci	}
12458c2ecf20Sopenharmony_ci
12468c2ecf20Sopenharmony_ci	osb = OCFS2_SB(old_dir->i_sb);
12478c2ecf20Sopenharmony_ci
12488c2ecf20Sopenharmony_ci	if (new_inode) {
12498c2ecf20Sopenharmony_ci		if (!igrab(new_inode))
12508c2ecf20Sopenharmony_ci			BUG();
12518c2ecf20Sopenharmony_ci	}
12528c2ecf20Sopenharmony_ci
12538c2ecf20Sopenharmony_ci	/* Assume a directory hierarchy thusly:
12548c2ecf20Sopenharmony_ci	 * a/b/c
12558c2ecf20Sopenharmony_ci	 * a/d
12568c2ecf20Sopenharmony_ci	 * a,b,c, and d are all directories.
12578c2ecf20Sopenharmony_ci	 *
12588c2ecf20Sopenharmony_ci	 * from cwd of 'a' on both nodes:
12598c2ecf20Sopenharmony_ci	 * node1: mv b/c d
12608c2ecf20Sopenharmony_ci	 * node2: mv d   b/c
12618c2ecf20Sopenharmony_ci	 *
12628c2ecf20Sopenharmony_ci	 * And that's why, just like the VFS, we need a file system
12638c2ecf20Sopenharmony_ci	 * rename lock. */
12648c2ecf20Sopenharmony_ci	if (old_dir != new_dir && S_ISDIR(old_inode->i_mode)) {
12658c2ecf20Sopenharmony_ci		status = ocfs2_rename_lock(osb);
12668c2ecf20Sopenharmony_ci		if (status < 0) {
12678c2ecf20Sopenharmony_ci			mlog_errno(status);
12688c2ecf20Sopenharmony_ci			goto bail;
12698c2ecf20Sopenharmony_ci		}
12708c2ecf20Sopenharmony_ci		rename_lock = 1;
12718c2ecf20Sopenharmony_ci
12728c2ecf20Sopenharmony_ci		/* here we cannot guarantee the inodes haven't just been
12738c2ecf20Sopenharmony_ci		 * changed, so check if they are nested again */
12748c2ecf20Sopenharmony_ci		status = ocfs2_check_if_ancestor(osb, new_dir->i_ino,
12758c2ecf20Sopenharmony_ci				old_inode->i_ino);
12768c2ecf20Sopenharmony_ci		if (status < 0) {
12778c2ecf20Sopenharmony_ci			mlog_errno(status);
12788c2ecf20Sopenharmony_ci			goto bail;
12798c2ecf20Sopenharmony_ci		} else if (status == 1) {
12808c2ecf20Sopenharmony_ci			status = -EPERM;
12818c2ecf20Sopenharmony_ci			trace_ocfs2_rename_not_permitted(
12828c2ecf20Sopenharmony_ci					(unsigned long long)old_inode->i_ino,
12838c2ecf20Sopenharmony_ci					(unsigned long long)new_dir->i_ino);
12848c2ecf20Sopenharmony_ci			goto bail;
12858c2ecf20Sopenharmony_ci		}
12868c2ecf20Sopenharmony_ci	}
12878c2ecf20Sopenharmony_ci
12888c2ecf20Sopenharmony_ci	/* if old and new are the same, this'll just do one lock. */
12898c2ecf20Sopenharmony_ci	status = ocfs2_double_lock(osb, &old_dir_bh, old_dir,
12908c2ecf20Sopenharmony_ci				   &new_dir_bh, new_dir, 1);
12918c2ecf20Sopenharmony_ci	if (status < 0) {
12928c2ecf20Sopenharmony_ci		mlog_errno(status);
12938c2ecf20Sopenharmony_ci		goto bail;
12948c2ecf20Sopenharmony_ci	}
12958c2ecf20Sopenharmony_ci	parents_locked = 1;
12968c2ecf20Sopenharmony_ci
12978c2ecf20Sopenharmony_ci	if (!new_dir->i_nlink) {
12988c2ecf20Sopenharmony_ci		status = -EACCES;
12998c2ecf20Sopenharmony_ci		goto bail;
13008c2ecf20Sopenharmony_ci	}
13018c2ecf20Sopenharmony_ci
13028c2ecf20Sopenharmony_ci	/* make sure both dirs have bhs
13038c2ecf20Sopenharmony_ci	 * get an extra ref on old_dir_bh if old==new */
13048c2ecf20Sopenharmony_ci	if (!new_dir_bh) {
13058c2ecf20Sopenharmony_ci		if (old_dir_bh) {
13068c2ecf20Sopenharmony_ci			new_dir_bh = old_dir_bh;
13078c2ecf20Sopenharmony_ci			get_bh(new_dir_bh);
13088c2ecf20Sopenharmony_ci		} else {
13098c2ecf20Sopenharmony_ci			mlog(ML_ERROR, "no old_dir_bh!\n");
13108c2ecf20Sopenharmony_ci			status = -EIO;
13118c2ecf20Sopenharmony_ci			goto bail;
13128c2ecf20Sopenharmony_ci		}
13138c2ecf20Sopenharmony_ci	}
13148c2ecf20Sopenharmony_ci
13158c2ecf20Sopenharmony_ci	/*
13168c2ecf20Sopenharmony_ci	 * Aside from allowing a meta data update, the locking here
13178c2ecf20Sopenharmony_ci	 * also ensures that the downconvert thread on other nodes
13188c2ecf20Sopenharmony_ci	 * won't have to concurrently downconvert the inode and the
13198c2ecf20Sopenharmony_ci	 * dentry locks.
13208c2ecf20Sopenharmony_ci	 */
13218c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock_nested(old_inode, &old_inode_bh, 1,
13228c2ecf20Sopenharmony_ci					 OI_LS_PARENT);
13238c2ecf20Sopenharmony_ci	if (status < 0) {
13248c2ecf20Sopenharmony_ci		if (status != -ENOENT)
13258c2ecf20Sopenharmony_ci			mlog_errno(status);
13268c2ecf20Sopenharmony_ci		goto bail;
13278c2ecf20Sopenharmony_ci	}
13288c2ecf20Sopenharmony_ci	old_child_locked = 1;
13298c2ecf20Sopenharmony_ci
13308c2ecf20Sopenharmony_ci	status = ocfs2_remote_dentry_delete(old_dentry);
13318c2ecf20Sopenharmony_ci	if (status < 0) {
13328c2ecf20Sopenharmony_ci		mlog_errno(status);
13338c2ecf20Sopenharmony_ci		goto bail;
13348c2ecf20Sopenharmony_ci	}
13358c2ecf20Sopenharmony_ci
13368c2ecf20Sopenharmony_ci	if (S_ISDIR(old_inode->i_mode)) {
13378c2ecf20Sopenharmony_ci		u64 old_inode_parent;
13388c2ecf20Sopenharmony_ci
13398c2ecf20Sopenharmony_ci		update_dot_dot = 1;
13408c2ecf20Sopenharmony_ci		status = ocfs2_find_files_on_disk("..", 2, &old_inode_parent,
13418c2ecf20Sopenharmony_ci						  old_inode,
13428c2ecf20Sopenharmony_ci						  &old_inode_dot_dot_res);
13438c2ecf20Sopenharmony_ci		if (status) {
13448c2ecf20Sopenharmony_ci			status = -EIO;
13458c2ecf20Sopenharmony_ci			goto bail;
13468c2ecf20Sopenharmony_ci		}
13478c2ecf20Sopenharmony_ci
13488c2ecf20Sopenharmony_ci		if (old_inode_parent != OCFS2_I(old_dir)->ip_blkno) {
13498c2ecf20Sopenharmony_ci			status = -EIO;
13508c2ecf20Sopenharmony_ci			goto bail;
13518c2ecf20Sopenharmony_ci		}
13528c2ecf20Sopenharmony_ci
13538c2ecf20Sopenharmony_ci		if (!new_inode && new_dir != old_dir &&
13548c2ecf20Sopenharmony_ci		    new_dir->i_nlink >= ocfs2_link_max(osb)) {
13558c2ecf20Sopenharmony_ci			status = -EMLINK;
13568c2ecf20Sopenharmony_ci			goto bail;
13578c2ecf20Sopenharmony_ci		}
13588c2ecf20Sopenharmony_ci	}
13598c2ecf20Sopenharmony_ci
13608c2ecf20Sopenharmony_ci	status = ocfs2_lookup_ino_from_name(old_dir, old_dentry->d_name.name,
13618c2ecf20Sopenharmony_ci					    old_dentry->d_name.len,
13628c2ecf20Sopenharmony_ci					    &old_de_ino);
13638c2ecf20Sopenharmony_ci	if (status) {
13648c2ecf20Sopenharmony_ci		status = -ENOENT;
13658c2ecf20Sopenharmony_ci		goto bail;
13668c2ecf20Sopenharmony_ci	}
13678c2ecf20Sopenharmony_ci
13688c2ecf20Sopenharmony_ci	/*
13698c2ecf20Sopenharmony_ci	 *  Check for inode number is _not_ due to possible IO errors.
13708c2ecf20Sopenharmony_ci	 *  We might rmdir the source, keep it as pwd of some process
13718c2ecf20Sopenharmony_ci	 *  and merrily kill the link to whatever was created under the
13728c2ecf20Sopenharmony_ci	 *  same name. Goodbye sticky bit ;-<
13738c2ecf20Sopenharmony_ci	 */
13748c2ecf20Sopenharmony_ci	if (old_de_ino != OCFS2_I(old_inode)->ip_blkno) {
13758c2ecf20Sopenharmony_ci		status = -ENOENT;
13768c2ecf20Sopenharmony_ci		goto bail;
13778c2ecf20Sopenharmony_ci	}
13788c2ecf20Sopenharmony_ci
13798c2ecf20Sopenharmony_ci	/* check if the target already exists (in which case we need
13808c2ecf20Sopenharmony_ci	 * to delete it */
13818c2ecf20Sopenharmony_ci	status = ocfs2_find_files_on_disk(new_dentry->d_name.name,
13828c2ecf20Sopenharmony_ci					  new_dentry->d_name.len,
13838c2ecf20Sopenharmony_ci					  &newfe_blkno, new_dir,
13848c2ecf20Sopenharmony_ci					  &target_lookup_res);
13858c2ecf20Sopenharmony_ci	/* The only error we allow here is -ENOENT because the new
13868c2ecf20Sopenharmony_ci	 * file not existing is perfectly valid. */
13878c2ecf20Sopenharmony_ci	if ((status < 0) && (status != -ENOENT)) {
13888c2ecf20Sopenharmony_ci		/* If we cannot find the file specified we should just */
13898c2ecf20Sopenharmony_ci		/* return the error... */
13908c2ecf20Sopenharmony_ci		mlog_errno(status);
13918c2ecf20Sopenharmony_ci		goto bail;
13928c2ecf20Sopenharmony_ci	}
13938c2ecf20Sopenharmony_ci	if (status == 0)
13948c2ecf20Sopenharmony_ci		target_exists = 1;
13958c2ecf20Sopenharmony_ci
13968c2ecf20Sopenharmony_ci	if (!target_exists && new_inode) {
13978c2ecf20Sopenharmony_ci		/*
13988c2ecf20Sopenharmony_ci		 * Target was unlinked by another node while we were
13998c2ecf20Sopenharmony_ci		 * waiting to get to ocfs2_rename(). There isn't
14008c2ecf20Sopenharmony_ci		 * anything we can do here to help the situation, so
14018c2ecf20Sopenharmony_ci		 * bubble up the appropriate error.
14028c2ecf20Sopenharmony_ci		 */
14038c2ecf20Sopenharmony_ci		status = -ENOENT;
14048c2ecf20Sopenharmony_ci		goto bail;
14058c2ecf20Sopenharmony_ci	}
14068c2ecf20Sopenharmony_ci
14078c2ecf20Sopenharmony_ci	/* In case we need to overwrite an existing file, we blow it
14088c2ecf20Sopenharmony_ci	 * away first */
14098c2ecf20Sopenharmony_ci	if (target_exists) {
14108c2ecf20Sopenharmony_ci		/* VFS didn't think there existed an inode here, but
14118c2ecf20Sopenharmony_ci		 * someone else in the cluster must have raced our
14128c2ecf20Sopenharmony_ci		 * rename to create one. Today we error cleanly, in
14138c2ecf20Sopenharmony_ci		 * the future we should consider calling iget to build
14148c2ecf20Sopenharmony_ci		 * a new struct inode for this entry. */
14158c2ecf20Sopenharmony_ci		if (!new_inode) {
14168c2ecf20Sopenharmony_ci			status = -EACCES;
14178c2ecf20Sopenharmony_ci
14188c2ecf20Sopenharmony_ci			trace_ocfs2_rename_target_exists(new_dentry->d_name.len,
14198c2ecf20Sopenharmony_ci						new_dentry->d_name.name);
14208c2ecf20Sopenharmony_ci			goto bail;
14218c2ecf20Sopenharmony_ci		}
14228c2ecf20Sopenharmony_ci
14238c2ecf20Sopenharmony_ci		if (OCFS2_I(new_inode)->ip_blkno != newfe_blkno) {
14248c2ecf20Sopenharmony_ci			status = -EACCES;
14258c2ecf20Sopenharmony_ci
14268c2ecf20Sopenharmony_ci			trace_ocfs2_rename_disagree(
14278c2ecf20Sopenharmony_ci			     (unsigned long long)OCFS2_I(new_inode)->ip_blkno,
14288c2ecf20Sopenharmony_ci			     (unsigned long long)newfe_blkno,
14298c2ecf20Sopenharmony_ci			     OCFS2_I(new_inode)->ip_flags);
14308c2ecf20Sopenharmony_ci			goto bail;
14318c2ecf20Sopenharmony_ci		}
14328c2ecf20Sopenharmony_ci
14338c2ecf20Sopenharmony_ci		status = ocfs2_inode_lock(new_inode, &newfe_bh, 1);
14348c2ecf20Sopenharmony_ci		if (status < 0) {
14358c2ecf20Sopenharmony_ci			if (status != -ENOENT)
14368c2ecf20Sopenharmony_ci				mlog_errno(status);
14378c2ecf20Sopenharmony_ci			goto bail;
14388c2ecf20Sopenharmony_ci		}
14398c2ecf20Sopenharmony_ci		new_child_locked = 1;
14408c2ecf20Sopenharmony_ci
14418c2ecf20Sopenharmony_ci		status = ocfs2_remote_dentry_delete(new_dentry);
14428c2ecf20Sopenharmony_ci		if (status < 0) {
14438c2ecf20Sopenharmony_ci			mlog_errno(status);
14448c2ecf20Sopenharmony_ci			goto bail;
14458c2ecf20Sopenharmony_ci		}
14468c2ecf20Sopenharmony_ci
14478c2ecf20Sopenharmony_ci		newfe = (struct ocfs2_dinode *) newfe_bh->b_data;
14488c2ecf20Sopenharmony_ci
14498c2ecf20Sopenharmony_ci		trace_ocfs2_rename_over_existing(
14508c2ecf20Sopenharmony_ci		     (unsigned long long)newfe_blkno, newfe_bh, newfe_bh ?
14518c2ecf20Sopenharmony_ci		     (unsigned long long)newfe_bh->b_blocknr : 0ULL);
14528c2ecf20Sopenharmony_ci
14538c2ecf20Sopenharmony_ci		if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) {
14548c2ecf20Sopenharmony_ci			status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
14558c2ecf20Sopenharmony_ci						OCFS2_I(new_inode)->ip_blkno,
14568c2ecf20Sopenharmony_ci						orphan_name, &orphan_insert,
14578c2ecf20Sopenharmony_ci						false);
14588c2ecf20Sopenharmony_ci			if (status < 0) {
14598c2ecf20Sopenharmony_ci				mlog_errno(status);
14608c2ecf20Sopenharmony_ci				goto bail;
14618c2ecf20Sopenharmony_ci			}
14628c2ecf20Sopenharmony_ci			should_add_orphan = true;
14638c2ecf20Sopenharmony_ci		}
14648c2ecf20Sopenharmony_ci	} else {
14658c2ecf20Sopenharmony_ci		BUG_ON(d_inode(new_dentry->d_parent) != new_dir);
14668c2ecf20Sopenharmony_ci
14678c2ecf20Sopenharmony_ci		status = ocfs2_check_dir_for_entry(new_dir,
14688c2ecf20Sopenharmony_ci						   new_dentry->d_name.name,
14698c2ecf20Sopenharmony_ci						   new_dentry->d_name.len);
14708c2ecf20Sopenharmony_ci		if (status)
14718c2ecf20Sopenharmony_ci			goto bail;
14728c2ecf20Sopenharmony_ci
14738c2ecf20Sopenharmony_ci		status = ocfs2_prepare_dir_for_insert(osb, new_dir, new_dir_bh,
14748c2ecf20Sopenharmony_ci						      new_dentry->d_name.name,
14758c2ecf20Sopenharmony_ci						      new_dentry->d_name.len,
14768c2ecf20Sopenharmony_ci						      &target_insert);
14778c2ecf20Sopenharmony_ci		if (status < 0) {
14788c2ecf20Sopenharmony_ci			mlog_errno(status);
14798c2ecf20Sopenharmony_ci			goto bail;
14808c2ecf20Sopenharmony_ci		}
14818c2ecf20Sopenharmony_ci	}
14828c2ecf20Sopenharmony_ci
14838c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_rename_credits(osb->sb));
14848c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
14858c2ecf20Sopenharmony_ci		status = PTR_ERR(handle);
14868c2ecf20Sopenharmony_ci		handle = NULL;
14878c2ecf20Sopenharmony_ci		mlog_errno(status);
14888c2ecf20Sopenharmony_ci		goto bail;
14898c2ecf20Sopenharmony_ci	}
14908c2ecf20Sopenharmony_ci
14918c2ecf20Sopenharmony_ci	if (target_exists) {
14928c2ecf20Sopenharmony_ci		if (S_ISDIR(new_inode->i_mode)) {
14938c2ecf20Sopenharmony_ci			if (new_inode->i_nlink != 2 ||
14948c2ecf20Sopenharmony_ci			    !ocfs2_empty_dir(new_inode)) {
14958c2ecf20Sopenharmony_ci				status = -ENOTEMPTY;
14968c2ecf20Sopenharmony_ci				goto bail;
14978c2ecf20Sopenharmony_ci			}
14988c2ecf20Sopenharmony_ci		}
14998c2ecf20Sopenharmony_ci		status = ocfs2_journal_access_di(handle, INODE_CACHE(new_inode),
15008c2ecf20Sopenharmony_ci						 newfe_bh,
15018c2ecf20Sopenharmony_ci						 OCFS2_JOURNAL_ACCESS_WRITE);
15028c2ecf20Sopenharmony_ci		if (status < 0) {
15038c2ecf20Sopenharmony_ci			mlog_errno(status);
15048c2ecf20Sopenharmony_ci			goto bail;
15058c2ecf20Sopenharmony_ci		}
15068c2ecf20Sopenharmony_ci
15078c2ecf20Sopenharmony_ci		/* change the dirent to point to the correct inode */
15088c2ecf20Sopenharmony_ci		status = ocfs2_update_entry(new_dir, handle, &target_lookup_res,
15098c2ecf20Sopenharmony_ci					    old_inode);
15108c2ecf20Sopenharmony_ci		if (status < 0) {
15118c2ecf20Sopenharmony_ci			mlog_errno(status);
15128c2ecf20Sopenharmony_ci			goto bail;
15138c2ecf20Sopenharmony_ci		}
15148c2ecf20Sopenharmony_ci		inode_inc_iversion(new_dir);
15158c2ecf20Sopenharmony_ci
15168c2ecf20Sopenharmony_ci		if (S_ISDIR(new_inode->i_mode))
15178c2ecf20Sopenharmony_ci			ocfs2_set_links_count(newfe, 0);
15188c2ecf20Sopenharmony_ci		else
15198c2ecf20Sopenharmony_ci			ocfs2_add_links_count(newfe, -1);
15208c2ecf20Sopenharmony_ci		ocfs2_journal_dirty(handle, newfe_bh);
15218c2ecf20Sopenharmony_ci		if (should_add_orphan) {
15228c2ecf20Sopenharmony_ci			status = ocfs2_orphan_add(osb, handle, new_inode,
15238c2ecf20Sopenharmony_ci					newfe_bh, orphan_name,
15248c2ecf20Sopenharmony_ci					&orphan_insert, orphan_dir, false);
15258c2ecf20Sopenharmony_ci			if (status < 0) {
15268c2ecf20Sopenharmony_ci				mlog_errno(status);
15278c2ecf20Sopenharmony_ci				goto bail;
15288c2ecf20Sopenharmony_ci			}
15298c2ecf20Sopenharmony_ci		}
15308c2ecf20Sopenharmony_ci	} else {
15318c2ecf20Sopenharmony_ci		/* if the name was not found in new_dir, add it now */
15328c2ecf20Sopenharmony_ci		status = ocfs2_add_entry(handle, new_dentry, old_inode,
15338c2ecf20Sopenharmony_ci					 OCFS2_I(old_inode)->ip_blkno,
15348c2ecf20Sopenharmony_ci					 new_dir_bh, &target_insert);
15358c2ecf20Sopenharmony_ci		if (status < 0) {
15368c2ecf20Sopenharmony_ci			mlog_errno(status);
15378c2ecf20Sopenharmony_ci			goto bail;
15388c2ecf20Sopenharmony_ci		}
15398c2ecf20Sopenharmony_ci	}
15408c2ecf20Sopenharmony_ci
15418c2ecf20Sopenharmony_ci	old_inode->i_ctime = current_time(old_inode);
15428c2ecf20Sopenharmony_ci	mark_inode_dirty(old_inode);
15438c2ecf20Sopenharmony_ci
15448c2ecf20Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(old_inode),
15458c2ecf20Sopenharmony_ci					 old_inode_bh,
15468c2ecf20Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
15478c2ecf20Sopenharmony_ci	if (status >= 0) {
15488c2ecf20Sopenharmony_ci		old_di = (struct ocfs2_dinode *) old_inode_bh->b_data;
15498c2ecf20Sopenharmony_ci
15508c2ecf20Sopenharmony_ci		old_di->i_ctime = cpu_to_le64(old_inode->i_ctime.tv_sec);
15518c2ecf20Sopenharmony_ci		old_di->i_ctime_nsec = cpu_to_le32(old_inode->i_ctime.tv_nsec);
15528c2ecf20Sopenharmony_ci		ocfs2_journal_dirty(handle, old_inode_bh);
15538c2ecf20Sopenharmony_ci	} else
15548c2ecf20Sopenharmony_ci		mlog_errno(status);
15558c2ecf20Sopenharmony_ci
15568c2ecf20Sopenharmony_ci	/*
15578c2ecf20Sopenharmony_ci	 * Now that the name has been added to new_dir, remove the old name.
15588c2ecf20Sopenharmony_ci	 *
15598c2ecf20Sopenharmony_ci	 * We don't keep any directory entry context around until now
15608c2ecf20Sopenharmony_ci	 * because the insert might have changed the type of directory
15618c2ecf20Sopenharmony_ci	 * we're dealing with.
15628c2ecf20Sopenharmony_ci	 */
15638c2ecf20Sopenharmony_ci	status = ocfs2_find_entry(old_dentry->d_name.name,
15648c2ecf20Sopenharmony_ci				  old_dentry->d_name.len, old_dir,
15658c2ecf20Sopenharmony_ci				  &old_entry_lookup);
15668c2ecf20Sopenharmony_ci	if (status) {
15678c2ecf20Sopenharmony_ci		if (!is_journal_aborted(osb->journal->j_journal)) {
15688c2ecf20Sopenharmony_ci			ocfs2_error(osb->sb, "new entry %.*s is added, but old entry %.*s "
15698c2ecf20Sopenharmony_ci					"is not deleted.",
15708c2ecf20Sopenharmony_ci					new_dentry->d_name.len, new_dentry->d_name.name,
15718c2ecf20Sopenharmony_ci					old_dentry->d_name.len, old_dentry->d_name.name);
15728c2ecf20Sopenharmony_ci		}
15738c2ecf20Sopenharmony_ci		goto bail;
15748c2ecf20Sopenharmony_ci	}
15758c2ecf20Sopenharmony_ci
15768c2ecf20Sopenharmony_ci	status = ocfs2_delete_entry(handle, old_dir, &old_entry_lookup);
15778c2ecf20Sopenharmony_ci	if (status < 0) {
15788c2ecf20Sopenharmony_ci		mlog_errno(status);
15798c2ecf20Sopenharmony_ci		if (!is_journal_aborted(osb->journal->j_journal)) {
15808c2ecf20Sopenharmony_ci			ocfs2_error(osb->sb, "new entry %.*s is added, but old entry %.*s "
15818c2ecf20Sopenharmony_ci					"is not deleted.",
15828c2ecf20Sopenharmony_ci					new_dentry->d_name.len, new_dentry->d_name.name,
15838c2ecf20Sopenharmony_ci					old_dentry->d_name.len, old_dentry->d_name.name);
15848c2ecf20Sopenharmony_ci		}
15858c2ecf20Sopenharmony_ci		goto bail;
15868c2ecf20Sopenharmony_ci	}
15878c2ecf20Sopenharmony_ci
15888c2ecf20Sopenharmony_ci	if (new_inode) {
15898c2ecf20Sopenharmony_ci		drop_nlink(new_inode);
15908c2ecf20Sopenharmony_ci		new_inode->i_ctime = current_time(new_inode);
15918c2ecf20Sopenharmony_ci	}
15928c2ecf20Sopenharmony_ci	old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
15938c2ecf20Sopenharmony_ci
15948c2ecf20Sopenharmony_ci	if (update_dot_dot) {
15958c2ecf20Sopenharmony_ci		status = ocfs2_update_entry(old_inode, handle,
15968c2ecf20Sopenharmony_ci					    &old_inode_dot_dot_res, new_dir);
15978c2ecf20Sopenharmony_ci		drop_nlink(old_dir);
15988c2ecf20Sopenharmony_ci		if (new_inode) {
15998c2ecf20Sopenharmony_ci			drop_nlink(new_inode);
16008c2ecf20Sopenharmony_ci		} else {
16018c2ecf20Sopenharmony_ci			inc_nlink(new_dir);
16028c2ecf20Sopenharmony_ci			mark_inode_dirty(new_dir);
16038c2ecf20Sopenharmony_ci		}
16048c2ecf20Sopenharmony_ci	}
16058c2ecf20Sopenharmony_ci	mark_inode_dirty(old_dir);
16068c2ecf20Sopenharmony_ci	ocfs2_mark_inode_dirty(handle, old_dir, old_dir_bh);
16078c2ecf20Sopenharmony_ci	if (new_inode) {
16088c2ecf20Sopenharmony_ci		mark_inode_dirty(new_inode);
16098c2ecf20Sopenharmony_ci		ocfs2_mark_inode_dirty(handle, new_inode, newfe_bh);
16108c2ecf20Sopenharmony_ci	}
16118c2ecf20Sopenharmony_ci
16128c2ecf20Sopenharmony_ci	if (old_dir != new_dir) {
16138c2ecf20Sopenharmony_ci		/* Keep the same times on both directories.*/
16148c2ecf20Sopenharmony_ci		new_dir->i_ctime = new_dir->i_mtime = old_dir->i_ctime;
16158c2ecf20Sopenharmony_ci
16168c2ecf20Sopenharmony_ci		/*
16178c2ecf20Sopenharmony_ci		 * This will also pick up the i_nlink change from the
16188c2ecf20Sopenharmony_ci		 * block above.
16198c2ecf20Sopenharmony_ci		 */
16208c2ecf20Sopenharmony_ci		ocfs2_mark_inode_dirty(handle, new_dir, new_dir_bh);
16218c2ecf20Sopenharmony_ci	}
16228c2ecf20Sopenharmony_ci
16238c2ecf20Sopenharmony_ci	if (old_dir_nlink != old_dir->i_nlink) {
16248c2ecf20Sopenharmony_ci		if (!old_dir_bh) {
16258c2ecf20Sopenharmony_ci			mlog(ML_ERROR, "need to change nlink for old dir "
16268c2ecf20Sopenharmony_ci			     "%llu from %d to %d but bh is NULL!\n",
16278c2ecf20Sopenharmony_ci			     (unsigned long long)OCFS2_I(old_dir)->ip_blkno,
16288c2ecf20Sopenharmony_ci			     (int)old_dir_nlink, old_dir->i_nlink);
16298c2ecf20Sopenharmony_ci		} else {
16308c2ecf20Sopenharmony_ci			struct ocfs2_dinode *fe;
16318c2ecf20Sopenharmony_ci			status = ocfs2_journal_access_di(handle,
16328c2ecf20Sopenharmony_ci							 INODE_CACHE(old_dir),
16338c2ecf20Sopenharmony_ci							 old_dir_bh,
16348c2ecf20Sopenharmony_ci							 OCFS2_JOURNAL_ACCESS_WRITE);
16358c2ecf20Sopenharmony_ci			fe = (struct ocfs2_dinode *) old_dir_bh->b_data;
16368c2ecf20Sopenharmony_ci			ocfs2_set_links_count(fe, old_dir->i_nlink);
16378c2ecf20Sopenharmony_ci			ocfs2_journal_dirty(handle, old_dir_bh);
16388c2ecf20Sopenharmony_ci		}
16398c2ecf20Sopenharmony_ci	}
16408c2ecf20Sopenharmony_ci	ocfs2_dentry_move(old_dentry, new_dentry, old_dir, new_dir);
16418c2ecf20Sopenharmony_ci	status = 0;
16428c2ecf20Sopenharmony_cibail:
16438c2ecf20Sopenharmony_ci	if (handle)
16448c2ecf20Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
16458c2ecf20Sopenharmony_ci
16468c2ecf20Sopenharmony_ci	if (orphan_dir) {
16478c2ecf20Sopenharmony_ci		/* This was locked for us in ocfs2_prepare_orphan_dir() */
16488c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir, 1);
16498c2ecf20Sopenharmony_ci		inode_unlock(orphan_dir);
16508c2ecf20Sopenharmony_ci		iput(orphan_dir);
16518c2ecf20Sopenharmony_ci	}
16528c2ecf20Sopenharmony_ci
16538c2ecf20Sopenharmony_ci	if (new_child_locked)
16548c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(new_inode, 1);
16558c2ecf20Sopenharmony_ci
16568c2ecf20Sopenharmony_ci	if (old_child_locked)
16578c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(old_inode, 1);
16588c2ecf20Sopenharmony_ci
16598c2ecf20Sopenharmony_ci	if (parents_locked)
16608c2ecf20Sopenharmony_ci		ocfs2_double_unlock(old_dir, new_dir);
16618c2ecf20Sopenharmony_ci
16628c2ecf20Sopenharmony_ci	if (rename_lock)
16638c2ecf20Sopenharmony_ci		ocfs2_rename_unlock(osb);
16648c2ecf20Sopenharmony_ci
16658c2ecf20Sopenharmony_ci	if (new_inode)
16668c2ecf20Sopenharmony_ci		sync_mapping_buffers(old_inode->i_mapping);
16678c2ecf20Sopenharmony_ci
16688c2ecf20Sopenharmony_ci	iput(new_inode);
16698c2ecf20Sopenharmony_ci
16708c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&target_lookup_res);
16718c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&old_entry_lookup);
16728c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&old_inode_dot_dot_res);
16738c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&orphan_insert);
16748c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&target_insert);
16758c2ecf20Sopenharmony_ci
16768c2ecf20Sopenharmony_ci	brelse(newfe_bh);
16778c2ecf20Sopenharmony_ci	brelse(old_inode_bh);
16788c2ecf20Sopenharmony_ci	brelse(old_dir_bh);
16798c2ecf20Sopenharmony_ci	brelse(new_dir_bh);
16808c2ecf20Sopenharmony_ci
16818c2ecf20Sopenharmony_ci	if (status)
16828c2ecf20Sopenharmony_ci		mlog_errno(status);
16838c2ecf20Sopenharmony_ci
16848c2ecf20Sopenharmony_ci	return status;
16858c2ecf20Sopenharmony_ci}
16868c2ecf20Sopenharmony_ci
16878c2ecf20Sopenharmony_ci/*
16888c2ecf20Sopenharmony_ci * we expect i_size = strlen(symname). Copy symname into the file
16898c2ecf20Sopenharmony_ci * data, including the null terminator.
16908c2ecf20Sopenharmony_ci */
16918c2ecf20Sopenharmony_cistatic int ocfs2_create_symlink_data(struct ocfs2_super *osb,
16928c2ecf20Sopenharmony_ci				     handle_t *handle,
16938c2ecf20Sopenharmony_ci				     struct inode *inode,
16948c2ecf20Sopenharmony_ci				     const char *symname)
16958c2ecf20Sopenharmony_ci{
16968c2ecf20Sopenharmony_ci	struct buffer_head **bhs = NULL;
16978c2ecf20Sopenharmony_ci	const char *c;
16988c2ecf20Sopenharmony_ci	struct super_block *sb = osb->sb;
16998c2ecf20Sopenharmony_ci	u64 p_blkno, p_blocks;
17008c2ecf20Sopenharmony_ci	int virtual, blocks, status, i, bytes_left;
17018c2ecf20Sopenharmony_ci
17028c2ecf20Sopenharmony_ci	bytes_left = i_size_read(inode) + 1;
17038c2ecf20Sopenharmony_ci	/* we can't trust i_blocks because we're actually going to
17048c2ecf20Sopenharmony_ci	 * write i_size + 1 bytes. */
17058c2ecf20Sopenharmony_ci	blocks = (bytes_left + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
17068c2ecf20Sopenharmony_ci
17078c2ecf20Sopenharmony_ci	trace_ocfs2_create_symlink_data((unsigned long long)inode->i_blocks,
17088c2ecf20Sopenharmony_ci					i_size_read(inode), blocks);
17098c2ecf20Sopenharmony_ci
17108c2ecf20Sopenharmony_ci	/* Sanity check -- make sure we're going to fit. */
17118c2ecf20Sopenharmony_ci	if (bytes_left >
17128c2ecf20Sopenharmony_ci	    ocfs2_clusters_to_bytes(sb, OCFS2_I(inode)->ip_clusters)) {
17138c2ecf20Sopenharmony_ci		status = -EIO;
17148c2ecf20Sopenharmony_ci		mlog_errno(status);
17158c2ecf20Sopenharmony_ci		goto bail;
17168c2ecf20Sopenharmony_ci	}
17178c2ecf20Sopenharmony_ci
17188c2ecf20Sopenharmony_ci	bhs = kcalloc(blocks, sizeof(struct buffer_head *), GFP_KERNEL);
17198c2ecf20Sopenharmony_ci	if (!bhs) {
17208c2ecf20Sopenharmony_ci		status = -ENOMEM;
17218c2ecf20Sopenharmony_ci		mlog_errno(status);
17228c2ecf20Sopenharmony_ci		goto bail;
17238c2ecf20Sopenharmony_ci	}
17248c2ecf20Sopenharmony_ci
17258c2ecf20Sopenharmony_ci	status = ocfs2_extent_map_get_blocks(inode, 0, &p_blkno, &p_blocks,
17268c2ecf20Sopenharmony_ci					     NULL);
17278c2ecf20Sopenharmony_ci	if (status < 0) {
17288c2ecf20Sopenharmony_ci		mlog_errno(status);
17298c2ecf20Sopenharmony_ci		goto bail;
17308c2ecf20Sopenharmony_ci	}
17318c2ecf20Sopenharmony_ci
17328c2ecf20Sopenharmony_ci	/* links can never be larger than one cluster so we know this
17338c2ecf20Sopenharmony_ci	 * is all going to be contiguous, but do a sanity check
17348c2ecf20Sopenharmony_ci	 * anyway. */
17358c2ecf20Sopenharmony_ci	if ((p_blocks << sb->s_blocksize_bits) < bytes_left) {
17368c2ecf20Sopenharmony_ci		status = -EIO;
17378c2ecf20Sopenharmony_ci		mlog_errno(status);
17388c2ecf20Sopenharmony_ci		goto bail;
17398c2ecf20Sopenharmony_ci	}
17408c2ecf20Sopenharmony_ci
17418c2ecf20Sopenharmony_ci	virtual = 0;
17428c2ecf20Sopenharmony_ci	while(bytes_left > 0) {
17438c2ecf20Sopenharmony_ci		c = &symname[virtual * sb->s_blocksize];
17448c2ecf20Sopenharmony_ci
17458c2ecf20Sopenharmony_ci		bhs[virtual] = sb_getblk(sb, p_blkno);
17468c2ecf20Sopenharmony_ci		if (!bhs[virtual]) {
17478c2ecf20Sopenharmony_ci			status = -ENOMEM;
17488c2ecf20Sopenharmony_ci			mlog_errno(status);
17498c2ecf20Sopenharmony_ci			goto bail;
17508c2ecf20Sopenharmony_ci		}
17518c2ecf20Sopenharmony_ci		ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode),
17528c2ecf20Sopenharmony_ci					      bhs[virtual]);
17538c2ecf20Sopenharmony_ci
17548c2ecf20Sopenharmony_ci		status = ocfs2_journal_access(handle, INODE_CACHE(inode),
17558c2ecf20Sopenharmony_ci					      bhs[virtual],
17568c2ecf20Sopenharmony_ci					      OCFS2_JOURNAL_ACCESS_CREATE);
17578c2ecf20Sopenharmony_ci		if (status < 0) {
17588c2ecf20Sopenharmony_ci			mlog_errno(status);
17598c2ecf20Sopenharmony_ci			goto bail;
17608c2ecf20Sopenharmony_ci		}
17618c2ecf20Sopenharmony_ci
17628c2ecf20Sopenharmony_ci		memset(bhs[virtual]->b_data, 0, sb->s_blocksize);
17638c2ecf20Sopenharmony_ci
17648c2ecf20Sopenharmony_ci		memcpy(bhs[virtual]->b_data, c,
17658c2ecf20Sopenharmony_ci		       (bytes_left > sb->s_blocksize) ? sb->s_blocksize :
17668c2ecf20Sopenharmony_ci		       bytes_left);
17678c2ecf20Sopenharmony_ci
17688c2ecf20Sopenharmony_ci		ocfs2_journal_dirty(handle, bhs[virtual]);
17698c2ecf20Sopenharmony_ci
17708c2ecf20Sopenharmony_ci		virtual++;
17718c2ecf20Sopenharmony_ci		p_blkno++;
17728c2ecf20Sopenharmony_ci		bytes_left -= sb->s_blocksize;
17738c2ecf20Sopenharmony_ci	}
17748c2ecf20Sopenharmony_ci
17758c2ecf20Sopenharmony_ci	status = 0;
17768c2ecf20Sopenharmony_cibail:
17778c2ecf20Sopenharmony_ci
17788c2ecf20Sopenharmony_ci	if (bhs) {
17798c2ecf20Sopenharmony_ci		for(i = 0; i < blocks; i++)
17808c2ecf20Sopenharmony_ci			brelse(bhs[i]);
17818c2ecf20Sopenharmony_ci		kfree(bhs);
17828c2ecf20Sopenharmony_ci	}
17838c2ecf20Sopenharmony_ci
17848c2ecf20Sopenharmony_ci	if (status)
17858c2ecf20Sopenharmony_ci		mlog_errno(status);
17868c2ecf20Sopenharmony_ci	return status;
17878c2ecf20Sopenharmony_ci}
17888c2ecf20Sopenharmony_ci
17898c2ecf20Sopenharmony_cistatic int ocfs2_symlink(struct inode *dir,
17908c2ecf20Sopenharmony_ci			 struct dentry *dentry,
17918c2ecf20Sopenharmony_ci			 const char *symname)
17928c2ecf20Sopenharmony_ci{
17938c2ecf20Sopenharmony_ci	int status, l, credits;
17948c2ecf20Sopenharmony_ci	u64 newsize;
17958c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = NULL;
17968c2ecf20Sopenharmony_ci	struct inode *inode = NULL;
17978c2ecf20Sopenharmony_ci	struct super_block *sb;
17988c2ecf20Sopenharmony_ci	struct buffer_head *new_fe_bh = NULL;
17998c2ecf20Sopenharmony_ci	struct buffer_head *parent_fe_bh = NULL;
18008c2ecf20Sopenharmony_ci	struct ocfs2_dinode *fe = NULL;
18018c2ecf20Sopenharmony_ci	struct ocfs2_dinode *dirfe;
18028c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
18038c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *inode_ac = NULL;
18048c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *data_ac = NULL;
18058c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *xattr_ac = NULL;
18068c2ecf20Sopenharmony_ci	int want_clusters = 0;
18078c2ecf20Sopenharmony_ci	int xattr_credits = 0;
18088c2ecf20Sopenharmony_ci	struct ocfs2_security_xattr_info si = {
18098c2ecf20Sopenharmony_ci		.name = NULL,
18108c2ecf20Sopenharmony_ci		.enable = 1,
18118c2ecf20Sopenharmony_ci	};
18128c2ecf20Sopenharmony_ci	int did_quota = 0, did_quota_inode = 0;
18138c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
18148c2ecf20Sopenharmony_ci	sigset_t oldset;
18158c2ecf20Sopenharmony_ci	int did_block_signals = 0;
18168c2ecf20Sopenharmony_ci	struct ocfs2_dentry_lock *dl = NULL;
18178c2ecf20Sopenharmony_ci
18188c2ecf20Sopenharmony_ci	trace_ocfs2_symlink_begin(dir, dentry, symname,
18198c2ecf20Sopenharmony_ci				  dentry->d_name.len, dentry->d_name.name);
18208c2ecf20Sopenharmony_ci
18218c2ecf20Sopenharmony_ci	status = dquot_initialize(dir);
18228c2ecf20Sopenharmony_ci	if (status) {
18238c2ecf20Sopenharmony_ci		mlog_errno(status);
18248c2ecf20Sopenharmony_ci		goto bail;
18258c2ecf20Sopenharmony_ci	}
18268c2ecf20Sopenharmony_ci
18278c2ecf20Sopenharmony_ci	sb = dir->i_sb;
18288c2ecf20Sopenharmony_ci	osb = OCFS2_SB(sb);
18298c2ecf20Sopenharmony_ci
18308c2ecf20Sopenharmony_ci	l = strlen(symname) + 1;
18318c2ecf20Sopenharmony_ci
18328c2ecf20Sopenharmony_ci	credits = ocfs2_calc_symlink_credits(sb);
18338c2ecf20Sopenharmony_ci
18348c2ecf20Sopenharmony_ci	/* lock the parent directory */
18358c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock(dir, &parent_fe_bh, 1);
18368c2ecf20Sopenharmony_ci	if (status < 0) {
18378c2ecf20Sopenharmony_ci		if (status != -ENOENT)
18388c2ecf20Sopenharmony_ci			mlog_errno(status);
18398c2ecf20Sopenharmony_ci		return status;
18408c2ecf20Sopenharmony_ci	}
18418c2ecf20Sopenharmony_ci
18428c2ecf20Sopenharmony_ci	dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
18438c2ecf20Sopenharmony_ci	if (!ocfs2_read_links_count(dirfe)) {
18448c2ecf20Sopenharmony_ci		/* can't make a file in a deleted directory. */
18458c2ecf20Sopenharmony_ci		status = -ENOENT;
18468c2ecf20Sopenharmony_ci		goto bail;
18478c2ecf20Sopenharmony_ci	}
18488c2ecf20Sopenharmony_ci
18498c2ecf20Sopenharmony_ci	status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
18508c2ecf20Sopenharmony_ci					   dentry->d_name.len);
18518c2ecf20Sopenharmony_ci	if (status)
18528c2ecf20Sopenharmony_ci		goto bail;
18538c2ecf20Sopenharmony_ci
18548c2ecf20Sopenharmony_ci	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
18558c2ecf20Sopenharmony_ci					      dentry->d_name.name,
18568c2ecf20Sopenharmony_ci					      dentry->d_name.len, &lookup);
18578c2ecf20Sopenharmony_ci	if (status < 0) {
18588c2ecf20Sopenharmony_ci		mlog_errno(status);
18598c2ecf20Sopenharmony_ci		goto bail;
18608c2ecf20Sopenharmony_ci	}
18618c2ecf20Sopenharmony_ci
18628c2ecf20Sopenharmony_ci	status = ocfs2_reserve_new_inode(osb, &inode_ac);
18638c2ecf20Sopenharmony_ci	if (status < 0) {
18648c2ecf20Sopenharmony_ci		if (status != -ENOSPC)
18658c2ecf20Sopenharmony_ci			mlog_errno(status);
18668c2ecf20Sopenharmony_ci		goto bail;
18678c2ecf20Sopenharmony_ci	}
18688c2ecf20Sopenharmony_ci
18698c2ecf20Sopenharmony_ci	inode = ocfs2_get_init_inode(dir, S_IFLNK | S_IRWXUGO);
18708c2ecf20Sopenharmony_ci	if (IS_ERR(inode)) {
18718c2ecf20Sopenharmony_ci		status = PTR_ERR(inode);
18728c2ecf20Sopenharmony_ci		inode = NULL;
18738c2ecf20Sopenharmony_ci		mlog_errno(status);
18748c2ecf20Sopenharmony_ci		goto bail;
18758c2ecf20Sopenharmony_ci	}
18768c2ecf20Sopenharmony_ci
18778c2ecf20Sopenharmony_ci	/* get security xattr */
18788c2ecf20Sopenharmony_ci	status = ocfs2_init_security_get(inode, dir, &dentry->d_name, &si);
18798c2ecf20Sopenharmony_ci	if (status) {
18808c2ecf20Sopenharmony_ci		if (status == -EOPNOTSUPP)
18818c2ecf20Sopenharmony_ci			si.enable = 0;
18828c2ecf20Sopenharmony_ci		else {
18838c2ecf20Sopenharmony_ci			mlog_errno(status);
18848c2ecf20Sopenharmony_ci			goto bail;
18858c2ecf20Sopenharmony_ci		}
18868c2ecf20Sopenharmony_ci	}
18878c2ecf20Sopenharmony_ci
18888c2ecf20Sopenharmony_ci	/* calculate meta data/clusters for setting security xattr */
18898c2ecf20Sopenharmony_ci	if (si.enable) {
18908c2ecf20Sopenharmony_ci		status = ocfs2_calc_security_init(dir, &si, &want_clusters,
18918c2ecf20Sopenharmony_ci						  &xattr_credits, &xattr_ac);
18928c2ecf20Sopenharmony_ci		if (status < 0) {
18938c2ecf20Sopenharmony_ci			mlog_errno(status);
18948c2ecf20Sopenharmony_ci			goto bail;
18958c2ecf20Sopenharmony_ci		}
18968c2ecf20Sopenharmony_ci	}
18978c2ecf20Sopenharmony_ci
18988c2ecf20Sopenharmony_ci	/* don't reserve bitmap space for fast symlinks. */
18998c2ecf20Sopenharmony_ci	if (l > ocfs2_fast_symlink_chars(sb))
19008c2ecf20Sopenharmony_ci		want_clusters += 1;
19018c2ecf20Sopenharmony_ci
19028c2ecf20Sopenharmony_ci	status = ocfs2_reserve_clusters(osb, want_clusters, &data_ac);
19038c2ecf20Sopenharmony_ci	if (status < 0) {
19048c2ecf20Sopenharmony_ci		if (status != -ENOSPC)
19058c2ecf20Sopenharmony_ci			mlog_errno(status);
19068c2ecf20Sopenharmony_ci		goto bail;
19078c2ecf20Sopenharmony_ci	}
19088c2ecf20Sopenharmony_ci
19098c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, credits + xattr_credits);
19108c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
19118c2ecf20Sopenharmony_ci		status = PTR_ERR(handle);
19128c2ecf20Sopenharmony_ci		handle = NULL;
19138c2ecf20Sopenharmony_ci		mlog_errno(status);
19148c2ecf20Sopenharmony_ci		goto bail;
19158c2ecf20Sopenharmony_ci	}
19168c2ecf20Sopenharmony_ci
19178c2ecf20Sopenharmony_ci	/* Starting to change things, restart is no longer possible. */
19188c2ecf20Sopenharmony_ci	ocfs2_block_signals(&oldset);
19198c2ecf20Sopenharmony_ci	did_block_signals = 1;
19208c2ecf20Sopenharmony_ci
19218c2ecf20Sopenharmony_ci	status = dquot_alloc_inode(inode);
19228c2ecf20Sopenharmony_ci	if (status)
19238c2ecf20Sopenharmony_ci		goto bail;
19248c2ecf20Sopenharmony_ci	did_quota_inode = 1;
19258c2ecf20Sopenharmony_ci
19268c2ecf20Sopenharmony_ci	trace_ocfs2_symlink_create(dir, dentry, dentry->d_name.len,
19278c2ecf20Sopenharmony_ci				   dentry->d_name.name,
19288c2ecf20Sopenharmony_ci				   (unsigned long long)OCFS2_I(dir)->ip_blkno,
19298c2ecf20Sopenharmony_ci				   inode->i_mode);
19308c2ecf20Sopenharmony_ci
19318c2ecf20Sopenharmony_ci	status = ocfs2_mknod_locked(osb, dir, inode,
19328c2ecf20Sopenharmony_ci				    0, &new_fe_bh, parent_fe_bh, handle,
19338c2ecf20Sopenharmony_ci				    inode_ac);
19348c2ecf20Sopenharmony_ci	if (status < 0) {
19358c2ecf20Sopenharmony_ci		mlog_errno(status);
19368c2ecf20Sopenharmony_ci		goto bail;
19378c2ecf20Sopenharmony_ci	}
19388c2ecf20Sopenharmony_ci
19398c2ecf20Sopenharmony_ci	fe = (struct ocfs2_dinode *) new_fe_bh->b_data;
19408c2ecf20Sopenharmony_ci	inode->i_rdev = 0;
19418c2ecf20Sopenharmony_ci	newsize = l - 1;
19428c2ecf20Sopenharmony_ci	inode->i_op = &ocfs2_symlink_inode_operations;
19438c2ecf20Sopenharmony_ci	inode_nohighmem(inode);
19448c2ecf20Sopenharmony_ci	if (l > ocfs2_fast_symlink_chars(sb)) {
19458c2ecf20Sopenharmony_ci		u32 offset = 0;
19468c2ecf20Sopenharmony_ci
19478c2ecf20Sopenharmony_ci		status = dquot_alloc_space_nodirty(inode,
19488c2ecf20Sopenharmony_ci		    ocfs2_clusters_to_bytes(osb->sb, 1));
19498c2ecf20Sopenharmony_ci		if (status)
19508c2ecf20Sopenharmony_ci			goto bail;
19518c2ecf20Sopenharmony_ci		did_quota = 1;
19528c2ecf20Sopenharmony_ci		inode->i_mapping->a_ops = &ocfs2_aops;
19538c2ecf20Sopenharmony_ci		status = ocfs2_add_inode_data(osb, inode, &offset, 1, 0,
19548c2ecf20Sopenharmony_ci					      new_fe_bh,
19558c2ecf20Sopenharmony_ci					      handle, data_ac, NULL,
19568c2ecf20Sopenharmony_ci					      NULL);
19578c2ecf20Sopenharmony_ci		if (status < 0) {
19588c2ecf20Sopenharmony_ci			if (status != -ENOSPC && status != -EINTR) {
19598c2ecf20Sopenharmony_ci				mlog(ML_ERROR,
19608c2ecf20Sopenharmony_ci				     "Failed to extend file to %llu\n",
19618c2ecf20Sopenharmony_ci				     (unsigned long long)newsize);
19628c2ecf20Sopenharmony_ci				mlog_errno(status);
19638c2ecf20Sopenharmony_ci				status = -ENOSPC;
19648c2ecf20Sopenharmony_ci			}
19658c2ecf20Sopenharmony_ci			goto bail;
19668c2ecf20Sopenharmony_ci		}
19678c2ecf20Sopenharmony_ci		i_size_write(inode, newsize);
19688c2ecf20Sopenharmony_ci		inode->i_blocks = ocfs2_inode_sector_count(inode);
19698c2ecf20Sopenharmony_ci	} else {
19708c2ecf20Sopenharmony_ci		inode->i_mapping->a_ops = &ocfs2_fast_symlink_aops;
19718c2ecf20Sopenharmony_ci		memcpy((char *) fe->id2.i_symlink, symname, l);
19728c2ecf20Sopenharmony_ci		i_size_write(inode, newsize);
19738c2ecf20Sopenharmony_ci		inode->i_blocks = 0;
19748c2ecf20Sopenharmony_ci	}
19758c2ecf20Sopenharmony_ci
19768c2ecf20Sopenharmony_ci	status = ocfs2_mark_inode_dirty(handle, inode, new_fe_bh);
19778c2ecf20Sopenharmony_ci	if (status < 0) {
19788c2ecf20Sopenharmony_ci		mlog_errno(status);
19798c2ecf20Sopenharmony_ci		goto bail;
19808c2ecf20Sopenharmony_ci	}
19818c2ecf20Sopenharmony_ci
19828c2ecf20Sopenharmony_ci	if (!ocfs2_inode_is_fast_symlink(inode)) {
19838c2ecf20Sopenharmony_ci		status = ocfs2_create_symlink_data(osb, handle, inode,
19848c2ecf20Sopenharmony_ci						   symname);
19858c2ecf20Sopenharmony_ci		if (status < 0) {
19868c2ecf20Sopenharmony_ci			mlog_errno(status);
19878c2ecf20Sopenharmony_ci			goto bail;
19888c2ecf20Sopenharmony_ci		}
19898c2ecf20Sopenharmony_ci	}
19908c2ecf20Sopenharmony_ci
19918c2ecf20Sopenharmony_ci	if (si.enable) {
19928c2ecf20Sopenharmony_ci		status = ocfs2_init_security_set(handle, inode, new_fe_bh, &si,
19938c2ecf20Sopenharmony_ci						 xattr_ac, data_ac);
19948c2ecf20Sopenharmony_ci		if (status < 0) {
19958c2ecf20Sopenharmony_ci			mlog_errno(status);
19968c2ecf20Sopenharmony_ci			goto bail;
19978c2ecf20Sopenharmony_ci		}
19988c2ecf20Sopenharmony_ci	}
19998c2ecf20Sopenharmony_ci
20008c2ecf20Sopenharmony_ci	/*
20018c2ecf20Sopenharmony_ci	 * Do this before adding the entry to the directory. We add
20028c2ecf20Sopenharmony_ci	 * also set d_op after success so that ->d_iput() will cleanup
20038c2ecf20Sopenharmony_ci	 * the dentry lock even if ocfs2_add_entry() fails below.
20048c2ecf20Sopenharmony_ci	 */
20058c2ecf20Sopenharmony_ci	status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
20068c2ecf20Sopenharmony_ci	if (status) {
20078c2ecf20Sopenharmony_ci		mlog_errno(status);
20088c2ecf20Sopenharmony_ci		goto bail;
20098c2ecf20Sopenharmony_ci	}
20108c2ecf20Sopenharmony_ci
20118c2ecf20Sopenharmony_ci	dl = dentry->d_fsdata;
20128c2ecf20Sopenharmony_ci
20138c2ecf20Sopenharmony_ci	status = ocfs2_add_entry(handle, dentry, inode,
20148c2ecf20Sopenharmony_ci				 le64_to_cpu(fe->i_blkno), parent_fe_bh,
20158c2ecf20Sopenharmony_ci				 &lookup);
20168c2ecf20Sopenharmony_ci	if (status < 0) {
20178c2ecf20Sopenharmony_ci		mlog_errno(status);
20188c2ecf20Sopenharmony_ci		goto bail;
20198c2ecf20Sopenharmony_ci	}
20208c2ecf20Sopenharmony_ci
20218c2ecf20Sopenharmony_ci	insert_inode_hash(inode);
20228c2ecf20Sopenharmony_ci	d_instantiate(dentry, inode);
20238c2ecf20Sopenharmony_cibail:
20248c2ecf20Sopenharmony_ci	if (status < 0 && did_quota)
20258c2ecf20Sopenharmony_ci		dquot_free_space_nodirty(inode,
20268c2ecf20Sopenharmony_ci					ocfs2_clusters_to_bytes(osb->sb, 1));
20278c2ecf20Sopenharmony_ci	if (status < 0 && did_quota_inode)
20288c2ecf20Sopenharmony_ci		dquot_free_inode(inode);
20298c2ecf20Sopenharmony_ci	if (handle) {
20308c2ecf20Sopenharmony_ci		if (status < 0 && fe)
20318c2ecf20Sopenharmony_ci			ocfs2_set_links_count(fe, 0);
20328c2ecf20Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
20338c2ecf20Sopenharmony_ci	}
20348c2ecf20Sopenharmony_ci
20358c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
20368c2ecf20Sopenharmony_ci	if (did_block_signals)
20378c2ecf20Sopenharmony_ci		ocfs2_unblock_signals(&oldset);
20388c2ecf20Sopenharmony_ci
20398c2ecf20Sopenharmony_ci	brelse(new_fe_bh);
20408c2ecf20Sopenharmony_ci	brelse(parent_fe_bh);
20418c2ecf20Sopenharmony_ci	kfree(si.value);
20428c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
20438c2ecf20Sopenharmony_ci	if (inode_ac)
20448c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(inode_ac);
20458c2ecf20Sopenharmony_ci	if (data_ac)
20468c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(data_ac);
20478c2ecf20Sopenharmony_ci	if (xattr_ac)
20488c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(xattr_ac);
20498c2ecf20Sopenharmony_ci	if ((status < 0) && inode) {
20508c2ecf20Sopenharmony_ci		if (dl)
20518c2ecf20Sopenharmony_ci			ocfs2_cleanup_add_entry_failure(osb, dentry, inode);
20528c2ecf20Sopenharmony_ci
20538c2ecf20Sopenharmony_ci		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SKIP_ORPHAN_DIR;
20548c2ecf20Sopenharmony_ci		clear_nlink(inode);
20558c2ecf20Sopenharmony_ci		iput(inode);
20568c2ecf20Sopenharmony_ci	}
20578c2ecf20Sopenharmony_ci
20588c2ecf20Sopenharmony_ci	if (status)
20598c2ecf20Sopenharmony_ci		mlog_errno(status);
20608c2ecf20Sopenharmony_ci
20618c2ecf20Sopenharmony_ci	return status;
20628c2ecf20Sopenharmony_ci}
20638c2ecf20Sopenharmony_ci
20648c2ecf20Sopenharmony_cistatic int ocfs2_blkno_stringify(u64 blkno, char *name)
20658c2ecf20Sopenharmony_ci{
20668c2ecf20Sopenharmony_ci	int status, namelen;
20678c2ecf20Sopenharmony_ci
20688c2ecf20Sopenharmony_ci	namelen = snprintf(name, OCFS2_ORPHAN_NAMELEN + 1, "%016llx",
20698c2ecf20Sopenharmony_ci			   (long long)blkno);
20708c2ecf20Sopenharmony_ci	if (namelen <= 0) {
20718c2ecf20Sopenharmony_ci		if (namelen)
20728c2ecf20Sopenharmony_ci			status = namelen;
20738c2ecf20Sopenharmony_ci		else
20748c2ecf20Sopenharmony_ci			status = -EINVAL;
20758c2ecf20Sopenharmony_ci		mlog_errno(status);
20768c2ecf20Sopenharmony_ci		goto bail;
20778c2ecf20Sopenharmony_ci	}
20788c2ecf20Sopenharmony_ci	if (namelen != OCFS2_ORPHAN_NAMELEN) {
20798c2ecf20Sopenharmony_ci		status = -EINVAL;
20808c2ecf20Sopenharmony_ci		mlog_errno(status);
20818c2ecf20Sopenharmony_ci		goto bail;
20828c2ecf20Sopenharmony_ci	}
20838c2ecf20Sopenharmony_ci
20848c2ecf20Sopenharmony_ci	trace_ocfs2_blkno_stringify(blkno, name, namelen);
20858c2ecf20Sopenharmony_ci
20868c2ecf20Sopenharmony_ci	status = 0;
20878c2ecf20Sopenharmony_cibail:
20888c2ecf20Sopenharmony_ci	if (status < 0)
20898c2ecf20Sopenharmony_ci		mlog_errno(status);
20908c2ecf20Sopenharmony_ci	return status;
20918c2ecf20Sopenharmony_ci}
20928c2ecf20Sopenharmony_ci
20938c2ecf20Sopenharmony_cistatic int ocfs2_lookup_lock_orphan_dir(struct ocfs2_super *osb,
20948c2ecf20Sopenharmony_ci					struct inode **ret_orphan_dir,
20958c2ecf20Sopenharmony_ci					struct buffer_head **ret_orphan_dir_bh)
20968c2ecf20Sopenharmony_ci{
20978c2ecf20Sopenharmony_ci	struct inode *orphan_dir_inode;
20988c2ecf20Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
20998c2ecf20Sopenharmony_ci	int ret = 0;
21008c2ecf20Sopenharmony_ci
21018c2ecf20Sopenharmony_ci	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
21028c2ecf20Sopenharmony_ci						       ORPHAN_DIR_SYSTEM_INODE,
21038c2ecf20Sopenharmony_ci						       osb->slot_num);
21048c2ecf20Sopenharmony_ci	if (!orphan_dir_inode) {
21058c2ecf20Sopenharmony_ci		ret = -ENOENT;
21068c2ecf20Sopenharmony_ci		mlog_errno(ret);
21078c2ecf20Sopenharmony_ci		return ret;
21088c2ecf20Sopenharmony_ci	}
21098c2ecf20Sopenharmony_ci
21108c2ecf20Sopenharmony_ci	inode_lock(orphan_dir_inode);
21118c2ecf20Sopenharmony_ci
21128c2ecf20Sopenharmony_ci	ret = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
21138c2ecf20Sopenharmony_ci	if (ret < 0) {
21148c2ecf20Sopenharmony_ci		inode_unlock(orphan_dir_inode);
21158c2ecf20Sopenharmony_ci		iput(orphan_dir_inode);
21168c2ecf20Sopenharmony_ci
21178c2ecf20Sopenharmony_ci		mlog_errno(ret);
21188c2ecf20Sopenharmony_ci		return ret;
21198c2ecf20Sopenharmony_ci	}
21208c2ecf20Sopenharmony_ci
21218c2ecf20Sopenharmony_ci	*ret_orphan_dir = orphan_dir_inode;
21228c2ecf20Sopenharmony_ci	*ret_orphan_dir_bh = orphan_dir_bh;
21238c2ecf20Sopenharmony_ci
21248c2ecf20Sopenharmony_ci	return 0;
21258c2ecf20Sopenharmony_ci}
21268c2ecf20Sopenharmony_ci
21278c2ecf20Sopenharmony_cistatic int __ocfs2_prepare_orphan_dir(struct inode *orphan_dir_inode,
21288c2ecf20Sopenharmony_ci				      struct buffer_head *orphan_dir_bh,
21298c2ecf20Sopenharmony_ci				      u64 blkno,
21308c2ecf20Sopenharmony_ci				      char *name,
21318c2ecf20Sopenharmony_ci				      struct ocfs2_dir_lookup_result *lookup,
21328c2ecf20Sopenharmony_ci				      bool dio)
21338c2ecf20Sopenharmony_ci{
21348c2ecf20Sopenharmony_ci	int ret;
21358c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(orphan_dir_inode->i_sb);
21368c2ecf20Sopenharmony_ci	int namelen = dio ?
21378c2ecf20Sopenharmony_ci			(OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN) :
21388c2ecf20Sopenharmony_ci			OCFS2_ORPHAN_NAMELEN;
21398c2ecf20Sopenharmony_ci
21408c2ecf20Sopenharmony_ci	if (dio) {
21418c2ecf20Sopenharmony_ci		ret = snprintf(name, OCFS2_DIO_ORPHAN_PREFIX_LEN + 1, "%s",
21428c2ecf20Sopenharmony_ci				OCFS2_DIO_ORPHAN_PREFIX);
21438c2ecf20Sopenharmony_ci		if (ret != OCFS2_DIO_ORPHAN_PREFIX_LEN) {
21448c2ecf20Sopenharmony_ci			ret = -EINVAL;
21458c2ecf20Sopenharmony_ci			mlog_errno(ret);
21468c2ecf20Sopenharmony_ci			return ret;
21478c2ecf20Sopenharmony_ci		}
21488c2ecf20Sopenharmony_ci
21498c2ecf20Sopenharmony_ci		ret = ocfs2_blkno_stringify(blkno,
21508c2ecf20Sopenharmony_ci				name + OCFS2_DIO_ORPHAN_PREFIX_LEN);
21518c2ecf20Sopenharmony_ci	} else
21528c2ecf20Sopenharmony_ci		ret = ocfs2_blkno_stringify(blkno, name);
21538c2ecf20Sopenharmony_ci	if (ret < 0) {
21548c2ecf20Sopenharmony_ci		mlog_errno(ret);
21558c2ecf20Sopenharmony_ci		return ret;
21568c2ecf20Sopenharmony_ci	}
21578c2ecf20Sopenharmony_ci
21588c2ecf20Sopenharmony_ci	ret = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode,
21598c2ecf20Sopenharmony_ci					   orphan_dir_bh, name,
21608c2ecf20Sopenharmony_ci					   namelen, lookup);
21618c2ecf20Sopenharmony_ci	if (ret < 0) {
21628c2ecf20Sopenharmony_ci		mlog_errno(ret);
21638c2ecf20Sopenharmony_ci		return ret;
21648c2ecf20Sopenharmony_ci	}
21658c2ecf20Sopenharmony_ci
21668c2ecf20Sopenharmony_ci	return 0;
21678c2ecf20Sopenharmony_ci}
21688c2ecf20Sopenharmony_ci
21698c2ecf20Sopenharmony_ci/**
21708c2ecf20Sopenharmony_ci * ocfs2_prepare_orphan_dir() - Prepare an orphan directory for
21718c2ecf20Sopenharmony_ci * insertion of an orphan.
21728c2ecf20Sopenharmony_ci * @osb: ocfs2 file system
21738c2ecf20Sopenharmony_ci * @ret_orphan_dir: Orphan dir inode - returned locked!
21748c2ecf20Sopenharmony_ci * @blkno: Actual block number of the inode to be inserted into orphan dir.
21758c2ecf20Sopenharmony_ci * @lookup: dir lookup result, to be passed back into functions like
21768c2ecf20Sopenharmony_ci *          ocfs2_orphan_add
21778c2ecf20Sopenharmony_ci *
21788c2ecf20Sopenharmony_ci * Returns zero on success and the ret_orphan_dir, name and lookup
21798c2ecf20Sopenharmony_ci * fields will be populated.
21808c2ecf20Sopenharmony_ci *
21818c2ecf20Sopenharmony_ci * Returns non-zero on failure.
21828c2ecf20Sopenharmony_ci */
21838c2ecf20Sopenharmony_cistatic int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
21848c2ecf20Sopenharmony_ci				    struct inode **ret_orphan_dir,
21858c2ecf20Sopenharmony_ci				    u64 blkno,
21868c2ecf20Sopenharmony_ci				    char *name,
21878c2ecf20Sopenharmony_ci				    struct ocfs2_dir_lookup_result *lookup,
21888c2ecf20Sopenharmony_ci				    bool dio)
21898c2ecf20Sopenharmony_ci{
21908c2ecf20Sopenharmony_ci	struct inode *orphan_dir_inode = NULL;
21918c2ecf20Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
21928c2ecf20Sopenharmony_ci	int ret = 0;
21938c2ecf20Sopenharmony_ci
21948c2ecf20Sopenharmony_ci	ret = ocfs2_lookup_lock_orphan_dir(osb, &orphan_dir_inode,
21958c2ecf20Sopenharmony_ci					   &orphan_dir_bh);
21968c2ecf20Sopenharmony_ci	if (ret < 0) {
21978c2ecf20Sopenharmony_ci		mlog_errno(ret);
21988c2ecf20Sopenharmony_ci		return ret;
21998c2ecf20Sopenharmony_ci	}
22008c2ecf20Sopenharmony_ci
22018c2ecf20Sopenharmony_ci	ret = __ocfs2_prepare_orphan_dir(orphan_dir_inode, orphan_dir_bh,
22028c2ecf20Sopenharmony_ci					 blkno, name, lookup, dio);
22038c2ecf20Sopenharmony_ci	if (ret < 0) {
22048c2ecf20Sopenharmony_ci		mlog_errno(ret);
22058c2ecf20Sopenharmony_ci		goto out;
22068c2ecf20Sopenharmony_ci	}
22078c2ecf20Sopenharmony_ci
22088c2ecf20Sopenharmony_ci	*ret_orphan_dir = orphan_dir_inode;
22098c2ecf20Sopenharmony_ci
22108c2ecf20Sopenharmony_ciout:
22118c2ecf20Sopenharmony_ci	brelse(orphan_dir_bh);
22128c2ecf20Sopenharmony_ci
22138c2ecf20Sopenharmony_ci	if (ret) {
22148c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir_inode, 1);
22158c2ecf20Sopenharmony_ci		inode_unlock(orphan_dir_inode);
22168c2ecf20Sopenharmony_ci		iput(orphan_dir_inode);
22178c2ecf20Sopenharmony_ci	}
22188c2ecf20Sopenharmony_ci
22198c2ecf20Sopenharmony_ci	if (ret)
22208c2ecf20Sopenharmony_ci		mlog_errno(ret);
22218c2ecf20Sopenharmony_ci	return ret;
22228c2ecf20Sopenharmony_ci}
22238c2ecf20Sopenharmony_ci
22248c2ecf20Sopenharmony_cistatic int ocfs2_orphan_add(struct ocfs2_super *osb,
22258c2ecf20Sopenharmony_ci			    handle_t *handle,
22268c2ecf20Sopenharmony_ci			    struct inode *inode,
22278c2ecf20Sopenharmony_ci			    struct buffer_head *fe_bh,
22288c2ecf20Sopenharmony_ci			    char *name,
22298c2ecf20Sopenharmony_ci			    struct ocfs2_dir_lookup_result *lookup,
22308c2ecf20Sopenharmony_ci			    struct inode *orphan_dir_inode,
22318c2ecf20Sopenharmony_ci			    bool dio)
22328c2ecf20Sopenharmony_ci{
22338c2ecf20Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
22348c2ecf20Sopenharmony_ci	int status = 0;
22358c2ecf20Sopenharmony_ci	struct ocfs2_dinode *orphan_fe;
22368c2ecf20Sopenharmony_ci	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
22378c2ecf20Sopenharmony_ci	int namelen = dio ?
22388c2ecf20Sopenharmony_ci			(OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN) :
22398c2ecf20Sopenharmony_ci			OCFS2_ORPHAN_NAMELEN;
22408c2ecf20Sopenharmony_ci
22418c2ecf20Sopenharmony_ci	trace_ocfs2_orphan_add_begin(
22428c2ecf20Sopenharmony_ci				(unsigned long long)OCFS2_I(inode)->ip_blkno);
22438c2ecf20Sopenharmony_ci
22448c2ecf20Sopenharmony_ci	status = ocfs2_read_inode_block(orphan_dir_inode, &orphan_dir_bh);
22458c2ecf20Sopenharmony_ci	if (status < 0) {
22468c2ecf20Sopenharmony_ci		mlog_errno(status);
22478c2ecf20Sopenharmony_ci		goto leave;
22488c2ecf20Sopenharmony_ci	}
22498c2ecf20Sopenharmony_ci
22508c2ecf20Sopenharmony_ci	status = ocfs2_journal_access_di(handle,
22518c2ecf20Sopenharmony_ci					 INODE_CACHE(orphan_dir_inode),
22528c2ecf20Sopenharmony_ci					 orphan_dir_bh,
22538c2ecf20Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
22548c2ecf20Sopenharmony_ci	if (status < 0) {
22558c2ecf20Sopenharmony_ci		mlog_errno(status);
22568c2ecf20Sopenharmony_ci		goto leave;
22578c2ecf20Sopenharmony_ci	}
22588c2ecf20Sopenharmony_ci
22598c2ecf20Sopenharmony_ci	/*
22608c2ecf20Sopenharmony_ci	 * We're going to journal the change of i_flags and i_orphaned_slot.
22618c2ecf20Sopenharmony_ci	 * It's safe anyway, though some callers may duplicate the journaling.
22628c2ecf20Sopenharmony_ci	 * Journaling within the func just make the logic look more
22638c2ecf20Sopenharmony_ci	 * straightforward.
22648c2ecf20Sopenharmony_ci	 */
22658c2ecf20Sopenharmony_ci	status = ocfs2_journal_access_di(handle,
22668c2ecf20Sopenharmony_ci					 INODE_CACHE(inode),
22678c2ecf20Sopenharmony_ci					 fe_bh,
22688c2ecf20Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
22698c2ecf20Sopenharmony_ci	if (status < 0) {
22708c2ecf20Sopenharmony_ci		mlog_errno(status);
22718c2ecf20Sopenharmony_ci		goto leave;
22728c2ecf20Sopenharmony_ci	}
22738c2ecf20Sopenharmony_ci
22748c2ecf20Sopenharmony_ci	/* we're a cluster, and nlink can change on disk from
22758c2ecf20Sopenharmony_ci	 * underneath us... */
22768c2ecf20Sopenharmony_ci	orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
22778c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
22788c2ecf20Sopenharmony_ci		ocfs2_add_links_count(orphan_fe, 1);
22798c2ecf20Sopenharmony_ci	set_nlink(orphan_dir_inode, ocfs2_read_links_count(orphan_fe));
22808c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, orphan_dir_bh);
22818c2ecf20Sopenharmony_ci
22828c2ecf20Sopenharmony_ci	status = __ocfs2_add_entry(handle, orphan_dir_inode, name,
22838c2ecf20Sopenharmony_ci				   namelen, inode,
22848c2ecf20Sopenharmony_ci				   OCFS2_I(inode)->ip_blkno,
22858c2ecf20Sopenharmony_ci				   orphan_dir_bh, lookup);
22868c2ecf20Sopenharmony_ci	if (status < 0) {
22878c2ecf20Sopenharmony_ci		mlog_errno(status);
22888c2ecf20Sopenharmony_ci		goto rollback;
22898c2ecf20Sopenharmony_ci	}
22908c2ecf20Sopenharmony_ci
22918c2ecf20Sopenharmony_ci	if (dio) {
22928c2ecf20Sopenharmony_ci		/* Update flag OCFS2_DIO_ORPHANED_FL and record the orphan
22938c2ecf20Sopenharmony_ci		 * slot.
22948c2ecf20Sopenharmony_ci		 */
22958c2ecf20Sopenharmony_ci		fe->i_flags |= cpu_to_le32(OCFS2_DIO_ORPHANED_FL);
22968c2ecf20Sopenharmony_ci		fe->i_dio_orphaned_slot = cpu_to_le16(osb->slot_num);
22978c2ecf20Sopenharmony_ci	} else {
22988c2ecf20Sopenharmony_ci		fe->i_flags |= cpu_to_le32(OCFS2_ORPHANED_FL);
22998c2ecf20Sopenharmony_ci		OCFS2_I(inode)->ip_flags &= ~OCFS2_INODE_SKIP_ORPHAN_DIR;
23008c2ecf20Sopenharmony_ci
23018c2ecf20Sopenharmony_ci		/* Record which orphan dir our inode now resides
23028c2ecf20Sopenharmony_ci		 * in. delete_inode will use this to determine which orphan
23038c2ecf20Sopenharmony_ci		 * dir to lock. */
23048c2ecf20Sopenharmony_ci		fe->i_orphaned_slot = cpu_to_le16(osb->slot_num);
23058c2ecf20Sopenharmony_ci	}
23068c2ecf20Sopenharmony_ci
23078c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, fe_bh);
23088c2ecf20Sopenharmony_ci
23098c2ecf20Sopenharmony_ci	trace_ocfs2_orphan_add_end((unsigned long long)OCFS2_I(inode)->ip_blkno,
23108c2ecf20Sopenharmony_ci				   osb->slot_num);
23118c2ecf20Sopenharmony_ci
23128c2ecf20Sopenharmony_cirollback:
23138c2ecf20Sopenharmony_ci	if (status < 0) {
23148c2ecf20Sopenharmony_ci		if (S_ISDIR(inode->i_mode))
23158c2ecf20Sopenharmony_ci			ocfs2_add_links_count(orphan_fe, -1);
23168c2ecf20Sopenharmony_ci		set_nlink(orphan_dir_inode, ocfs2_read_links_count(orphan_fe));
23178c2ecf20Sopenharmony_ci	}
23188c2ecf20Sopenharmony_ci
23198c2ecf20Sopenharmony_cileave:
23208c2ecf20Sopenharmony_ci	brelse(orphan_dir_bh);
23218c2ecf20Sopenharmony_ci
23228c2ecf20Sopenharmony_ci	return status;
23238c2ecf20Sopenharmony_ci}
23248c2ecf20Sopenharmony_ci
23258c2ecf20Sopenharmony_ci/* unlike orphan_add, we expect the orphan dir to already be locked here. */
23268c2ecf20Sopenharmony_ciint ocfs2_orphan_del(struct ocfs2_super *osb,
23278c2ecf20Sopenharmony_ci		     handle_t *handle,
23288c2ecf20Sopenharmony_ci		     struct inode *orphan_dir_inode,
23298c2ecf20Sopenharmony_ci		     struct inode *inode,
23308c2ecf20Sopenharmony_ci		     struct buffer_head *orphan_dir_bh,
23318c2ecf20Sopenharmony_ci		     bool dio)
23328c2ecf20Sopenharmony_ci{
23338c2ecf20Sopenharmony_ci	char name[OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN + 1];
23348c2ecf20Sopenharmony_ci	struct ocfs2_dinode *orphan_fe;
23358c2ecf20Sopenharmony_ci	int status = 0;
23368c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
23378c2ecf20Sopenharmony_ci
23388c2ecf20Sopenharmony_ci	if (dio) {
23398c2ecf20Sopenharmony_ci		status = snprintf(name, OCFS2_DIO_ORPHAN_PREFIX_LEN + 1, "%s",
23408c2ecf20Sopenharmony_ci				OCFS2_DIO_ORPHAN_PREFIX);
23418c2ecf20Sopenharmony_ci		if (status != OCFS2_DIO_ORPHAN_PREFIX_LEN) {
23428c2ecf20Sopenharmony_ci			status = -EINVAL;
23438c2ecf20Sopenharmony_ci			mlog_errno(status);
23448c2ecf20Sopenharmony_ci			return status;
23458c2ecf20Sopenharmony_ci		}
23468c2ecf20Sopenharmony_ci
23478c2ecf20Sopenharmony_ci		status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno,
23488c2ecf20Sopenharmony_ci				name + OCFS2_DIO_ORPHAN_PREFIX_LEN);
23498c2ecf20Sopenharmony_ci	} else
23508c2ecf20Sopenharmony_ci		status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
23518c2ecf20Sopenharmony_ci	if (status < 0) {
23528c2ecf20Sopenharmony_ci		mlog_errno(status);
23538c2ecf20Sopenharmony_ci		goto leave;
23548c2ecf20Sopenharmony_ci	}
23558c2ecf20Sopenharmony_ci
23568c2ecf20Sopenharmony_ci	trace_ocfs2_orphan_del(
23578c2ecf20Sopenharmony_ci	     (unsigned long long)OCFS2_I(orphan_dir_inode)->ip_blkno,
23588c2ecf20Sopenharmony_ci	     name, strlen(name));
23598c2ecf20Sopenharmony_ci
23608c2ecf20Sopenharmony_ci	status = ocfs2_journal_access_di(handle,
23618c2ecf20Sopenharmony_ci					 INODE_CACHE(orphan_dir_inode),
23628c2ecf20Sopenharmony_ci					 orphan_dir_bh,
23638c2ecf20Sopenharmony_ci					 OCFS2_JOURNAL_ACCESS_WRITE);
23648c2ecf20Sopenharmony_ci	if (status < 0) {
23658c2ecf20Sopenharmony_ci		mlog_errno(status);
23668c2ecf20Sopenharmony_ci		goto leave;
23678c2ecf20Sopenharmony_ci	}
23688c2ecf20Sopenharmony_ci
23698c2ecf20Sopenharmony_ci	/* find it's spot in the orphan directory */
23708c2ecf20Sopenharmony_ci	status = ocfs2_find_entry(name, strlen(name), orphan_dir_inode,
23718c2ecf20Sopenharmony_ci				  &lookup);
23728c2ecf20Sopenharmony_ci	if (status) {
23738c2ecf20Sopenharmony_ci		mlog_errno(status);
23748c2ecf20Sopenharmony_ci		goto leave;
23758c2ecf20Sopenharmony_ci	}
23768c2ecf20Sopenharmony_ci
23778c2ecf20Sopenharmony_ci	/* remove it from the orphan directory */
23788c2ecf20Sopenharmony_ci	status = ocfs2_delete_entry(handle, orphan_dir_inode, &lookup);
23798c2ecf20Sopenharmony_ci	if (status < 0) {
23808c2ecf20Sopenharmony_ci		mlog_errno(status);
23818c2ecf20Sopenharmony_ci		goto leave;
23828c2ecf20Sopenharmony_ci	}
23838c2ecf20Sopenharmony_ci
23848c2ecf20Sopenharmony_ci	/* do the i_nlink dance! :) */
23858c2ecf20Sopenharmony_ci	orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
23868c2ecf20Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
23878c2ecf20Sopenharmony_ci		ocfs2_add_links_count(orphan_fe, -1);
23888c2ecf20Sopenharmony_ci	set_nlink(orphan_dir_inode, ocfs2_read_links_count(orphan_fe));
23898c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, orphan_dir_bh);
23908c2ecf20Sopenharmony_ci
23918c2ecf20Sopenharmony_cileave:
23928c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
23938c2ecf20Sopenharmony_ci
23948c2ecf20Sopenharmony_ci	if (status)
23958c2ecf20Sopenharmony_ci		mlog_errno(status);
23968c2ecf20Sopenharmony_ci	return status;
23978c2ecf20Sopenharmony_ci}
23988c2ecf20Sopenharmony_ci
23998c2ecf20Sopenharmony_ci/**
24008c2ecf20Sopenharmony_ci * ocfs2_prep_new_orphaned_file() - Prepare the orphan dir to receive a newly
24018c2ecf20Sopenharmony_ci * allocated file. This is different from the typical 'add to orphan dir'
24028c2ecf20Sopenharmony_ci * operation in that the inode does not yet exist. This is a problem because
24038c2ecf20Sopenharmony_ci * the orphan dir stringifies the inode block number to come up with it's
24048c2ecf20Sopenharmony_ci * dirent. Obviously if the inode does not yet exist we have a chicken and egg
24058c2ecf20Sopenharmony_ci * problem. This function works around it by calling deeper into the orphan
24068c2ecf20Sopenharmony_ci * and suballoc code than other callers. Use this only by necessity.
24078c2ecf20Sopenharmony_ci * @dir: The directory which this inode will ultimately wind up under - not the
24088c2ecf20Sopenharmony_ci * orphan dir!
24098c2ecf20Sopenharmony_ci * @dir_bh: buffer_head the @dir inode block
24108c2ecf20Sopenharmony_ci * @orphan_name: string of length (CFS2_ORPHAN_NAMELEN + 1). Will be filled
24118c2ecf20Sopenharmony_ci * with the string to be used for orphan dirent. Pass back to the orphan dir
24128c2ecf20Sopenharmony_ci * code.
24138c2ecf20Sopenharmony_ci * @ret_orphan_dir: orphan dir inode returned to be passed back into orphan
24148c2ecf20Sopenharmony_ci * dir code.
24158c2ecf20Sopenharmony_ci * @ret_di_blkno: block number where the new inode will be allocated.
24168c2ecf20Sopenharmony_ci * @orphan_insert: Dir insert context to be passed back into orphan dir code.
24178c2ecf20Sopenharmony_ci * @ret_inode_ac: Inode alloc context to be passed back to the allocator.
24188c2ecf20Sopenharmony_ci *
24198c2ecf20Sopenharmony_ci * Returns zero on success and the ret_orphan_dir, name and lookup
24208c2ecf20Sopenharmony_ci * fields will be populated.
24218c2ecf20Sopenharmony_ci *
24228c2ecf20Sopenharmony_ci * Returns non-zero on failure.
24238c2ecf20Sopenharmony_ci */
24248c2ecf20Sopenharmony_cistatic int ocfs2_prep_new_orphaned_file(struct inode *dir,
24258c2ecf20Sopenharmony_ci					struct buffer_head *dir_bh,
24268c2ecf20Sopenharmony_ci					char *orphan_name,
24278c2ecf20Sopenharmony_ci					struct inode **ret_orphan_dir,
24288c2ecf20Sopenharmony_ci					u64 *ret_di_blkno,
24298c2ecf20Sopenharmony_ci					struct ocfs2_dir_lookup_result *orphan_insert,
24308c2ecf20Sopenharmony_ci					struct ocfs2_alloc_context **ret_inode_ac)
24318c2ecf20Sopenharmony_ci{
24328c2ecf20Sopenharmony_ci	int ret;
24338c2ecf20Sopenharmony_ci	u64 di_blkno;
24348c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
24358c2ecf20Sopenharmony_ci	struct inode *orphan_dir = NULL;
24368c2ecf20Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
24378c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *inode_ac = NULL;
24388c2ecf20Sopenharmony_ci
24398c2ecf20Sopenharmony_ci	ret = ocfs2_lookup_lock_orphan_dir(osb, &orphan_dir, &orphan_dir_bh);
24408c2ecf20Sopenharmony_ci	if (ret < 0) {
24418c2ecf20Sopenharmony_ci		mlog_errno(ret);
24428c2ecf20Sopenharmony_ci		return ret;
24438c2ecf20Sopenharmony_ci	}
24448c2ecf20Sopenharmony_ci
24458c2ecf20Sopenharmony_ci	/* reserve an inode spot */
24468c2ecf20Sopenharmony_ci	ret = ocfs2_reserve_new_inode(osb, &inode_ac);
24478c2ecf20Sopenharmony_ci	if (ret < 0) {
24488c2ecf20Sopenharmony_ci		if (ret != -ENOSPC)
24498c2ecf20Sopenharmony_ci			mlog_errno(ret);
24508c2ecf20Sopenharmony_ci		goto out;
24518c2ecf20Sopenharmony_ci	}
24528c2ecf20Sopenharmony_ci
24538c2ecf20Sopenharmony_ci	ret = ocfs2_find_new_inode_loc(dir, dir_bh, inode_ac,
24548c2ecf20Sopenharmony_ci				       &di_blkno);
24558c2ecf20Sopenharmony_ci	if (ret) {
24568c2ecf20Sopenharmony_ci		mlog_errno(ret);
24578c2ecf20Sopenharmony_ci		goto out;
24588c2ecf20Sopenharmony_ci	}
24598c2ecf20Sopenharmony_ci
24608c2ecf20Sopenharmony_ci	ret = __ocfs2_prepare_orphan_dir(orphan_dir, orphan_dir_bh,
24618c2ecf20Sopenharmony_ci					 di_blkno, orphan_name, orphan_insert,
24628c2ecf20Sopenharmony_ci					 false);
24638c2ecf20Sopenharmony_ci	if (ret < 0) {
24648c2ecf20Sopenharmony_ci		mlog_errno(ret);
24658c2ecf20Sopenharmony_ci		goto out;
24668c2ecf20Sopenharmony_ci	}
24678c2ecf20Sopenharmony_ci
24688c2ecf20Sopenharmony_ciout:
24698c2ecf20Sopenharmony_ci	if (ret == 0) {
24708c2ecf20Sopenharmony_ci		*ret_orphan_dir = orphan_dir;
24718c2ecf20Sopenharmony_ci		*ret_di_blkno = di_blkno;
24728c2ecf20Sopenharmony_ci		*ret_inode_ac = inode_ac;
24738c2ecf20Sopenharmony_ci		/*
24748c2ecf20Sopenharmony_ci		 * orphan_name and orphan_insert are already up to
24758c2ecf20Sopenharmony_ci		 * date via prepare_orphan_dir
24768c2ecf20Sopenharmony_ci		 */
24778c2ecf20Sopenharmony_ci	} else {
24788c2ecf20Sopenharmony_ci		/* Unroll reserve_new_inode* */
24798c2ecf20Sopenharmony_ci		if (inode_ac)
24808c2ecf20Sopenharmony_ci			ocfs2_free_alloc_context(inode_ac);
24818c2ecf20Sopenharmony_ci
24828c2ecf20Sopenharmony_ci		/* Unroll orphan dir locking */
24838c2ecf20Sopenharmony_ci		inode_unlock(orphan_dir);
24848c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir, 1);
24858c2ecf20Sopenharmony_ci		iput(orphan_dir);
24868c2ecf20Sopenharmony_ci	}
24878c2ecf20Sopenharmony_ci
24888c2ecf20Sopenharmony_ci	brelse(orphan_dir_bh);
24898c2ecf20Sopenharmony_ci
24908c2ecf20Sopenharmony_ci	return ret;
24918c2ecf20Sopenharmony_ci}
24928c2ecf20Sopenharmony_ci
24938c2ecf20Sopenharmony_ciint ocfs2_create_inode_in_orphan(struct inode *dir,
24948c2ecf20Sopenharmony_ci				 int mode,
24958c2ecf20Sopenharmony_ci				 struct inode **new_inode)
24968c2ecf20Sopenharmony_ci{
24978c2ecf20Sopenharmony_ci	int status, did_quota_inode = 0;
24988c2ecf20Sopenharmony_ci	struct inode *inode = NULL;
24998c2ecf20Sopenharmony_ci	struct inode *orphan_dir = NULL;
25008c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
25018c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
25028c2ecf20Sopenharmony_ci	char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
25038c2ecf20Sopenharmony_ci	struct buffer_head *parent_di_bh = NULL;
25048c2ecf20Sopenharmony_ci	struct buffer_head *new_di_bh = NULL;
25058c2ecf20Sopenharmony_ci	struct ocfs2_alloc_context *inode_ac = NULL;
25068c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
25078c2ecf20Sopenharmony_ci	u64 di_blkno, suballoc_loc;
25088c2ecf20Sopenharmony_ci	u16 suballoc_bit;
25098c2ecf20Sopenharmony_ci
25108c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock(dir, &parent_di_bh, 1);
25118c2ecf20Sopenharmony_ci	if (status < 0) {
25128c2ecf20Sopenharmony_ci		if (status != -ENOENT)
25138c2ecf20Sopenharmony_ci			mlog_errno(status);
25148c2ecf20Sopenharmony_ci		return status;
25158c2ecf20Sopenharmony_ci	}
25168c2ecf20Sopenharmony_ci
25178c2ecf20Sopenharmony_ci	status = ocfs2_prep_new_orphaned_file(dir, parent_di_bh,
25188c2ecf20Sopenharmony_ci					      orphan_name, &orphan_dir,
25198c2ecf20Sopenharmony_ci					      &di_blkno, &orphan_insert, &inode_ac);
25208c2ecf20Sopenharmony_ci	if (status < 0) {
25218c2ecf20Sopenharmony_ci		if (status != -ENOSPC)
25228c2ecf20Sopenharmony_ci			mlog_errno(status);
25238c2ecf20Sopenharmony_ci		goto leave;
25248c2ecf20Sopenharmony_ci	}
25258c2ecf20Sopenharmony_ci
25268c2ecf20Sopenharmony_ci	inode = ocfs2_get_init_inode(dir, mode);
25278c2ecf20Sopenharmony_ci	if (IS_ERR(inode)) {
25288c2ecf20Sopenharmony_ci		status = PTR_ERR(inode);
25298c2ecf20Sopenharmony_ci		inode = NULL;
25308c2ecf20Sopenharmony_ci		mlog_errno(status);
25318c2ecf20Sopenharmony_ci		goto leave;
25328c2ecf20Sopenharmony_ci	}
25338c2ecf20Sopenharmony_ci
25348c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb, 0, 0));
25358c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
25368c2ecf20Sopenharmony_ci		status = PTR_ERR(handle);
25378c2ecf20Sopenharmony_ci		handle = NULL;
25388c2ecf20Sopenharmony_ci		mlog_errno(status);
25398c2ecf20Sopenharmony_ci		goto leave;
25408c2ecf20Sopenharmony_ci	}
25418c2ecf20Sopenharmony_ci
25428c2ecf20Sopenharmony_ci	status = dquot_alloc_inode(inode);
25438c2ecf20Sopenharmony_ci	if (status)
25448c2ecf20Sopenharmony_ci		goto leave;
25458c2ecf20Sopenharmony_ci	did_quota_inode = 1;
25468c2ecf20Sopenharmony_ci
25478c2ecf20Sopenharmony_ci	status = ocfs2_claim_new_inode_at_loc(handle, dir, inode_ac,
25488c2ecf20Sopenharmony_ci					      &suballoc_loc,
25498c2ecf20Sopenharmony_ci					      &suballoc_bit, di_blkno);
25508c2ecf20Sopenharmony_ci	if (status < 0) {
25518c2ecf20Sopenharmony_ci		mlog_errno(status);
25528c2ecf20Sopenharmony_ci		goto leave;
25538c2ecf20Sopenharmony_ci	}
25548c2ecf20Sopenharmony_ci
25558c2ecf20Sopenharmony_ci	clear_nlink(inode);
25568c2ecf20Sopenharmony_ci	/* do the real work now. */
25578c2ecf20Sopenharmony_ci	status = __ocfs2_mknod_locked(dir, inode,
25588c2ecf20Sopenharmony_ci				      0, &new_di_bh, parent_di_bh, handle,
25598c2ecf20Sopenharmony_ci				      inode_ac, di_blkno, suballoc_loc,
25608c2ecf20Sopenharmony_ci				      suballoc_bit);
25618c2ecf20Sopenharmony_ci	if (status < 0) {
25628c2ecf20Sopenharmony_ci		mlog_errno(status);
25638c2ecf20Sopenharmony_ci		goto leave;
25648c2ecf20Sopenharmony_ci	}
25658c2ecf20Sopenharmony_ci
25668c2ecf20Sopenharmony_ci	status = ocfs2_orphan_add(osb, handle, inode, new_di_bh, orphan_name,
25678c2ecf20Sopenharmony_ci				  &orphan_insert, orphan_dir, false);
25688c2ecf20Sopenharmony_ci	if (status < 0) {
25698c2ecf20Sopenharmony_ci		mlog_errno(status);
25708c2ecf20Sopenharmony_ci		goto leave;
25718c2ecf20Sopenharmony_ci	}
25728c2ecf20Sopenharmony_ci
25738c2ecf20Sopenharmony_ci	/* get open lock so that only nodes can't remove it from orphan dir. */
25748c2ecf20Sopenharmony_ci	status = ocfs2_open_lock(inode);
25758c2ecf20Sopenharmony_ci	if (status < 0)
25768c2ecf20Sopenharmony_ci		mlog_errno(status);
25778c2ecf20Sopenharmony_ci
25788c2ecf20Sopenharmony_ci	insert_inode_hash(inode);
25798c2ecf20Sopenharmony_cileave:
25808c2ecf20Sopenharmony_ci	if (status < 0 && did_quota_inode)
25818c2ecf20Sopenharmony_ci		dquot_free_inode(inode);
25828c2ecf20Sopenharmony_ci	if (handle)
25838c2ecf20Sopenharmony_ci		ocfs2_commit_trans(osb, handle);
25848c2ecf20Sopenharmony_ci
25858c2ecf20Sopenharmony_ci	if (orphan_dir) {
25868c2ecf20Sopenharmony_ci		/* This was locked for us in ocfs2_prepare_orphan_dir() */
25878c2ecf20Sopenharmony_ci		ocfs2_inode_unlock(orphan_dir, 1);
25888c2ecf20Sopenharmony_ci		inode_unlock(orphan_dir);
25898c2ecf20Sopenharmony_ci		iput(orphan_dir);
25908c2ecf20Sopenharmony_ci	}
25918c2ecf20Sopenharmony_ci
25928c2ecf20Sopenharmony_ci	if ((status < 0) && inode) {
25938c2ecf20Sopenharmony_ci		clear_nlink(inode);
25948c2ecf20Sopenharmony_ci		iput(inode);
25958c2ecf20Sopenharmony_ci	}
25968c2ecf20Sopenharmony_ci
25978c2ecf20Sopenharmony_ci	if (inode_ac)
25988c2ecf20Sopenharmony_ci		ocfs2_free_alloc_context(inode_ac);
25998c2ecf20Sopenharmony_ci
26008c2ecf20Sopenharmony_ci	brelse(new_di_bh);
26018c2ecf20Sopenharmony_ci
26028c2ecf20Sopenharmony_ci	if (!status)
26038c2ecf20Sopenharmony_ci		*new_inode = inode;
26048c2ecf20Sopenharmony_ci
26058c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&orphan_insert);
26068c2ecf20Sopenharmony_ci
26078c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
26088c2ecf20Sopenharmony_ci	brelse(parent_di_bh);
26098c2ecf20Sopenharmony_ci	return status;
26108c2ecf20Sopenharmony_ci}
26118c2ecf20Sopenharmony_ci
26128c2ecf20Sopenharmony_ciint ocfs2_add_inode_to_orphan(struct ocfs2_super *osb,
26138c2ecf20Sopenharmony_ci	struct inode *inode)
26148c2ecf20Sopenharmony_ci{
26158c2ecf20Sopenharmony_ci	char orphan_name[OCFS2_DIO_ORPHAN_PREFIX_LEN + OCFS2_ORPHAN_NAMELEN + 1];
26168c2ecf20Sopenharmony_ci	struct inode *orphan_dir_inode = NULL;
26178c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
26188c2ecf20Sopenharmony_ci	struct buffer_head *di_bh = NULL;
26198c2ecf20Sopenharmony_ci	int status = 0;
26208c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
26218c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = NULL;
26228c2ecf20Sopenharmony_ci
26238c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock(inode, &di_bh, 1);
26248c2ecf20Sopenharmony_ci	if (status < 0) {
26258c2ecf20Sopenharmony_ci		mlog_errno(status);
26268c2ecf20Sopenharmony_ci		goto bail;
26278c2ecf20Sopenharmony_ci	}
26288c2ecf20Sopenharmony_ci
26298c2ecf20Sopenharmony_ci	di = (struct ocfs2_dinode *) di_bh->b_data;
26308c2ecf20Sopenharmony_ci	/*
26318c2ecf20Sopenharmony_ci	 * Another append dio crashed?
26328c2ecf20Sopenharmony_ci	 * If so, manually recover it first.
26338c2ecf20Sopenharmony_ci	 */
26348c2ecf20Sopenharmony_ci	if (unlikely(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL))) {
26358c2ecf20Sopenharmony_ci		status = ocfs2_truncate_file(inode, di_bh, i_size_read(inode));
26368c2ecf20Sopenharmony_ci		if (status < 0) {
26378c2ecf20Sopenharmony_ci			if (status != -ENOSPC)
26388c2ecf20Sopenharmony_ci				mlog_errno(status);
26398c2ecf20Sopenharmony_ci			goto bail_unlock_inode;
26408c2ecf20Sopenharmony_ci		}
26418c2ecf20Sopenharmony_ci
26428c2ecf20Sopenharmony_ci		status = ocfs2_del_inode_from_orphan(osb, inode, di_bh, 0, 0);
26438c2ecf20Sopenharmony_ci		if (status < 0) {
26448c2ecf20Sopenharmony_ci			mlog_errno(status);
26458c2ecf20Sopenharmony_ci			goto bail_unlock_inode;
26468c2ecf20Sopenharmony_ci		}
26478c2ecf20Sopenharmony_ci	}
26488c2ecf20Sopenharmony_ci
26498c2ecf20Sopenharmony_ci	status = ocfs2_prepare_orphan_dir(osb, &orphan_dir_inode,
26508c2ecf20Sopenharmony_ci			OCFS2_I(inode)->ip_blkno,
26518c2ecf20Sopenharmony_ci			orphan_name,
26528c2ecf20Sopenharmony_ci			&orphan_insert,
26538c2ecf20Sopenharmony_ci			true);
26548c2ecf20Sopenharmony_ci	if (status < 0) {
26558c2ecf20Sopenharmony_ci		mlog_errno(status);
26568c2ecf20Sopenharmony_ci		goto bail_unlock_inode;
26578c2ecf20Sopenharmony_ci	}
26588c2ecf20Sopenharmony_ci
26598c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb,
26608c2ecf20Sopenharmony_ci			OCFS2_INODE_ADD_TO_ORPHAN_CREDITS);
26618c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
26628c2ecf20Sopenharmony_ci		status = PTR_ERR(handle);
26638c2ecf20Sopenharmony_ci		goto bail_unlock_orphan;
26648c2ecf20Sopenharmony_ci	}
26658c2ecf20Sopenharmony_ci
26668c2ecf20Sopenharmony_ci	status = ocfs2_orphan_add(osb, handle, inode, di_bh, orphan_name,
26678c2ecf20Sopenharmony_ci			&orphan_insert, orphan_dir_inode, true);
26688c2ecf20Sopenharmony_ci	if (status)
26698c2ecf20Sopenharmony_ci		mlog_errno(status);
26708c2ecf20Sopenharmony_ci
26718c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
26728c2ecf20Sopenharmony_ci
26738c2ecf20Sopenharmony_cibail_unlock_orphan:
26748c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(orphan_dir_inode, 1);
26758c2ecf20Sopenharmony_ci	inode_unlock(orphan_dir_inode);
26768c2ecf20Sopenharmony_ci	iput(orphan_dir_inode);
26778c2ecf20Sopenharmony_ci
26788c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&orphan_insert);
26798c2ecf20Sopenharmony_ci
26808c2ecf20Sopenharmony_cibail_unlock_inode:
26818c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(inode, 1);
26828c2ecf20Sopenharmony_ci	brelse(di_bh);
26838c2ecf20Sopenharmony_ci
26848c2ecf20Sopenharmony_cibail:
26858c2ecf20Sopenharmony_ci	return status;
26868c2ecf20Sopenharmony_ci}
26878c2ecf20Sopenharmony_ci
26888c2ecf20Sopenharmony_ciint ocfs2_del_inode_from_orphan(struct ocfs2_super *osb,
26898c2ecf20Sopenharmony_ci		struct inode *inode, struct buffer_head *di_bh,
26908c2ecf20Sopenharmony_ci		int update_isize, loff_t end)
26918c2ecf20Sopenharmony_ci{
26928c2ecf20Sopenharmony_ci	struct inode *orphan_dir_inode = NULL;
26938c2ecf20Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
26948c2ecf20Sopenharmony_ci	struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data;
26958c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
26968c2ecf20Sopenharmony_ci	int status = 0;
26978c2ecf20Sopenharmony_ci
26988c2ecf20Sopenharmony_ci	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
26998c2ecf20Sopenharmony_ci			ORPHAN_DIR_SYSTEM_INODE,
27008c2ecf20Sopenharmony_ci			le16_to_cpu(di->i_dio_orphaned_slot));
27018c2ecf20Sopenharmony_ci	if (!orphan_dir_inode) {
27028c2ecf20Sopenharmony_ci		status = -ENOENT;
27038c2ecf20Sopenharmony_ci		mlog_errno(status);
27048c2ecf20Sopenharmony_ci		goto bail;
27058c2ecf20Sopenharmony_ci	}
27068c2ecf20Sopenharmony_ci
27078c2ecf20Sopenharmony_ci	inode_lock(orphan_dir_inode);
27088c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
27098c2ecf20Sopenharmony_ci	if (status < 0) {
27108c2ecf20Sopenharmony_ci		inode_unlock(orphan_dir_inode);
27118c2ecf20Sopenharmony_ci		iput(orphan_dir_inode);
27128c2ecf20Sopenharmony_ci		mlog_errno(status);
27138c2ecf20Sopenharmony_ci		goto bail;
27148c2ecf20Sopenharmony_ci	}
27158c2ecf20Sopenharmony_ci
27168c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb,
27178c2ecf20Sopenharmony_ci			OCFS2_INODE_DEL_FROM_ORPHAN_CREDITS);
27188c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
27198c2ecf20Sopenharmony_ci		status = PTR_ERR(handle);
27208c2ecf20Sopenharmony_ci		goto bail_unlock_orphan;
27218c2ecf20Sopenharmony_ci	}
27228c2ecf20Sopenharmony_ci
27238c2ecf20Sopenharmony_ci	BUG_ON(!(di->i_flags & cpu_to_le32(OCFS2_DIO_ORPHANED_FL)));
27248c2ecf20Sopenharmony_ci
27258c2ecf20Sopenharmony_ci	status = ocfs2_orphan_del(osb, handle, orphan_dir_inode,
27268c2ecf20Sopenharmony_ci				inode, orphan_dir_bh, true);
27278c2ecf20Sopenharmony_ci	if (status < 0) {
27288c2ecf20Sopenharmony_ci		mlog_errno(status);
27298c2ecf20Sopenharmony_ci		goto bail_commit;
27308c2ecf20Sopenharmony_ci	}
27318c2ecf20Sopenharmony_ci
27328c2ecf20Sopenharmony_ci	status = ocfs2_journal_access_di(handle,
27338c2ecf20Sopenharmony_ci			INODE_CACHE(inode),
27348c2ecf20Sopenharmony_ci			di_bh,
27358c2ecf20Sopenharmony_ci			OCFS2_JOURNAL_ACCESS_WRITE);
27368c2ecf20Sopenharmony_ci	if (status < 0) {
27378c2ecf20Sopenharmony_ci		mlog_errno(status);
27388c2ecf20Sopenharmony_ci		goto bail_commit;
27398c2ecf20Sopenharmony_ci	}
27408c2ecf20Sopenharmony_ci
27418c2ecf20Sopenharmony_ci	di->i_flags &= ~cpu_to_le32(OCFS2_DIO_ORPHANED_FL);
27428c2ecf20Sopenharmony_ci	di->i_dio_orphaned_slot = 0;
27438c2ecf20Sopenharmony_ci
27448c2ecf20Sopenharmony_ci	if (update_isize) {
27458c2ecf20Sopenharmony_ci		status = ocfs2_set_inode_size(handle, inode, di_bh, end);
27468c2ecf20Sopenharmony_ci		if (status)
27478c2ecf20Sopenharmony_ci			mlog_errno(status);
27488c2ecf20Sopenharmony_ci	} else
27498c2ecf20Sopenharmony_ci		ocfs2_journal_dirty(handle, di_bh);
27508c2ecf20Sopenharmony_ci
27518c2ecf20Sopenharmony_cibail_commit:
27528c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
27538c2ecf20Sopenharmony_ci
27548c2ecf20Sopenharmony_cibail_unlock_orphan:
27558c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(orphan_dir_inode, 1);
27568c2ecf20Sopenharmony_ci	inode_unlock(orphan_dir_inode);
27578c2ecf20Sopenharmony_ci	brelse(orphan_dir_bh);
27588c2ecf20Sopenharmony_ci	iput(orphan_dir_inode);
27598c2ecf20Sopenharmony_ci
27608c2ecf20Sopenharmony_cibail:
27618c2ecf20Sopenharmony_ci	return status;
27628c2ecf20Sopenharmony_ci}
27638c2ecf20Sopenharmony_ci
27648c2ecf20Sopenharmony_ciint ocfs2_mv_orphaned_inode_to_new(struct inode *dir,
27658c2ecf20Sopenharmony_ci				   struct inode *inode,
27668c2ecf20Sopenharmony_ci				   struct dentry *dentry)
27678c2ecf20Sopenharmony_ci{
27688c2ecf20Sopenharmony_ci	int status = 0;
27698c2ecf20Sopenharmony_ci	struct buffer_head *parent_di_bh = NULL;
27708c2ecf20Sopenharmony_ci	handle_t *handle = NULL;
27718c2ecf20Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
27728c2ecf20Sopenharmony_ci	struct ocfs2_dinode *dir_di, *di;
27738c2ecf20Sopenharmony_ci	struct inode *orphan_dir_inode = NULL;
27748c2ecf20Sopenharmony_ci	struct buffer_head *orphan_dir_bh = NULL;
27758c2ecf20Sopenharmony_ci	struct buffer_head *di_bh = NULL;
27768c2ecf20Sopenharmony_ci	struct ocfs2_dir_lookup_result lookup = { NULL, };
27778c2ecf20Sopenharmony_ci
27788c2ecf20Sopenharmony_ci	trace_ocfs2_mv_orphaned_inode_to_new(dir, dentry,
27798c2ecf20Sopenharmony_ci				dentry->d_name.len, dentry->d_name.name,
27808c2ecf20Sopenharmony_ci				(unsigned long long)OCFS2_I(dir)->ip_blkno,
27818c2ecf20Sopenharmony_ci				(unsigned long long)OCFS2_I(inode)->ip_blkno);
27828c2ecf20Sopenharmony_ci
27838c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock(dir, &parent_di_bh, 1);
27848c2ecf20Sopenharmony_ci	if (status < 0) {
27858c2ecf20Sopenharmony_ci		if (status != -ENOENT)
27868c2ecf20Sopenharmony_ci			mlog_errno(status);
27878c2ecf20Sopenharmony_ci		return status;
27888c2ecf20Sopenharmony_ci	}
27898c2ecf20Sopenharmony_ci
27908c2ecf20Sopenharmony_ci	dir_di = (struct ocfs2_dinode *) parent_di_bh->b_data;
27918c2ecf20Sopenharmony_ci	if (!dir_di->i_links_count) {
27928c2ecf20Sopenharmony_ci		/* can't make a file in a deleted directory. */
27938c2ecf20Sopenharmony_ci		status = -ENOENT;
27948c2ecf20Sopenharmony_ci		goto leave;
27958c2ecf20Sopenharmony_ci	}
27968c2ecf20Sopenharmony_ci
27978c2ecf20Sopenharmony_ci	status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
27988c2ecf20Sopenharmony_ci					   dentry->d_name.len);
27998c2ecf20Sopenharmony_ci	if (status)
28008c2ecf20Sopenharmony_ci		goto leave;
28018c2ecf20Sopenharmony_ci
28028c2ecf20Sopenharmony_ci	/* get a spot inside the dir. */
28038c2ecf20Sopenharmony_ci	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_di_bh,
28048c2ecf20Sopenharmony_ci					      dentry->d_name.name,
28058c2ecf20Sopenharmony_ci					      dentry->d_name.len, &lookup);
28068c2ecf20Sopenharmony_ci	if (status < 0) {
28078c2ecf20Sopenharmony_ci		mlog_errno(status);
28088c2ecf20Sopenharmony_ci		goto leave;
28098c2ecf20Sopenharmony_ci	}
28108c2ecf20Sopenharmony_ci
28118c2ecf20Sopenharmony_ci	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
28128c2ecf20Sopenharmony_ci						       ORPHAN_DIR_SYSTEM_INODE,
28138c2ecf20Sopenharmony_ci						       osb->slot_num);
28148c2ecf20Sopenharmony_ci	if (!orphan_dir_inode) {
28158c2ecf20Sopenharmony_ci		status = -ENOENT;
28168c2ecf20Sopenharmony_ci		mlog_errno(status);
28178c2ecf20Sopenharmony_ci		goto leave;
28188c2ecf20Sopenharmony_ci	}
28198c2ecf20Sopenharmony_ci
28208c2ecf20Sopenharmony_ci	inode_lock(orphan_dir_inode);
28218c2ecf20Sopenharmony_ci
28228c2ecf20Sopenharmony_ci	status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1);
28238c2ecf20Sopenharmony_ci	if (status < 0) {
28248c2ecf20Sopenharmony_ci		mlog_errno(status);
28258c2ecf20Sopenharmony_ci		inode_unlock(orphan_dir_inode);
28268c2ecf20Sopenharmony_ci		iput(orphan_dir_inode);
28278c2ecf20Sopenharmony_ci		goto leave;
28288c2ecf20Sopenharmony_ci	}
28298c2ecf20Sopenharmony_ci
28308c2ecf20Sopenharmony_ci	status = ocfs2_read_inode_block(inode, &di_bh);
28318c2ecf20Sopenharmony_ci	if (status < 0) {
28328c2ecf20Sopenharmony_ci		mlog_errno(status);
28338c2ecf20Sopenharmony_ci		goto orphan_unlock;
28348c2ecf20Sopenharmony_ci	}
28358c2ecf20Sopenharmony_ci
28368c2ecf20Sopenharmony_ci	handle = ocfs2_start_trans(osb, ocfs2_rename_credits(osb->sb));
28378c2ecf20Sopenharmony_ci	if (IS_ERR(handle)) {
28388c2ecf20Sopenharmony_ci		status = PTR_ERR(handle);
28398c2ecf20Sopenharmony_ci		handle = NULL;
28408c2ecf20Sopenharmony_ci		mlog_errno(status);
28418c2ecf20Sopenharmony_ci		goto orphan_unlock;
28428c2ecf20Sopenharmony_ci	}
28438c2ecf20Sopenharmony_ci
28448c2ecf20Sopenharmony_ci	status = ocfs2_journal_access_di(handle, INODE_CACHE(inode),
28458c2ecf20Sopenharmony_ci					 di_bh, OCFS2_JOURNAL_ACCESS_WRITE);
28468c2ecf20Sopenharmony_ci	if (status < 0) {
28478c2ecf20Sopenharmony_ci		mlog_errno(status);
28488c2ecf20Sopenharmony_ci		goto out_commit;
28498c2ecf20Sopenharmony_ci	}
28508c2ecf20Sopenharmony_ci
28518c2ecf20Sopenharmony_ci	status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
28528c2ecf20Sopenharmony_ci				  orphan_dir_bh, false);
28538c2ecf20Sopenharmony_ci	if (status < 0) {
28548c2ecf20Sopenharmony_ci		mlog_errno(status);
28558c2ecf20Sopenharmony_ci		goto out_commit;
28568c2ecf20Sopenharmony_ci	}
28578c2ecf20Sopenharmony_ci
28588c2ecf20Sopenharmony_ci	di = (struct ocfs2_dinode *)di_bh->b_data;
28598c2ecf20Sopenharmony_ci	di->i_flags &= ~cpu_to_le32(OCFS2_ORPHANED_FL);
28608c2ecf20Sopenharmony_ci	di->i_orphaned_slot = 0;
28618c2ecf20Sopenharmony_ci	set_nlink(inode, 1);
28628c2ecf20Sopenharmony_ci	ocfs2_set_links_count(di, inode->i_nlink);
28638c2ecf20Sopenharmony_ci	ocfs2_update_inode_fsync_trans(handle, inode, 1);
28648c2ecf20Sopenharmony_ci	ocfs2_journal_dirty(handle, di_bh);
28658c2ecf20Sopenharmony_ci
28668c2ecf20Sopenharmony_ci	status = ocfs2_add_entry(handle, dentry, inode,
28678c2ecf20Sopenharmony_ci				 OCFS2_I(inode)->ip_blkno, parent_di_bh,
28688c2ecf20Sopenharmony_ci				 &lookup);
28698c2ecf20Sopenharmony_ci	if (status < 0) {
28708c2ecf20Sopenharmony_ci		mlog_errno(status);
28718c2ecf20Sopenharmony_ci		goto out_commit;
28728c2ecf20Sopenharmony_ci	}
28738c2ecf20Sopenharmony_ci
28748c2ecf20Sopenharmony_ci	status = ocfs2_dentry_attach_lock(dentry, inode,
28758c2ecf20Sopenharmony_ci					  OCFS2_I(dir)->ip_blkno);
28768c2ecf20Sopenharmony_ci	if (status) {
28778c2ecf20Sopenharmony_ci		mlog_errno(status);
28788c2ecf20Sopenharmony_ci		goto out_commit;
28798c2ecf20Sopenharmony_ci	}
28808c2ecf20Sopenharmony_ci
28818c2ecf20Sopenharmony_ci	d_instantiate(dentry, inode);
28828c2ecf20Sopenharmony_ci	status = 0;
28838c2ecf20Sopenharmony_ciout_commit:
28848c2ecf20Sopenharmony_ci	ocfs2_commit_trans(osb, handle);
28858c2ecf20Sopenharmony_ciorphan_unlock:
28868c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(orphan_dir_inode, 1);
28878c2ecf20Sopenharmony_ci	inode_unlock(orphan_dir_inode);
28888c2ecf20Sopenharmony_ci	iput(orphan_dir_inode);
28898c2ecf20Sopenharmony_cileave:
28908c2ecf20Sopenharmony_ci
28918c2ecf20Sopenharmony_ci	ocfs2_inode_unlock(dir, 1);
28928c2ecf20Sopenharmony_ci
28938c2ecf20Sopenharmony_ci	brelse(di_bh);
28948c2ecf20Sopenharmony_ci	brelse(parent_di_bh);
28958c2ecf20Sopenharmony_ci	brelse(orphan_dir_bh);
28968c2ecf20Sopenharmony_ci
28978c2ecf20Sopenharmony_ci	ocfs2_free_dir_lookup_result(&lookup);
28988c2ecf20Sopenharmony_ci
28998c2ecf20Sopenharmony_ci	if (status)
29008c2ecf20Sopenharmony_ci		mlog_errno(status);
29018c2ecf20Sopenharmony_ci
29028c2ecf20Sopenharmony_ci	return status;
29038c2ecf20Sopenharmony_ci}
29048c2ecf20Sopenharmony_ci
29058c2ecf20Sopenharmony_ciconst struct inode_operations ocfs2_dir_iops = {
29068c2ecf20Sopenharmony_ci	.create		= ocfs2_create,
29078c2ecf20Sopenharmony_ci	.lookup		= ocfs2_lookup,
29088c2ecf20Sopenharmony_ci	.link		= ocfs2_link,
29098c2ecf20Sopenharmony_ci	.unlink		= ocfs2_unlink,
29108c2ecf20Sopenharmony_ci	.rmdir		= ocfs2_unlink,
29118c2ecf20Sopenharmony_ci	.symlink	= ocfs2_symlink,
29128c2ecf20Sopenharmony_ci	.mkdir		= ocfs2_mkdir,
29138c2ecf20Sopenharmony_ci	.mknod		= ocfs2_mknod,
29148c2ecf20Sopenharmony_ci	.rename		= ocfs2_rename,
29158c2ecf20Sopenharmony_ci	.setattr	= ocfs2_setattr,
29168c2ecf20Sopenharmony_ci	.getattr	= ocfs2_getattr,
29178c2ecf20Sopenharmony_ci	.permission	= ocfs2_permission,
29188c2ecf20Sopenharmony_ci	.listxattr	= ocfs2_listxattr,
29198c2ecf20Sopenharmony_ci	.fiemap         = ocfs2_fiemap,
29208c2ecf20Sopenharmony_ci	.get_acl	= ocfs2_iop_get_acl,
29218c2ecf20Sopenharmony_ci	.set_acl	= ocfs2_iop_set_acl,
29228c2ecf20Sopenharmony_ci};
2923