Skip to content

Commit b855099

Browse files
committed
mds: add ceph.dir.subvolume.snaps.visible vxattr
using SNAPDIR_VISIBILITY flag added in sr_t Fixes: https://tracker.ceph.com/issues/71740 Signed-off-by: Dhairya Parmar <[email protected]>
1 parent b2db494 commit b855099

File tree

5 files changed

+126
-4
lines changed

5 files changed

+126
-4
lines changed

src/mds/Server.cc

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/mds/Server.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,8 @@ class Server {
500500
xattr_name == "ceph.dir.charmap"sv ||
501501
xattr_name == "ceph.dir.normalization"sv ||
502502
xattr_name == "ceph.dir.encoding"sv ||
503-
xattr_name == "ceph.dir.casesensitive"sv;
503+
xattr_name == "ceph.dir.casesensitive"sv ||
504+
xattr_name == "ceph.dir.subvolume.snaps.visible"sv;
504505
}
505506

506507
static bool is_ceph_dir_vxattr(std::string_view xattr_name) {
@@ -520,7 +521,8 @@ class Server {
520521
xattr_name == "ceph.dir.normalization"sv ||
521522
xattr_name == "ceph.dir.encoding"sv ||
522523
xattr_name == "ceph.dir.casesensitive"sv ||
523-
xattr_name == "ceph.dir.subvolume"sv;
524+
xattr_name == "ceph.dir.subvolume"sv ||
525+
xattr_name == "ceph.dir.subvolume.snaps.visible"sv;
524526
}
525527

526528
static bool is_ceph_file_vxattr(std::string_view xattr_name) {

src/mds/SnapRealm.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ ostream& operator<<(ostream& out, const SnapRealm& realm)
5858
if (realm.srnode.is_parent_global())
5959
out << " global ";
6060
out << " last_modified " << realm.srnode.last_modified
61-
<< " change_attr " << realm.srnode.change_attr;
61+
<< " change_attr " << realm.srnode.change_attr
62+
<< " is_snapdir_visible " << realm.srnode.is_snapdir_visible();
6263
out << " " << &realm << ")";
6364
return out;
6465
}

src/mds/snap.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ void sr_t::dump(Formatter *f) const
194194
f->dump_unsigned("last_destroyed", last_destroyed);
195195
f->dump_stream("last_modified") << last_modified;
196196
f->dump_unsigned("change_attr", change_attr);
197+
f->dump_unsigned("is_snapdir_visible", is_snapdir_visible());
197198
f->dump_unsigned("current_parent_since", current_parent_since);
198199

199200
f->open_array_section("snaps");
@@ -247,3 +248,11 @@ std::list<sr_t> sr_t::generate_test_instances()
247248
return ls;
248249
}
249250

251+
void sr_t::print(std::ostream& out) const {
252+
out << "sr_t(seq=" << seq
253+
<< " created=" << created
254+
<< " last_created=" << last_created
255+
<< " last_destroyed=" << last_destroyed
256+
<< " flags=" << flags << ")";
257+
}
258+

src/mds/snap.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,15 @@ struct sr_t {
8787
void clear_subvolume() { flags &= ~SUBVOLUME; }
8888
bool is_subvolume() const { return flags & SUBVOLUME; }
8989

90+
void set_snapdir_visibility() { flags |= SNAPDIR_VISIBILITY; }
91+
void unset_snapdir_visibility() { flags &= ~SNAPDIR_VISIBILITY; }
92+
bool is_snapdir_visible() const { return flags & SNAPDIR_VISIBILITY; }
93+
9094
void encode(ceph::buffer::list &bl) const;
9195
void decode(ceph::buffer::list::const_iterator &bl);
9296
void dump(ceph::Formatter *f) const;
9397
static std::list<sr_t> generate_test_instances();
98+
void print(std::ostream&) const;
9499

95100
snapid_t seq = 0; // basically, a version/seq # for changes to _this_ realm.
96101
snapid_t created = 0; // when this realm was created.
@@ -105,11 +110,13 @@ struct sr_t {
105110
uint64_t change_attr = 0; // tracks changes to snap
106111
// realm attrs.
107112

108-
__u32 flags = 0;
109113
enum {
110114
PARENT_GLOBAL = 1 << 0,
111115
SUBVOLUME = 1 << 1,
116+
SNAPDIR_VISIBILITY = 1 << 2,
112117
};
118+
119+
__u32 flags = SNAPDIR_VISIBILITY; // snapdir visibility is always on by default
113120
};
114121
WRITE_CLASS_ENCODER(sr_t)
115122

0 commit comments

Comments
 (0)