From: Sage Weil Date: Fri, 25 Sep 2009 18:19:08 +0000 (-0700) Subject: filestore: use btrfs TRANS_RESV_START ioctl if present X-Git-Tag: v0.16~65^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=56affd7f85628cb30129e6e4cce0b736321f5725;p=ceph.git filestore: use btrfs TRANS_RESV_START ioctl if present This will detect ENOSPC when starting the transaction, instead of failing part way through. --- diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index 21a31b5476b07..69c19eed3a0aa 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -47,6 +47,11 @@ #ifndef DARWIN # include # define BTRFS_IOCTL_MAGIC 0x94 +struct btrfs_ioctl_trans_resv_start { + __u64 bytes, ops; +}; +# define BTRFS_IOC_TRANS_RESV_START _IOW(BTRFS_IOCTL_MAGIC, 5, \ + struct btrfs_ioctl_trans_resv_start) # define BTRFS_IOC_TRANS_START _IO(BTRFS_IOCTL_MAGIC, 6) # define BTRFS_IOC_TRANS_END _IO(BTRFS_IOCTL_MAGIC, 7) # define BTRFS_IOC_SYNC _IO(BTRFS_IOCTL_MAGIC, 8) @@ -494,8 +499,16 @@ int FileStore::mount() // is this btrfs? Transaction empty; btrfs = 1; + btrfs_trans_resv_start = true; btrfs_trans_start_end = true; // trans start/end interface r = apply_transaction(empty, 0); + if (r != 0) { + dout(0) << "mount lame, new TRANS_RESV_START ioctl is NOT supported" << dendl; + btrfs_trans_resv_start = false; + r = apply_transaction(empty, 0); + } else { + dout(0) << "mount yay, new TRANS_RESV_START ioctl is supported" << dendl; + } if (r == 0) { // do we have the shiny new CLONE_RANGE ioctl? btrfs = 2; @@ -553,7 +566,7 @@ unsigned FileStore::apply_transaction(Transaction &t, op_start(); // non-atomic implementation - int id = _transaction_start(0);// t.get_trans_len()); + int id = _transaction_start(t.get_num_bytes(), t.get_num_ops()); if (id < 0) { op_journal_start(); op_finish(); @@ -586,7 +599,15 @@ unsigned FileStore::apply_transactions(list &tls, { op_start(); - int id = _transaction_start(0);// t.get_trans_len()); + __u64 bytes = 0, ops = 0; + for (list::iterator p = tls.begin(); + p != tls.end(); + p++) { + bytes += (*p)->get_num_bytes(); + ops += (*p)->get_num_ops(); + } + + int id = _transaction_start(bytes, ops); if (id < 0) { op_journal_start(); op_finish(); @@ -623,7 +644,7 @@ unsigned FileStore::apply_transactions(list &tls, // btrfs transaction start/end interface -int FileStore::_transaction_start(int len) +int FileStore::_transaction_start(__u64 bytes, __u64 ops) { #ifdef DARWIN return 0; @@ -639,7 +660,17 @@ int FileStore::_transaction_start(int len) << " from btrfs open" << dendl; assert(0); } - if (::ioctl(fd, BTRFS_IOC_TRANS_START) < 0) { + + int r; + if (btrfs_trans_resv_start) { + btrfs_ioctl_trans_resv_start resv; + resv.bytes = bytes; + resv.ops = ops; + r = ::ioctl(fd, BTRFS_IOC_TRANS_RESV_START, (unsigned long)&resv); + } else { + r = ::ioctl(fd, BTRFS_IOC_TRANS_START); + } + if (r < 0) { derr(0) << "transaction_start got " << strerror_r(errno, buf, sizeof(buf)) << " from btrfs ioctl" << dendl; ::close(fd); diff --git a/src/os/FileStore.h b/src/os/FileStore.h index 01c891dd63ebc..1372d9ca6976e 100644 --- a/src/os/FileStore.h +++ b/src/os/FileStore.h @@ -38,6 +38,7 @@ class FileStore : public JournalingObjectStore { __u64 fsid; int btrfs; + bool btrfs_trans_resv_start; bool btrfs_trans_start_end; int fsid_fd, op_fd; @@ -80,7 +81,7 @@ class FileStore : public JournalingObjectStore { public: FileStore(const char *base, const char *jdev = 0) : basedir(base), journalpath(jdev ? jdev:""), - btrfs(false), btrfs_trans_start_end(false), + btrfs(false), btrfs_trans_resv_start(false), btrfs_trans_start_end(false), fsid_fd(-1), op_fd(-1), attrs(this), fake_attrs(false), collections(this), fake_collections(false), @@ -95,7 +96,7 @@ class FileStore : public JournalingObjectStore { unsigned apply_transaction(Transaction& t, Context *onjournal=0, Context *ondisk=0); unsigned apply_transactions(list& tls, Context *onjournal=0, Context *ondisk=0); - int _transaction_start(int len); + int _transaction_start(__u64 bytes, __u64 ops); void _transaction_finish(int id); unsigned _apply_transaction(Transaction& t); diff --git a/src/os/ObjectStore.h b/src/os/ObjectStore.h index 725ed8da35492..cb641cd5b562d 100644 --- a/src/os/ObjectStore.h +++ b/src/os/ObjectStore.h @@ -128,13 +128,13 @@ public: int get_btrfs_len() { return blen; } */ - __u64 disk_space_required() { + __u64 get_num_bytes() { // be conservative! __u64 s = 16384 + (ops.size() + oids.size() + cids.size() + lengths.size()) * 4096; for (vector::iterator p = bls.begin(); p != bls.end(); p++) s += bls.size() + 4096; - return s; + return s; } bool empty() {