Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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 #include "cls_cephfs_client.h"
17 #include "include/rados/librados.hpp"
18 #include "mds/CInode.h"
19
20 #define XATTR_CEILING "scan_ceiling"
21 #define XATTR_MAX_MTIME "scan_max_mtime"
22 #define XATTR_MAX_SIZE "scan_max_size"
23
24 int ClsCephFSClient::accumulate_inode_metadata(
25   librados::IoCtx &ctx,
26   inodeno_t inode_no,
27   const uint64_t obj_index,
28   const uint64_t obj_size,
29   const time_t mtime)
30 {
31   AccumulateArgs args(
32       obj_index,
33       obj_size,
34       mtime,
35       XATTR_CEILING,
36       XATTR_MAX_MTIME,
37       XATTR_MAX_SIZE);
38
39   // Generate 0th object name, where we will accumulate sizes/mtimes
40   object_t zeroth_object = InodeStore::get_object_name(inode_no, frag_t(), "");
41
42   // Construct a librados operation invoking our class method
43   librados::ObjectReadOperation op;
44   bufferlist inbl;
45   args.encode(inbl);
46   op.exec("cephfs", "accumulate_inode_metadata", inbl);
47
48   // Execute op
49   bufferlist outbl;
50   return ctx.operate(zeroth_object.name, &op, &outbl);
51 }
52
53 int ClsCephFSClient::delete_inode_accumulate_result(
54     librados::IoCtx &ctx,
55     const std::string &oid)
56 {
57   librados::ObjectWriteOperation op;
58
59   // Remove xattrs from object
60   //
61   op.rmxattr(XATTR_CEILING);
62   op.rmxattr(XATTR_MAX_SIZE);
63   op.rmxattr(XATTR_MAX_MTIME);
64
65   return (ctx.operate(oid, &op));
66 }
67
68 int ClsCephFSClient::fetch_inode_accumulate_result(
69   librados::IoCtx &ctx,
70   const std::string &oid,
71   inode_backtrace_t *backtrace,
72   file_layout_t *layout,
73   AccumulateResult *result)
74 {
75   assert(backtrace != NULL);
76   assert(result != NULL);
77
78   librados::ObjectReadOperation op;
79
80   int scan_ceiling_r = 0;
81   bufferlist scan_ceiling_bl;
82   op.getxattr(XATTR_CEILING, &scan_ceiling_bl, &scan_ceiling_r);
83
84   int scan_max_size_r = 0;
85   bufferlist scan_max_size_bl;
86   op.getxattr(XATTR_MAX_SIZE, &scan_max_size_bl, &scan_max_size_r);
87
88   int scan_max_mtime_r = 0;
89   bufferlist scan_max_mtime_bl;
90   op.getxattr(XATTR_MAX_MTIME, &scan_max_mtime_bl, &scan_max_mtime_r);
91
92   int parent_r = 0;
93   bufferlist parent_bl;
94   op.getxattr("parent", &parent_bl, &parent_r);
95   op.set_op_flags2(librados::OP_FAILOK);
96
97   int layout_r = 0;
98   bufferlist layout_bl;
99   op.getxattr("layout", &layout_bl, &layout_r);
100   op.set_op_flags2(librados::OP_FAILOK);
101
102   bufferlist op_bl;
103   int r = ctx.operate(oid, &op, &op_bl);
104   if (r < 0) {
105     return r;
106   }
107
108   // Load scan_ceiling
109   try {
110     bufferlist::iterator scan_ceiling_bl_iter = scan_ceiling_bl.begin();
111     ObjCeiling ceiling;
112     ceiling.decode(scan_ceiling_bl_iter);
113     result->ceiling_obj_index = ceiling.id;
114     result->ceiling_obj_size = ceiling.size;
115   } catch (const buffer::error &err) {
116     //dout(4) << "Invalid size attr on '" << oid << "'" << dendl;
117     return -EINVAL;
118   }
119
120   // Load scan_max_size
121   try {
122     bufferlist::iterator scan_max_size_bl_iter = scan_max_size_bl.begin();
123     ::decode(result->max_obj_size, scan_max_size_bl_iter);
124   } catch (const buffer::error &err) {
125     //dout(4) << "Invalid size attr on '" << oid << "'" << dendl;
126     return -EINVAL;
127   }
128
129   // Load scan_max_mtime
130   try {
131     bufferlist::iterator scan_max_mtime_bl_iter = scan_max_mtime_bl.begin();
132     ::decode(result->max_mtime, scan_max_mtime_bl_iter);
133   } catch (const buffer::error &err) {
134     //dout(4) << "Invalid size attr on '" << oid << "'" << dendl;
135     return -EINVAL;
136   }
137
138   // Deserialize backtrace
139   if (parent_bl.length()) {
140     try {
141       bufferlist::iterator q = parent_bl.begin();
142       backtrace->decode(q);
143     } catch (buffer::error &e) {
144       //dout(4) << "Corrupt backtrace on '" << oid << "': " << e << dendl;
145       return -EINVAL;
146     }
147   }
148
149   // Deserialize layout
150   if (layout_bl.length()) {
151     try {
152       bufferlist::iterator q = layout_bl.begin();
153       ::decode(*layout, q);
154     } catch (buffer::error &e) {
155       return -EINVAL;
156     }
157   }
158
159   return 0;
160 }
161
162 void ClsCephFSClient::build_tag_filter(
163           const std::string &scrub_tag,
164           bufferlist *out_bl)
165 {
166   assert(out_bl != NULL);
167
168   // Leading part of bl is un-versioned string naming the filter
169   ::encode(std::string("cephfs.inode_tag"), *out_bl);
170
171   // Filter-specific part of the bl: in our case this is a versioned structure
172   InodeTagFilterArgs args;
173   args.scrub_tag = scrub_tag;
174   args.encode(*out_bl);
175 }
176