@@ -6518,6 +6518,96 @@ void Server::handle_client_setvxattr(const MDRequestRef& mdr, CInode *cur)
65186518 mdr->no_early_reply = true ;
65196519 pip = pi.inode .get ();
65206520 adjust_realm = true ;
6521+ } else if (name == " ceph.dir.subvolume.snaps.visible" sv) {
6522+ if (!cur->is_dir ()) {
6523+ respond_to_request (mdr, -EINVAL);
6524+ return ;
6525+ }
6526+
6527+ bool val = true ;
6528+ try {
6529+ std::string errstr;
6530+ val = strict_strtob (value, &errstr);
6531+ if (!errstr.empty ()) {
6532+ dout (10 ) << " bad vxattr value, unable to parse bool for " << name
6533+ << " : " << errstr << dendl;
6534+ respond_to_request (mdr, -EINVAL);
6535+ return ;
6536+ }
6537+ } catch (boost::bad_lexical_cast const & e) {
6538+ dout (10 ) << " bad vxattr value, unable to parse bool for " << name
6539+ << " : " << e.what () << dendl;
6540+ respond_to_request (mdr, -EINVAL);
6541+ return ;
6542+ }
6543+
6544+ // perform few checks with lightweight rdlock
6545+ if (!mdr->more ()->rdonly_checks ) {
6546+ lov.add_rdlock (&cur->snaplock );
6547+ if (!mds->locker ->acquire_locks (mdr, lov)) {
6548+ dout (20 ) << " handle_client_getvxattr could not acquire rdlock on "
6549+ << *cur << dendl;
6550+ return ;
6551+ }
6552+
6553+ const auto srnode = cur->get_projected_srnode ();
6554+ if (!srnode) {
6555+ dout (10 ) << " no-op since no snaprealm node found for "
6556+ << req->get_filepath () << dendl;
6557+ respond_to_request (mdr, 0 );
6558+ return ;
6559+ }
6560+ // check if visibility already matches the desired value
6561+ if (val == srnode->is_snapdir_visible ()) {
6562+ dout (20 ) << " snapdir visibility for " << req->get_filepath ()
6563+ << " is already set to " << std::boolalpha << val << dendl;
6564+ respond_to_request (mdr, 0 );
6565+ return ;
6566+ }
6567+
6568+ mdr->more ()->rdonly_checks = true ;
6569+ dout (20 ) << " dropping rdlock on " << *cur << dendl;
6570+ mds->locker ->drop_locks (mdr.get ());
6571+ }
6572+
6573+ if (!xlock_policylock (mdr, cur, false , true )) {
6574+ return ;
6575+ }
6576+
6577+ /* Repeat rdlocks checks to see if anything changed b/w rdlock release and
6578+ * xlock policylock acquisition
6579+ */
6580+ {
6581+ const auto srnode = cur->get_projected_srnode ();
6582+ if (!srnode) {
6583+ dout (10 ) << " no-op since no snaprealm node found for "
6584+ << req->get_filepath () << dendl;
6585+ respond_to_request (mdr, 0 );
6586+ return ;
6587+ }
6588+
6589+ if (val == srnode->is_snapdir_visible ()) {
6590+ dout (20 ) << " snapdir visibility for " << req->get_filepath ()
6591+ << " is already set to " << std::boolalpha << val << dendl;
6592+ respond_to_request (mdr, 0 );
6593+ return ;
6594+ }
6595+ }
6596+
6597+ adjust_realm = true ;
6598+ auto pi = cur->project_inode (mdr, false , adjust_realm);
6599+ dout (20 ) << " setting snapdir visibility to " << std::boolalpha
6600+ << val << " for " << req->get_filepath () << dendl;
6601+ if (val) {
6602+ pi.snapnode ->set_snapdir_visibility ();
6603+ } else {
6604+ pi.snapnode ->unset_snapdir_visibility ();
6605+ }
6606+ pi.snapnode ->last_modified = mdr->get_op_stamp ();
6607+ pi.snapnode ->change_attr ++;
6608+
6609+ mdr->no_early_reply = true ;
6610+ pip = pi.inode .get ();
65216611 } else if (name == " ceph.dir.pin" sv) {
65226612 if (!cur->is_dir () || cur->is_root ()) {
65236613 respond_to_request (mdr, -EINVAL);
@@ -7287,6 +7377,19 @@ void Server::handle_client_getvxattr(const MDRequestRef& mdr)
72877377 } else if (xattr_name == " ceph.dir.subvolume" sv) {
72887378 const auto * srnode = cur->get_projected_srnode ();
72897379 *css << (srnode && srnode->is_subvolume () ? " 1" sv : " 0" sv);
7380+ } else if (xattr_name == " ceph.dir.subvolume.snaps.visible" sv) {
7381+ if (!cur->is_dir ()) {
7382+ r = -ENOTDIR;
7383+ } else {
7384+ const auto srnode = cur->get_projected_srnode ();
7385+ if (!srnode) {
7386+ dout (10 ) << " no-op since no snaprealm node found for "
7387+ << mdr->client_request ->get_filepath () << dendl;
7388+ r = 0 ;
7389+ } else {
7390+ *css << srnode->is_snapdir_visible ();
7391+ }
7392+ }
72907393 } else {
72917394 // otherwise respond as invalid request
72927395 // since we only handle ceph vxattrs here
0 commit comments