From ce56246431df1be43564682361749282c59a5911 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 31 Jan 2008 11:53:58 -0800 Subject: [PATCH] client: fstat support --- src/TODO | 13 ++++------- src/client/Client.cc | 51 +++++++++++++++++++++++++++++++++++++------- src/client/Client.h | 4 +++- 3 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/TODO b/src/TODO index b8513b55aa6c6..7b3c0740546c6 100644 --- 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 diff --git a/src/client/Client.cc b/src/client/Client.cc index 44d695bb98cdd..6be605f11668a 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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 { diff --git a/src/client/Client.h b/src/client/Client.h index 5b034de2e3eb1..0a42016aac699 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -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); -- 2.39.5