GNU Linux-libre 5.19-rc6-gnu
[releases.git] / fs / jfs / jfs_inode.c
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, 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(-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(&init_user_ns, inode, 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(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         inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
101         jfs_inode->otime = inode->i_ctime.tv_sec;
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(rc);
130
131 fail_put:
132         iput(inode);
133         return ERR_PTR(rc);
134 }