File add-upstream-btrfs-journal-fragmentation-fixes.patch of Package systemd.1059

diff -Naur systemd-210/Makefile.am systemd-210.mod/Makefile.am
--- systemd-210/Makefile.am	2015-01-15 14:00:36.153136568 +0100
+++ systemd-210.mod/Makefile.am	2015-01-19 14:38:08.150615856 +0100
@@ -779,7 +779,10 @@
 	src/shared/condition-util.c \
 	src/shared/condition-util.h \
 	src/shared/bus-label.c \
-	src/shared/bus-label.h
+	src/shared/bus-label.h \
+	src/shared/btrfs-util.c \
+	src/shared/btrfs-util.h
+
 
 nodist_libsystemd_shared_la_SOURCES = \
 	src/shared/errno-from-name.h \
@@ -820,7 +823,7 @@
 	src/shared/fileio-label.c \
 	src/shared/fileio-label.h \
 	src/shared/dev-setup.c \
-	src/shared/dev-setup.h
+	src/shared/dev-setup.h 
 
 libsystemd_label_la_CFLAGS = \
 	$(AM_CFLAGS) \
diff -Naur systemd-210/src/journal/journalctl.c systemd-210.mod/src/journal/journalctl.c
--- systemd-210/src/journal/journalctl.c	2015-01-15 14:00:36.022136058 +0100
+++ systemd-210.mod/src/journal/journalctl.c	2015-01-19 13:22:39.747737834 +0100
@@ -1219,7 +1219,7 @@
         size_t mpk_size, seed_size, state_size, i;
         uint8_t *mpk, *seed, *state;
         ssize_t l;
-        int fd = -1, r, attr = 0;
+        int fd = -1, r;
         sd_id128_t machine, boot;
         char *p = NULL, *k = NULL;
         struct FSSHeader h;
@@ -1320,13 +1320,9 @@
 
         /* Enable secure remove, exclusion from dump, synchronous
          * writing and in-place updating */
-        if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
-                log_warning("FS_IOC_GETFLAGS failed: %m");
-
-        attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL;
-
-        if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0)
-                log_warning("FS_IOC_SETFLAGS failed: %m");
+        r = chattr_fd(fd, true, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL);
+        if (r < 0)
+                log_warning("Failed to set file attributes: %m");
 
         zero(h);
         memcpy(h.signature, "KSHHRHLP", 8);
diff -Naur systemd-210/src/journal/journal-file.c systemd-210.mod/src/journal/journal-file.c
--- systemd-210/src/journal/journal-file.c	2015-01-15 14:00:36.016136035 +0100
+++ systemd-210.mod/src/journal/journal-file.c	2015-01-19 14:02:07.313619805 +0100
@@ -26,8 +26,10 @@
 #include <sys/statvfs.h>
 #include <fcntl.h>
 #include <stddef.h>
+#include <linux/fs.h>
 #include <sys/xattr.h>
 
+#include "btrfs-util.h"
 #include "journal-def.h"
 #include "journal-file.h"
 #include "journal-authenticate.h"
@@ -125,6 +127,18 @@
         if (f->mmap && f->fd >= 0)
                 mmap_cache_close_fd(f->mmap, f->fd);
 
+        if (f->fd >= 0 && f->defrag_on_close) {
+
+                /* Be friendly to btrfs: turn COW back on again now,
+                 * and defragment the file. We won't write to the file
+                 * ever again, hence remove all fragmentation, and
+                 * reenable all the good bits COW usually provides
+                 * (such as data checksumming). */
+
+                (void) chattr_fd(f->fd, false, FS_NOCOW_FL);
+                (void) btrfs_defrag_fd(f->fd);
+        }
+
         journal_file_set_offline(f);
 
         if (f->header)
@@ -2514,6 +2528,17 @@
         if (f->last_stat.st_size == 0 && f->writable) {
                 uint64_t crtime;
 
+                /* Before we write anything, turn off COW logic. Given
+                 * our write pattern that is quite unfriendly to COW
+                 * file systems this should greatly improve
+                 * performance on COW file systems, such as btrfs, at
+                 * the expense of data integrity features (which
+                 * shouldn't be too bad, given that we do our own
+                 * checksumming). */
+                r = chattr_fd(f->fd, true, FS_NOCOW_FL);
+                if (r < 0)
+                        log_warning("Failed to set file attributes: %m");
+
                 /* Let's attach the creation time to the journal file,
                  * so that the vacuuming code knows the age of this
                  * file even if the file might end up corrupted one
@@ -2658,6 +2683,11 @@
 
         old_file->header->state = STATE_ARCHIVED;
 
+        /* Currently, btrfs is not very good with out write patterns
+         * and fragments heavily. Let's defrag our journal files when
+         * we archive them */
+        old_file->defrag_on_close = true;
+
         r = journal_file_open(old_file->path, old_file->flags, old_file->mode, compress, seal, NULL, old_file->mmap, old_file, &new_file);
         journal_file_close(old_file);
 
@@ -2712,6 +2742,11 @@
         if (r < 0)
                 return -errno;
 
+        /* btrfs doesn't cope well with our write pattern and
+         * fragments heavily. Let's defrag all files we rotate */
+        (void) chattr_path(p, false, FS_NOCOW_FL);
+        (void) btrfs_defrag(p);
+
         log_warning("File %s corrupted or uncleanly shut down, renaming and replacing.", fname);
 
         return journal_file_open(fname, flags, mode, compress, seal,
diff -Naur systemd-210/src/journal/journal-file.h systemd-210.mod/src/journal/journal-file.h
--- systemd-210/src/journal/journal-file.h	2015-01-15 14:00:35.910135623 +0100
+++ systemd-210.mod/src/journal/journal-file.h	2015-01-16 16:54:26.846047051 +0100
@@ -58,7 +58,7 @@
         bool writable:1;
         bool compress:1;
         bool seal:1;
-
+        bool defrag_on_close:1;
         bool tail_entry_monotonic_valid:1;
 
         direction_t last_direction;
diff -Naur systemd-210/src/shared/btrfs-util.c systemd-210.mod/src/shared/btrfs-util.c
--- systemd-210/src/shared/btrfs-util.c	1970-01-01 01:00:00.000000000 +0100
+++ systemd-210.mod/src/shared/btrfs-util.c	2015-01-19 12:12:45.502318392 +0100
@@ -0,0 +1,56 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <sys/vfs.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_LINUX_BTRFS_H
+#include <linux/btrfs.h>
+#endif
+
+#include "missing.h"
+#include "util.h"
+#include "path-util.h"
+#include "macro.h"
+#include "strv.h"
+#include "selinux-util.h"
+#include "smack-util.h"
+#include "btrfs-util.h"
+
+int btrfs_defrag_fd(int fd) {
+        assert(fd >= 0);
+
+        if (ioctl(fd, BTRFS_IOC_DEFRAG, NULL) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int btrfs_defrag(const char *p) {
+        _cleanup_close_ int fd = -1;
+
+        fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+        if (fd < 0)
+                return -errno;
+
+        return btrfs_defrag_fd(fd);
+}
diff -Naur systemd-210/src/shared/btrfs-util.h systemd-210.mod/src/shared/btrfs-util.h
--- systemd-210/src/shared/btrfs-util.h	1970-01-01 01:00:00.000000000 +0100
+++ systemd-210.mod/src/shared/btrfs-util.h	2015-01-16 16:48:29.746609450 +0100
@@ -0,0 +1,28 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <sys/types.h>
+
+#include "time-util.h"
+
+int btrfs_defrag_fd(int fd);
+int btrfs_defrag(const char *p);
diff -Naur systemd-210/src/shared/util.c systemd-210.mod/src/shared/util.c
--- systemd-210/src/shared/util.c	2015-01-15 14:00:36.027136078 +0100
+++ systemd-210.mod/src/shared/util.c	2015-01-16 17:18:22.601775285 +0100
@@ -61,6 +61,7 @@
 #include <locale.h>
 #include <sys/personality.h>
 #include <libgen.h>
+#include <linux/fs.h>
 #undef basename
 
 #ifdef HAVE_SYS_AUXV_H
@@ -6518,3 +6519,35 @@
 
         return NULL;
 }
+
+int chattr_fd(int fd, bool b, int mask) {
+        int old_attr, new_attr;
+
+        assert(fd >= 0);
+
+        if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
+                return -errno;
+
+        if (b)
+                new_attr = old_attr | mask;
+        else
+                new_attr = old_attr & ~mask;
+
+        if (new_attr == old_attr)
+                return 0;
+
+        if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
+                return -errno;
+
+        return 0;
+}
+
+int chattr_path(const char *p, bool b, int mask) {
+        _cleanup_close_ int fd = -1;
+
+        fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+        if (fd < 0)
+                return -errno;
+
+        return chattr_fd(fd, b, mask);
+}
diff -Naur systemd-210/src/shared/util.h systemd-210.mod/src/shared/util.h
--- systemd-210/src/shared/util.h	2015-01-15 14:00:36.026136074 +0100
+++ systemd-210.mod/src/shared/util.h	2015-01-16 17:19:18.406996683 +0100
@@ -901,3 +901,6 @@
 int umount_recursive(const char *target, int flags);
 
 int sethostname_idempotent(const char *s);
+
+int chattr_fd(int fd, bool b, int mask);
+int chattr_path(const char *p, bool b, int mask);
openSUSE Build Service is sponsored by