Here is basic extended attributes implementation for tmpfs.
The extattrs follows semantic of ufs, mean it cannot be set to char/block devices and fifos. The attributes are allocated using regular malloc with M_WAITOK
allocation with the own malloc tag M_TMPFSEA. The memory consumed by extended attributes is limited to avoid OOM triggering by tmpfs_mount variable tm_ea_memory_max,
which is set initially to 16 MB. The extended attributes entries are stored as linked list in the tmpfs node.
The mount point lock is required only under setextattr and deleteextattr to update extended attributes memory-inuse counter, all other operations are doing under vnode lock.
Details
- Reviewers
kib markj - Commits
- rG56242a4c6566: Add extended attributes
The all extended attributes kyua tests are passed successfully:
root@fb:~ # kyua test -k /usr/tests/Kyuafile usr.sbin/extattr
usr.sbin/extattr/extattr_test:bad_namespace -> passed [0.018s]
usr.sbin/extattr/extattr_test:hex -> passed [0.018s]
usr.sbin/extattr/extattr_test:hex_nonascii -> passed [0.019s]
usr.sbin/extattr/extattr_test:long_name -> passed [0.029s]
usr.sbin/extattr/extattr_test:loud -> passed [0.029s]
usr.sbin/extattr/extattr_test:noattrs -> passed [0.015s]
usr.sbin/extattr/extattr_test:nonexistent_file -> passed [0.024s]
usr.sbin/extattr/extattr_test:null -> passed [0.017s]
usr.sbin/extattr/extattr_test:one_system_attr -> passed [0.028s]
usr.sbin/extattr/extattr_test:one_user_attr -> passed [0.026s]
usr.sbin/extattr/extattr_test:stdin -> passed [0.022s]
usr.sbin/extattr/extattr_test:stringify -> passed [0.018s]
usr.sbin/extattr/extattr_test:symlink -> passed [0.021s]
usr.sbin/extattr/extattr_test:symlink_nofollow -> passed [0.031s]
usr.sbin/extattr/extattr_test:system_and_user_attrs -> passed [0.043s]
usr.sbin/extattr/extattr_test:two_files -> passed [0.027s]
usr.sbin/extattr/extattr_test:two_files_force -> passed [0.041s]
usr.sbin/extattr/extattr_test:two_user_attrs -> passed [0.034s]
usr.sbin/extattr/extattr_test:unprivileged_user_cannot_set_system_attr -> passed [0.017s]
...
lib/libarchive/functional_test:test_extattr_freebsd -> passed [0.030s]
...
sys/audit/file-attribute-access:extattr_get_fd_failure -> passed [0.004s]
sys/audit/file-attribute-access:extattr_get_fd_success -> passed [0.004s]
sys/audit/file-attribute-access:extattr_get_file_failure -> passed [0.004s]
sys/audit/file-attribute-access:extattr_get_file_success -> passed [0.004s]
sys/audit/file-attribute-access:extattr_get_link_failure -> passed [0.004s]
sys/audit/file-attribute-access:extattr_get_link_success -> passed [0.005s]
sys/audit/file-attribute-access:extattr_list_fd_failure -> passed [0.006s]
sys/audit/file-attribute-access:extattr_list_fd_success -> passed [0.004s]
sys/audit/file-attribute-access:extattr_list_file_failure -> passed [0.004s]
sys/audit/file-attribute-access:extattr_list_file_success -> passed [0.004s]
sys/audit/file-attribute-access:extattr_list_link_failure -> passed [0.004s]
sys/audit/file-attribute-access:extattr_list_link_success -> passed [0.004s]
...
sys/audit/file-attribute-modify:extattr_delete_fd_failure -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_delete_fd_success -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_delete_file_failure -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_delete_file_success -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_delete_link_failure -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_delete_link_success -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_set_fd_failure -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_set_fd_success -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_set_file_failure -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_set_file_success -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_set_link_failure -> passed [0.004s]
sys/audit/file-attribute-modify:extattr_set_link_success -> passed [0.004s]
The tmpfs kyua tests are passed successfully too:
root@fb:~ # kyua test -k /usr/tests/Kyuafile sys/fs/tmpfs
sys/fs/tmpfs/create_test:attrs -> passed [0.075s]
sys/fs/tmpfs/create_test:create -> passed [0.027s]
sys/fs/tmpfs/create_test:kqueue -> passed [0.055s]
sys/fs/tmpfs/dots_test:nesteddir -> passed [0.030s]
sys/fs/tmpfs/dots_test:topdir -> passed [0.029s]
sys/fs/tmpfs/exec_test:basic -> passed [0.029s]
sys/fs/tmpfs/link_test:basic -> passed [0.045s]
sys/fs/tmpfs/link_test:kqueue -> expected_failure: fails with: dir/b did not receive NOTE_LINK - bug 213662: dir/b did not receive NOTE_LINK [0.074s]
sys/fs/tmpfs/link_test:subdirs -> passed [0.044s]
sys/fs/tmpfs/mkdir_test:attrs -> passed [0.058s]
sys/fs/tmpfs/mkdir_test:kqueue -> passed [0.055s]
sys/fs/tmpfs/mkdir_test:many -> passed [0.856s]
sys/fs/tmpfs/mkdir_test:nested -> passed [0.027s]
sys/fs/tmpfs/mkdir_test:single -> passed [0.028s]
sys/fs/tmpfs/mknod_test:block -> passed [0.023s]
sys/fs/tmpfs/mknod_test:block_kqueue -> passed [0.068s]
sys/fs/tmpfs/mknod_test:char -> passed [0.024s]
sys/fs/tmpfs/mknod_test:char_kqueue -> passed [0.060s]
sys/fs/tmpfs/mknod_test:pipe -> passed [0.024s]
sys/fs/tmpfs/mknod_test:pipe_kqueue -> passed [0.057s]
sys/fs/tmpfs/mount_test:attrs -> passed [0.019s]
sys/fs/tmpfs/mount_test:large -> expected_failure: -o size=<large-size> succeeds unexpectedly on FreeBSD - bug 212862: atf-check failed; see the output of the test for details [0.025s]
sys/fs/tmpfs/mount_test:mntpt -> passed [0.026s]
sys/fs/tmpfs/mount_test:negative -> passed [0.019s]
sys/fs/tmpfs/mount_test:options -> passed [0.023s]
sys/fs/tmpfs/mount_test:plain -> passed [0.019s]
sys/fs/tmpfs/read_write_test:basic -> passed [0.027s]
sys/fs/tmpfs/read_write_test:kqueue -> passed [0.100s]
sys/fs/tmpfs/readdir_test:caching -> passed [0.034s]
sys/fs/tmpfs/readdir_test:dots -> passed [0.036s]
sys/fs/tmpfs/readdir_test:many -> passed [0.456s]
sys/fs/tmpfs/readdir_test:types -> passed [0.054s]
sys/fs/tmpfs/remove_test:dot -> passed [0.030s]
sys/fs/tmpfs/remove_test:kqueue -> passed [0.062s]
sys/fs/tmpfs/remove_test:single -> passed [0.037s]
sys/fs/tmpfs/remove_test:uchg -> expected_failure: this fails on FreeBSD with root - bug 212861: atf-check failed; see the output of the test for details [0.032s]
sys/fs/tmpfs/rename_test:basic -> passed [0.040s]
sys/fs/tmpfs/rename_test:crossdev -> passed [0.038s]
sys/fs/tmpfs/rename_test:dir_to_emptydir -> passed [0.046s]
sys/fs/tmpfs/rename_test:dir_to_file -> passed [0.044s]
sys/fs/tmpfs/rename_test:dir_to_fulldir -> passed [0.068s]
sys/fs/tmpfs/rename_test:dotdot -> passed [0.097s]
sys/fs/tmpfs/rename_test:dots -> passed [0.034s]
sys/fs/tmpfs/rename_test:file_to_dir -> passed [0.042s]
sys/fs/tmpfs/rename_test:kqueue -> passed [0.160s]
sys/fs/tmpfs/rmdir_test:curdir -> passed [0.030s]
sys/fs/tmpfs/rmdir_test:dots -> passed [0.039s]
sys/fs/tmpfs/rmdir_test:kqueue -> passed [0.075s]
sys/fs/tmpfs/rmdir_test:links -> passed [0.043s]
sys/fs/tmpfs/rmdir_test:mntpt -> passed [0.027s]
sys/fs/tmpfs/rmdir_test:nested -> passed [0.042s]
sys/fs/tmpfs/rmdir_test:non_empty -> passed [0.058s]
sys/fs/tmpfs/rmdir_test:non_existent -> passed [0.030s]
sys/fs/tmpfs/rmdir_test:single -> passed [0.032s]
sys/fs/tmpfs/setattr_test:chgrp -> passed [0.031s]
sys/fs/tmpfs/setattr_test:chgrp_kqueue -> passed [0.049s]
sys/fs/tmpfs/setattr_test:chmod -> passed [0.033s]
sys/fs/tmpfs/setattr_test:chmod_kqueue -> passed [0.056s]
sys/fs/tmpfs/setattr_test:chown -> passed [0.035s]
sys/fs/tmpfs/setattr_test:chown_kqueue -> passed [0.053s]
sys/fs/tmpfs/setattr_test:chowngrp -> passed [0.029s]
sys/fs/tmpfs/setattr_test:chowngrp_kqueue -> passed [0.060s]
sys/fs/tmpfs/setattr_test:chtimes -> passed [0.029s]
sys/fs/tmpfs/setattr_test:chtimes_kqueue -> passed [0.058s]
sys/fs/tmpfs/sizes_test:big -> passed [0.040s]
sys/fs/tmpfs/sizes_test:overflow -> passed [0.043s]
sys/fs/tmpfs/sizes_test:overwrite -> passed [0.035s]
sys/fs/tmpfs/sizes_test:small -> passed [0.032s]
sys/fs/tmpfs/sockets_test:basic -> passed [0.066s]
sys/fs/tmpfs/statvfs_test:values -> passed [0.021s]
sys/fs/tmpfs/symlink_test:dir -> passed [0.042s]
sys/fs/tmpfs/symlink_test:exec -> passed [0.035s]
sys/fs/tmpfs/symlink_test:file -> passed [0.040s]
sys/fs/tmpfs/symlink_test:kqueue -> passed [0.059s]
sys/fs/tmpfs/times_test:empty -> passed [2.135s]
sys/fs/tmpfs/times_test:link -> passed [1.101s]
sys/fs/tmpfs/times_test:non_empty -> passed [1.063s]
sys/fs/tmpfs/times_test:rename -> passed [1.115s]
sys/fs/tmpfs/trail_slash_test:main -> passed [0.033s]
sys/fs/tmpfs/truncate_test:basic -> passed [0.024s]
sys/fs/tmpfs/vnd_test:basic -> passed [0.406s]
sys/fs/tmpfs/vnode_leak_test:main -> passed [2.563s]
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
fs/tmpfs/tmpfs.h | ||
---|---|---|
143 ↗ | (On Diff #115127) | |
145 ↗ | (On Diff #115127) | |
fs/tmpfs/tmpfs_vnops.c | ||
1860 ↗ | (On Diff #115127) | and return true/false. Same for functions below. |
1866 ↗ | (On Diff #115127) | Check attrname[0] == '\0' or memoize and use strlen() result instead of calling it twice |
1895 ↗ | (On Diff #115127) | Why is this not a mount option? |
1938 ↗ | (On Diff #115127) | What if, with your approach of having tmpfs_ea_mem_reserved controlled by a sysctl, somebody creates ea, then set the var to 0. There are undeletable entries now. |
1949 ↗ | (On Diff #115127) | |
1952 ↗ | (On Diff #115127) | Why strnlen instead of strlen? |
1961 ↗ | (On Diff #115127) | if (ea == NULL) return (ENOATTR); Then you can de-indent the block. |
1981 ↗ | (On Diff #115127) | ASSERT_VOP_LOCKED() Really not needed. |
1984 ↗ | (On Diff #115127) | Extra blank line. Same note for (almost) all blank lines |
Changes:
- Implement extended attributes max size variable as mount option instead of sysctl, the value could be changed during remount (MNT_UPDATE)
- Misc refactoring:
- Remove tmpfs_extattr_valid_attrname() function to avoid double strlen call.
- The if expressions fixes.
- Decrease number of blank lines.