aboutsummaryrefslogtreecommitdiffstats
path: root/design/XFS_Filesystem_Structure/symbolic_links.asciidoc
blob: bfe5eb9233344c9209357615aafddf3424f67dbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
[[Symbolic_Links]]
= Symbolic Links

Symbolic links to a file can be stored in one of two formats: ``local'' and
``extents''. The length of the symlink contents is always specified by the inode's
+di_size+ value.


[[Shortform_Symbolic_Links]]
== Short Form Symbolic Links

Symbolic links are stored with the ``local'' +di_format+ if the symbolic link can
fit within the inode's data fork. The link data is an array of characters
(+di_symlink+ array in the data fork union).

.Symbolic link short form layout
image::images/61.png[]

=== xfs_db Short Form Symbolic Link Example

A short symbolic link to a file is created:

----
xfs_db> inode <inode#>
xfs_db> p
core.magic = 0x494e
core.mode = 0120777
core.version = 1
core.format = 1 (local)
...
core.size = 12
core.nblocks = 0
core.extsize = 0
core.nextents = 0
...
u.symlink = "small_target"
----

Raw on-disk data with the link contents highlighted:

[subs="quotes"]
----
xfs_db> type text
xfs_db> p
00: 49 4e a1 ff 01 01 00 01 00 00 00 00 00 00 00 00 IN..............
10: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 ................
20: 44 be e1 c7 03 c4 d4 18 44 be el c7 03 c4 d4 18 D.......D.......
30: 44 be e1 c7 03 c4 d4 18 00 00 00 00 00 00 00 Oc D...............
40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
50: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 ................
60: ff ff ff ff *73 6d 61 6c 6c 5f 74 61 72 67 65 74* ....small.target
70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
----


[[Extent_Symbolic_Links]]
== Extent Symbolic Links

If the length of the symbolic link exceeds the space available in the inode's
data fork, the link is moved to a new filesystem block and the inode's
+di_format+ is changed to ``extents''. The location of the block(s) is specified
by the data fork's +di_bmx[]+ array. In the significant majority of cases, this
will be in one filesystem block as a symlink cannot be longer than 1024
characters.

On a v5 filesystem, the first block of each extent starts with the following
header structure:

[source, c]
----
struct xfs_dsymlink_hdr {
     __be32                    sl_magic;
     __be32                    sl_offset;
     __be32                    sl_bytes;
     __be32                    sl_crc;
     uuid_t                    sl_uuid;
     __be64                    sl_owner;
     __be64                    sl_blkno;
     __be64                    sl_lsn;
};
-----

*sl_magic*::
Specifies the magic number for the symlink block: "XSLM" (0x58534c4d).

*sl_offset*::
Offset of the symbolic link target data, in bytes.

*sl_bytes*::
Number of bytes used to contain the link target data.

*sl_crc*::
Checksum of the symlink block.

*sl_uuid*::
The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+
depending on which features are set.

*sl_owner*::
The inode number that this symlink block belongs to.

*sl_blkno*::
Disk block number of this symlink.

*sl_lsn*::
Log sequence number of the last write to this block.

Filesystems formatted prior to v5 do not have this header in the remote block.
Symlink data begins immediately at offset zero.

.Symbolic link extent layout
image::images/62.png[]

=== xfs_db Symbolic Link Extent Example

A longer link is created (greater than 156 bytes):

----
xfs_db> inode <inode#>
xfs_db> p
core.magic = 0x494e
core.mode = 0120777
core.version = 1
core.format = 2 (extents)
...
core.size = 182
core.nblocks = 1
core.extsize = 0
core.nextents = 1
...
u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,37530,1,0]
xfs_db> dblock 0
xfs_db> type symlink
xfs_db> p
"symlink contents..."
----