1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * linux/drivers/staging/erofs/inode.c
4 *
5 * Copyright (C) 2017-2018 HUAWEI, Inc.
6 * http://www.huawei.com/
7 * Created by Gao Xiang <gaoxiang25@huawei.com>
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of the Linux
11 * distribution for more details.
12 */
13 #include "xattr.h"
14
15 #include <trace/events/erofs.h>
16
17 /* no locking */
read_inode(struct inode * inode,void * data)18 static int read_inode(struct inode *inode, void *data)
19 {
20 struct erofs_vnode *vi = EROFS_V(inode);
21 struct erofs_inode_v1 *v1 = data;
22 const unsigned advise = le16_to_cpu(v1->i_advise);
23
24 vi->data_mapping_mode = __inode_data_mapping(advise);
25
26 if (unlikely(vi->data_mapping_mode >= EROFS_INODE_LAYOUT_MAX)) {
27 errln("unknown data mapping mode %u of nid %llu",
28 vi->data_mapping_mode, vi->nid);
29 DBG_BUGON(1);
30 return -EIO;
31 }
32
33 if (__inode_version(advise) == EROFS_INODE_LAYOUT_V2) {
34 struct erofs_inode_v2 *v2 = data;
35
36 vi->inode_isize = sizeof(struct erofs_inode_v2);
37 vi->xattr_isize = ondisk_xattr_ibody_size(v2->i_xattr_icount);
38
39 inode->i_mode = le16_to_cpu(v2->i_mode);
40 if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
41 S_ISLNK(inode->i_mode)) {
42 vi->raw_blkaddr = le32_to_cpu(v2->i_u.raw_blkaddr);
43 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
44 inode->i_rdev =
45 new_decode_dev(le32_to_cpu(v2->i_u.rdev));
46 } else if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
47 inode->i_rdev = 0;
48 } else {
49 return -EIO;
50 }
51
52 i_uid_write(inode, le32_to_cpu(v2->i_uid));
53 i_gid_write(inode, le32_to_cpu(v2->i_gid));
54 set_nlink(inode, le32_to_cpu(v2->i_nlink));
55
56 /* ns timestamp */
57 inode->i_mtime.tv_sec = inode->i_ctime.tv_sec =
58 le64_to_cpu(v2->i_ctime);
59 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec =
60 le32_to_cpu(v2->i_ctime_nsec);
61
62 inode->i_size = le64_to_cpu(v2->i_size);
63 } else if (__inode_version(advise) == EROFS_INODE_LAYOUT_V1) {
64 struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
65
66 vi->inode_isize = sizeof(struct erofs_inode_v1);
67 vi->xattr_isize = ondisk_xattr_ibody_size(v1->i_xattr_icount);
68
69 inode->i_mode = le16_to_cpu(v1->i_mode);
70 if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
71 S_ISLNK(inode->i_mode)) {
72 vi->raw_blkaddr = le32_to_cpu(v1->i_u.raw_blkaddr);
73 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
74 inode->i_rdev =
75 new_decode_dev(le32_to_cpu(v1->i_u.rdev));
76 } else if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
77 inode->i_rdev = 0;
78 } else {
79 return -EIO;
80 }
81
82 i_uid_write(inode, le16_to_cpu(v1->i_uid));
83 i_gid_write(inode, le16_to_cpu(v1->i_gid));
84 set_nlink(inode, le16_to_cpu(v1->i_nlink));
85
86 /* use build time to derive all file time */
87 inode->i_mtime.tv_sec = inode->i_ctime.tv_sec =
88 sbi->build_time;
89 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec =
90 sbi->build_time_nsec;
91
92 inode->i_size = le32_to_cpu(v1->i_size);
93 } else {
94 errln("unsupported on-disk inode version %u of nid %llu",
95 __inode_version(advise), vi->nid);
96 DBG_BUGON(1);
97 return -EIO;
98 }
99
100 /* measure inode.i_blocks as the generic filesystem */
101 inode->i_blocks = ((inode->i_size - 1) >> 9) + 1;
102 return 0;
103 }
104
105 /*
106 * try_lock can be required since locking order is:
107 * file data(fs_inode)
108 * meta(bd_inode)
109 * but the majority of the callers is "iget",
110 * in that case we are pretty sure no deadlock since
111 * no data operations exist. However I tend to
112 * try_lock since it takes no much overhead and
113 * will success immediately.
114 */
fill_inline_data(struct inode * inode,void * data,unsigned m_pofs)115 static int fill_inline_data(struct inode *inode, void *data, unsigned m_pofs)
116 {
117 struct erofs_vnode *vi = EROFS_V(inode);
118 struct erofs_sb_info *sbi = EROFS_I_SB(inode);
119 int mode = vi->data_mapping_mode;
120
121 DBG_BUGON(mode >= EROFS_INODE_LAYOUT_MAX);
122
123 /* should be inode inline C */
124 if (mode != EROFS_INODE_LAYOUT_INLINE)
125 return 0;
126
127 /* fast symlink (following ext4) */
128 if (S_ISLNK(inode->i_mode) && inode->i_size < PAGE_SIZE) {
129 char *lnk = erofs_kmalloc(sbi, inode->i_size + 1, GFP_KERNEL);
130
131 if (unlikely(lnk == NULL))
132 return -ENOMEM;
133
134 m_pofs += vi->inode_isize + vi->xattr_isize;
135 BUG_ON(m_pofs + inode->i_size > PAGE_SIZE);
136
137 /* get in-page inline data */
138 memcpy(lnk, data + m_pofs, inode->i_size);
139 lnk[inode->i_size] = '\0';
140
141 inode->i_link = lnk;
142 set_inode_fast_symlink(inode);
143 }
144 return -EAGAIN;
145 }
146
fill_inode(struct inode * inode,int isdir)147 static int fill_inode(struct inode *inode, int isdir)
148 {
149 struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
150 struct erofs_vnode *vi = EROFS_V(inode);
151 struct page *page;
152 void *data;
153 int err;
154 erofs_blk_t blkaddr;
155 unsigned ofs;
156
157 trace_erofs_fill_inode(inode, isdir);
158
159 blkaddr = erofs_blknr(iloc(sbi, vi->nid));
160 ofs = erofs_blkoff(iloc(sbi, vi->nid));
161
162 debugln("%s, reading inode nid %llu at %u of blkaddr %u",
163 __func__, vi->nid, ofs, blkaddr);
164
165 page = erofs_get_meta_page(inode->i_sb, blkaddr, isdir);
166
167 if (IS_ERR(page)) {
168 errln("failed to get inode (nid: %llu) page, err %ld",
169 vi->nid, PTR_ERR(page));
170 return PTR_ERR(page);
171 }
172
173 BUG_ON(!PageUptodate(page));
174 data = page_address(page);
175
176 err = read_inode(inode, data + ofs);
177 if (!err) {
178 /* setup the new inode */
179 if (S_ISREG(inode->i_mode)) {
180 #ifdef CONFIG_EROFS_FS_XATTR
181 if (vi->xattr_isize)
182 inode->i_op = &erofs_generic_xattr_iops;
183 #endif
184 inode->i_fop = &generic_ro_fops;
185 } else if (S_ISDIR(inode->i_mode)) {
186 inode->i_op =
187 #ifdef CONFIG_EROFS_FS_XATTR
188 vi->xattr_isize ? &erofs_dir_xattr_iops :
189 #endif
190 &erofs_dir_iops;
191 inode->i_fop = &erofs_dir_fops;
192 } else if (S_ISLNK(inode->i_mode)) {
193 /* by default, page_get_link is used for symlink */
194 inode->i_op =
195 #ifdef CONFIG_EROFS_FS_XATTR
196 &erofs_symlink_xattr_iops,
197 #else
198 &page_symlink_inode_operations;
199 #endif
200 inode_nohighmem(inode);
201 } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
202 S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
203 #ifdef CONFIG_EROFS_FS_XATTR
204 inode->i_op = &erofs_special_inode_operations;
205 #endif
206 init_special_inode(inode, inode->i_mode, inode->i_rdev);
207 } else {
208 err = -EIO;
209 goto out_unlock;
210 }
211
212 if (is_inode_layout_compression(inode)) {
213 #ifdef CONFIG_EROFS_FS_ZIP
214 inode->i_mapping->a_ops =
215 &z_erofs_vle_normalaccess_aops;
216 #else
217 err = -ENOTSUPP;
218 #endif
219 goto out_unlock;
220 }
221
222 inode->i_mapping->a_ops = &erofs_raw_access_aops;
223
224 /* fill last page if inline data is available */
225 fill_inline_data(inode, data, ofs);
226 }
227
228 out_unlock:
229 unlock_page(page);
230 put_page(page);
231 return err;
232 }
233
erofs_iget(struct super_block * sb,erofs_nid_t nid,bool isdir)234 struct inode *erofs_iget(struct super_block *sb,
235 erofs_nid_t nid, bool isdir)
236 {
237 struct inode *inode = iget_locked(sb, nid);
238
239 if (unlikely(inode == NULL))
240 return ERR_PTR(-ENOMEM);
241
242 if (inode->i_state & I_NEW) {
243 int err;
244 struct erofs_vnode *vi = EROFS_V(inode);
245 vi->nid = nid;
246
247 err = fill_inode(inode, isdir);
248 if (likely(!err))
249 unlock_new_inode(inode);
250 else {
251 iget_failed(inode);
252 inode = ERR_PTR(err);
253 }
254 }
255 return inode;
256 }
257
258 #ifdef CONFIG_EROFS_FS_XATTR
259 const struct inode_operations erofs_generic_xattr_iops = {
260 .listxattr = erofs_listxattr,
261 };
262 #endif
263
264 #ifdef CONFIG_EROFS_FS_XATTR
265 const struct inode_operations erofs_symlink_xattr_iops = {
266 .get_link = page_get_link,
267 .listxattr = erofs_listxattr,
268 };
269 #endif
270
271 const struct inode_operations erofs_special_inode_operations = {
272 #ifdef CONFIG_EROFS_FS_XATTR
273 .listxattr = erofs_listxattr,
274 #endif
275 };
276
277 #ifdef CONFIG_EROFS_FS_XATTR
278 const struct inode_operations erofs_fast_symlink_xattr_iops = {
279 .get_link = simple_get_link,
280 .listxattr = erofs_listxattr,
281 };
282 #endif
283
284