بخش تخصصی (۴): RBD — چیدمان روی RADOS، striping، object map و fast-diff، و مرجع rbd
حوصله ندارم این فصل در چند خط
- هر image با قالب ۲ از
rbd_id، omap شیء rbd_header.<id> و اشیای دادهی rbd_data.<id>.<objectno> تشکیل میشود؛ متادیتا فقط از راه کلاس rbd تغییر میکند. - striping پیشفرض اشیای پشتسرهم ۴ مگابایتی است؛ striping سفارشی نوشتنهای کوچک ترتیبی را بهصورت round-robin میان
stripe_count شیء پخش میکند. - object map برای هر شیء دو بیت نگه میدارد تا fast-diff و
rbd du لازم نباشد تکتک اشیا را بپرسند. - فصل با مرجع فرمانهای rbd تمام میشود.
۳۷-۱ پیش از شروع#
فصل ۲ نشان داد یک image قالب ۲ چه اشیایی دارد و شناسهی آن چگونه ساخته میشود (الگوریتم ۲-۱). این فصل همان چیدمان را کلید به کلید باز میکند: header یک image دقیقاً چه کلیدهای omap دارد، اشیای سطح pool (rbd_directory، rbd_trash، rbd_mirroring، rbd_namespace و دیگران) چه چیزی نگه میدارند، striping با stripe_unit و stripe_count آفست را چگونه به شیء میبرد، object map بیتها را چگونه بستهبندی و ذخیره میکند، و fast-diff چگونه بدون خواندن داده تغییرات میان دو snapshot را مییابد. فصل با مرجع کامل دستور rbd و rbd-nbd تمام میشود. نامها با شاخهی main مخزن ceph/ceph (نوامبر ۲۰۲۶) تطبیق داده شدهاند.
۳۷-۱-۱ این فصل به چه سؤالهایی جواب میدهد؟#
- header یک image چه کلیدهایی دارد و هر کدام چه کسی آن را مینویسد؟
- نام شیء داده با data pool جدا چه فرقی میکند؟
- با
stripe_unit=64K و stripe_count=4، آفست ۱۰۰۰۰۰۰ در کدام شیء است؟ - object map هر شیء را با چند بیت نگه میدارد و بایتها روی دیسک چه ترتیبی دارند؟
-
EXISTS_CLEAN چه معنایی دارد و چه زمانی تنظیم میشود؟ - fast-diff از کدام حالتها برای تشخیص تغییر استفاده میکند؟
- pool و namespace و trash و گروهها در RADOS چگونه نمایه میشوند؟
۳۷-۱-۲ پیشنیاز#
فصل ۲ (RBD)، فصل ۱۵ (cls)، فصل ۳۴ و ۳۶ (omap، SnapContext و clone).
۳۷-۲ اشیای یک image#
۳۷-۲-۱ header#
همهی فرادادهی یک image قالب ۲ در omap شیء rbd_header.<id> است و فقط از طریق متدهای کلاس rbd (src/cls/rbd/cls_rbd.cc) تغییر میکند:
| کلید omap | نوع | محتوا |
|---|---|---|
size | u64 | اندازهی image به بایت |
order | u8 | لگاریتم دودویی اندازهی شیء (۲۲ یعنی ۴ MiB) |
object_prefix | string | پیشوند اشیای داده، مثلاً rbd_data.5f3a2b8c1d4e |
features | u64 | بیتهای ویژگی (جدول بعد) |
flags | u64 | OBJECT_MAP_INVALID (۱) و FAST_DIFF_INVALID (۲) |
op_features | u64 | ویژگیهای عملیاتی مثل clone-parent، clone-child، group، snap-trash |
snap_seq | u64 | بزرگترین snap id ساختهشده برای این image |
snapshot_<id:016x> | cls_rbd_snap | نام، اندازه، parent، پرچمها و namespace هر snapshot |
snap_children_<id:016x> | set | فرزندان clone قالب ۲ روی آن snapshot |
parent | cls_rbd_parent | pool، namespace، image و snap والد و overlap (برای clone) |
stripe_unit، stripe_count | u64 | فقط اگر striping سفارشی باشد |
data_pool_id | s64 | فقط اگر data pool جدا باشد |
create_timestamp، access_timestamp، modify_timestamp | utime | زمانها |
snap_limit | u64 | سقف تعداد snapshot |
metadata_<key> | string | متادیتای image؛ مثلاً conf_rbd_cache برای تنظیمات هر image |
migration | cls_rbd_migration | وضعیت مهاجرت زنده |
افزون بر omap، xattr lock.rbd_lock (کلاس lock) قفل مشورتی را نگه میدارد که ManagedLock برای exclusive-lock از آن استفاده میکند (فصل ۳۸). همین شیء header هدف watch همهی کلاینتهای باز آن image است.
| ویژگی | بیت | پیشفرض |
|---|---|---|
layering | ۱ | بله |
striping | ۲ | فقط اگر stripe سفارشی باشد |
exclusive-lock | ۴ | بله |
object-map | ۸ | بله |
fast-diff | ۱۶ | بله |
deep-flatten | ۳۲ | بله |
journaling | ۶۴ | خیر |
data-pool | ۱۲۸ | فقط اگر --data-pool داده شود |
operations | ۲۵۶ | داخلی |
migrating | ۵۱۲ | داخلی |
non-primary | ۱۰۲۴ | داخلی، برای image مقصد mirror |
dirty-cache | ۲۰۴۸ | داخلی، برای cache پایدار PWL |
مجموع پیشفرض (rbd_default_features) برابر ۱+۴+۸+۱۶+۳۲ = ۶۱ است.
۳۷-۲-۲ اشیای داده و object map#
اشیای داده <object_prefix>.<objectno:016x> نام دارند. اگر image با --data-pool ساخته شود، header و فراداده در pool اصلی میمانند (که باید replicated باشد) و داده در pool دوم (اغلب EC با allow_ec_overwrites) نوشته میشود. در این حالت پیشوند شامل شناسهی pool اصلی است: rbd_data.<metadata-pool-id>.<image-id>، تا اشیای imageهای چند pool مختلف در یک data pool مشترک با هم برخورد نکنند.
object map در شیء rbd_object_map.<id> برای head و rbd_object_map.<id>.<snapid:016x> برای هر snapshot ذخیره میشود.
۳۷-۲-۳ اشیای سطح pool#
| شیء | omap یا داده | کاربرد |
|---|---|---|
rbd_id.<name> | داده: شناسهی image | یافتن id از نام |
rbd_directory | name_<name> → id و id_<id> → name | فهرست imageهای pool یا namespace |
rbd_trash | id_<id> → نام، زمان حذف، زمان مجاز بازگرداندن، منبع | imageهای در سطل زباله |
rbd_children | کلید: parent spec، مقدار: فرزندان | فقط برای clone قالب ۱ |
rbd_info | omap conf_<option> و نشانگر اعتبارسنجی pool | تنظیمات سطح pool (rbd config pool set) و نتیجهی بررسی قابلیت overwrite در data pool |
rbd_namespace | name_<ns> | فهرست namespaceهای pool |
rbd_mirroring | mirror_mode، mirror_uuid، mirror_peer_<uuid>، image_<id>، global_<gid>، status_global_<gid>، instance_<id>، image_map_<gid> | وضعیت mirroring (فصل ۳۹) |
rbd_group_directory و rbd_group_header.<id> | omap | گروههای consistency |
rbd_task | omap | صف کارهای پسزمینهی mgr (rbd task add flatten و مانند آن) |
namespace در RBD همان namespace در RADOS است (فصل ۳۴). همهی اشیای فهرستشده در بالا جداگانه در هر namespace ساخته میشوند. با cap profile rbd pool=P namespace=N میتوان یک کلاینت را به یک namespace محدود کرد، بیآنکه برای هر مستاجر pool جدا ساخت.
# مثال: خواندن مستقیم header (فقط برای بررسی؛ هرگز با rados تغییرش ندهید)
rados -p rbd listomapkeys rbd_header.5f3a2b8c1d4e
rados -p rbd getomapval rbd_header.5f3a2b8c1d4e object_prefixمثال (خروجی):
access_timestamp
create_timestamp
features
flags
modify_timestamp
object_prefix
order
size
snap_seq
snapshot_0000000000000004
value (25 bytes) :
00000000 15 00 00 00 72 62 64 5f 64 61 74 61 2e 35 66 33 |....rbd_data.5f3|
00000010 61 32 62 38 63 31 64 34 65 |a2b8c1d4e|چهار بایت اول (15 00 00 00 یعنی ۲۱) طول رشته بهصورت little-endian است؛ همهی رشتهها در کدگذاری Ceph همین قالب را دارند.

۳۷-۳ striping#
بهطور پیشفرض stripe_unit برابر اندازهی شیء و stripe_count برابر ۱ است، پس image بهسادگی به قطعههای پشتسرهم ۴ MiB تقسیم میشود. با striping سفارشی، داده بهصورت round-robin میان stripe_count شیء پخش میشود تا نوشتنهای ترتیبی کوچک همزمان به چند OSD بروند.
منبع در کد: src/osdc/Striper.cc :: Striper::file_to_extents
پیچیدگی: O(len / stripe_unit) قطعه
pseudocode
su = stripe_unit ; sc = stripe_count ; os = object_size
if sc == 1: su = os
stripes_per_object = os / su
while left > 0:
blockno = cur / su
stripeno = blockno / sc
stripepos = blockno % sc
objectsetno = stripeno / stripes_per_object
objectno = objectsetno * sc + stripepos
x_offset = (stripeno % stripes_per_object) * su + cur % su
x_len = min(su - cur % su, left)
emit (objectno, x_offset, x_len) ; cur += x_len ; left -= x_lenمثال عددی. object_size = 4 MiB، stripe_unit = 64 KiB، stripe_count = 4، نوشتن ۳۰۰۰۰۰ بایت از آفست ۱۰۰۰۰۰۰. هر شیء ۶۴ stripe دارد و یک «object set» از ۴ شیء ۱۶ MiB را میپوشاند.
| block | stripe | stripepos | شیء | آفست درون شیء | طول |
|---|---|---|---|---|---|
| ۱۵ | ۳ | ۳ | ۳ | ۲۱۳۵۶۸ | ۴۸۵۷۶ |
| ۱۶ | ۴ | ۰ | ۰ | ۲۶۲۱۴۴ | ۶۵۵۳۶ |
| ۱۷ | ۴ | ۱ | ۱ | ۲۶۲۱۴۴ | ۶۵۵۳۶ |
| ۱۸ | ۴ | ۲ | ۲ | ۲۶۲۱۴۴ | ۶۵۵۳۶ |
| ۱۹ | ۴ | ۳ | ۳ | ۲۶۲۱۴۴ | ۵۴۸۱۶ |
نوشتن ۳۰۰ KB به هر چهار شیء میرسد. با striping پیشفرض همین نوشتن فقط شیء ۰ را (آفست ۱۰۰۰۰۰۰ تا ۱۳۰۰۰۰۰) لمس میکرد. striping برای بار ترتیبی تکجریانی با عمق صف کم سودمند است، ولی برای بار تصادفی ۴K فقط تعداد اشیای درگیر را زیاد میکند. krbd از نسخهی ۴.۱۷ هسته striping سفارشی را پشتیبانی میکند (فصل ۲۹).

نگاشت striping در RBD
اندازهٔ شیء، stripe_unit و stripe_count یک image و offset و طول یک I/O را تعیین کنید: ببینید به کدام شیءهای rbd_data و کجای آنها دست میزند.
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| s0… | ||||
| s2… | ||||
| s4… | ||||
| s6… | ||||
| s8… | ||||
| s10… | ||||
| s12… | ||||
| s14… | ||||
| s16… | ||||
| s18… | ||||
| s20… | ||||
| s22… | ||||
| s24… | ||||
| s26… | ||||
| s28… | ||||
| s30… | ||||
| s32… | ||||
| s34… | ||||
| s36… | ||||
| s38… | ||||
| s40… | ||||
| s42… | ||||
| s44… | ||||
| s46… | ||||
| s48… | ||||
| s50… | ||||
| s52… | ||||
| s54… | ||||
| s56… | ||||
| s58… | ||||
| s60… | ||||
| s62… |
| شیء | offset در شیء | طول | buffer_extents |
|---|---|---|---|
rbd_data.10226b8b4567.0000000000000000 | 262144 | 65536 | [48576, 65536] |
rbd_data.10226b8b4567.0000000000000001 | 262144 | 65536 | [114112, 65536] |
rbd_data.10226b8b4567.0000000000000002 | 262144 | 65536 | [179648, 65536] |
rbd_data.10226b8b4567.0000000000000003 | 213568 | 103392 | [0, 48576] [245184, 54816] |
rbd create pool/img --size 10G --object-size ۴M --stripe-unit 64K --stripe-count 4مطابق با:
src/osdc/Striper.cc :: Striper::file_to_extentsاز بازهٔ image تا extentهای شیءStriper.cc :: get_num_objects, get_file_offset, object_truncate_sizeشمار شیءها و نگاشت وارونsrc/librbd/ImageCtx.cc :: ImageCtx::init (format_string "%s.%016llx")نام شیء دادهsrc/include/rbd_types.h :: RBD_DATA_PREFIX "rbd_data."پیشوند نامsrc/test/test_striper.cc :: the upstream test vectors used by tests/simsبردارهایی که آزمونها با آن مقایسه میکنند
۳۷-۴ object map#
۳۷-۴-۱ حالتها و بستهبندی بیت#
object map برای هر شیء ۲ بیت دارد (BitVector<2>):
| مقدار | ثابت | معنی |
|---|---|---|
| ۰ | OBJECT_NONEXISTENT | شیء وجود ندارد؛ خواندن صفر برمیگرداند و نیازی به رفتن به OSD نیست |
| ۱ | OBJECT_EXISTS | شیء وجود دارد و از آخرین snapshot تغییر کرده است |
| ۲ | OBJECT_PENDING | حذف در جریان است (discard یا resize) |
| ۳ | OBJECT_EXISTS_CLEAN | شیء وجود دارد و از آخرین snapshot تغییر نکرده است |
هر بایت چهار شیء را نگه میدارد و شیء با شمارهی کوچکتر در بیتهای بالاتر است: shift = (3 − objectno % 4) × 2. کدگذاری روی دیسک سه بخش دارد: header (طول، نسخه و تعداد عناصر)، دادهی خام، و footer شامل crc32c header و یک crc32c برای هر بلوک ۴۰۹۶ بایتی داده. پس بهروزرسانی یک شیء فقط یک بلوک ۴ KiB و crc آن را بازنویسی میکند (متد object_map_update در cls_rbd).

۳۷-۴-۲ چه کسی حالت را عوض میکند؟#
- نوشتن روی شیئی که NONEXISTENT یا EXISTS_CLEAN است، پیش از ارسال نوشتن، object map را به EXISTS بهروز میکند (اول در حافظه، سپس با
object_map_update روی RADOS). اگر شیء از قبل EXISTS باشد، هیچ هزینهای ندارد. - discard یا حذف ابتدا حالت را PENDING میکند، شیء را حذف میکند و سپس NONEXISTENT.
- گرفتن snapshot نقشهی head را در
rbd_object_map.<id>.<snapid> کپی و سپس همهی EXISTSهای head را به EXISTS_CLEAN تبدیل میکند (object_map_snap_add در cls_rbd). - حذف snapshot بیتهای EXISTS نقشهی آن snapshot را با نقشهی snapshot بعدی (یا head) ادغام میکند تا اطلاعات «تغییر کرده» از دست نرود (
object_map_snap_remove).
object map فقط با exclusive-lock معتبر است، چون فقط مالک قفل حق تغییر آن را دارد. اگر کلاینت در میانهی بهروزرسانی از کار بیفتد، پرچم OBJECT_MAP_INVALID در flags مینشیند و rbd object-map rebuild باید اجرا شود.
۳۷-۴-۳ fast-diff#
منبع در کد: src/librbd/object_map/DiffRequest.cc :: DiffRequest::handle_load_object_map
پیچیدگی: O(N × S) برای N شیء و S نقشهی بارشده؛ بدون هیچ خواندن داده
pseudocode
# برای هر snapshot از from_snap تا end_snap (و head)، نقشهی آن بارگذاری و با وضعیت قبلی ترکیب میشود
first map (from_snap): state[o] = HOLE if NONEXISTENT else DATA (PENDING → DATA_UPDATED)
each later map m:
HOLE: if m[o] != NONEXISTENT → DATA_UPDATED (diff-iterate: فقط در نقشهی پایانی)
DATA: if m[o] == NONEXISTENT → HOLE_UPDATED
elif m[o] != EXISTS_CLEAN → DATA_UPDATED
HOLE_UPDATED: if m[o] != NONEXISTENT → DATA_UPDATED
DATA_UPDATED: if m[o] == NONEXISTENT → HOLE_UPDATED
objects beyond the previous size (image grew) → HOLE or DATA_UPDATEDنکتهی کلیدی EXISTS_CLEAN است: اگر شیئی در from_snap وجود داشته و در همهی نقشههای بعدی EXISTS_CLEAN مانده، یعنی پس از from_snap نوشتنی نداشته است و در diff نمیآید. rbd diff --whole-object، rbd du و rbd export-diff (و حالت snapshot در rbd-mirror) همه از همین محاسبه استفاده میکنند. اگر FAST_DIFF_INVALID روشن باشد، librbd به list_snaps روی تکتک اشیا برمیگردد که بسیار کندتر است.
مثال عددی. image ۱۰ GiB با ۲۵۶۰ شیء. پس از snap1، بیست شیء نوشته شده و سه شیء discard شده است. با fast-diff، rbd export-diff --from-snap snap1 فقط دو نقشهی ۶۴۰ بایتی (و header و footer) میخواند و ۲۳ شیء را پیدا میکند. بدون آن، ۲۵۶۰ فراخوانی list_snaps لازم بود.
۳۷-۵ مرجع rbd#
۳۷-۵-۱ image و snapshot#
| دستور | کاربرد |
|---|---|
rbd create P/I --size 10G [--object-size 4M] [--stripe-unit 64K --stripe-count 4] [--data-pool DP] [--image-feature F] | ساخت image |
rbd ls [-l] P[/NS] / rbd info P/I / rbd status P/I | فهرست، جزئیات، watcherها |
rbd resize P/I --size N [--allow-shrink] | تغییر اندازه |
rbd feature {enable,disable} P/I F | روشن و خاموش کردن ویژگی |
rbd object-map {rebuild,check} P/I[@S] | بازسازی و بررسی object map |
rbd du P/I / rbd diff [--from-snap S] [--whole-object] P/I | مصرف و تغییرات |
rbd snap {create,ls,rm,purge,rollback,rename,limit set} | snapshot |
rbd snap {protect,unprotect} P/I@S | فقط برای clone قالب ۱ |
rbd clone P/I@S P2/C [--rbd-default-clone-format 2] / rbd children P/I@S / rbd flatten P2/C | layering (فصل ۳۸) |
rbd export P/I FILE / import / export-diff / import-diff / merge-diff | پشتیبان |
rbd deep cp P/I P2/I2 / rbd cp | کپی (deep با snapshotها) |
rbd trash {mv,ls,restore,rm,purge} | سطل زباله |
rbd migration {prepare,execute,commit,abort} | مهاجرت زنده |
rbd image-meta {list,get,set,remove} P/I | متادیتا و تنظیمات هر image |
rbd config {pool,image,global} {get,set,list} | تنظیمات سطح pool یا image |
rbd namespace {create,ls,remove} P/NS | namespace |
rbd group {create,image add,snap create} | گروه consistency |
rbd lock {ls,add,rm} | قفل مشورتی (نه exclusive-lock) |
rbd bench P/I --io-type {read,write,readwrite} --io-size 4K --io-threads 16 --io-pattern rand | آزمون کارایی |
rbd perf image {iostat,iotop} | آمار زنده از mgr |
rbd pool init P / rbd pool stats P | آمادهسازی و آمار pool |
۳۷-۵-۲ map کردن#
| دستور | کاربرد |
|---|---|
rbd device map [-t krbd] P/I [-o OPTS] / rbd device unmap / rbd device list | krbd |
rbd device map -t nbd P/I یا rbd-nbd map P/I [--try-netlink] [--timeout N] | rbd-nbd (librbd در فضای کاربر) |
rbd-nbd list-mapped / rbd-nbd unmap /dev/nbdX | فهرست و قطع |
rbd device map -t ubbd P/I | ubbd، اگر بستهی آن نصب باشد |
# مثال: ساخت image با striping و data pool، و بررسی آن
rbd create rbd/vm01 --size 10G --stripe-unit 64K --stripe-count 4 --data-pool rbd-ec
rbd info rbd/vm01مثال (خروجی):
rbd image 'vm01':
size 10 GiB in 2560 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 5f3a2b8c1d4e
data_pool: rbd-ec
block_name_prefix: rbd_data.3.5f3a2b8c1d4e
format: 2
features: layering, striping, exclusive-lock, object-map, fast-diff, deep-flatten, data-pool
op_features:
flags:
create_timestamp: Sun Nov 15 09:41:07 2026
access_timestamp: Sun Nov 15 09:41:07 2026
modify_timestamp: Sun Nov 15 09:41:07 2026
stripe unit: 64 KiB
stripe count: 4block_name_prefix همان object_prefix است و عدد ۳ در آن شناسهی pool rbd است، چون data pool جدا داریم.
۳۷-۶ تنظیم و عیبیابی#
- کندی نخستین نوشتن روی image تازه: هر نخستین نوشتن روی یک شیء یک
object_map_update هم دارد. پس از پر شدن image این هزینه از بین میرود. برای آزمون کارایی، image را اول پر کنید. -
rbd du یا export-diff کند است: rbd info را ببینید؛ اگر flags: object map invalid, fast diff invalid است، rbd object-map rebuild اجرا کنید (روی snapshotها هم جداگانه). - image با
--data-pool روی EC ساخته نمیشود: allow_ec_overwrites روی pool EC و اجرای rbd pool init روی هر دو pool را بررسی کنید. - حذف image بزرگ کند است: حذف به تعداد اشیای موجود وابسته است؛ با object map فقط اشیای موجود حذف میشوند. برای کارهای بلند از
rbd trash mv و سپس rbd trash rm یا ceph rbd task add remove استفاده کنید. - هرگز header را با
rados setomapval تغییر ندهید: cls_rbd ناسازگاریها را بررسی میکند ولی کلاینتهای باز از تغییر خبر نمیگیرند (هیچ notify فرستاده نمیشود).
۳۷-۷ تکمیلی و بهروز#
- clone قالب ۲ (پیشفرض
rbd_default_clone_format: auto، که اگر همهی کلاینتها Mimic یا جدیدتر باشند قالب ۲ را برمیگزیند) به protect نیازی ندارد و فرزندان را در snap_children_* همان header والد نگه میدارد. - مقدار
op_features در نسخههای جدید بیتهایی برای snapshot در trash و گروهها دارد؛ کلاینت قدیمی که op_feature ناشناخته ببیند، image را باز نمیکند. - در شاخهی main،
rbd-nbd با netlink و --try-netlink پایدارتر از روش ioctl است؛ پشتیبانی از ubbd به بستهبندی توزیع وابسته است.
۳۷-۸ تمرین عملی#
- ۱. یک image بسازید و با
rados listomapkeys و getomapval همهی کلیدهای header را بخوانید. سپس یک snapshot بگیرید و کلید تازه را پیدا کنید. - ۲. یک image با
--stripe-unit 64K --stripe-count 4 بسازید، ۳۰۰۰۰۰ بایت در آفست ۱۰۰۰۰۰۰ بنویسید (rbd bench یا dd روی rbd-nbd) و با rados ls | grep ببینید کدام اشیا ساخته شدند. با جدول مثال مقایسه کنید. - ۳.
rados get rbd_object_map.<id> /tmp/om بگیرید و با xxd چهار بایت اول داده (پس از header هجدهبایتی) را با حالت اشیای ۰ تا ۱۵ تطبیق دهید. - ۴. پس از یک snapshot، چند شیء بنویسید و
rbd diff --from-snap را با و بدون fast-diff (پس از rbd feature disable ... fast-diff) زمانگیری کنید.
۳۷-۹ پرسشهای مرور#
- ۱. کدام کلیدهای header برای ساختن نام اشیای داده لازماند؟
- ۲. با data pool جدا، نام اشیای داده چه تغییری میکند و چرا؟
- ۳.
rbd_directory چه دو نوع کلیدی دارد؟ - ۴. در مثال striping، بایت آفست ۱۱۰۰۰۰۰ در کدام شیء و کدام آفست است؟
- ۵. object map هر شیء را با چند بیت نگه میدارد و شیء ۰ در کدام بیتهای بایت اول است؟
- ۶. چرا footer object map برای هر بلوک ۴ KiB یک crc جدا دارد؟
- ۷. EXISTS_CLEAN چه زمانی تنظیم و چه زمانی پاک میشود؟
- ۸. در fast-diff اگر شیء در from_snap DATA و در head EXISTS باشد، نتیجه چیست؟
- ۹. چرا object map به exclusive-lock وابسته است؟
- ۱۰. namespace در RBD چگونه پیاده شده و چه مزیتی دارد؟
پاسخ این پرسشها در پیوست ه: پاسخ پرسشها آمده است. پاسخ پرسشهای این فصل →
۳۷-۱۰ منابع این فصل#
- cls_rbd.cc
https://github.com/ceph/ceph/blob/main/src/cls/rbd/cls_rbd.cc - rbd_types.h و features.h
https://github.com/ceph/ceph/blob/main/src/include/rbd/features.h - Striper.cc
https://github.com/ceph/ceph/blob/main/src/osdc/Striper.cc - bit_vector.hpp
https://github.com/ceph/ceph/blob/main/src/common/bit_vector.hpp - librbd/object_map/DiffRequest.cc
https://github.com/ceph/ceph/blob/main/src/librbd/object_map/DiffRequest.cc - مستند RBD layering و striping
https://docs.ceph.com/en/latest/dev/rbd-layering/ - مرجع دستور rbd
https://docs.ceph.com/en/latest/man/8/rbd/ - مرجع rbd-nbd
https://docs.ceph.com/en/latest/man/8/rbd-nbd/