]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
FileJournal: Remove CEPH_PAGE_SIZE assumptions 4864/head
authorSteve Capper <steve.capper@linaro.org>
Wed, 6 May 2015 12:04:37 +0000 (12:04 +0000)
committerSteve Capper <steve.capper@linaro.or>
Thu, 4 Jun 2015 14:14:32 +0000 (15:14 +0100)
Ceph currently assumes a FileJournal block_size equal to a multiple of
CEPH_PAGE_SIZE. For x86, this will always be 4KB which matches the sector
size of Advanced Format drives, and works quite well.

Other architectures, such as ARM and PowerPC, can have a much larger
CEPH_PAGE_SIZE == PAGE_SIZE (64KB).

Unfortunately, a block_size of 64KB can lead to a significant increase
in the amount of disk activity required by the journal over one with a
block_size of 4KB (especially when carrying out a lot of 4KB writes).

This patch removes the assumption from the FileJournal that the
block_size should always be at least CEPH_PAGE_SIZE, and replaces it
with the assumption that this should be at least:
CEPH_MINIMUM_BLOCK_SIZE == 4KB.

For PAGE_SIZE values of 4KB (for x86 say), this patch shouldn't lead
to any change in behaviour.

For a 64KB PAGE_SIZE where the FileJournal is hosted on a block device
directly, the block_size will go down from 64KB to 4KB with this patch.
Where the FileJournal is hosted on an ext4 filesystem we will see a
similar reduction in block_size. If the FileJournal is hosted on an
XFS or btrfs filesystem then we won't see any reduction in the block_size
(because both XFS and btrfs return the PAGE_CACHE_SIZE as the minimum io
block size in fstat).

Signed-off-by: Steve Capper <steve.capper@linaro.org>
src/os/FileJournal.cc

index c6bb6f2c0755d870f01c276783906ec3b5d77114..3ae6bd08cfd99bd6476aa36dcbea6a3847e62601 100644 (file)
@@ -40,6 +40,7 @@
 #define dout_prefix *_dout << "journal "
 
 const static int64_t ONE_MEG(1 << 20);
+const static int CEPH_MINIMUM_BLOCK_SIZE(4096);
 
 int FileJournal::_open(bool forwrite, bool create)
 {
@@ -154,8 +155,7 @@ int FileJournal::_open_block_device()
           << dendl;
   max_size = bdev_sz;
 
-  /* block devices have to write in blocks of CEPH_PAGE_SIZE */
-  block_size = CEPH_PAGE_SIZE;
+  block_size = CEPH_MINIMUM_BLOCK_SIZE;
 
   if (g_conf->journal_discard) {
     discard = block_device_support_discard(fn.c_str());
@@ -295,7 +295,7 @@ int FileJournal::_open_file(int64_t oldsize, blksize_t blksize,
   else {
     max_size = oldsize;
   }
-  block_size = MAX(blksize, (blksize_t)CEPH_PAGE_SIZE);
+  block_size = MAX(blksize, (blksize_t)CEPH_MINIMUM_BLOCK_SIZE);
 
   if (create && g_conf->journal_zero_on_create) {
     derr << "FileJournal::_open_file : zeroing journal" << dendl;
@@ -505,9 +505,9 @@ int FileJournal::open(uint64_t fs_op_seq)
            << block_size << " (required for direct_io journal mode)" << dendl;
     return -EINVAL;
   }
-  if ((header.alignment % CEPH_PAGE_SIZE) && directio) {
-    dout(0) << "open journal alignment " << header.alignment << " is not multiple of page size " << CEPH_PAGE_SIZE
-           << " (required for direct_io journal mode)" << dendl;
+  if ((header.alignment % CEPH_MINIMUM_BLOCK_SIZE) && directio) {
+    dout(0) << "open journal alignment " << header.alignment << " is not multiple of minimum block size "
+           << CEPH_MINIMUM_BLOCK_SIZE << " (required for direct_io journal mode)" << dendl;
     return -EINVAL;
   }
 
@@ -952,15 +952,15 @@ int FileJournal::prepare_single_write(bufferlist& bl, off64_t& queue_pos, uint64
 void FileJournal::align_bl(off64_t pos, bufferlist& bl)
 {
   // make sure list segments are page aligned
-  if (directio && (!bl.is_page_aligned() ||
-                  !bl.is_n_page_sized())) {
-    bl.rebuild_page_aligned();
+  if (directio && (!bl.is_aligned(block_size) ||
+                  !bl.is_n_align_sized(CEPH_MINIMUM_BLOCK_SIZE))) {
+    bl.rebuild_aligned(CEPH_MINIMUM_BLOCK_SIZE);
     dout(10) << __func__ << " total memcopy: " << bl.get_memcopy_count() << dendl;
-    if ((bl.length() & ~CEPH_PAGE_MASK) != 0 ||
-       (pos & ~CEPH_PAGE_MASK) != 0)
+    if ((bl.length() & (CEPH_MINIMUM_BLOCK_SIZE - 1)) != 0 ||
+       (pos & (CEPH_MINIMUM_BLOCK_SIZE - 1)) != 0)
       dout(0) << "rebuild_page_aligned failed, " << bl << dendl;
-    assert((bl.length() & ~CEPH_PAGE_MASK) == 0);
-    assert((pos & ~CEPH_PAGE_MASK) == 0);
+    assert((bl.length() & (CEPH_MINIMUM_BLOCK_SIZE - 1)) == 0);
+    assert((pos & (CEPH_MINIMUM_BLOCK_SIZE - 1)) == 0);
   }
 }