162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *   Copyright (C) International Business Machines Corp., 2000-2004
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/fs.h>
762306a36Sopenharmony_ci#include <linux/quotaops.h>
862306a36Sopenharmony_ci#include "jfs_incore.h"
962306a36Sopenharmony_ci#include "jfs_inode.h"
1062306a36Sopenharmony_ci#include "jfs_filsys.h"
1162306a36Sopenharmony_ci#include "jfs_imap.h"
1262306a36Sopenharmony_ci#include "jfs_dinode.h"
1362306a36Sopenharmony_ci#include "jfs_debug.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_civoid jfs_set_inode_flags(struct inode *inode)
1762306a36Sopenharmony_ci{
1862306a36Sopenharmony_ci	unsigned int flags = JFS_IP(inode)->mode2;
1962306a36Sopenharmony_ci	unsigned int new_fl = 0;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	if (flags & JFS_IMMUTABLE_FL)
2262306a36Sopenharmony_ci		new_fl |= S_IMMUTABLE;
2362306a36Sopenharmony_ci	if (flags & JFS_APPEND_FL)
2462306a36Sopenharmony_ci		new_fl |= S_APPEND;
2562306a36Sopenharmony_ci	if (flags & JFS_NOATIME_FL)
2662306a36Sopenharmony_ci		new_fl |= S_NOATIME;
2762306a36Sopenharmony_ci	if (flags & JFS_DIRSYNC_FL)
2862306a36Sopenharmony_ci		new_fl |= S_DIRSYNC;
2962306a36Sopenharmony_ci	if (flags & JFS_SYNC_FL)
3062306a36Sopenharmony_ci		new_fl |= S_SYNC;
3162306a36Sopenharmony_ci	inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND | S_NOATIME |
3262306a36Sopenharmony_ci			S_DIRSYNC | S_SYNC);
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/*
3662306a36Sopenharmony_ci * NAME:	ialloc()
3762306a36Sopenharmony_ci *
3862306a36Sopenharmony_ci * FUNCTION:	Allocate a new inode
3962306a36Sopenharmony_ci *
4062306a36Sopenharmony_ci */
4162306a36Sopenharmony_cistruct inode *ialloc(struct inode *parent, umode_t mode)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	struct super_block *sb = parent->i_sb;
4462306a36Sopenharmony_ci	struct inode *inode;
4562306a36Sopenharmony_ci	struct jfs_inode_info *jfs_inode;
4662306a36Sopenharmony_ci	int rc;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	inode = new_inode(sb);
4962306a36Sopenharmony_ci	if (!inode) {
5062306a36Sopenharmony_ci		jfs_warn("ialloc: new_inode returned NULL!");
5162306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
5262306a36Sopenharmony_ci	}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	jfs_inode = JFS_IP(inode);
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	rc = diAlloc(parent, S_ISDIR(mode), inode);
5762306a36Sopenharmony_ci	if (rc) {
5862306a36Sopenharmony_ci		jfs_warn("ialloc: diAlloc returned %d!", rc);
5962306a36Sopenharmony_ci		goto fail_put;
6062306a36Sopenharmony_ci	}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	if (insert_inode_locked(inode) < 0) {
6362306a36Sopenharmony_ci		rc = -EINVAL;
6462306a36Sopenharmony_ci		goto fail_put;
6562306a36Sopenharmony_ci	}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	inode_init_owner(&nop_mnt_idmap, inode, parent, mode);
6862306a36Sopenharmony_ci	/*
6962306a36Sopenharmony_ci	 * New inodes need to save sane values on disk when
7062306a36Sopenharmony_ci	 * uid & gid mount options are used
7162306a36Sopenharmony_ci	 */
7262306a36Sopenharmony_ci	jfs_inode->saved_uid = inode->i_uid;
7362306a36Sopenharmony_ci	jfs_inode->saved_gid = inode->i_gid;
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	/*
7662306a36Sopenharmony_ci	 * Allocate inode to quota.
7762306a36Sopenharmony_ci	 */
7862306a36Sopenharmony_ci	rc = dquot_initialize(inode);
7962306a36Sopenharmony_ci	if (rc)
8062306a36Sopenharmony_ci		goto fail_drop;
8162306a36Sopenharmony_ci	rc = dquot_alloc_inode(inode);
8262306a36Sopenharmony_ci	if (rc)
8362306a36Sopenharmony_ci		goto fail_drop;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	/* inherit flags from parent */
8662306a36Sopenharmony_ci	jfs_inode->mode2 = JFS_IP(parent)->mode2 & JFS_FL_INHERIT;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	if (S_ISDIR(mode)) {
8962306a36Sopenharmony_ci		jfs_inode->mode2 |= IDIRECTORY;
9062306a36Sopenharmony_ci		jfs_inode->mode2 &= ~JFS_DIRSYNC_FL;
9162306a36Sopenharmony_ci	}
9262306a36Sopenharmony_ci	else {
9362306a36Sopenharmony_ci		jfs_inode->mode2 |= INLINEEA | ISPARSE;
9462306a36Sopenharmony_ci		if (S_ISLNK(mode))
9562306a36Sopenharmony_ci			jfs_inode->mode2 &= ~(JFS_IMMUTABLE_FL|JFS_APPEND_FL);
9662306a36Sopenharmony_ci	}
9762306a36Sopenharmony_ci	jfs_inode->mode2 |= inode->i_mode;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	inode->i_blocks = 0;
10062306a36Sopenharmony_ci	inode->i_mtime = inode->i_atime = inode_set_ctime_current(inode);
10162306a36Sopenharmony_ci	jfs_inode->otime = inode_get_ctime(inode).tv_sec;
10262306a36Sopenharmony_ci	inode->i_generation = JFS_SBI(sb)->gengen++;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	jfs_inode->cflag = 0;
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	/* Zero remaining fields */
10762306a36Sopenharmony_ci	memset(&jfs_inode->acl, 0, sizeof(dxd_t));
10862306a36Sopenharmony_ci	memset(&jfs_inode->ea, 0, sizeof(dxd_t));
10962306a36Sopenharmony_ci	jfs_inode->next_index = 0;
11062306a36Sopenharmony_ci	jfs_inode->acltype = 0;
11162306a36Sopenharmony_ci	jfs_inode->btorder = 0;
11262306a36Sopenharmony_ci	jfs_inode->btindex = 0;
11362306a36Sopenharmony_ci	jfs_inode->bxflag = 0;
11462306a36Sopenharmony_ci	jfs_inode->blid = 0;
11562306a36Sopenharmony_ci	jfs_inode->atlhead = 0;
11662306a36Sopenharmony_ci	jfs_inode->atltail = 0;
11762306a36Sopenharmony_ci	jfs_inode->xtlid = 0;
11862306a36Sopenharmony_ci	jfs_set_inode_flags(inode);
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	jfs_info("ialloc returns inode = 0x%p", inode);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	return inode;
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cifail_drop:
12562306a36Sopenharmony_ci	dquot_drop(inode);
12662306a36Sopenharmony_ci	inode->i_flags |= S_NOQUOTA;
12762306a36Sopenharmony_ci	clear_nlink(inode);
12862306a36Sopenharmony_ci	discard_new_inode(inode);
12962306a36Sopenharmony_ci	return ERR_PTR(rc);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_cifail_put:
13262306a36Sopenharmony_ci	iput(inode);
13362306a36Sopenharmony_ci	return ERR_PTR(rc);
13462306a36Sopenharmony_ci}
135