]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: fstat support
authorSage Weil <sage@newdream.net>
Thu, 31 Jan 2008 19:53:58 +0000 (11:53 -0800)
committerSage Weil <sage@newdream.net>
Thu, 31 Jan 2008 19:53:58 +0000 (11:53 -0800)
src/TODO
src/client/Client.cc
src/client/Client.h

index b8513b55aa6c6eee468459bdd3336bcc9ee98b62..7b3c0740546c6354ba1eb7078bf5a6ddb88b2707 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -87,17 +87,10 @@ mds mustfix
 
 - rerun destro trace against latest, with various journal lengths
 
-- EOpen vs other journal events... update ordering problem?
-
 mds
 - fix file_data_version
+- on recovery, validate file sizes when max_size > size
 
-- client cap timeouts
-/  - stale -> resume
-  - tolerate connection break
-- client needs to be smart about all of this..
-  - revoke own caps when they time out,
-  
 
 
 - extend/clean up filepath to allow paths relative to an ino
@@ -138,11 +131,13 @@ mds
 
 
 client
+- obey file_max
+- client needs to be smart about all of this..
+  - revoke own caps when they time out,
 - clean up client mds session vs mdsmap behavior?
 - client caps migration races
   - caps need a seq number; reap logic needs to be a bit smarter
   - also needs cope with mds failures
-- fstat
 
 
 
index 44d695bb98cdd39d06b7f2622813e7caf5c710a4..6be605f11668a5b3e3828f9d5e490c1620943cf0 100644 (file)
@@ -1470,7 +1470,8 @@ int Client::mount()
   // hack: get+pin root inode.
   //  fuse assumes it's always there.
   Inode *root;
-  _do_lstat("/", STAT_MASK_ALL, &root);
+  filepath fpath("", 1);
+  _do_lstat(fpath, STAT_MASK_ALL, &root);
   _ll_get(root);
 
   // trace?
@@ -1922,7 +1923,8 @@ int Client::readlink(const char *path, char *buf, off_t size)
 int Client::_readlink(const char *path, char *buf, off_t size) 
 { 
   Inode *in;
-  int r = _do_lstat(path, STAT_MASK_BASE, &in);
+  filepath fpath(path);
+  int r = _do_lstat(fpath, STAT_MASK_BASE, &in);
   if (r == 0 && !in->inode.is_symlink()) r = -EINVAL;
   if (r == 0) {
     // copy into buf (at most size bytes)
@@ -1942,10 +1944,9 @@ int Client::_readlink(const char *path, char *buf, off_t size)
 
 // inode stuff
 
-int Client::_do_lstat(const char *path, int mask, Inode **in)
+int Client::_do_lstat(filepath &fpath, int mask, Inode **in)
 {  
   MClientRequest *req = 0;
-  filepath fpath(path);
   
   // check whether cache content is fresh enough
   int res = 0;
@@ -1956,7 +1957,7 @@ int Client::_do_lstat(const char *path, int mask, Inode **in)
 
   if (dn && 
       now <= dn->inode->valid_until)
-    dout(10) << "_lstat has inode " << path << " with mask " << dn->inode->mask << ", want " << mask << dendl;
+    dout(10) << "_lstat has inode " << fpath << " with mask " << dn->inode->mask << ", want " << mask << dendl;
   
   if (dn && dn->inode &&
       now <= dn->inode->valid_until &&
@@ -2046,7 +2047,8 @@ int Client::lstat(const char *relpath, struct stat *stbuf)
 int Client::_lstat(const char *path, struct stat *stbuf)
 {
   Inode *in = 0;
-  int res = _do_lstat(path, STAT_MASK_ALL, &in);
+  filepath fpath(path);
+  int res = _do_lstat(fpath, STAT_MASK_ALL, &in);
   if (res == 0) {
     assert(in);
     fill_stat(in, stbuf);
@@ -3250,6 +3252,37 @@ int Client::_fsync(Fh *f, bool syncdataonly)
 }
 
 
+
+int Client::fstat(int fd, struct stat *stbuf) 
+{
+  Mutex::Locker lock(client_lock);
+  tout << "fstat" << std::endl;
+  tout << fd << std::endl;
+
+  assert(fd_map.count(fd));
+  Fh *f = fd_map[fd];
+  int r = _fstat(f, stbuf);
+  dout(3) << "fstat(" << fd << ", " << stbuf << ") = " << r << dendl;
+  return r;
+}
+
+int Client::_fstat(Fh *f, struct stat *stbuf)
+{
+  Inode *in = 0;
+  filepath fpath("", f->inode->ino());
+  int res = _do_lstat(fpath, STAT_MASK_ALL, &in);
+  if (res == 0) {
+    assert(in);
+    fill_stat(in, stbuf);
+    dout(10) << "stat sez size = " << in->inode.size << " mode = 0" << oct << stbuf->st_mode << dec << " ino = " << stbuf->st_ino << dendl;
+  }
+
+  trim_cache();
+  dout(3) << "fstat(\"" << f << "\", " << stbuf << ") = " << res << dendl;
+  return res;
+}
+
+
 // not written yet, but i want to link!
 
 int Client::chdir(const char *path)
@@ -3451,7 +3484,8 @@ int Client::ll_lookup(inodeno_t parent, const char *name, struct stat *attr)
     diri->make_path(path);
     path += "/";
     path += name;
-    _do_lstat(path.c_str(), 0, &in);
+    filepath fpath(path);
+    _do_lstat(fpath, 0, &in);
   }
   if (in) {
     fill_stat(in, attr);
@@ -3537,7 +3571,8 @@ Inode *Client::_ll_get_inode(inodeno_t ino)
   if (inode_map.count(ino) == 0) {
     assert(ino == 1);  // must be the root inode.
     Inode *in;
-    int r = _do_lstat("/", 0, &in);
+    filepath fpath("");
+    int r = _do_lstat(fpath, 0, &in);
     assert(r >= 0);
     return in;
   } else {
index 5b034de2e3eb140b4a089a855ef853e7ff6ea926..0a42016aac69928014a2f452b27cd3b40a4caccf 100644 (file)
@@ -710,7 +710,7 @@ private:
   };
 
   // some helpers
-  int _do_lstat(const char *path, int mask, Inode **in);
+  int _do_lstat(filepath &fpath, int mask, Inode **in);
   int _opendir(const char *name, DirResult **dirpp);
   void _readdir_add_dirent(DirResult *dirp, const string& name, Inode *in);
   void _readdir_fill_dirent(struct dirent *de, DirEntry *entry, off_t);
@@ -745,6 +745,7 @@ private:
   int _truncate(const char *file, off_t length);
   int _ftruncate(Fh *fh, off_t length);
   int _fsync(Fh *fh, bool syncdataonly);
+  int _fstat(Fh *fh, struct stat *stbuf);
   int _statfs(struct statvfs *stbuf);
 
 
@@ -806,6 +807,7 @@ public:
   int truncate(const char *file, off_t size);
   int ftruncate(int fd, off_t size);
   int fsync(int fd, bool syncdataonly);
+  int fstat(int fd, struct stat *stbuf);
 
   // hpc lazyio
   int lazyio_propogate(int fd, off_t offset, size_t count);