]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
uclient: add getdnames()
authorSage Weil <sage@newdream.net>
Fri, 21 Aug 2009 20:11:44 +0000 (13:11 -0700)
committerSage Weil <sage@newdream.net>
Fri, 21 Aug 2009 20:11:44 +0000 (13:11 -0700)
src/client/Client.cc
src/client/Client.h
src/client/libceph.cc
src/client/libceph.h

index 21d576292b8828b686643ee6857723b7060e1c64..7fbec190d083273a3ad7b8729505e87f41863215 100644 (file)
@@ -3644,6 +3644,56 @@ int Client::readdirplus_r(DIR *d, struct dirent *de, struct stat *st, int *stmas
   assert(0);
 }
 
+int Client::getdnames(DIR *d, char *buf, int buflen)
+{
+  DirResult *dirp = (DirResult*)d;
+  int ret = 0;
+  
+  while (1) {
+    if (dirp->at_end())
+      return 0;
+
+    if (dirp->buffer.count(dirp->frag()) == 0) {
+      Mutex::Locker lock(client_lock);
+      _readdir_get_frag(dirp);
+      if (dirp->at_end())
+       return 0;
+    }
+
+    frag_t fg = dirp->frag();
+    uint32_t pos = dirp->fragpos();
+    assert(dirp->buffer.count(fg));   
+    vector<DirEntry> &ent = dirp->buffer[fg];
+
+    if (ent.empty()) {
+      dout(10) << "empty frag " << fg << ", moving on to next" << dendl;
+      _readdir_next_frag(dirp);
+      continue;
+    }
+
+    assert(pos < ent.size());
+
+    // is there room?
+    int dlen = ent[pos].d_name.length();
+    const char *dname = ent[pos].d_name.c_str();
+    if (ret + dlen + 1 > buflen) {
+      if (!ret)
+       return -ERANGE;  // the buffer is too small for the first name!
+      return ret;
+    }
+    memcpy(buf + ret, dname, dlen + 1);
+    ret += dlen + 1;
+
+    pos++;
+    dirp->offset++;
+
+    if (pos == ent.size()) 
+      _readdir_next_frag(dirp);
+  }
+  assert(0);
+}
+
+
 
 int Client::closedir(DIR *dir) 
 {
index c724e0ec0edfe0c7bcf2b24e0ae911419bab5baf..afb91d0174739a3b14ee75ec06f223f791932173 100644 (file)
@@ -1112,6 +1112,7 @@ public:
   int closedir(DIR *dirp);
   int readdir_r(DIR *dirp, struct dirent *de);
   int readdirplus_r(DIR *dirp, struct dirent *de, struct stat *st, int *stmask);
+  int getdnames(DIR *dirp, char *buf, int buflen);  // get a bunch of dentries at once
   void rewinddir(DIR *dirp); 
   loff_t telldir(DIR *dirp);
   void seekdir(DIR *dirp, loff_t offset);
index 3205fdf45f5ba61e91a094c19c91828da6004a82..e9a07a2ba0cc4791d11d6bdcf5d40aaca8c935ed 100644 (file)
@@ -117,6 +117,11 @@ extern "C" int ceph_readdirplus_r(DIR *dirp, struct dirent *de, struct stat *st,
   return client->readdirplus_r(dirp, de, st, stmask);
 }
 
+extern "C" int ceph_getdnames(DIR *dirp, char *buf, int buflen)
+{
+  return client->getdnames(dirp, buf, buflen);
+}
+
 extern "C" void ceph_rewinddir(DIR *dirp)
 {
   client->rewinddir(dirp);
index 3b055862fa975e050ac71f4d487f0a3f3e9f2a80..8a749b2e767dd110cbcb0da3d655cd4b83b55f2d 100644 (file)
@@ -31,6 +31,7 @@ int ceph_opendir(const char *name, DIR **dirpp);
 int ceph_closedir(DIR *dirp);
 int ceph_readdir_r(DIR *dirp, struct dirent *de);
 int ceph_readdirplus_r(DIR *dirp, struct dirent *de, struct stat *st, int *stmask);
+int ceph_getdnames(DIR *dirp, char *name, int buflen);
 void ceph_rewinddir(DIR *dirp); 
 loff_t ceph_telldir(DIR *dirp);
 void ceph_seekdir(DIR *dirp, loff_t offset);