[PATCH v2 2/2] erofs-utils: fix cross-device submounts
Gao Xiang
hsiangkao at aol.com
Sat Dec 5 04:56:42 AEDT 2020
From: Gao Xiang <hsiangkao at aol.com>
Use device ID and inode number to identify hardlinks
rather than inode number only.
Fixes: a17497f0844a ("erofs-utils: introduce inode operations")
Signed-off-by: Gao Xiang <hsiangkao at aol.com>
---
changes since v1:
- fix improper inline comment update;
include/erofs/internal.h | 7 ++++++-
lib/inode.c | 14 ++++++++------
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index bf13c166ba16..ac5b270329e2 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -112,7 +112,12 @@ EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM)
struct erofs_inode {
struct list_head i_hash, i_subdirs, i_xattrs;
- unsigned int flags;
+ union {
+ /* (erofsfuse) runtime flags */
+ unsigned int flags;
+ /* (mkfs.erofs) device ID containing source file */
+ u32 dev;
+ };
unsigned int i_count;
struct erofs_inode *i_parent;
diff --git a/lib/inode.c b/lib/inode.c
index 1cf813daa396..618eb284550f 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -35,7 +35,7 @@ static unsigned char erofs_type_by_mode[S_IFMT >> S_SHIFT] = {
[S_IFLNK >> S_SHIFT] = EROFS_FT_SYMLINK,
};
-#define NR_INODE_HASHTABLE 64
+#define NR_INODE_HASHTABLE 16384
struct list_head inode_hashtable[NR_INODE_HASHTABLE];
@@ -54,14 +54,14 @@ static struct erofs_inode *erofs_igrab(struct erofs_inode *inode)
}
/* get the inode from the (source) inode # */
-struct erofs_inode *erofs_iget(ino_t ino)
+struct erofs_inode *erofs_iget(dev_t dev, ino_t ino)
{
struct list_head *head =
- &inode_hashtable[ino % NR_INODE_HASHTABLE];
+ &inode_hashtable[(ino ^ dev) % NR_INODE_HASHTABLE];
struct erofs_inode *inode;
list_for_each_entry(inode, head, i_hash)
- if (inode->i_ino[1] == ino)
+ if (inode->i_ino[1] == ino && inode->dev == dev)
return erofs_igrab(inode);
return NULL;
}
@@ -764,6 +764,7 @@ int erofs_fill_inode(struct erofs_inode *inode,
strncpy(inode->i_srcpath, path, sizeof(inode->i_srcpath) - 1);
inode->i_srcpath[sizeof(inode->i_srcpath) - 1] = '\0';
+ inode->dev = st->st_dev;
inode->i_ino[1] = st->st_ino;
if (erofs_should_use_inode_extended(inode)) {
@@ -778,7 +779,8 @@ int erofs_fill_inode(struct erofs_inode *inode,
}
list_add(&inode->i_hash,
- &inode_hashtable[st->st_ino % NR_INODE_HASHTABLE]);
+ &inode_hashtable[(st->st_ino ^ st->st_dev) %
+ NR_INODE_HASHTABLE]);
return 0;
}
@@ -829,7 +831,7 @@ struct erofs_inode *erofs_iget_from_path(const char *path, bool is_src)
* since hard-link directory isn't allowed.
*/
if (!S_ISDIR(st.st_mode)) {
- inode = erofs_iget(st.st_ino);
+ inode = erofs_iget(st.st_dev, st.st_ino);
if (inode)
return inode;
}
--
2.24.0
More information about the Linux-erofs
mailing list