The script from attachment could be uses{F1418347}.
Details
Diff Detail
- Lint
Lint Skipped - Unit
Tests Skipped
Event Timeline
This patch doesn't implement dir_nlink: by enabling dir_nlink you should be able to set up more than 65000 links. (linux extends the number of links somewhere, don't remember).
65000 should be supported for the base ext4, however we don't for a simple reason:
http://src.illumos.org/source/xref/freebsd-head/sys/fs/ext2fs/ext2_vnops.c#344
va_nlink is of type short.
sys/fs/ext2fs/ext2_dir.h | ||
---|---|---|
76 | This is actually EXT4_LINK_MAX. |
But we able to set 65000. I tested it on x86_64, but I can see the same for 32 bit platforms _types.h:
typedef uint64_t nlink_t; /* link count */
In case of linux, if n_link > 65000, the n_link count is immediately set to 1. The same logic is represented in the patch.
sys/fs/ext2fs/ext2_dir.h | ||
---|---|---|
76 | Yep, if it needed I can make: |
Actually: va_nlink is now nlink_t, this was a change for INO64, but the illumos' opengrok hasn't caught up.
The change is fine, but only on -current.
In case of linux, if n_link > 65000, the n_link count is immediately set to 1. The same logic is represented in the patch.
OK. Still we have to enforce the 32000 limit on ext2.
I don't see EXT4_LINK_MAX (?):
in the case where we are using EXT4 (extents), without the EXT2F_ROCOMPAT_DIR_NLINK feature, we should enforce the 54000 limit.
For the case where EXT2F_ROCOMPAT_DIR_NLINK is defined, should be able to handle more that 65000 links.
This code doesn't support that case so we are not really supporting the feature.
I suspect the feature is not really usable on ext2.
sys/fs/ext2fs/ext2_vnops.c | ||
---|---|---|
676 | Note that this function never returns a number bigger that 65000. |
No, we should not. You can see it here:https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout
0x20 Indicates that the old ext3 32,000 subdirectory limit no longer applies (RO_COMPAT_DIR_NLINK).
The case when > 65000 is supported is when dir_index feature applied. It could be checked on linux:
root@user:~ # mkfs.ext2 -O ^dir_index -O dir_nlink /dev/md1
mke2fs 1.43.4 (31-Jan-2017)
Creating filesystem with 4194304 4k blocks and 1048576 inodes
Filesystem UUID: 832ff2e8-b1c2-42f1-838a-2e64daf151ab
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
root@user:~ # dumpe2fs /dev/md1 | head -20
dumpe2fs 1.43.4 (31-Jan-2017)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: 832ff2e8-b1c2-42f1-838a-2e64daf151ab
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: ext_attr resize_inode filetype sparse_super large_file dir_nlink
...
root@user:/mnt/TEST_DIR# for i in {1..70000}; do mkdir dir_$i; done
mkdir: cannot create directory ‘dir_64999’: Too many links
I suspect the feature is not really usable on ext2.
And, unfortunately it is usable too.
Approved with a sidenote:
The helpers to increment and decrement i_nlink involve a deviation to how it's done in UFS.
I don't see any way around it, it's just the way ext4 works.
There is something wrong still, we cannot just bump i_nlink without considering how the information is stored on disk,
http://src.illumos.org/source/xref/freebsd-head/sys/fs/ext2fs/ext2_inode_cnv.c#89
In particular, e2di_nlink is still uint16_t (see ext2_dinode.h). The higher bits must be stored somewhere.
Nevermind ... I forgot we never get to write when dir_nlink is set.
The 65000 of course does fit in e2di_nlink.