]> git.proxmox.com Git - ceph.git/blob - ceph/src/cls/cephfs/cls_cephfs_client.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / cls / cephfs / cls_cephfs_client.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2015 Red Hat
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15
16
17 #include "include/rados/librados.hpp"
18 #include "mds/CInode.h"
19
20 #include "cls_cephfs_client.h"
21
22 using ceph::bufferlist;
23 using ceph::decode;
24
25 #define XATTR_CEILING "scan_ceiling"
26 #define XATTR_MAX_MTIME "scan_max_mtime"
27 #define XATTR_MAX_SIZE "scan_max_size"
28
29 int ClsCephFSClient::accumulate_inode_metadata(
30 librados::IoCtx &ctx,
31 inodeno_t inode_no,
32 const uint64_t obj_index,
33 const uint64_t obj_size,
34 const time_t mtime)
35 {
36 AccumulateArgs args(
37 obj_index,
38 obj_size,
39 mtime,
40 XATTR_CEILING,
41 XATTR_MAX_MTIME,
42 XATTR_MAX_SIZE);
43
44 // Generate 0th object name, where we will accumulate sizes/mtimes
45 object_t zeroth_object = InodeStore::get_object_name(inode_no, frag_t(), "");
46
47 // Construct a librados operation invoking our class method
48 librados::ObjectReadOperation op;
49 bufferlist inbl;
50 args.encode(inbl);
51 op.exec("cephfs", "accumulate_inode_metadata", inbl);
52
53 // Execute op
54 bufferlist outbl;
55 return ctx.operate(zeroth_object.name, &op, &outbl);
56 }
57
58 int ClsCephFSClient::delete_inode_accumulate_result(
59 librados::IoCtx &ctx,
60 const std::string &oid)
61 {
62 librados::ObjectWriteOperation op;
63
64 // Remove xattrs from object
65 //
66 op.rmxattr(XATTR_CEILING);
67 op.rmxattr(XATTR_MAX_SIZE);
68 op.rmxattr(XATTR_MAX_MTIME);
69
70 return (ctx.operate(oid, &op));
71 }
72
73 int ClsCephFSClient::fetch_inode_accumulate_result(
74 librados::IoCtx &ctx,
75 const std::string &oid,
76 inode_backtrace_t *backtrace,
77 file_layout_t *layout,
78 std::string *symlink,
79 AccumulateResult *result)
80 {
81 ceph_assert(backtrace != NULL);
82 ceph_assert(result != NULL);
83
84 librados::ObjectReadOperation op;
85
86 int scan_ceiling_r = 0;
87 bufferlist scan_ceiling_bl;
88 op.getxattr(XATTR_CEILING, &scan_ceiling_bl, &scan_ceiling_r);
89
90 int scan_max_size_r = 0;
91 bufferlist scan_max_size_bl;
92 op.getxattr(XATTR_MAX_SIZE, &scan_max_size_bl, &scan_max_size_r);
93
94 int scan_max_mtime_r = 0;
95 bufferlist scan_max_mtime_bl;
96 op.getxattr(XATTR_MAX_MTIME, &scan_max_mtime_bl, &scan_max_mtime_r);
97
98 int parent_r = 0;
99 bufferlist parent_bl;
100 op.getxattr("parent", &parent_bl, &parent_r);
101 op.set_op_flags2(librados::OP_FAILOK);
102
103 int layout_r = 0;
104 bufferlist layout_bl;
105 op.getxattr("layout", &layout_bl, &layout_r);
106 op.set_op_flags2(librados::OP_FAILOK);
107
108 int symlink_r = 0;
109 bufferlist symlink_bl;
110 op.getxattr("symlink", &symlink_bl, &symlink_r);
111 op.set_op_flags2(librados::OP_FAILOK);
112
113 bufferlist op_bl;
114 int r = ctx.operate(oid, &op, &op_bl);
115 if (r < 0) {
116 return r;
117 }
118
119 // Load scan_ceiling
120 try {
121 auto scan_ceiling_bl_iter = scan_ceiling_bl.cbegin();
122 ObjCeiling ceiling;
123 ceiling.decode(scan_ceiling_bl_iter);
124 result->ceiling_obj_index = ceiling.id;
125 result->ceiling_obj_size = ceiling.size;
126 } catch (const ceph::buffer::error &err) {
127 //dout(4) << "Invalid size attr on '" << oid << "'" << dendl;
128 return -EINVAL;
129 }
130
131 // Load scan_max_size
132 try {
133 auto scan_max_size_bl_iter = scan_max_size_bl.cbegin();
134 decode(result->max_obj_size, scan_max_size_bl_iter);
135 } catch (const ceph::buffer::error &err) {
136 //dout(4) << "Invalid size attr on '" << oid << "'" << dendl;
137 return -EINVAL;
138 }
139
140 // Load scan_max_mtime
141 try {
142 auto scan_max_mtime_bl_iter = scan_max_mtime_bl.cbegin();
143 decode(result->max_mtime, scan_max_mtime_bl_iter);
144 } catch (const ceph::buffer::error &err) {
145 //dout(4) << "Invalid size attr on '" << oid << "'" << dendl;
146 return -EINVAL;
147 }
148
149 // Deserialize backtrace
150 if (parent_bl.length()) {
151 try {
152 auto q = parent_bl.cbegin();
153 backtrace->decode(q);
154 } catch (ceph::buffer::error &e) {
155 //dout(4) << "Corrupt backtrace on '" << oid << "': " << e << dendl;
156 return -EINVAL;
157 }
158 }
159
160 // Deserialize layout
161 if (layout_bl.length()) {
162 try {
163 auto q = layout_bl.cbegin();
164 decode(*layout, q);
165 } catch (ceph::buffer::error &e) {
166 return -EINVAL;
167 }
168 }
169
170 // Deserialize symlink
171 if (symlink_bl.length()) {
172 try {
173 auto q = symlink_bl.cbegin();
174 decode(*symlink, q);
175 } catch (ceph::buffer::error &e) {
176 return -EINVAL;
177 }
178 }
179
180 return 0;
181 }
182
183 void ClsCephFSClient::build_tag_filter(
184 const std::string &scrub_tag,
185 bufferlist *out_bl)
186 {
187 ceph_assert(out_bl != NULL);
188
189 // Leading part of bl is un-versioned string naming the filter
190 encode(std::string("cephfs.inode_tag"), *out_bl);
191
192 // Filter-specific part of the bl: in our case this is a versioned structure
193 InodeTagFilterArgs args;
194 args.scrub_tag = scrub_tag;
195 args.encode(*out_bl);
196 }