[patch][freebsd] correct offsets of STAT structure fields due to ino64 changes

FreeBSD CI team has reported that CI can’t fetch SVN repository if Jenkins is installed on FreeBSD 12.0 (quite fresh release). The error message is ‘svn: E155004: Lock file ‘/usr/home/mizhka/.jenkins/workspace/test/.svn/lock’ is not a regular file’ but actually it’s file. The root cause is that SVNKit treated it as directory due to incorrect offset of MODE field in STAT structure.

This patch fixes SVNKit functionality on FreeBSD version 12 and later. The part of release 12.0 was change of inode size to 64 bits and adjustment of “struct stat”. More details can be found in SVN commit:

Patch is tested on FreeBSD 13-CURRENT. Patch is based on git mirror and against 1.9.3 (version used by Jenkins) and HEAD.
Both versions has been tested by simple test:

package pkg;

import org.tmatesoft.svn.core.internal.util.jna.*;
import java.io.File;

public class Test {
public static void main(String[] args) {
String path="/home/mizhka/.jenkins/workspace/test/.svn/lock";
System.out.println(SVNLinuxUtil.getFileType(new File(path)));


Please let me know if SVN patches are required (not git)

@kitaev , could please look at this ticket? Many thanks in advance!

Hello Michael!
Thank you for the patch! If looks ok, though
looks a bit fragile to me, though I couldn’t find a counter-example.

I wonder whether
12.0 < 12.0-CURRENT
could be a problem? I don’t know how FreeBSD versions are named and whether ‘12.0’ could be “os.version” value as something later than ‘12.0-CURRENT’.

I’ll also discuss that with my colleagues and if that’s ok, we’ll accept the patch. Thank you very much!

Thanks Dmitry!
Yes, it’s good question. FreeBSD versioning is ._. Phases are:

  • CURRENT - long life, only for zero’s MINOR, it’s HEAD of project, used only for development. Right now, it’s 13.0-CURRENT.
  • RELEASE - long life, released version, like 11.2-RELEASE or 12.0-RELEASE
  • STABLE - long life, branch with backported fixes (and sometimes features) from HEAD between releases. example: 12.0-STABLE, 11.2-STABLE
  • ALPHA, BETA, RC - very short life versions, pre-releases.

So from support point of view condition: “os.version” >= 12.0-CURRENT is OK because it covers all after 12.0-RELEASE including 12.0-RELEASE.

The only exceptions are 12.0-CURRENT, 12.0-ALPHA, 12.0-BETA. On other hand these versions had used only for development mainly, i.e. not supported as of now. So there is no problem with them.

If string comparison doesn’t look good, we need to implement FreeBSDVersionComparator for precise comparison. Is it worth to do?

Feel free to ask any question.

Thank you!

@dmitry.pavlenko , @kitaev ,

Do you have any update?

Hello Michael,
I’ve discussed the problem with Alexander and we think that it would be better to create a generic class named ‘Version’ with
format support and implementing Comparable. Then use it instead of lexicographical comparison.

is code below is not enough?
isIno64 = (isBSD && "freebsd".equals(osNameLC) && (12 <= Double.parseDouble(System.getProperty("os.version").split("-")[0]) ) );

1.10.1 is not a fix for a problem on 12.0-RELEASE-pX can you add lines I gave you? they work.

Thanks for pointing to that! This time the problem should be fixed at r10781 of trunk. Could you please have a look at the fix?

I don’t like the hacky code you propose. First, it could become broken in the future if versions will adopt X.0.0 naming scheme (so parseDouble() would fail). Second, the double values are stored not exactly but might be (12+epsilon) and this epsilon can be both positive and negative; and moreover it could depend on certain FPU implementation…

So I prefer a generic SVNVersion class-based solution that it be also reused later by SVNKit itself or by the library users if needed.

Hi Dmitry, I can confirm it works fine from a trunk. Thanks for that.

Hi Guys ;) It is not working anymore ;( FreeBsd12.1 happen.

:) Sorry, but I surprised.
Can you share your library version and FreeBSD version?
Do you use jails or not?