diff options
author | Brian Behlendorf <[email protected]> | 2012-07-19 14:50:25 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2012-07-20 12:20:57 -0700 |
commit | fc173c85892841c283aac4e5174d6d8762463062 (patch) | |
tree | e6ebd29eb87d4b03804b8e8a1398ed3c4c1ceaa4 /module | |
parent | 2a4a9dc2f09d7672268af4a4f70e1a26b481b5e9 (diff) |
Disable .zfs directory on 32-bit systems
The .zfs control directory implementation currently relies on
the fact that there is a direct 1:1 mapping from an object id
to its inode number. This works well as long as the system
uses a 64-bit value to store the inode number.
Unfortunately, the Linux kernel defines the inode number as
an 'unsigned long' type. This means that for 32-bit systems
will only have 32-bit inode numbers but we still have 64-bit
object ids.
This problem is particularly acute for the .zfs directories
which leverage those upper 32-bits. This is done to avoid
conflicting with object ids which are allocated monotonically
starting from 0. This is likely to also be a problem for
datasets on 32-bit systems with more than ~2 billion files.
The right long term fix must remove the simple 1:1 mapping.
Until that's done the only safe thing to do is to disable the
.zfs directory on 32-bit systems.
Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'module')
-rw-r--r-- | module/zfs/zfs_ctldir.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/module/zfs/zfs_ctldir.c b/module/zfs/zfs_ctldir.c index 1923934cd..c49d7172a 100644 --- a/module/zfs/zfs_ctldir.c +++ b/module/zfs/zfs_ctldir.c @@ -225,13 +225,13 @@ zfsctl_inode_alloc(zfs_sb_t *zsb, uint64_t id, * Lookup the inode with given id, it will be allocated if needed. */ static struct inode * -zfsctl_inode_lookup(zfs_sb_t *zsb, unsigned long id, +zfsctl_inode_lookup(zfs_sb_t *zsb, uint64_t id, const struct file_operations *fops, const struct inode_operations *ops) { struct inode *ip = NULL; while (ip == NULL) { - ip = ilookup(zsb->z_sb, id); + ip = ilookup(zsb->z_sb, (unsigned long)id); if (ip) break; @@ -267,10 +267,14 @@ zfsctl_inode_inactive(struct inode *ip) * therefore checks against a vfs_count of 2 instead of 1. This reference * is removed when the ctldir is destroyed in the unmount. All other entities * under the '.zfs' directory are created dynamically as needed. + * + * Because the dynamically created '.zfs' directory entries assume the use + * of 64-bit inode numbers this support must be disabled on 32-bit systems. */ int zfsctl_create(zfs_sb_t *zsb) { +#if defined(CONFIG_64BIT) ASSERT(zsb->z_ctldir == NULL); zsb->z_ctldir = zfsctl_inode_alloc(zsb, ZFSCTL_INO_ROOT, @@ -279,6 +283,9 @@ zfsctl_create(zfs_sb_t *zsb) return (ENOENT); return (0); +#else + return (EOPNOTSUPP); +#endif /* CONFIG_64BIT */ } /* |