From: Sage Weil Date: Tue, 1 Sep 2009 23:37:10 +0000 (-0700) Subject: uclient: implement CREATE operation X-Git-Tag: v0.14~52^2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f445219330f3d04444fcff1c2fd80051d12390f5;p=ceph.git uclient: implement CREATE operation This avoids an additional async cap wanted update in the usual case. And let's us pass in default layout info! Untested... --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 1ce70ca90f3d..7645111c929b 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3775,6 +3775,8 @@ int Client::open(const char *relpath, int flags, mode_t mode) tout << relpath << std::endl; tout << flags << std::endl; + Fh *fh = NULL; + filepath path(relpath); Inode *in; int r = path_walk(path, &in); @@ -3788,21 +3790,17 @@ int Client::open(const char *relpath, int flags, mode_t mode) r = path_walk(dirpath, &dir); if (r < 0) return r; - r = _mknod(dir, dname.c_str(), mode, 0); - if (r == 0) { - Dentry *dn = dir->dir->dentries[dname]; - in = dn->inode; - assert(in); - } + r = _create(dir, dname.c_str(), flags, mode, &in, &fh); } if (r < 0) return r; - Fh *fh; - r = _open(in, flags, mode, &fh); + if (!fh) + r = _open(in, flags, mode, &fh); if (r >= 0) { // allocate a integer file descriptor assert(fh); + assert(in); r = get_fd(); assert(fd_map.count(r) == 0); fd_map[r] = fh; @@ -3813,6 +3811,30 @@ int Client::open(const char *relpath, int flags, mode_t mode) return r; } +Fh *Client::_create_fh(Inode *in, int flags, int cmode) +{ + // yay + Fh *f = new Fh; + f->mode = cmode; + if (flags & O_APPEND) + f->append = true; + + // inode + assert(in); + f->inode = in; + f->inode->get(); + + dout(10) << "_create_fh " << in->ino << " mode " << cmode << dendl; + + if (in->snapid != CEPH_NOSNAP) { + in->snap_cap_refs++; + dout(5) << "open success, fh is " << f << " combined IMMUTABLE SNAP caps " + << ccap_string(in->caps_issued()) << dendl; + } + + return f; +} + int Client::_open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid, int gid) { int cmode = ceph_flags_to_mode(flags); @@ -3836,25 +3858,7 @@ int Client::_open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid, int gid) // success? if (result >= 0) { - // yay - Fh *f = new Fh; - if (fhp) *fhp = f; - f->mode = cmode; - if (flags & O_APPEND) - f->append = true; - - // inode - assert(in); - f->inode = in; - f->inode->get(); - - dout(10) << in->ino << " mode " << cmode << dendl; - - if (in->snapid != CEPH_NOSNAP) { - in->snap_cap_refs++; - dout(5) << "open success, fh is " << f << " combined IMMUTABLE SNAP caps " - << ccap_string(in->caps_issued()) << dendl; - } + *fhp = _create_fh(in, flags, cmode); } else { in->put_open_ref(cmode); } @@ -5008,6 +5012,36 @@ int Client::ll_mknod(vinodeno_t parent, const char *name, mode_t mode, dev_t rde return r; } +int Client::_create(Inode *dir, const char *name, int flags, mode_t mode, Inode **inp, Fh **fhp, int uid, int gid) +{ + dout(3) << "_create(" << dir->ino << " " << name << ", 0" << oct << mode << dec << ")" << dendl; + + MClientRequest *req = new MClientRequest(CEPH_MDS_OP_CREATE); + filepath path; + dir->make_path(path); + path.push_dentry(name); + req->set_filepath(path); + req->head.args.open.flags = flags | O_CREAT; + req->head.args.open.mode = mode; + + int res = make_request(req, uid, gid); + + if (res >= 0) { + res = _lookup(dir, name, inp); + if (res >= 0) { + int cmode = ceph_flags_to_mode(flags); + (*inp)->get_open_ref(cmode); + *fhp = _create_fh(*inp, flags, cmode); + } + } + + trim_cache(); + + dout(3) << "create(" << path << ", 0" << oct << mode << dec << ") = " << res << dendl; + return res; +} + + int Client::_mkdir(Inode *dir, const char *name, mode_t mode, int uid, int gid) { MClientRequest *req = new MClientRequest(dir->snapid == CEPH_SNAPDIR ? CEPH_MDS_OP_MKSNAP:CEPH_MDS_OP_MKDIR); diff --git a/src/client/Client.h b/src/client/Client.h index 9452070789e3..fe12fee6c0e9 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -1064,6 +1064,8 @@ private: int _ll_put(Inode *in, int num); void _ll_drop_pins(); + Fh *_create_fh(Inode *in, int flags, int cmode); + int _read_sync(Fh *f, __u64 off, __u64 len, bufferlist *bl); int _read_async(Fh *f, __u64 off, __u64 len, bufferlist *bl); @@ -1086,6 +1088,7 @@ private: int _setxattr(Inode *in, const char *name, const void *value, size_t len, int flags, int uid=-1, int gid=-1); int _removexattr(Inode *in, const char *nm, int uid=-1, int gid=-1); int _open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid=-1, int gid=-1); + int _create(Inode *in, const char *name, int flags, mode_t mode, Inode **inp, Fh **fhp, int uid=-1, int gid=-1); int _release(Fh *fh); loff_t _lseek(Fh *fh, loff_t offset, int whence); int _read(Fh *fh, __s64 offset, __u64 size, bufferlist *bl);