<br><br><div class="gmail_quote">On Tue, Sep 25, 2012 at 8:44 PM, Dave Chinner <span dir="ltr">&lt;<a href="mailto:david@fromorbit.com" target="_blank">david@fromorbit.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On Tue, Sep 25, 2012 at 07:26:32PM -0600, Anand Tiwari wrote:<br>
&gt; On Mon, Sep 24, 2012 at 6:51 AM, Anand Tiwari &lt;<a href="mailto:tiwarikanand@gmail.com">tiwarikanand@gmail.com</a>&gt;wrote:<br>
&gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; On Mon, Sep 24, 2012 at 1:55 AM, Dave Chinner &lt;<a href="mailto:david@fromorbit.com">david@fromorbit.com</a>&gt; wrote:<br>
&gt; &gt;<br>
&gt; &gt;&gt; On Fri, Sep 21, 2012 at 12:00:13AM -0500, Eric Sandeen wrote:<br>
&gt; &gt;&gt; &gt; On 9/20/12 7:40 PM, Anand Tiwari wrote:<br>
&gt; &gt;&gt; &gt; &gt; Hi All,<br>
&gt; &gt;&gt; &gt; &gt;<br>
&gt; &gt;&gt; &gt; &gt; I have been looking into an issue with xfs_repair with realtime sub<br>
&gt; &gt;&gt; volume. some times while running xfs_repair I see following errors<br>
&gt; &gt;&gt; &gt; &gt;<br>
&gt; &gt;&gt; &gt; &gt; ----------------------------<br>
&gt; &gt;&gt; &gt; &gt; data fork in rt inode 134 claims used rt block 19607<br>
&gt; &gt;&gt; &gt; &gt; bad data fork in inode 134<br>
&gt; &gt;&gt; &gt; &gt; would have cleared inode 134<br>
&gt; &gt;&gt; &gt; &gt; data fork in rt inode 135 claims used rt block 29607<br>
&gt; &gt;&gt; &gt; &gt; bad data fork in inode 135<br>
&gt; &gt;&gt; &gt; &gt; would have cleared inode 135<br>
&gt; &gt;&gt; .....<br>
&gt; &gt;&gt; &gt; &gt; xfs_db&gt; inode 135<br>
&gt; &gt;&gt; &gt; &gt; xfs_db&gt; bmap<br>
&gt; &gt;&gt; &gt; &gt; data offset 0 startblock 13062144 (12/479232) count 2097000 flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 2097000 startblock 15159144 (14/479080) count 2097000<br>
&gt; &gt;&gt; flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 4194000 startblock 17256144 (16/478928) count 2097000<br>
&gt; &gt;&gt; flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 6291000 startblock 19353144 (18/478776) count 2097000<br>
&gt; &gt;&gt; flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 8388000 startblock 21450144 (20/478624) count 2097000<br>
&gt; &gt;&gt; flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 10485000 startblock 23547144 (22/478472) count 2097000<br>
&gt; &gt;&gt; flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 12582000 startblock 25644144 (24/478320) count 2097000<br>
&gt; &gt;&gt; flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 14679000 startblock 27741144 (26/478168) count 2097000<br>
&gt; &gt;&gt; flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 16776000 startblock 29838144 (28/478016) count 2097000<br>
&gt; &gt;&gt; flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 18873000 startblock 31935144 (30/477864) count 1607000<br>
&gt; &gt;&gt; flag 0<br>
&gt; &gt;&gt; &gt; &gt; xfs_db&gt; inode 134<br>
&gt; &gt;&gt; &gt; &gt; xfs_db&gt; bmap<br>
&gt; &gt;&gt; &gt; &gt; data offset 0 startblock 7942144 (7/602112) count 2097000 flag 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 2097000 startblock 10039144 (9/601960) count 2097000 flag<br>
&gt; &gt;&gt; 0<br>
&gt; &gt;&gt; &gt; &gt; data offset 4194000 startblock 12136144 (11/601808) count 926000 flag<br>
&gt; &gt;&gt; 0<br>
&gt; &gt;&gt; &gt;<br>
&gt; &gt;&gt; &gt; It&#39;s been a while since I thought about realtime, but -<br>
&gt; &gt;&gt; &gt;<br>
&gt; &gt;&gt; &gt; That all seems fine, I don&#39;t see anything overlapping there, they are<br>
&gt; &gt;&gt; &gt; all perfectly adjacent, though of interesting size.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Yeah, the size is the problem.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; ....<br>
&gt; &gt;&gt; &gt; Every extent above is length 2097000 blocks, and they are adjacent.<br>
&gt; &gt;&gt; &gt; But you say your realtime extent size is 512 blocks ... which doesn&#39;t go<br>
&gt; &gt;&gt; &gt; into 2097000 evenly.   So that&#39;s odd, at least.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Once you realise that the bmapbt is recording multiples of FSB (4k)<br>
&gt; &gt;&gt; rather than rtextsz (2MB), it becomes more obvious what the problem<br>
&gt; &gt;&gt; is: rounding of the extent size at MAXEXTLEN - 2097000 is only 152<br>
&gt; &gt;&gt; blocks short of 2^21 (2097152).<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; I haven&#39;t looked at the kernel code yet to work out why it is<br>
&gt; &gt;&gt; rounding to a non-rtextsz multiple, but that is the source of the<br>
&gt; &gt;&gt; problem.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; The repair code is detecting that extents are not of the<br>
&gt; &gt;&gt; correct granularity, but the error message indicates that this was<br>
&gt; &gt;&gt; only ever expected for duplicate blocks occurring rather than a<br>
&gt; &gt;&gt; kernel bug. So &quot;fixing repair&quot; is not what is needd here - finding<br>
&gt; &gt;&gt; and fixing the kernel bug is what you shoul be looking at.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Cheers,<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Dave.<br>
&gt; &gt;&gt; --<br>
&gt; &gt;&gt; Dave Chinner<br>
&gt; &gt;&gt; <a href="mailto:david@fromorbit.com">david@fromorbit.com</a><br>
&gt; &gt;&gt;<br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; thanks, I started looking at allocator code and and will report if see<br>
&gt; &gt; something<br>
&gt; &gt;<br>
&gt;<br>
&gt;<br>
&gt; I think this is what happening.  If we have following conditions,<br>
&gt;   1) we have more than 8gb contiguous space available to allocate. ( i.e.<br>
&gt; more than 2^21 4k blocks)<br>
&gt;   2) only one file is open for writing in real-time volume.<br>
&gt;<br>
&gt; To satisfy first condition, I just took empty file-system.<br>
&gt;<br>
&gt; Now lets start allocating, lets say in chucks of 25000, realtime allocator<br>
&gt; will have no problem allocating &quot;exact&quot; block while searching forward.<br>
&gt; xfs_rtfind_forw(). It will allocate 49 &quot;real-time extents&quot;, where the 49th<br>
&gt; &quot;real-time extent&quot; is partially full.  (25000/512 = 48)<br>
&gt;<br>
&gt; everything is fine for first 83 allocations, as we were able to grow the<br>
&gt; extent. Now we have 2075000 (25000*83) blocks in first extent ie 4053<br>
&gt; &quot;real-time extents&quot; (where last &quot;real-time extent&quot; is partially full).<br>
&gt;<br>
&gt; for 84th allocation, real-time allocator will allocate another 49<br>
&gt; &quot;real-time extents&quot; as it does not know about maximum extent size, but we<br>
&gt; can not grow the extent in xfs_bmap_add_extent_unwritten_real().  so we<br>
&gt; insert a new extent (case BMAP_LEFT_FILLING).  now the new extent starts<br>
&gt; from 2075000, which is not aligned with rextsize (512 in this case).<br>
<br>
</div></div>Ok, so it&#39;s a problem with using unwritten extents and converting<br>
them. That is, the issue probably has nothing to do with the<br>
realtime allocator at all.<br>
<br>
Basically, when the unwritten extent occurs, we end up with a map<br>
like this:<br>
<br>
ext 0:  offset 0, length 2075000 state written<br>
ext 1:  offset 2075000 length 25000 state unwritten<br>
<br>
This will occur because you can&#39;t mix written/unwritten state in a<br>
single extent.<br>
<br>
What xfs_bmap_add_extent_unwritten_real() is attempting to do is<br>
convert the unwritten extent to written state and merge it with it&#39;s<br>
siblings. In this case, 2075000 + 25000 &gt; MAXEXTLEN, so it does not<br>
merge them because of this check:<br>
<br>
        if ((state &amp; BMAP_LEFT_VALID) &amp;&amp; !(state &amp; BMAP_LEFT_DELAY) &amp;&amp;<br>
            LEFT.br_startoff + LEFT.br_blockcount == new-&gt;br_startoff &amp;&amp;<br>
            LEFT.br_startblock + LEFT.br_blockcount == new-&gt;br_startblock &amp;&amp;<br>
            LEFT.br_state == newext &amp;&amp;<br>
&gt;&gt;&gt;&gt;&gt;&gt;      LEFT.br_blockcount + new-&gt;br_blockcount &lt;= MAXEXTLEN)<br>
                state |= BMAP_LEFT_CONTIG;<br>
<br>
Which means that BMAP_LEFT_CONTIG is not set, indicating that the no<br>
merging with the an adjacent left extent should occur. Hence we end<br>
up wwith this:<br>
<br>
ext 0:  offset 0, length 2075000 state written<br>
ext 1:  offset 2075000 length 25000 state written<br>
<br>
That&#39;s fine for normal operation, but it means that large contiguous<br>
regions written via direct IO with non-rtextsz aligned/sized IO will<br>
have problem this problem.<br>
<br>
What technically should happen for these real time files is that the<br>
LEFT extent should be shortened to be aligned, and the new extent be<br>
lengthened and have it&#39;s startblock adjusted accordingly.<br>
<br>
i.e. we should end up with this:<br>
<br>
ext 0:  offset 0, length 2074624 state written<br>
ext 1:  offset 2074624 length 25376 state written<br>
<div class="im"><br>
&gt; To fix this, I see two options,<br>
&gt; 1) fix real-time allocator and teach it about maximum extent size.<br>
&gt; 2) for real-time files, aligned new extent before inserting.<br>
<br>
</div>3) Fix the {BMAP_LEFT_CONTIG,MAXEXTLEN,rtextsz} handling in<br>
xfs_bmap_add_extent_unwritten_real().<br>
<br>
It&#39;s possible that the BMAP_RIGHT_CONTIG case also needs similar<br>
fixing...<br>
<div class="im"><br>
&gt; In my opinion, we should not worry about either of above, as this looks<br>
&gt; good method for allocation.  I can fix xfs_repair tool and make it aware of<br>
&gt; these conditions (&quot;real-time extents&quot; shared by two or more extents).<br>
<br>
</div>Personally, I&#39;d prefer that 3) is done because RT extents should<br>
always be rtextsz aligned and sized, and the bmapbt should respect<br>
that requirement in all cases.<br>
<div class="HOEnZb"><div class="h5"><br>
Cheers,<br>
<br>
Dave.<br>
--<br>
Dave Chinner<br>
<a href="mailto:david@fromorbit.com">david@fromorbit.com</a><br>
</div></div></blockquote></div><br><div>thanks Dave for prompt reply, I meant to implement option 2 as you explained (option 3).  I will start working on it tomorrow. In the mean time, I also had  to put something in xfs_repair for the files which already exists on the disk. Would you guys willing to review/comment on that ? </div>
<div><br></div><div>anand</div>