diff options
Diffstat (limited to 'drivers/staging/erofs/inode.c')
-rw-r--r-- | drivers/staging/erofs/inode.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/staging/erofs/inode.c b/drivers/staging/erofs/inode.c index fbf6ff25cd1b..04c61a9d7b76 100644 --- a/drivers/staging/erofs/inode.c +++ b/drivers/staging/erofs/inode.c @@ -19,7 +19,7 @@ static int read_inode(struct inode *inode, void *data) { struct erofs_vnode *vi = EROFS_V(inode); struct erofs_inode_v1 *v1 = data; - const unsigned advise = le16_to_cpu(v1->i_advise); + const unsigned int advise = le16_to_cpu(v1->i_advise); vi->data_mapping_mode = __inode_data_mapping(advise); @@ -112,7 +112,8 @@ static int read_inode(struct inode *inode, void *data) * try_lock since it takes no much overhead and * will success immediately. */ -static int fill_inline_data(struct inode *inode, void *data, unsigned m_pofs) +static int fill_inline_data(struct inode *inode, void *data, + unsigned int m_pofs) { struct erofs_vnode *vi = EROFS_V(inode); struct erofs_sb_info *sbi = EROFS_I_SB(inode); @@ -152,7 +153,7 @@ static int fill_inode(struct inode *inode, int isdir) void *data; int err; erofs_blk_t blkaddr; - unsigned ofs; + unsigned int ofs; trace_erofs_fill_inode(inode, isdir); @@ -231,10 +232,45 @@ out_unlock: return err; } +/* + * erofs nid is 64bits, but i_ino is 'unsigned long', therefore + * we should do more for 32-bit platform to find the right inode. + */ +#if BITS_PER_LONG == 32 +static int erofs_ilookup_test_actor(struct inode *inode, void *opaque) +{ + const erofs_nid_t nid = *(erofs_nid_t *)opaque; + + return EROFS_V(inode)->nid == nid; +} + +static int erofs_iget_set_actor(struct inode *inode, void *opaque) +{ + const erofs_nid_t nid = *(erofs_nid_t *)opaque; + + inode->i_ino = erofs_inode_hash(nid); + return 0; +} +#endif + +static inline struct inode *erofs_iget_locked(struct super_block *sb, + erofs_nid_t nid) +{ + const unsigned long hashval = erofs_inode_hash(nid); + +#if BITS_PER_LONG >= 64 + /* it is safe to use iget_locked for >= 64-bit platform */ + return iget_locked(sb, hashval); +#else + return iget5_locked(sb, hashval, erofs_ilookup_test_actor, + erofs_iget_set_actor, &nid); +#endif +} + struct inode *erofs_iget(struct super_block *sb, erofs_nid_t nid, bool isdir) { - struct inode *inode = iget_locked(sb, nid); + struct inode *inode = erofs_iget_locked(sb, nid); if (unlikely(inode == NULL)) return ERR_PTR(-ENOMEM); @@ -259,22 +295,16 @@ struct inode *erofs_iget(struct super_block *sb, const struct inode_operations erofs_generic_xattr_iops = { .listxattr = erofs_listxattr, }; -#endif -#ifdef CONFIG_EROFS_FS_XATTR const struct inode_operations erofs_symlink_xattr_iops = { .get_link = page_get_link, .listxattr = erofs_listxattr, }; -#endif const struct inode_operations erofs_special_inode_operations = { -#ifdef CONFIG_EROFS_FS_XATTR .listxattr = erofs_listxattr, -#endif }; -#ifdef CONFIG_EROFS_FS_XATTR const struct inode_operations erofs_fast_symlink_xattr_iops = { .get_link = simple_get_link, .listxattr = erofs_listxattr, |