1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (C) International Business Machines Corp., 2000-2004 |
4 | */ |
5 | |
6 | #include <linux/fs.h> |
7 | #include <linux/quotaops.h> |
8 | #include "jfs_incore.h" |
9 | #include "jfs_inode.h" |
10 | #include "jfs_filsys.h" |
11 | #include "jfs_imap.h" |
12 | #include "jfs_dinode.h" |
13 | #include "jfs_debug.h" |
14 | |
15 | |
16 | void jfs_set_inode_flags(struct inode *inode) |
17 | { |
18 | unsigned int flags = JFS_IP(inode)->mode2; |
19 | unsigned int new_fl = 0; |
20 | |
21 | if (flags & JFS_IMMUTABLE_FL) |
22 | new_fl |= S_IMMUTABLE; |
23 | if (flags & JFS_APPEND_FL) |
24 | new_fl |= S_APPEND; |
25 | if (flags & JFS_NOATIME_FL) |
26 | new_fl |= S_NOATIME; |
27 | if (flags & JFS_DIRSYNC_FL) |
28 | new_fl |= S_DIRSYNC; |
29 | if (flags & JFS_SYNC_FL) |
30 | new_fl |= S_SYNC; |
31 | inode_set_flags(inode, flags: new_fl, S_IMMUTABLE | S_APPEND | S_NOATIME | |
32 | S_DIRSYNC | S_SYNC); |
33 | } |
34 | |
35 | /* |
36 | * NAME: ialloc() |
37 | * |
38 | * FUNCTION: Allocate a new inode |
39 | * |
40 | */ |
41 | struct inode *ialloc(struct inode *parent, umode_t mode) |
42 | { |
43 | struct super_block *sb = parent->i_sb; |
44 | struct inode *inode; |
45 | struct jfs_inode_info *jfs_inode; |
46 | int rc; |
47 | |
48 | inode = new_inode(sb); |
49 | if (!inode) { |
50 | jfs_warn("ialloc: new_inode returned NULL!" ); |
51 | return ERR_PTR(error: -ENOMEM); |
52 | } |
53 | |
54 | jfs_inode = JFS_IP(inode); |
55 | |
56 | rc = diAlloc(parent, S_ISDIR(mode), inode); |
57 | if (rc) { |
58 | jfs_warn("ialloc: diAlloc returned %d!" , rc); |
59 | goto fail_put; |
60 | } |
61 | |
62 | if (insert_inode_locked(inode) < 0) { |
63 | rc = -EINVAL; |
64 | goto fail_put; |
65 | } |
66 | |
67 | inode_init_owner(idmap: &nop_mnt_idmap, inode, dir: parent, mode); |
68 | /* |
69 | * New inodes need to save sane values on disk when |
70 | * uid & gid mount options are used |
71 | */ |
72 | jfs_inode->saved_uid = inode->i_uid; |
73 | jfs_inode->saved_gid = inode->i_gid; |
74 | |
75 | /* |
76 | * Allocate inode to quota. |
77 | */ |
78 | rc = dquot_initialize(inode); |
79 | if (rc) |
80 | goto fail_drop; |
81 | rc = dquot_alloc_inode(inode); |
82 | if (rc) |
83 | goto fail_drop; |
84 | |
85 | /* inherit flags from parent */ |
86 | jfs_inode->mode2 = JFS_IP(inode: parent)->mode2 & JFS_FL_INHERIT; |
87 | |
88 | if (S_ISDIR(mode)) { |
89 | jfs_inode->mode2 |= IDIRECTORY; |
90 | jfs_inode->mode2 &= ~JFS_DIRSYNC_FL; |
91 | } |
92 | else { |
93 | jfs_inode->mode2 |= INLINEEA | ISPARSE; |
94 | if (S_ISLNK(mode)) |
95 | jfs_inode->mode2 &= ~(JFS_IMMUTABLE_FL|JFS_APPEND_FL); |
96 | } |
97 | jfs_inode->mode2 |= inode->i_mode; |
98 | |
99 | inode->i_blocks = 0; |
100 | simple_inode_init_ts(inode); |
101 | jfs_inode->otime = inode_get_ctime_sec(inode); |
102 | inode->i_generation = JFS_SBI(sb)->gengen++; |
103 | |
104 | jfs_inode->cflag = 0; |
105 | |
106 | /* Zero remaining fields */ |
107 | memset(&jfs_inode->acl, 0, sizeof(dxd_t)); |
108 | memset(&jfs_inode->ea, 0, sizeof(dxd_t)); |
109 | jfs_inode->next_index = 0; |
110 | jfs_inode->acltype = 0; |
111 | jfs_inode->btorder = 0; |
112 | jfs_inode->btindex = 0; |
113 | jfs_inode->bxflag = 0; |
114 | jfs_inode->blid = 0; |
115 | jfs_inode->atlhead = 0; |
116 | jfs_inode->atltail = 0; |
117 | jfs_inode->xtlid = 0; |
118 | jfs_set_inode_flags(inode); |
119 | |
120 | jfs_info("ialloc returns inode = 0x%p" , inode); |
121 | |
122 | return inode; |
123 | |
124 | fail_drop: |
125 | dquot_drop(inode); |
126 | inode->i_flags |= S_NOQUOTA; |
127 | clear_nlink(inode); |
128 | discard_new_inode(inode); |
129 | return ERR_PTR(error: rc); |
130 | |
131 | fail_put: |
132 | iput(inode); |
133 | return ERR_PTR(error: rc); |
134 | } |
135 | |