@@ -417,3 +417,41 @@ TEST(LibCephFS, FsCrypt) {
417417 ceph_shutdown (cmount);
418418}
419419
420+ #define ACL_EA_ACCESS " system.posix_acl_access"
421+ #define ACL_EA_DEFAULT " system.posix_acl_default"
422+
423+ TEST (LibCephFS, Removexattr) {
424+ struct ceph_mount_info *cmount;
425+ ASSERT_EQ (ceph_create (&cmount, NULL ), 0 );
426+ ASSERT_EQ (ceph_conf_read_file (cmount, NULL ), 0 );
427+ ASSERT_EQ (0 , ceph_conf_parse_env (cmount, NULL ));
428+ ASSERT_EQ (ceph_mount (cmount, NULL ), 0 );
429+
430+ char test_xattr_file[NAME_MAX];
431+ sprintf (test_xattr_file, " test_removexattr_%d" , getpid ());
432+ int fd = ceph_open (cmount, test_xattr_file, O_RDWR|O_CREAT, 0666 );
433+ ASSERT_GT (fd, 0 );
434+
435+ // remove xattr
436+ ASSERT_EQ (-CEPHFS_ENODATA, ceph_fremovexattr (cmount, fd, " user.remove.xattr" ));
437+ ASSERT_EQ (0 , ceph_fsetxattr (cmount, fd, " user.remove.xattr" , " foo" , 3 , XATTR_CREATE));
438+ ASSERT_EQ (0 , ceph_fremovexattr (cmount, fd, " user.remove.xattr" ));
439+
440+ // remove xattr via setxattr & XATTR_REPLACE
441+ ASSERT_EQ (-CEPHFS_ENODATA, ceph_fsetxattr (cmount, fd, " user.remove.xattr" , nullptr , 0 , XATTR_REPLACE));
442+ ASSERT_EQ (0 , ceph_fsetxattr (cmount, fd, " user.remove.xattr" , " foo" , 3 , XATTR_CREATE));
443+ ASSERT_EQ (0 , ceph_fsetxattr (cmount, fd, " user.remove.xattr" , nullptr , 0 , XATTR_REPLACE));
444+
445+ // ACL_EA_ACCESS and ACL_EA_DEFAULT are special and will always return success.
446+ // If the corresponding attributes exist already the first one will remove it
447+ // and the second one will remove the non-existing acl attributes.
448+ ASSERT_EQ (0 , ceph_fremovexattr (cmount, fd, ACL_EA_ACCESS));
449+ ASSERT_EQ (0 , ceph_fremovexattr (cmount, fd, ACL_EA_ACCESS));
450+ ASSERT_EQ (0 , ceph_fremovexattr (cmount, fd, ACL_EA_DEFAULT));
451+ ASSERT_EQ (0 , ceph_fremovexattr (cmount, fd, ACL_EA_DEFAULT));
452+
453+ ASSERT_EQ (0 , ceph_close (cmount, fd));
454+ ASSERT_EQ (0 , ceph_unmount (cmount));
455+ ceph_shutdown (cmount);
456+ }
457+
0 commit comments