inode.c (ea68a3e9d14e9e0bf017d178fb4bd53b6deb1482) inode.c (3acea5fc335420ba7ef53947cf2d98d07fac39f7)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2017-2018 HUAWEI, Inc.
4 * https://www.huawei.com/
5 * Copyright (C) 2021, Alibaba Cloud
6 */
7#include "xattr.h"
8

--- 9 unchanged lines hidden (view full) ---

18
19 erofs_blk_t blkaddr, nblks = 0;
20 void *kaddr;
21 struct erofs_inode_compact *dic;
22 struct erofs_inode_extended *die, *copied = NULL;
23 unsigned int ifmt;
24 int err;
25
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2017-2018 HUAWEI, Inc.
4 * https://www.huawei.com/
5 * Copyright (C) 2021, Alibaba Cloud
6 */
7#include "xattr.h"
8

--- 9 unchanged lines hidden (view full) ---

18
19 erofs_blk_t blkaddr, nblks = 0;
20 void *kaddr;
21 struct erofs_inode_compact *dic;
22 struct erofs_inode_extended *die, *copied = NULL;
23 unsigned int ifmt;
24 int err;
25
26 blkaddr = erofs_blknr(inode_loc);
27 *ofs = erofs_blkoff(inode_loc);
26 blkaddr = erofs_blknr(sb, inode_loc);
27 *ofs = erofs_blkoff(sb, inode_loc);
28
29 erofs_dbg("%s, reading inode nid %llu at %u of blkaddr %u",
30 __func__, vi->nid, *ofs, blkaddr);
31
32 kaddr = erofs_read_metabuf(buf, sb, blkaddr, EROFS_KMAP);
33 if (IS_ERR(kaddr)) {
34 erofs_err(sb, "failed to get inode (nid: %llu) page, err %ld",
35 vi->nid, PTR_ERR(kaddr));

--- 17 unchanged lines hidden (view full) ---

53 err = -EOPNOTSUPP;
54 goto err_out;
55 }
56
57 switch (erofs_inode_version(ifmt)) {
58 case EROFS_INODE_LAYOUT_EXTENDED:
59 vi->inode_isize = sizeof(struct erofs_inode_extended);
60 /* check if the extended inode acrosses block boundary */
28
29 erofs_dbg("%s, reading inode nid %llu at %u of blkaddr %u",
30 __func__, vi->nid, *ofs, blkaddr);
31
32 kaddr = erofs_read_metabuf(buf, sb, blkaddr, EROFS_KMAP);
33 if (IS_ERR(kaddr)) {
34 erofs_err(sb, "failed to get inode (nid: %llu) page, err %ld",
35 vi->nid, PTR_ERR(kaddr));

--- 17 unchanged lines hidden (view full) ---

53 err = -EOPNOTSUPP;
54 goto err_out;
55 }
56
57 switch (erofs_inode_version(ifmt)) {
58 case EROFS_INODE_LAYOUT_EXTENDED:
59 vi->inode_isize = sizeof(struct erofs_inode_extended);
60 /* check if the extended inode acrosses block boundary */
61 if (*ofs + vi->inode_isize <= EROFS_BLKSIZ) {
61 if (*ofs + vi->inode_isize <= sb->s_blocksize) {
62 *ofs += vi->inode_isize;
63 die = (struct erofs_inode_extended *)dic;
64 } else {
62 *ofs += vi->inode_isize;
63 die = (struct erofs_inode_extended *)dic;
64 } else {
65 const unsigned int gotten = EROFS_BLKSIZ - *ofs;
65 const unsigned int gotten = sb->s_blocksize - *ofs;
66
67 copied = kmalloc(vi->inode_isize, GFP_NOFS);
68 if (!copied) {
69 err = -ENOMEM;
70 goto err_out;
71 }
72 memcpy(copied, dic, gotten);
73 kaddr = erofs_read_metabuf(buf, sb, blkaddr + 1,

--- 97 unchanged lines hidden (view full) ---

171 if (vi->datalayout == EROFS_INODE_CHUNK_BASED) {
172 if (vi->chunkformat & ~EROFS_CHUNK_FORMAT_ALL) {
173 erofs_err(inode->i_sb,
174 "unsupported chunk format %x of nid %llu",
175 vi->chunkformat, vi->nid);
176 err = -EOPNOTSUPP;
177 goto err_out;
178 }
66
67 copied = kmalloc(vi->inode_isize, GFP_NOFS);
68 if (!copied) {
69 err = -ENOMEM;
70 goto err_out;
71 }
72 memcpy(copied, dic, gotten);
73 kaddr = erofs_read_metabuf(buf, sb, blkaddr + 1,

--- 97 unchanged lines hidden (view full) ---

171 if (vi->datalayout == EROFS_INODE_CHUNK_BASED) {
172 if (vi->chunkformat & ~EROFS_CHUNK_FORMAT_ALL) {
173 erofs_err(inode->i_sb,
174 "unsupported chunk format %x of nid %llu",
175 vi->chunkformat, vi->nid);
176 err = -EOPNOTSUPP;
177 goto err_out;
178 }
179 vi->chunkbits = LOG_BLOCK_SIZE +
179 vi->chunkbits = sb->s_blocksize_bits +
180 (vi->chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK);
181 }
182 inode->i_mtime.tv_sec = inode->i_ctime.tv_sec;
183 inode->i_atime.tv_sec = inode->i_ctime.tv_sec;
184 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec;
185 inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec;
186
187 inode->i_flags &= ~S_DAX;
188 if (test_opt(&sbi->opt, DAX_ALWAYS) && S_ISREG(inode->i_mode) &&
189 vi->datalayout == EROFS_INODE_FLAT_PLAIN)
190 inode->i_flags |= S_DAX;
180 (vi->chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK);
181 }
182 inode->i_mtime.tv_sec = inode->i_ctime.tv_sec;
183 inode->i_atime.tv_sec = inode->i_ctime.tv_sec;
184 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec;
185 inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec;
186
187 inode->i_flags &= ~S_DAX;
188 if (test_opt(&sbi->opt, DAX_ALWAYS) && S_ISREG(inode->i_mode) &&
189 vi->datalayout == EROFS_INODE_FLAT_PLAIN)
190 inode->i_flags |= S_DAX;
191
191 if (!nblks)
192 /* measure inode.i_blocks as generic filesystems */
192 if (!nblks)
193 /* measure inode.i_blocks as generic filesystems */
193 inode->i_blocks = roundup(inode->i_size, EROFS_BLKSIZ) >> 9;
194 inode->i_blocks = round_up(inode->i_size, sb->s_blocksize) >> 9;
194 else
195 else
195 inode->i_blocks = nblks << LOG_SECTORS_PER_BLOCK;
196 inode->i_blocks = nblks << (sb->s_blocksize_bits - 9);
196 return kaddr;
197
198bogusimode:
199 erofs_err(inode->i_sb, "bogus i_mode (%o) @ nid %llu",
200 inode->i_mode, vi->nid);
201 err = -EFSCORRUPTED;
202err_out:
203 DBG_BUGON(1);
204 kfree(copied);
205 erofs_put_metabuf(buf);
206 return ERR_PTR(err);
207}
208
209static int erofs_fill_symlink(struct inode *inode, void *kaddr,
210 unsigned int m_pofs)
211{
212 struct erofs_inode *vi = EROFS_I(inode);
197 return kaddr;
198
199bogusimode:
200 erofs_err(inode->i_sb, "bogus i_mode (%o) @ nid %llu",
201 inode->i_mode, vi->nid);
202 err = -EFSCORRUPTED;
203err_out:
204 DBG_BUGON(1);
205 kfree(copied);
206 erofs_put_metabuf(buf);
207 return ERR_PTR(err);
208}
209
210static int erofs_fill_symlink(struct inode *inode, void *kaddr,
211 unsigned int m_pofs)
212{
213 struct erofs_inode *vi = EROFS_I(inode);
214 unsigned int bsz = i_blocksize(inode);
213 char *lnk;
214
215 /* if it cannot be handled with fast symlink scheme */
216 if (vi->datalayout != EROFS_INODE_FLAT_INLINE ||
215 char *lnk;
216
217 /* if it cannot be handled with fast symlink scheme */
218 if (vi->datalayout != EROFS_INODE_FLAT_INLINE ||
217 inode->i_size >= EROFS_BLKSIZ || inode->i_size < 0) {
219 inode->i_size >= bsz || inode->i_size < 0) {
218 inode->i_op = &erofs_symlink_iops;
219 return 0;
220 }
221
222 lnk = kmalloc(inode->i_size + 1, GFP_KERNEL);
223 if (!lnk)
224 return -ENOMEM;
225
226 m_pofs += vi->xattr_isize;
227 /* inline symlink data shouldn't cross block boundary */
220 inode->i_op = &erofs_symlink_iops;
221 return 0;
222 }
223
224 lnk = kmalloc(inode->i_size + 1, GFP_KERNEL);
225 if (!lnk)
226 return -ENOMEM;
227
228 m_pofs += vi->xattr_isize;
229 /* inline symlink data shouldn't cross block boundary */
228 if (m_pofs + inode->i_size > EROFS_BLKSIZ) {
230 if (m_pofs + inode->i_size > bsz) {
229 kfree(lnk);
230 erofs_err(inode->i_sb,
231 "inline data cross block boundary @ nid %llu",
232 vi->nid);
233 DBG_BUGON(1);
234 return -EFSCORRUPTED;
235 }
236 memcpy(lnk, kaddr + m_pofs, inode->i_size);

--- 158 unchanged lines hidden ---
231 kfree(lnk);
232 erofs_err(inode->i_sb,
233 "inline data cross block boundary @ nid %llu",
234 vi->nid);
235 DBG_BUGON(1);
236 return -EFSCORRUPTED;
237 }
238 memcpy(lnk, kaddr + m_pofs, inode->i_size);

--- 158 unchanged lines hidden ---