Page MenuHomeFreeBSD

[tmpfs]: Add extended attributes
ClosedPublic

Authored by fsu on Jan 14 2023, 12:25 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Jun 6, 7:42 AM
Unknown Object (File)
Thu, May 23, 8:40 PM
Unknown Object (File)
Wed, May 15, 9:19 AM
Unknown Object (File)
May 7 2024, 11:23 PM
Unknown Object (File)
May 7 2024, 2:33 PM
Unknown Object (File)
Apr 19 2024, 7:23 PM
Unknown Object (File)
Mar 18 2024, 12:53 AM
Unknown Object (File)
Feb 22 2024, 3:39 AM
Subscribers

Details

Summary

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.

Test Plan

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 Skipped
Unit
Tests Skipped

Event Timeline

fsu requested review of this revision.Jan 14 2023, 12:25 PM
fsu added reviewers: kib, markj.
fs/tmpfs/tmpfs.h
143
145
fs/tmpfs/tmpfs_vnops.c
1860

and return true/false.

Same for functions below.

1866

Check attrname[0] == '\0' or memoize and use strlen() result instead of calling it twice

1895

Why is this not a mount option?

1938

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
1952

Why strnlen instead of strlen?

1961
if (ea == NULL)
  return (ENOATTR);

Then you can de-indent the block.

1981

ASSERT_VOP_LOCKED()

Really not needed.

1984

Extra blank line. Same note for (almost) all blank lines

fsu edited the summary of this revision. (Show Details)

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.
fs/tmpfs/tmpfs_vnops.c
1860

Remove it completely to avoid duplicated strlen call

1895

Do it as mount point option

1938

Do not return EOPNOTSUPPORTED

1952

strlen used

kib added inline comments.
share/man/man5/tmpfs.5
144 ↗(On Diff #115399)

Is it total or max?

sys/fs/tmpfs/tmpfs.h
405 ↗(On Diff #115399)

It is strange to have different types for inuse vs. max.

sys/fs/tmpfs/tmpfs_vnops.c
1888 ↗(On Diff #115399)

I am curious why do you deny use of extattrs on special nodes.

2048 ↗(On Diff #115399)

Pointless blank line

This revision is now accepted and ready to land.Jan 22 2023, 12:44 PM
This revision was automatically updated to reflect the committed changes.
share/man/man5/tmpfs.5
144 ↗(On Diff #115399)

Yes, the max will be more correct.

sys/fs/tmpfs/tmpfs.h
405 ↗(On Diff #115399)

Fixed.

sys/fs/tmpfs/tmpfs_vnops.c
1888 ↗(On Diff #115399)

The ufs does not support extattrs for special nodes, just keep the difference between tmpfs and ufs as little as possible.
Could be added later.