Skip to content

Commit cf51417

Browse files
authored
Merge pull request ceph#55945 from lxbsz/wip-64679-new
mds/client: return -ENODATA when xattr doesn't exist for removexattr Reviewed-by: Venky Shankar <[email protected]>
2 parents 9d2646b + b2a07f8 commit cf51417

File tree

7 files changed

+103
-37
lines changed

7 files changed

+103
-37
lines changed

qa/workunits/libcephfs/test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ ceph_test_libcephfs_lazyio
77
ceph_test_libcephfs_newops
88
ceph_test_libcephfs_suidsgid
99
ceph_test_libcephfs_snapdiff
10+
ceph_test_libcephfs_vxattr
1011

1112
exit 0

src/client/Client.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13868,7 +13868,7 @@ int Client::_do_setxattr(Inode *in, const char *name, const void *value,
1386813868

1386913869
int xattr_flags = 0;
1387013870
if (!value)
13871-
xattr_flags |= CEPH_XATTR_REMOVE;
13871+
xattr_flags |= CEPH_XATTR_REMOVE | CEPH_XATTR_REMOVE2;
1387213872
if (flags & XATTR_CREATE)
1387313873
xattr_flags |= CEPH_XATTR_CREATE;
1387413874
if (flags & XATTR_REPLACE)
@@ -13926,6 +13926,7 @@ int Client::_setxattr(Inode *in, const char *name, const void *value,
1392613926
mode_t new_mode = in->mode;
1392713927
if (value) {
1392813928
int ret = posix_acl_equiv_mode(value, size, &new_mode);
13929+
ldout(cct, 3) << __func__ << "(" << in->ino << ", \"" << name << "\") = " << ret << dendl;
1392913930
if (ret < 0)
1393013931
return ret;
1393113932
if (ret == 0) {
@@ -13975,6 +13976,11 @@ int Client::_setxattr(Inode *in, const char *name, const void *value,
1397513976
ret = -CEPHFS_EOPNOTSUPP;
1397613977
}
1397713978

13979+
if ((!strcmp(name, ACL_EA_ACCESS) ||
13980+
!strcmp(name, ACL_EA_DEFAULT)) &&
13981+
ret == -CEPHFS_ENODATA)
13982+
ret = 0;
13983+
1397813984
return ret;
1397913985
}
1398013986

@@ -14063,7 +14069,7 @@ int Client::ll_setxattr(Inode *in, const char *name, const void *value,
1406314069

1406414070
vinodeno_t vino = _get_vino(in);
1406514071

14066-
ldout(cct, 3) << __func__ << " " << vino << " " << name << " size " << size << dendl;
14072+
ldout(cct, 3) << __func__ << " " << vino << " " << name << " size " << size << " value " << !!value << dendl;
1406714073
tout(cct) << __func__ << std::endl;
1406814074
tout(cct) << vino.ino.val << std::endl;
1406914075
tout(cct) << name << std::endl;

src/include/ceph_fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ int ceph_flags_sys2wire(int flags);
488488
*/
489489
#define CEPH_XATTR_CREATE (1 << 0)
490490
#define CEPH_XATTR_REPLACE (1 << 1)
491+
#define CEPH_XATTR_REMOVE2 (1 << 30)
491492
#define CEPH_XATTR_REMOVE (1 << 31)
492493

493494
/*

src/mds/Server.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6534,6 +6534,11 @@ int Server::xattr_validate(CInode *cur, const InodeStoreBase::xattr_map_const_pt
65346534
return -CEPHFS_ENODATA;
65356535
}
65366536

6537+
if ((flags & CEPH_XATTR_REMOVE2) && !(xattrs && xattrs->count(mempool::mds_co::string(xattr_name)))) {
6538+
dout(10) << "setxattr '" << xattr_name << "' XATTR_REMOVE2 and CEPHFS_ENODATA on " << *cur << dendl;
6539+
return -CEPHFS_ENODATA;
6540+
}
6541+
65376542
return 0;
65386543
}
65396544

@@ -6743,7 +6748,7 @@ void Server::handle_client_setxattr(const MDRequestRef& mdr)
67436748
pi.inode->change_attr++;
67446749
pi.inode->xattr_version++;
67456750

6746-
if ((flags & CEPH_XATTR_REMOVE)) {
6751+
if ((flags & (CEPH_XATTR_REMOVE | CEPH_XATTR_REMOVE2))) {
67476752
std::invoke(handler->removexattr, this, cur, pi.xattrs, xattr_op);
67486753
} else {
67496754
std::invoke(handler->setxattr, this, cur, pi.xattrs, xattr_op);

src/test/libcephfs/CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ if(WITH_LIBCEPHFS)
1010
main.cc
1111
deleg.cc
1212
monconfig.cc
13-
vxattr.cc
1413
)
1514
target_link_libraries(ceph_test_libcephfs
1615
ceph-common
@@ -50,6 +49,21 @@ if(WITH_LIBCEPHFS)
5049
install(TARGETS ceph_test_libcephfs_suidsgid
5150
DESTINATION ${CMAKE_INSTALL_BINDIR})
5251

52+
add_executable(ceph_test_libcephfs_vxattr
53+
vxattr.cc
54+
main.cc
55+
)
56+
target_link_libraries(ceph_test_libcephfs_vxattr
57+
ceph-common
58+
cephfs
59+
librados
60+
${UNITTEST_LIBS}
61+
${EXTRALIBS}
62+
${CMAKE_DL_LIBS}
63+
)
64+
install(TARGETS ceph_test_libcephfs_vxattr
65+
DESTINATION ${CMAKE_INSTALL_BINDIR})
66+
5367
add_executable(ceph_test_libcephfs_newops
5468
main.cc
5569
newops.cc

src/test/libcephfs/test.cc

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3520,39 +3520,6 @@ TEST(LibCephFS, SetMountTimeout) {
35203520
ceph_shutdown(cmount);
35213521
}
35223522

3523-
TEST(LibCephFS, FsCrypt) {
3524-
struct ceph_mount_info *cmount;
3525-
ASSERT_EQ(ceph_create(&cmount, NULL), 0);
3526-
ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
3527-
ASSERT_EQ(0, ceph_conf_parse_env(cmount, NULL));
3528-
ASSERT_EQ(ceph_mount(cmount, NULL), 0);
3529-
3530-
char test_xattr_file[NAME_MAX];
3531-
sprintf(test_xattr_file, "test_fscrypt_%d", getpid());
3532-
int fd = ceph_open(cmount, test_xattr_file, O_RDWR|O_CREAT, 0666);
3533-
ASSERT_GT(fd, 0);
3534-
3535-
ASSERT_EQ(0, ceph_fsetxattr(cmount, fd, "ceph.fscrypt.auth", "foo", 3, CEPH_XATTR_CREATE));
3536-
ASSERT_EQ(0, ceph_fsetxattr(cmount, fd, "ceph.fscrypt.file", "foo", 3, CEPH_XATTR_CREATE));
3537-
3538-
char buf[64];
3539-
ASSERT_EQ(3, ceph_fgetxattr(cmount, fd, "ceph.fscrypt.auth", buf, sizeof(buf)));
3540-
ASSERT_EQ(3, ceph_fgetxattr(cmount, fd, "ceph.fscrypt.file", buf, sizeof(buf)));
3541-
ASSERT_EQ(0, ceph_close(cmount, fd));
3542-
3543-
ASSERT_EQ(0, ceph_unmount(cmount));
3544-
ASSERT_EQ(0, ceph_mount(cmount, NULL));
3545-
3546-
fd = ceph_open(cmount, test_xattr_file, O_RDWR, 0666);
3547-
ASSERT_GT(fd, 0);
3548-
ASSERT_EQ(3, ceph_fgetxattr(cmount, fd, "ceph.fscrypt.auth", buf, sizeof(buf)));
3549-
ASSERT_EQ(3, ceph_fgetxattr(cmount, fd, "ceph.fscrypt.file", buf, sizeof(buf)));
3550-
3551-
ASSERT_EQ(0, ceph_close(cmount, fd));
3552-
ASSERT_EQ(0, ceph_unmount(cmount));
3553-
ceph_shutdown(cmount);
3554-
}
3555-
35563523
TEST(LibCephFS, SnapdirAttrs) {
35573524
struct ceph_mount_info *cmount;
35583525
ASSERT_EQ(ceph_create(&cmount, NULL), 0);

src/test/libcephfs/vxattr.cc

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,75 @@ TEST(LibCephFS, GetAndSetDirRandom) {
383383

384384
ceph_shutdown(cmount);
385385
}
386+
387+
TEST(LibCephFS, FsCrypt) {
388+
struct ceph_mount_info *cmount;
389+
ASSERT_EQ(ceph_create(&cmount, NULL), 0);
390+
ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
391+
ASSERT_EQ(0, ceph_conf_parse_env(cmount, NULL));
392+
ASSERT_EQ(ceph_mount(cmount, NULL), 0);
393+
394+
char test_xattr_file[NAME_MAX];
395+
sprintf(test_xattr_file, "test_fscrypt_%d", getpid());
396+
int fd = ceph_open(cmount, test_xattr_file, O_RDWR|O_CREAT, 0666);
397+
ASSERT_GT(fd, 0);
398+
399+
ASSERT_EQ(0, ceph_fsetxattr(cmount, fd, "ceph.fscrypt.auth", "foo", 3, XATTR_CREATE));
400+
ASSERT_EQ(0, ceph_fsetxattr(cmount, fd, "ceph.fscrypt.file", "foo", 3, XATTR_CREATE));
401+
402+
char buf[64];
403+
ASSERT_EQ(3, ceph_fgetxattr(cmount, fd, "ceph.fscrypt.auth", buf, sizeof(buf)));
404+
ASSERT_EQ(3, ceph_fgetxattr(cmount, fd, "ceph.fscrypt.file", buf, sizeof(buf)));
405+
ASSERT_EQ(0, ceph_close(cmount, fd));
406+
407+
ASSERT_EQ(0, ceph_unmount(cmount));
408+
ASSERT_EQ(0, ceph_mount(cmount, NULL));
409+
410+
fd = ceph_open(cmount, test_xattr_file, O_RDWR, 0666);
411+
ASSERT_GT(fd, 0);
412+
ASSERT_EQ(3, ceph_fgetxattr(cmount, fd, "ceph.fscrypt.auth", buf, sizeof(buf)));
413+
ASSERT_EQ(3, ceph_fgetxattr(cmount, fd, "ceph.fscrypt.file", buf, sizeof(buf)));
414+
415+
ASSERT_EQ(0, ceph_close(cmount, fd));
416+
ASSERT_EQ(0, ceph_unmount(cmount));
417+
ceph_shutdown(cmount);
418+
}
419+
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

Comments
 (0)