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 --- |