]>
git.proxmox.com Git - ceph.git/blob - ceph/src/tools/cephfs/PgFiles.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2016 Red Hat
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.
15 #include "common/errno.h"
16 #include "osdc/Striper.h"
21 #define dout_context g_ceph_context
22 #define dout_subsys ceph_subsys_mds
24 #define dout_prefix *_dout << "pgeffects." << __func__ << ": "
28 int r
= ceph_create_with_context(&cmount
, g_ceph_context
);
33 return ceph_init(cmount
);
36 PgFiles::PgFiles(Objecter
*o
, const std::set
<pg_t
> &pgs_
)
37 : objecter(o
), pgs(pgs_
)
39 for (const auto &i
: pgs
) {
40 pools
.insert(i
.m_pool
);
49 void PgFiles::hit_dir(std::string
const &path
)
51 dout(10) << "entering " << path
<< dendl
;
53 ceph_dir_result
*dr
= nullptr;
54 int r
= ceph_opendir(cmount
, path
.c_str(), &dr
);
56 derr
<< "Failed to open path: " << cpp_strerror(r
) << dendl
;
61 while((r
= ceph_readdir_r(cmount
, dr
, &de
)) != 0) {
63 derr
<< "Error reading path " << path
<< ": " << cpp_strerror(r
)
65 ceph_closedir(cmount
, dr
); // best effort, ignore r
69 if (std::string(de
.d_name
) == "." || std::string(de
.d_name
) == "..") {
73 struct ceph_statx stx
;
74 std::string de_path
= (path
+ std::string("/") + de
.d_name
);
75 r
= ceph_statx(cmount
, de_path
.c_str(), &stx
,
76 CEPH_STATX_INO
|CEPH_STATX_SIZE
, 0);
78 derr
<< "Failed to stat path " << de_path
<< ": "
79 << cpp_strerror(r
) << dendl
;
80 // Don't hold up the whole process for one bad inode
84 if (S_ISREG(stx
.stx_mode
)) {
85 hit_file(de_path
, stx
);
86 } else if (S_ISDIR(stx
.stx_mode
)) {
89 dout(20) << "Skipping non reg/dir file: " << de_path
<< dendl
;
93 r
= ceph_closedir(cmount
, dr
);
95 derr
<< "Error closing path " << path
<< ": " << cpp_strerror(r
) << dendl
;
100 void PgFiles::hit_file(std::string
const &path
, const struct ceph_statx
&stx
)
102 ceph_assert(S_ISREG(stx
.stx_mode
));
104 dout(20) << "Hitting file '" << path
<< "'" << dendl
;
106 int l_stripe_unit
= 0;
107 int l_stripe_count
= 0;
108 int l_object_size
= 0;
110 int r
= ceph_get_path_layout(cmount
, path
.c_str(), &l_stripe_unit
,
111 &l_stripe_count
, &l_object_size
,
114 derr
<< "Error reading layout on " << path
<< ": " << cpp_strerror(r
)
119 struct file_layout_t layout
;
120 layout
.stripe_unit
= l_stripe_unit
;
121 layout
.stripe_count
= l_stripe_count
;
122 layout
.object_size
= l_object_size
;
123 layout
.pool_id
= l_pool_id
;
125 // Avoid calculating PG if the layout targeted a completely different pool
126 if (pools
.count(layout
.pool_id
) == 0) {
127 dout(20) << "Fast check missed: pool " << layout
.pool_id
<< " not in "
128 "target set" << dendl
;
132 auto num_objects
= Striper::get_num_objects(layout
, stx
.stx_size
);
134 for (uint64_t i
= 0; i
< num_objects
; ++i
) {
136 snprintf(buf
, sizeof(buf
), "%llx.%08llx", (long long unsigned)stx
.stx_ino
,
137 (long long unsigned int)i
);
138 dout(20) << " object " << std::string(buf
) << dendl
;
142 object_locator_t loc
;
143 loc
.pool
= layout
.pool_id
;
144 loc
.key
= std::string(buf
);
146 unsigned pg_num_mask
= 0;
150 objecter
->with_osdmap([&r
, oid
, loc
, &target
, &pg_num_mask
, &pg_num
]
151 (const OSDMap
&osd_map
) {
152 r
= osd_map
.object_locator_to_pg(oid
, loc
, target
);
154 auto pool
= osd_map
.get_pg_pool(loc
.pool
);
155 pg_num_mask
= pool
->get_pg_num_mask();
156 pg_num
= pool
->get_pg_num();
160 // Can happen if layout pointed to pool not in osdmap, for example
164 target
.m_seed
= ceph_stable_mod(target
.ps(), pg_num
, pg_num_mask
);
166 dout(20) << " target " << target
<< dendl
;
168 if (pgs
.count(target
)) {
169 std::cout
<< path
<< std::endl
;
176 int PgFiles::scan_path(std::string
const &path
)
178 int r
= ceph_mount(cmount
, "/");
180 derr
<< "Failed to mount: " << cpp_strerror(r
) << dendl
;
186 r
= ceph_unmount(cmount
);
188 derr
<< "Failed to unmount: " << cpp_strerror(r
) << dendl
;