Commit 8a765682 authored by Gao Xiang's avatar Gao Xiang Committed by Greg Kroah-Hartman

erofs: better naming for erofs inode related stuffs

updates inode naming
 - kill is_inode_layout_compression [1]
 - kill magic underscores [2] [3]
 - better naming for datamode & data_mapping_mode [3]
 - better naming erofs_inode_{compact, extended} [4]

[1] https://lore.kernel.org/r/20190829102426.GE20598@infradead.org/
[2] https://lore.kernel.org/r/20190829102426.GE20598@infradead.org/
[3] https://lore.kernel.org/r/20190902122627.GN15931@infradead.org/
[4] https://lore.kernel.org/r/20190902125438.GA17750@infradead.org/Reported-by: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarGao Xiang <gaoxiang25@huawei.com>
Link: https://lore.kernel.org/r/20190904020912.63925-8-gaoxiang25@huawei.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 426a9308
...@@ -113,11 +113,12 @@ static int erofs_map_blocks_flatmode(struct inode *inode, ...@@ -113,11 +113,12 @@ static int erofs_map_blocks_flatmode(struct inode *inode,
erofs_blk_t nblocks, lastblk; erofs_blk_t nblocks, lastblk;
u64 offset = map->m_la; u64 offset = map->m_la;
struct erofs_vnode *vi = EROFS_V(inode); struct erofs_vnode *vi = EROFS_V(inode);
bool tailendpacking = (vi->datalayout == EROFS_INODE_FLAT_INLINE);
trace_erofs_map_blocks_flatmode_enter(inode, map, flags); trace_erofs_map_blocks_flatmode_enter(inode, map, flags);
nblocks = DIV_ROUND_UP(inode->i_size, PAGE_SIZE); nblocks = DIV_ROUND_UP(inode->i_size, PAGE_SIZE);
lastblk = nblocks - is_inode_flat_inline(inode); lastblk = nblocks - tailendpacking;
if (offset >= inode->i_size) { if (offset >= inode->i_size) {
/* leave out-of-bound access unmapped */ /* leave out-of-bound access unmapped */
...@@ -132,7 +133,7 @@ static int erofs_map_blocks_flatmode(struct inode *inode, ...@@ -132,7 +133,7 @@ static int erofs_map_blocks_flatmode(struct inode *inode,
if (offset < blknr_to_addr(lastblk)) { if (offset < blknr_to_addr(lastblk)) {
map->m_pa = blknr_to_addr(vi->raw_blkaddr) + map->m_la; map->m_pa = blknr_to_addr(vi->raw_blkaddr) + map->m_la;
map->m_plen = blknr_to_addr(lastblk) - offset; map->m_plen = blknr_to_addr(lastblk) - offset;
} else if (is_inode_flat_inline(inode)) { } else if (tailendpacking) {
/* 2 - inode inline B: inode, [xattrs], inline last blk... */ /* 2 - inode inline B: inode, [xattrs], inline last blk... */
struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
...@@ -169,7 +170,7 @@ static int erofs_map_blocks_flatmode(struct inode *inode, ...@@ -169,7 +170,7 @@ static int erofs_map_blocks_flatmode(struct inode *inode,
int erofs_map_blocks(struct inode *inode, int erofs_map_blocks(struct inode *inode,
struct erofs_map_blocks *map, int flags) struct erofs_map_blocks *map, int flags)
{ {
if (is_inode_layout_compression(inode)) { if (erofs_inode_is_data_compressed(EROFS_V(inode)->datalayout)) {
int err = z_erofs_map_blocks_iter(inode, map, flags); int err = z_erofs_map_blocks_iter(inode, map, flags);
if (map->mpage) { if (map->mpage) {
...@@ -403,7 +404,7 @@ static sector_t erofs_bmap(struct address_space *mapping, sector_t block) ...@@ -403,7 +404,7 @@ static sector_t erofs_bmap(struct address_space *mapping, sector_t block)
{ {
struct inode *inode = mapping->host; struct inode *inode = mapping->host;
if (is_inode_flat_inline(inode)) { if (EROFS_V(inode)->datalayout == EROFS_INODE_FLAT_INLINE) {
erofs_blk_t blks = i_size_read(inode) >> LOG_BLOCK_SIZE; erofs_blk_t blks = i_size_read(inode) >> LOG_BLOCK_SIZE;
if (block >> LOG_SECTORS_PER_BLOCK >= blks) if (block >> LOG_SECTORS_PER_BLOCK >= blks)
......
...@@ -41,7 +41,7 @@ struct erofs_super_block { ...@@ -41,7 +41,7 @@ struct erofs_super_block {
}; };
/* /*
* erofs inode data mapping: * erofs inode datalayout:
* 0 - inode plain without inline data A: * 0 - inode plain without inline data A:
* inode, [xattrs], ... | ... | no-holed data * inode, [xattrs], ... | ... | no-holed data
* 1 - inode VLE compression B (legacy): * 1 - inode VLE compression B (legacy):
...@@ -57,7 +57,7 @@ enum { ...@@ -57,7 +57,7 @@ enum {
EROFS_INODE_FLAT_COMPRESSION_LEGACY = 1, EROFS_INODE_FLAT_COMPRESSION_LEGACY = 1,
EROFS_INODE_FLAT_INLINE = 2, EROFS_INODE_FLAT_INLINE = 2,
EROFS_INODE_FLAT_COMPRESSION = 3, EROFS_INODE_FLAT_COMPRESSION = 3,
EROFS_INODE_LAYOUT_MAX EROFS_INODE_DATALAYOUT_MAX
}; };
static inline bool erofs_inode_is_data_compressed(unsigned int datamode) static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
...@@ -68,14 +68,14 @@ static inline bool erofs_inode_is_data_compressed(unsigned int datamode) ...@@ -68,14 +68,14 @@ static inline bool erofs_inode_is_data_compressed(unsigned int datamode)
/* bit definitions of inode i_advise */ /* bit definitions of inode i_advise */
#define EROFS_I_VERSION_BITS 1 #define EROFS_I_VERSION_BITS 1
#define EROFS_I_DATA_MAPPING_BITS 3 #define EROFS_I_DATALAYOUT_BITS 3
#define EROFS_I_VERSION_BIT 0 #define EROFS_I_VERSION_BIT 0
#define EROFS_I_DATA_MAPPING_BIT 1 #define EROFS_I_DATALAYOUT_BIT 1
/* 32-byte reduced form of an ondisk inode */ /* 32-byte reduced form of an ondisk inode */
struct erofs_inode_v1 { struct erofs_inode_compact {
__le16 i_advise; /* inode hints */ __le16 i_format; /* inode format hints */
/* 1 header + n-1 * 4 bytes inline xattr to keep continuity */ /* 1 header + n-1 * 4 bytes inline xattr to keep continuity */
__le16 i_xattr_icount; __le16 i_xattr_icount;
...@@ -98,13 +98,13 @@ struct erofs_inode_v1 { ...@@ -98,13 +98,13 @@ struct erofs_inode_v1 {
}; };
/* 32 bytes on-disk inode */ /* 32 bytes on-disk inode */
#define EROFS_INODE_LAYOUT_V1 0 #define EROFS_INODE_LAYOUT_COMPACT 0
/* 64 bytes on-disk inode */ /* 64 bytes on-disk inode */
#define EROFS_INODE_LAYOUT_V2 1 #define EROFS_INODE_LAYOUT_EXTENDED 1
/* 64-byte complete form of an ondisk inode */ /* 64-byte complete form of an ondisk inode */
struct erofs_inode_v2 { struct erofs_inode_extended {
__le16 i_advise; /* inode hints */ __le16 i_format; /* inode format hints */
/* 1 header + n-1 * 4 bytes inline xattr to keep continuity */ /* 1 header + n-1 * 4 bytes inline xattr to keep continuity */
__le16 i_xattr_icount; __le16 i_xattr_icount;
...@@ -299,8 +299,8 @@ struct erofs_dirent { ...@@ -299,8 +299,8 @@ struct erofs_dirent {
static inline void erofs_check_ondisk_layout_definitions(void) static inline void erofs_check_ondisk_layout_definitions(void)
{ {
BUILD_BUG_ON(sizeof(struct erofs_super_block) != 128); BUILD_BUG_ON(sizeof(struct erofs_super_block) != 128);
BUILD_BUG_ON(sizeof(struct erofs_inode_v1) != 32); BUILD_BUG_ON(sizeof(struct erofs_inode_compact) != 32);
BUILD_BUG_ON(sizeof(struct erofs_inode_v2) != 64); BUILD_BUG_ON(sizeof(struct erofs_inode_extended) != 64);
BUILD_BUG_ON(sizeof(struct erofs_xattr_ibody_header) != 12); BUILD_BUG_ON(sizeof(struct erofs_xattr_ibody_header) != 12);
BUILD_BUG_ON(sizeof(struct erofs_xattr_entry) != 4); BUILD_BUG_ON(sizeof(struct erofs_xattr_entry) != 4);
BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8); BUILD_BUG_ON(sizeof(struct z_erofs_map_header) != 8);
......
...@@ -12,73 +12,90 @@ ...@@ -12,73 +12,90 @@
static int read_inode(struct inode *inode, void *data) static int read_inode(struct inode *inode, void *data)
{ {
struct erofs_vnode *vi = EROFS_V(inode); struct erofs_vnode *vi = EROFS_V(inode);
struct erofs_inode_v1 *v1 = data; struct erofs_inode_compact *dic = data;
const unsigned int advise = le16_to_cpu(v1->i_advise); struct erofs_inode_extended *die;
const unsigned int ifmt = le16_to_cpu(dic->i_format);
struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
erofs_blk_t nblks = 0; erofs_blk_t nblks = 0;
vi->datamode = __inode_data_mapping(advise); vi->datalayout = erofs_inode_datalayout(ifmt);
if (vi->datamode >= EROFS_INODE_LAYOUT_MAX) { if (vi->datalayout >= EROFS_INODE_DATALAYOUT_MAX) {
errln("unsupported data mapping %u of nid %llu", errln("unsupported datalayout %u of nid %llu",
vi->datamode, vi->nid); vi->datalayout, vi->nid);
DBG_BUGON(1); DBG_BUGON(1);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (__inode_version(advise) == EROFS_INODE_LAYOUT_V2) { switch (erofs_inode_version(ifmt)) {
struct erofs_inode_v2 *v2 = data; case EROFS_INODE_LAYOUT_EXTENDED:
die = data;
vi->inode_isize = sizeof(struct erofs_inode_v2); vi->inode_isize = sizeof(struct erofs_inode_extended);
vi->xattr_isize = erofs_xattr_ibody_size(v2->i_xattr_icount); vi->xattr_isize = erofs_xattr_ibody_size(die->i_xattr_icount);
inode->i_mode = le16_to_cpu(v2->i_mode); inode->i_mode = le16_to_cpu(die->i_mode);
if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || switch (inode->i_mode & S_IFMT) {
S_ISLNK(inode->i_mode)) case S_IFREG:
vi->raw_blkaddr = le32_to_cpu(v2->i_u.raw_blkaddr); case S_IFDIR:
else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) case S_IFLNK:
vi->raw_blkaddr = le32_to_cpu(die->i_u.raw_blkaddr);
break;
case S_IFCHR:
case S_IFBLK:
inode->i_rdev = inode->i_rdev =
new_decode_dev(le32_to_cpu(v2->i_u.rdev)); new_decode_dev(le32_to_cpu(die->i_u.rdev));
else if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) break;
case S_IFIFO:
case S_IFSOCK:
inode->i_rdev = 0; inode->i_rdev = 0;
else break;
default:
goto bogusimode; goto bogusimode;
}
i_uid_write(inode, le32_to_cpu(v2->i_uid)); i_uid_write(inode, le32_to_cpu(die->i_uid));
i_gid_write(inode, le32_to_cpu(v2->i_gid)); i_gid_write(inode, le32_to_cpu(die->i_gid));
set_nlink(inode, le32_to_cpu(v2->i_nlink)); set_nlink(inode, le32_to_cpu(die->i_nlink));
/* ns timestamp */ /* ns timestamp */
inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = inode->i_mtime.tv_sec = inode->i_ctime.tv_sec =
le64_to_cpu(v2->i_ctime); le64_to_cpu(die->i_ctime);
inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec =
le32_to_cpu(v2->i_ctime_nsec); le32_to_cpu(die->i_ctime_nsec);
inode->i_size = le64_to_cpu(v2->i_size); inode->i_size = le64_to_cpu(die->i_size);
/* total blocks for compressed files */ /* total blocks for compressed files */
if (is_inode_layout_compression(inode)) if (erofs_inode_is_data_compressed(vi->datalayout))
nblks = le32_to_cpu(v2->i_u.compressed_blocks); nblks = le32_to_cpu(die->i_u.compressed_blocks);
} else if (__inode_version(advise) == EROFS_INODE_LAYOUT_V1) { break;
struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); case EROFS_INODE_LAYOUT_COMPACT:
vi->inode_isize = sizeof(struct erofs_inode_compact);
vi->inode_isize = sizeof(struct erofs_inode_v1); vi->xattr_isize = erofs_xattr_ibody_size(dic->i_xattr_icount);
vi->xattr_isize = erofs_xattr_ibody_size(v1->i_xattr_icount);
inode->i_mode = le16_to_cpu(dic->i_mode);
inode->i_mode = le16_to_cpu(v1->i_mode); switch (inode->i_mode & S_IFMT) {
if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || case S_IFREG:
S_ISLNK(inode->i_mode)) case S_IFDIR:
vi->raw_blkaddr = le32_to_cpu(v1->i_u.raw_blkaddr); case S_IFLNK:
else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) vi->raw_blkaddr = le32_to_cpu(dic->i_u.raw_blkaddr);
break;
case S_IFCHR:
case S_IFBLK:
inode->i_rdev = inode->i_rdev =
new_decode_dev(le32_to_cpu(v1->i_u.rdev)); new_decode_dev(le32_to_cpu(dic->i_u.rdev));
else if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) break;
case S_IFIFO:
case S_IFSOCK:
inode->i_rdev = 0; inode->i_rdev = 0;
else break;
default:
goto bogusimode; goto bogusimode;
}
i_uid_write(inode, le16_to_cpu(v1->i_uid)); i_uid_write(inode, le16_to_cpu(dic->i_uid));
i_gid_write(inode, le16_to_cpu(v1->i_gid)); i_gid_write(inode, le16_to_cpu(dic->i_gid));
set_nlink(inode, le16_to_cpu(v1->i_nlink)); set_nlink(inode, le16_to_cpu(dic->i_nlink));
/* use build time to derive all file time */ /* use build time to derive all file time */
inode->i_mtime.tv_sec = inode->i_ctime.tv_sec = inode->i_mtime.tv_sec = inode->i_ctime.tv_sec =
...@@ -86,12 +103,13 @@ static int read_inode(struct inode *inode, void *data) ...@@ -86,12 +103,13 @@ static int read_inode(struct inode *inode, void *data)
inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec =
sbi->build_time_nsec; sbi->build_time_nsec;
inode->i_size = le32_to_cpu(v1->i_size); inode->i_size = le32_to_cpu(dic->i_size);
if (is_inode_layout_compression(inode)) if (erofs_inode_is_data_compressed(vi->datalayout))
nblks = le32_to_cpu(v1->i_u.compressed_blocks); nblks = le32_to_cpu(dic->i_u.compressed_blocks);
} else { break;
default:
errln("unsupported on-disk inode version %u of nid %llu", errln("unsupported on-disk inode version %u of nid %llu",
__inode_version(advise), vi->nid); erofs_inode_version(ifmt), vi->nid);
DBG_BUGON(1); DBG_BUGON(1);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -125,8 +143,8 @@ static int fill_inline_data(struct inode *inode, void *data, ...@@ -125,8 +143,8 @@ static int fill_inline_data(struct inode *inode, void *data,
struct erofs_vnode *vi = EROFS_V(inode); struct erofs_vnode *vi = EROFS_V(inode);
struct erofs_sb_info *sbi = EROFS_I_SB(inode); struct erofs_sb_info *sbi = EROFS_I_SB(inode);
/* should be inode inline C */ /* should be tail-packing data inline */
if (!is_inode_flat_inline(inode)) if (vi->datalayout != EROFS_INODE_FLAT_INLINE)
return 0; return 0;
/* fast symlink (following ext4) */ /* fast symlink (following ext4) */
...@@ -216,7 +234,7 @@ static int fill_inode(struct inode *inode, int isdir) ...@@ -216,7 +234,7 @@ static int fill_inode(struct inode *inode, int isdir)
goto out_unlock; goto out_unlock;
} }
if (is_inode_layout_compression(inode)) { if (erofs_inode_is_data_compressed(vi->datalayout)) {
err = z_erofs_fill_inode(inode); err = z_erofs_fill_inode(inode);
goto out_unlock; goto out_unlock;
} }
...@@ -299,7 +317,7 @@ int erofs_getattr(const struct path *path, struct kstat *stat, ...@@ -299,7 +317,7 @@ int erofs_getattr(const struct path *path, struct kstat *stat,
{ {
struct inode *const inode = d_inode(path->dentry); struct inode *const inode = d_inode(path->dentry);
if (is_inode_layout_compression(inode)) if (erofs_inode_is_data_compressed(EROFS_V(inode)->datalayout))
stat->attributes |= STATX_ATTR_COMPRESSED; stat->attributes |= STATX_ATTR_COMPRESSED;
stat->attributes |= STATX_ATTR_IMMUTABLE; stat->attributes |= STATX_ATTR_IMMUTABLE;
......
...@@ -285,7 +285,7 @@ struct erofs_vnode { ...@@ -285,7 +285,7 @@ struct erofs_vnode {
/* atomic flags (including bitlocks) */ /* atomic flags (including bitlocks) */
unsigned long flags; unsigned long flags;
unsigned char datamode; unsigned char datalayout;
unsigned char inode_isize; unsigned char inode_isize;
unsigned short xattr_isize; unsigned short xattr_isize;
...@@ -310,31 +310,30 @@ struct erofs_vnode { ...@@ -310,31 +310,30 @@ struct erofs_vnode {
#define EROFS_V(ptr) \ #define EROFS_V(ptr) \
container_of(ptr, struct erofs_vnode, vfs_inode) container_of(ptr, struct erofs_vnode, vfs_inode)
#define __inode_advise(x, bit, bits) \
(((x) >> (bit)) & ((1 << (bits)) - 1))
#define __inode_version(advise) \
__inode_advise(advise, EROFS_I_VERSION_BIT, \
EROFS_I_VERSION_BITS)
#define __inode_data_mapping(advise) \
__inode_advise(advise, EROFS_I_DATA_MAPPING_BIT,\
EROFS_I_DATA_MAPPING_BITS)
static inline unsigned long inode_datablocks(struct inode *inode) static inline unsigned long inode_datablocks(struct inode *inode)
{ {
/* since i_size cannot be changed */ /* since i_size cannot be changed */
return DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ); return DIV_ROUND_UP(inode->i_size, EROFS_BLKSIZ);
} }
static inline bool is_inode_layout_compression(struct inode *inode) static inline unsigned int erofs_bitrange(unsigned int value, unsigned int bit,
unsigned int bits)
{
return (value >> bit) & ((1 << bits) - 1);
}
static inline unsigned int erofs_inode_version(unsigned int value)
{ {
return erofs_inode_is_data_compressed(EROFS_V(inode)->datamode); return erofs_bitrange(value, EROFS_I_VERSION_BIT,
EROFS_I_VERSION_BITS);
} }
static inline bool is_inode_flat_inline(struct inode *inode) static inline unsigned int erofs_inode_datalayout(unsigned int value)
{ {
return EROFS_V(inode)->datamode == EROFS_INODE_FLAT_INLINE; return erofs_bitrange(value, EROFS_I_DATALAYOUT_BIT,
EROFS_I_DATALAYOUT_BITS);
} }
extern const struct super_operations erofs_sops; extern const struct super_operations erofs_sops;
......
...@@ -121,7 +121,7 @@ static int superblock_read(struct super_block *sb) ...@@ -121,7 +121,7 @@ static int superblock_read(struct super_block *sb)
#ifdef CONFIG_EROFS_FS_XATTR #ifdef CONFIG_EROFS_FS_XATTR
sbi->xattr_blkaddr = le32_to_cpu(layout->xattr_blkaddr); sbi->xattr_blkaddr = le32_to_cpu(layout->xattr_blkaddr);
#endif #endif
sbi->islotbits = ffs(sizeof(struct erofs_inode_v1)) - 1; sbi->islotbits = ilog2(sizeof(struct erofs_inode_compact));
sbi->root_nid = le16_to_cpu(layout->root_nid); sbi->root_nid = le16_to_cpu(layout->root_nid);
sbi->inos = le64_to_cpu(layout->inos); sbi->inos = le64_to_cpu(layout->inos);
......
...@@ -12,7 +12,7 @@ int z_erofs_fill_inode(struct inode *inode) ...@@ -12,7 +12,7 @@ int z_erofs_fill_inode(struct inode *inode)
{ {
struct erofs_vnode *const vi = EROFS_V(inode); struct erofs_vnode *const vi = EROFS_V(inode);
if (vi->datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY) { if (vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) {
vi->z_advise = 0; vi->z_advise = 0;
vi->z_algorithmtype[0] = 0; vi->z_algorithmtype[0] = 0;
vi->z_algorithmtype[1] = 0; vi->z_algorithmtype[1] = 0;
...@@ -46,7 +46,7 @@ static int fill_inode_lazy(struct inode *inode) ...@@ -46,7 +46,7 @@ static int fill_inode_lazy(struct inode *inode)
if (test_bit(EROFS_V_Z_INITED_BIT, &vi->flags)) if (test_bit(EROFS_V_Z_INITED_BIT, &vi->flags))
goto out_unlock; goto out_unlock;
DBG_BUGON(vi->datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY); DBG_BUGON(vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY);
pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize + pos = ALIGN(iloc(EROFS_SB(sb), vi->nid) + vi->inode_isize +
vi->xattr_isize, 8); vi->xattr_isize, 8);
...@@ -314,7 +314,7 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m, ...@@ -314,7 +314,7 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
static int vle_load_cluster_from_disk(struct z_erofs_maprecorder *m, static int vle_load_cluster_from_disk(struct z_erofs_maprecorder *m,
unsigned int lcn) unsigned int lcn)
{ {
const unsigned int datamode = EROFS_V(m->inode)->datamode; const unsigned int datamode = EROFS_V(m->inode)->datalayout;
if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY) if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
return vle_legacy_load_cluster_from_disk(m, lcn); return vle_legacy_load_cluster_from_disk(m, lcn);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment