Page MenuHomeFreeBSD

[tmpfs]: Add extended attributes
ClosedPublic

Authored by fsu on Jan 14 2023, 12:25 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, May 7, 11:23 PM
Unknown Object (File)
Tue, May 7, 2:33 PM
Unknown Object (File)
Fri, Apr 19, 7:23 PM
Unknown Object (File)
Mar 18 2024, 12:53 AM
Unknown Object (File)
Feb 22 2024, 3:39 AM
Unknown Object (File)
Jan 15 2024, 12:18 AM
Unknown Object (File)
Jan 2 2024, 11:59 PM
Unknown Object (File)
Dec 28 2023, 2:58 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 Not Applicable
Unit
Tests Not Applicable

Event Timeline

fsu requested review of this revision.Jan 14 2023, 12:25 PM
fsu added reviewers: kib, markj.
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

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 ↗(On Diff #115127)

Remove it completely to avoid duplicated strlen call

1895 ↗(On Diff #115127)

Do it as mount point option

1938 ↗(On Diff #115127)

Do not return EOPNOTSUPPORTED

1952 ↗(On Diff #115127)

strlen used

kib added inline comments.
share/man/man5/tmpfs.5
144

Is it total or max?

sys/fs/tmpfs/tmpfs.h
405

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

sys/fs/tmpfs/tmpfs_vnops.c
1900

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

2060

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

Yes, the max will be more correct.

sys/fs/tmpfs/tmpfs.h
405

Fixed.

sys/fs/tmpfs/tmpfs_vnops.c
1900

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.