libc - Add 'xlink' chflags
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 17 Nov 2015 23:19:42 +0000 (15:19 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 17 Nov 2015 23:52:55 +0000 (15:52 -0800)
* Add the xlink flag.  This will be used by hammer2 to demark boundaries
  where cross-link hardlinks will not be allowed.  In otherwords, this tells
  hammer2 how far up the directory tree it has to store the inode used for
  a hardlink.

* Automatically set the xlink flag for /*, /usr/*, and /var/*.

* Note that for the case where all hardlinks are situated in the same
  directory, hammer2 will place the hardlink inode in that directory.
  It is when hardlinks cross directories that hammer2 has to emplace the
  target inode in some parent directory where it can find it.  This is
  where the xlink flag helps.

  It is not required to use the xlink flag, but if you have cross-directory
  hardlinks in hammer2 and you do not use the flag the inodes for those
  hardlinks will be consolidated at the root of the mount which will have
  obvious performance issues and cause snapshots of subdirectories to be
  imprecise because they won't cover the hardlink target.

* Represents a trade-off for a very difficult problem that I haven't been
  able to solve.  While HAMMER2 can easily calculate a common parent
  directory for the hardlink target inode when hardlinks are created or
  deleted or renamed, problems arise when a directory in the directory
  path leading from that point to the hardlink is radically moved within
  the larger directory hierarchy, breaking the ability for hammer2 to locate
  the hardlink target using the above method.

  Rather than force hardlinks to be stored in the root of the mount, which
  reduces the usefulness of subdirectory snapshots, this new mechanism is
  being added to give the sysop the ability to retain nearly all the
  advantages of hardlinks without losing the ability to snapshot reasonable
  subdirectory elements.

etc/Makefile
lib/libc/gen/strtofflags.c
sys/sys/stat.h

index e6b6595..25e4fbb 100644 (file)
@@ -343,12 +343,16 @@ distribution:
        cd ${.CURDIR}/../share/man; ${MAKE} makedb
 .endif
 
+#
+#
 distrib-dirs:
        mtree -deU -f ${.CURDIR}/mtree/BSD.root.dist -p ${DESTDIR}/
        mtree -deU -f ${.CURDIR}/mtree/BSD.var.dist -p ${DESTDIR}/var
        mtree -deU -f ${.CURDIR}/mtree/BSD.usr.dist -p ${DESTDIR}/usr
        mtree -deU -f ${.CURDIR}/mtree/BSD.include.dist \
                -p ${DESTDIR}/usr/include
+       -chflags xlink ${DESTDIR}/* ${DESTDIR}/usr/* ${DESTDIR}/var/* \
+                       ${DESTDIR}/home/*
        cd ${DESTDIR}/; test -e sys || (rm -f sys;  ${LN} -s usr/src/sys sys)
        cd ${DESTDIR}/usr/share/nls; \
        set - `grep "^[a-zA-Z]" ${.CURDIR}/nls.alias`; \
index f505563..94fe125 100644 (file)
@@ -79,6 +79,11 @@ static struct {
        { "noucache",           UF_CACHE,       0 },
        { "noscache",           SF_NOCACHE,     1 },
 #endif
+#ifdef UF_XLINK
+       { "noxlink",            UF_XLINK,       0 },
+       { "nouxlink",           UF_XLINK,       0 },
+       { "nosxlink",           SF_XLINK,       0 },
+#endif
 };
 #define longestflaglen 12
 #define nmappings      (sizeof(mapping) / sizeof(mapping[0]))
index 89b0c7d..12a7cde 100644 (file)
@@ -183,6 +183,8 @@ struct stat {
 #define        UF_FBSDRSVD20   0x00000020      /* (unused) */
 #define        UF_NOHISTORY    0x00000040      /* do not retain history/snapshots */
 #define        UF_CACHE        0x00000080      /* enable data swapcache */
+#define UF_XLINK       0x00000100      /* cross-link (hardlink) boundary */
+
 /*
  * Super-user changeable flags.
  */
@@ -194,6 +196,7 @@ struct stat {
 #define        SF_FBSDRSVD20   0x00200000      /* (used by FreeBSD for snapshots) */
 #define        SF_NOHISTORY    0x00400000      /* do not retain history/snapshots */
 #define        SF_NOCACHE      0x00800000      /* disable data swapcache */
+#define SF_XLINK       0x01000000      /* cross-link (hardlink) boundary */
 
 #ifdef _KERNEL
 /*