cephfs文件存放与文件系统inode关系整理

参考博客zphj1987.com
cephfs文件系统下,写入rados的文件的对象分布情况
首先往集群挂载点写入文件:
dd if=/dev/zero of=/mnt/testfile bs=4M count=10

ceph10环境下使用cephfs命令查看对象,ceph12以后没有这个命令了,如何查看对象下面会介绍。
查看对象分布 : cephfs /mnt/testfile map
可以看到该文件对于rados底层来说,对象由10000000000作为prefix前缀后面加上每个切片号
10000000000.00000000
10000000000.00000008
10000000000.00000006
10000000000.00000004
10000000000.00000001
10000000000.00000002
10000000000.00000009
10000000000.00000003
10000000000.00000005
10000000000.00000007
然后根据每个对象查看存放在哪个osd上面。
[root@node1 mnt]# ceph osd map data 10000000000.00000001
osdmap e48 pool ‘data’ (1) object ‘10000000000.00000001’ -> pg 1.53388f2a (1.a) -> up ([0], p0) acting ([0], p0)

现在抛开cephfs的计算,单纯的计算文件testfile在rados的分布:
[root@node1 mnt]# stat testfile
File: ‘testfile’
Size: 41943040 Blocks: 81920 IO Block: 4194304 regular file
Device: 0h/0d Inode: 1099511627776 Links: 1
Access: (0644/-rw-r–r–) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-02-03 15:52:19.167000000 +0800
Modify: 2020-02-03 15:52:24.426000000 +0800
Change: 2020-02-03 15:52:19.167000000 +0800
Birth: –

1、计算该文件的整体大小 filesize stat -c %s /mnt/testfile 41943040
2、计算该文件的inode号 fileinode stat -c %i /mnt/testfile 1099511627776
3、计算该文件的io block大小 fileblock stat -c %o /mnt/testfile 4194304

1、通过文件大小除以block大小得到分块数 filesize/fileblock 这里到10
2、通过文件名获取对象前缀(是16进制的数)objectname=echo "obase=16;$fileinode"|bc 这里的bc可以进行计算以及进制转换
[root@node1 mnt]# echo "obase=16;$fileinode"|bc
10000000000(16进制)
3、获取后缀。之前计算得到有10个分块数,则后缀为0-9

[root@node1 ~]# printf "%.8x\n" 0
00000000
[root@node1 ~]# printf "%.8x\n" 1
00000001
[root@node1 ~]# printf "%.8x\n" 2
00000002
[root@node1 ~]# printf "%.8x\n" 3
00000003

[root@node1 ~]# objectname=10000000000 前缀prefix
[root@node1 ~]# for num in seq 0 9;do backname=printf "%.8x\n" $num;echo $objectname.$backname;done;
10000000000.00000000
10000000000.00000001
10000000000.00000002
10000000000.00000003
10000000000.00000004
10000000000.00000005
10000000000.00000006
10000000000.00000007
10000000000.00000008
10000000000.00000009

可以看到用算法进行定位的时候,整个过程都没有跟集群ceph进行查询交互,只用到了获取文件的stat的信息,所以根据算法就可以完全定位到具体的对象名称了。

现在若知道对象名,如何计算文件名
假定对象名为:10000000001.00000006

1、对象名称取10000000001前面加上0x,并且去掉.后面的,得到:
0x10000000001
根据对象名前缀获取文件inode号
[root@node1 mnt]# printf "%d\n" 0x10000000001
1099511627777
根据inode号查找文件名
[root@node1 mnt]# find /mnt/ -inum 1099511627777 –printf "%i %p\n"
1099511627777 /mnt/myfile
[root@node1 mnt]# ll
total 71680
-rw-r–r– 1 root root 31457280 Feb 3 16:23 myfile
-rw-r–r– 1 root root 41943040 Feb 3 15:52 testfile

2、通过进制转换
16进制转换10进制得到inode号
[root@node1 mnt]# echo "obase=10;ibase=16;10000000001"|bc
1099511627777