]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
filestore: improve lseek64 error checking, and use buffer::list::write_fd()
authorSage Weil <sage@newdream.net>
Thu, 8 Jul 2010 17:14:23 +0000 (10:14 -0700)
committerSage Weil <sage@newdream.net>
Thu, 8 Jul 2010 17:14:23 +0000 (10:14 -0700)
Signed-off-by: Sage Weil <sage@newdream.net>
src/os/FileStore.cc

index 46cc13b8e59a301b06e0287cee1fd1c6b547d691..657f93e665618d5d5fe16150a75354f1f1db8e1c 100644 (file)
@@ -1393,48 +1393,48 @@ int FileStore::_write(coll_t cid, const sobject_t& oid,
   dout(15) << "write " << fn << " " << offset << "~" << len << dendl;
   int r;
 
+  int64_t actual;
+
   char buf[80];
   int flags = O_WRONLY|O_CREAT;
   int fd = ::open(fn, flags, 0644);
   if (fd < 0) {
     derr(0) << "write couldn't open " << fn << " flags " << flags << " errno " << errno << " " << strerror_r(errno, buf, sizeof(buf)) << dendl;
     r = -errno;
-  } else {
-    
-    // seek
-    uint64_t actual = ::lseek64(fd, offset, SEEK_SET);
-    int did = 0;
-    assert(actual == offset);
-    
-    // write buffers
-    for (list<bufferptr>::const_iterator it = bl.buffers().begin();
-        it != bl.buffers().end();
-        it++) {
-      int r = ::write(fd, (char*)(*it).c_str(), (*it).length());
-      if (r > 0)
-       did += r;
-      else {
-       derr(0) << "couldn't write to " << fn << " len " << len << " off " << offset << " errno " << errno << " " << strerror_r(errno, buf, sizeof(buf)) << dendl;
-      }
-    }
+    goto out;
+  }
     
-    if (did < 0) {
-      derr(0) << "couldn't write to " << fn << " len " << len << " off " << offset << " errno " << errno << " " << strerror_r(errno, buf, sizeof(buf)) << dendl;
-    }
+  // seek
+  actual = ::lseek64(fd, offset, SEEK_SET);
+  if (actual < 0) {
+    dout(0) << "write lseek64 to " << offset << " failed: " << strerror_r(errno, buf, sizeof(buf)) << dendl;
+    r = -errno;
+    goto out;
+  }
+  if (actual != (int64_t)offset) {
+    dout(0) << "write lseek64 to " << offset << " gave bad offset " << actual << dendl;
+    r = -EIO;
+    goto out;
+  }
 
+  // write
+  r = bl.write_fd(fd);
+  if (r == 0)
+    r = bl.length();
+
+  // flush?
 #ifdef HAVE_SYNC_FILE_RANGE
-    if (!g_conf.filestore_flusher ||
-       !queue_flusher(fd, offset, len)) {
-      if (g_conf.filestore_sync_flush)
-       ::sync_file_range(fd, offset, len, SYNC_FILE_RANGE_WRITE);
-      ::close(fd);
-    }
-#else
+  if (!g_conf.filestore_flusher ||
+      !queue_flusher(fd, offset, len)) {
+    if (g_conf.filestore_sync_flush)
+      ::sync_file_range(fd, offset, len, SYNC_FILE_RANGE_WRITE);
     ::close(fd);
-#endif
-    r = did;
   }
+#else
+  ::close(fd);
+#endif
 
+ out:
   dout(10) << "write " << fn << " " << offset << "~" << len << " = " << r << dendl;
   return r;
 }