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) 2004-2006 Sage Weil <sage@newdream.net>
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.
25 #include "osd/osd_types.h"
26 #include "include/object.h"
27 #include "common/ceph_crypto.h"
29 #include "CollectionIndex.h"
32 * LFNIndex also encapsulates logic for manipulating
33 * subdirectories of a collection as well as the long filename
36 * The protected methods provide machinery for derived classes to
37 * manipulate subdirectories and objects.
39 * The virtual methods are to be overridden to provide the actual
42 * User must call created when an object is created.
44 * Synchronization: Calling code must ensure that there are no object
45 * creations or deletions during the lifetime of a Path object (except
46 * of an object at that path).
48 * Unless otherwise noted, methods which return an int return 0 on success
49 * and a negative error code on failure.
51 #define WRAP_RETRY(x) { \
52 bool failed = false; \
54 init_inject_failure(); \
59 ceph_assert(r == 0); \
63 complete_inject_failure(); \
65 } catch (RetryException&) { \
76 class LFNIndex : public CollectionIndex {
77 /// Hash digest output size.
78 static const int FILENAME_LFN_DIGEST_SIZE
= CEPH_CRYPTO_SHA1_DIGESTSIZE
;
79 /// Length of filename hash.
80 static const int FILENAME_HASH_LEN
= FILENAME_LFN_DIGEST_SIZE
;
81 /// Max filename size.
82 static const int FILENAME_MAX_LEN
= 4096;
83 /// Length of hashed filename.
84 static const int FILENAME_SHORT_LEN
= 255;
85 /// Length of hashed filename prefix.
86 static const int FILENAME_PREFIX_LEN
;
87 /// Length of hashed filename cookie.
88 static const int FILENAME_EXTRA
= 4;
90 static const std::string FILENAME_COOKIE
;
91 /// Name of LFN attribute for storing full name.
92 static const std::string LFN_ATTR
;
93 /// Prefix for subdir index attributes.
94 static const std::string PHASH_ATTR_PREFIX
;
95 /// Prefix for index subdirectories.
96 static const std::string SUBDIR_PREFIX
;
98 /// Path to Index base.
99 const std::string base_path
;
102 const uint32_t index_version
;
104 /// true if retry injection is enabled
105 struct RetryException
: public std::exception
{};
106 bool error_injection_enabled
;
107 bool error_injection_on
;
108 double error_injection_probability
;
109 uint64_t last_failure
;
110 uint64_t current_failure
;
111 void init_inject_failure() {
112 if (error_injection_on
) {
113 error_injection_enabled
= true;
114 last_failure
= current_failure
= 0;
117 void maybe_inject_failure();
118 void complete_inject_failure() {
119 error_injection_enabled
= false;
123 std::string lfn_attribute
, lfn_alt_attribute
;
131 const char *base_path
, ///< [in] path to Index root
132 uint32_t index_version
,
133 double _error_injection_probability
=0)
134 : CollectionIndex(cct
, collection
),
135 base_path(base_path
),
136 index_version(index_version
),
137 error_injection_enabled(false),
138 error_injection_on(_error_injection_probability
!= 0),
139 error_injection_probability(_error_injection_probability
),
140 last_failure(0), current_failure(0),
141 collection(collection
) {
142 if (index_version
== HASH_INDEX_TAG
) {
143 lfn_attribute
= LFN_ATTR
;
146 snprintf(buf
, sizeof(buf
), "%d", index_version
);
147 lfn_attribute
= LFN_ATTR
+ std::string(buf
);
148 lfn_alt_attribute
= LFN_ATTR
+ std::string(buf
) + "-alt";
152 coll_t
coll() const override
{ return collection
; }
154 /// Virtual destructor
155 ~LFNIndex() override
{}
157 /// @see CollectionIndex
160 /// @see CollectionIndex
161 int cleanup() override
= 0;
163 /// @see CollectionIndex
165 const ghobject_t
&oid
,
169 /// @see CollectionIndex
171 const ghobject_t
&oid
174 /// @see CollectionIndex
176 const ghobject_t
&oid
,
181 /// @see CollectionIndex;
182 int pre_hash_collection(
184 uint64_t expected_num_objs
187 /// @see CollectionIndex
188 int collection_list_partial(
189 const ghobject_t
&start
,
190 const ghobject_t
&end
,
192 std::vector
<ghobject_t
> *ls
,
197 uint32_t match
, //< [in] value to match
198 uint32_t bits
, //< [in] bits to check
199 CollectionIndex
* dest
//< [in] destination index
202 uint32_t bits
, //< [in] bits for target
203 CollectionIndex
* dest
//< [in] destination index
206 /// @see CollectionIndex
210 CollectionIndex
* dest
213 r
= _split(match
, bits
, dest
);
218 /// @see CollectionIndex
221 CollectionIndex
* dest
224 r
= _merge(bits
, dest
);
230 * Returns the length of the longest escaped name which could result
231 * from any clone, shard, or rollback object of this object
233 static uint64_t get_max_escaped_name_len(const hobject_t
&obj
);
236 virtual int _init() = 0;
238 /// Will be called upon object creation
239 virtual int _created(
240 const std::vector
<std::string
> &path
, ///< [in] Path to subdir.
241 const ghobject_t
&oid
, ///< [in] Object created.
242 const std::string
&mangled_name
///< [in] Mangled filename.
245 /// Will be called to remove an object
247 const std::vector
<std::string
> &path
, ///< [in] Path to subdir.
248 const ghobject_t
&oid
, ///< [in] Object to remove.
249 const std::string
&mangled_name
///< [in] Mangled filename.
252 /// Return the path and mangled_name for oid.
254 const ghobject_t
&oid
,///< [in] Object for lookup.
255 std::vector
<std::string
> *path
, ///< [out] Path to the object.
256 std::string
*mangled_name
, ///< [out] Mangled filename.
257 int *exists
///< [out] True if the object exists.
260 /// Pre-hash the collection with the given pg number and
261 /// expected number of objects in the collection.
262 virtual int _pre_hash_collection(
264 uint64_t expected_num_objs
267 /// @see CollectionIndex
268 virtual int _collection_list_partial(
269 const ghobject_t
&start
,
270 const ghobject_t
&end
,
272 std::vector
<ghobject_t
> *ls
,
278 /* Non-virtual utility methods */
280 /// Sync a subdirectory
282 const std::vector
<std::string
> &path
///< [in] Path to sync
283 ); ///< @return Error Code, 0 on success
285 /// Link an object from from into to
287 const std::vector
<std::string
> &from
, ///< [in] Source subdirectory.
288 const std::vector
<std::string
> &to
, ///< [in] Dest subdirectory.
289 const ghobject_t
&oid
, ///< [in] Object to move.
290 const std::string
&from_short_name
///< [in] Mangled filename of oid.
291 ); ///< @return Error Code, 0 on success
294 * Efficiently remove objects from a subdirectory
296 * remove_object invalidates mangled names in the directory requiring
297 * the mangled name of each additional object to be looked up a second
298 * time. remove_objects removes the need for additional lookups
300 * @param [in] dir Directory from which to remove.
301 * @param [in] map of objects to remove to mangle names
302 * @param [in,out] map of filenames to objects
303 * @return Error Code, 0 on success.
306 const std::vector
<std::string
> &dir
,
307 const std::map
<std::string
, ghobject_t
> &to_remove
,
308 std::map
<std::string
, ghobject_t
> *remaining
313 * Moves contents of from into to.
315 * Invalidates mangled names in to. If interrupted, all objects will be
316 * present in to before objects are removed from from. Ignores EEXIST
317 * while linking into to.
318 * @return Error Code, 0 on success
321 const std::vector
<std::string
> &from
, ///< [in] Source subdirectory.
322 const std::vector
<std::string
> &to
///< [in] Dest subdirectory.
326 * Remove an object from from.
328 * Invalidates mangled names in from.
329 * @return Error Code, 0 on success
332 const std::vector
<std::string
> &from
, ///< [in] Directory from which to remove.
333 const ghobject_t
&to_remove
///< [in] Object to remove.
337 * Gets the filename corresponding to oid in from.
339 * The filename may differ between subdirectories. Furthermore,
340 * file creations ore removals in from may invalidate the name.
341 * @return Error code on failure, 0 on success
343 int get_mangled_name(
344 const std::vector
<std::string
> &from
, ///< [in] Subdirectory
345 const ghobject_t
&oid
, ///< [in] Object
346 std::string
*mangled_name
, ///< [out] Filename
347 int *hardlink
///< [out] hardlink for this file, hardlink=0 mean no-exist
350 /// do move subdir from from to dest
351 static int move_subdir(
352 LFNIndex
&from
, ///< [in] from index
353 LFNIndex
&dest
, ///< [in] to index
354 const std::vector
<std::string
> &path
, ///< [in] path containing dir
355 std::string dir
///< [in] dir to move
358 /// do move object from from to dest
359 static int move_object(
360 LFNIndex
&from
, ///< [in] from index
361 LFNIndex
&dest
, ///< [in] to index
362 const std::vector
<std::string
> &path
, ///< [in] path to split
363 const std::pair
<std::string
, ghobject_t
> &obj
///< [in] obj to move
367 * Lists objects in to_list.
369 * @param [in] to_list Directory to list.
370 * @param [in] max_objects Max number to list.
371 * @param [in,out] handle Cookie for continuing the listing.
372 * Initialize to zero to start at the beginning of the directory.
373 * @param [out] out Mapping of listed object filenames to objects.
374 * @return Error code on failure, 0 on success
377 const std::vector
<std::string
> &to_list
,
380 std::map
<std::string
, ghobject_t
> *out
383 /// Lists subdirectories.
385 const std::vector
<std::string
> &to_list
, ///< [in] Directory to list.
386 std::vector
<std::string
> *out
///< [out] Subdirectories listed.
389 /// Create subdirectory.
391 const std::vector
<std::string
> &to_create
///< [in] Subdirectory to create.
394 /// Remove subdirectory.
396 const std::vector
<std::string
> &to_remove
///< [in] Subdirectory to remove.
399 /// Check whether to_check exists.
401 const std::vector
<std::string
> &to_check
, ///< [in] Subdirectory to check.
402 int *exists
///< [out] 1 if it exists, 0 else
405 /// Save attr_value to attr_name attribute on path.
407 const std::vector
<std::string
> &path
, ///< [in] Path to modify.
408 const std::string
&attr_name
, ///< [in] Name of attribute.
409 ceph::buffer::list
&attr_value
///< [in] Value to save.
412 /// Read into attr_value attribute attr_name on path.
414 const std::vector
<std::string
> &path
, ///< [in] Path to read.
415 const std::string
&attr_name
, ///< [in] Attribute to read.
416 ceph::buffer::list
&attr_value
///< [out] Attribute value read.
419 /// Remove attr from path
420 int remove_attr_path(
421 const std::vector
<std::string
> &path
, ///< [in] path from which to remove attr
422 const std::string
&attr_name
///< [in] attr to remove
423 ); ///< @return Error code, 0 on success
426 /* lfn translation functions */
429 * Gets the version specific lfn attribute tag
431 const std::string
&get_lfn_attr() const {
432 return lfn_attribute
;
434 const std::string
&get_alt_lfn_attr() const {
435 return lfn_alt_attribute
;
439 * Gets the filename corresponding to oid in path.
441 * @param [in] path Path in which to get filename for oid.
442 * @param [in] oid Object for which to get filename.
443 * @param [out] mangled_name Filename for oid, pass NULL if not needed.
444 * @param [out] full_path Fullpath for oid, pass NULL if not needed.
445 * @param [out] hardlink of this file, 0 mean no-exist, pass NULL if
447 * @return Error Code, 0 on success.
450 const std::vector
<std::string
> &path
,
451 const ghobject_t
&oid
,
452 std::string
*mangled_name
,
453 std::string
*full_path
,
457 /// Adjusts path contents when oid is created at name mangled_name.
459 const std::vector
<std::string
> &path
, ///< [in] Path to adjust.
460 const ghobject_t
&oid
, ///< [in] Object created.
461 const std::string
&mangled_name
///< [in] Filename of created object.
464 /// Removes oid from path while adjusting path contents
466 const std::vector
<std::string
> &path
, ///< [in] Path containing oid.
467 const ghobject_t
&oid
, ///< [in] Object to remove.
468 const std::string
&mangled_name
///< [in] Filename of object to remove.
471 ///Transate a file into and ghobject_t.
473 const std::vector
<std::string
> &path
, ///< [in] Path containing the file.
474 const std::string
&short_name
, ///< [in] Filename to translate.
475 ghobject_t
*out
///< [out] Object found.
476 ); ///< @return Negative error code on error, 0 if not an object, 1 else
478 /* manglers/demanglers */
479 /// Filters object filenames
481 const std::string
&short_name
///< [in] Filename to check
482 ); ///< True if short_name is an object, false otherwise
484 /// Filters subdir filenames
486 const std::string
&short_name
, ///< [in] Filename to check.
487 std::string
*demangled_name
///< [out] Demangled subdir name.
488 ); ///< @return True if short_name is a subdir, false otherwise
490 /// Generate object name
491 std::string
lfn_generate_object_name_keyless(
492 const ghobject_t
&oid
///< [in] Object for which to generate.
493 ); ///< @return Generated object name.
495 /// Generate object name
496 std::string
lfn_generate_object_name_poolless(
497 const ghobject_t
&oid
///< [in] Object for which to generate.
498 ); ///< @return Generated object name.
500 /// Generate object name
501 static std::string
lfn_generate_object_name_current(
502 const ghobject_t
&oid
///< [in] Object for which to generate.
503 ); ///< @return Generated object name.
505 /// Generate object name
506 std::string
lfn_generate_object_name(
507 const ghobject_t
&oid
///< [in] Object for which to generate.
509 if (index_version
== HASH_INDEX_TAG
)
510 return lfn_generate_object_name_keyless(oid
);
511 if (index_version
== HASH_INDEX_TAG_2
)
512 return lfn_generate_object_name_poolless(oid
);
514 return lfn_generate_object_name_current(oid
);
515 } ///< @return Generated object name.
517 /// Parse object name
518 int lfn_parse_object_name_keyless(
519 const std::string
&long_name
, ///< [in] Name to parse
520 ghobject_t
*out
///< [out] Resulting Object
521 ); ///< @return True if successful, False otherwise.
523 /// Parse object name
524 int lfn_parse_object_name_poolless(
525 const std::string
&long_name
, ///< [in] Name to parse
526 ghobject_t
*out
///< [out] Resulting Object
527 ); ///< @return True if successful, False otherwise.
529 /// Parse object name
530 int lfn_parse_object_name(
531 const std::string
&long_name
, ///< [in] Name to parse
532 ghobject_t
*out
///< [out] Resulting Object
533 ); ///< @return True if successful, False otherwise.
535 /// Checks whether short_name is a hashed filename.
536 bool lfn_is_hashed_filename(
537 const std::string
&short_name
///< [in] Name to check.
538 ); ///< @return True if short_name is hashed, False otherwise.
540 /// Checks whether long_name must be hashed.
542 const std::string
&long_name
///< [in] Name to check.
543 ); ///< @return True if long_name must be hashed, False otherwise.
545 /// Generate hashed name.
546 std::string
lfn_get_short_name(
547 const ghobject_t
&oid
, ///< [in] Object for which to generate.
548 int i
///< [in] Index of hashed name to generate.
549 ); ///< @return Hashed filename.
551 /* other common methods */
552 /// Gets the base path
553 const std::string
&get_base_path(); ///< @return Index base_path
555 /// Get full path the subdir
556 std::string
get_full_path_subdir(
557 const std::vector
<std::string
> &rel
///< [in] The subdir.
558 ); ///< @return Full path to rel.
560 /// Get full path to object
561 std::string
get_full_path(
562 const std::vector
<std::string
> &rel
, ///< [in] Path to object.
563 const std::string
&name
///< [in] Filename of object.
564 ); ///< @return Fullpath to object at name in rel.
566 /// Get mangled path component
567 std::string
mangle_path_component(
568 const std::string
&component
///< [in] Component to mangle
569 ); /// @return Mangled component
571 /// Demangle component
572 std::string
demangle_path_component(
573 const std::string
&component
///< [in] Subdir name to demangle
574 ); ///< @return Demangled path component.
576 /// Decompose full path into object name and filename.
577 int decompose_full_path(
578 const char *in
, ///< [in] Full path to object.
579 std::vector
<std::string
> *out
, ///< [out] Path to object at in.
580 ghobject_t
*oid
, ///< [out] Object at in.
581 std::string
*shortname
///< [out] Filename of object at in.
582 ); ///< @return Error Code, 0 on success.
584 /// Mangle attribute name
585 std::string
mangle_attr_name(
586 const std::string
&attr
///< [in] Attribute to mangle.
587 ); ///< @return Mangled attribute name.
589 /// checks whether long_name could hash to short_name
590 bool short_name_matches(
591 const char *short_name
, ///< [in] name to check against
592 const char *cand_long_name
///< [in] candidate long name
595 /// Builds hashed filename
597 const char *old_filename
, ///< [in] Filename to convert.
598 int i
, ///< [in] Index of hash.
599 char *filename
, ///< [out] Resulting filename.
600 int len
///< [in] Size of buffer for filename
601 ); ///< @return Error Code, 0 on success
603 /// Get hash of filename
605 const char *filename
, ///< [in] Filename to hash.
606 char *hash
, ///< [out] Hash of filename.
607 int len
///< [in] Size of hash buffer.
608 ); ///< @return Error Code, 0 on success.
610 friend class TestWrapLFNIndex
;
612 typedef LFNIndex::IndexedPath IndexedPath
;