diff options
author | Sage Weil <sage@newdream.net> | 2009-02-17 21:27:51 -0800 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2009-02-19 15:25:46 -0800 |
commit | e8d370a91a97adc1a084b04d563c1a8bd6a014af (patch) | |
tree | 82ffe2163692b82f37b4937d3f1cef1a6b53ed37 | |
parent | 142af495d85d1de32a54d21307dbafaad57bdab6 (diff) | |
download | ceph-e8d370a91a97adc1a084b04d563c1a8bd6a014af.tar.gz |
mds: CREATE op for async creation writeback
-rw-r--r-- | src/include/ceph_fs.h | 8 | ||||
-rw-r--r-- | src/mds/Server.cc | 59 | ||||
-rw-r--r-- | src/mds/Server.h | 1 |
3 files changed, 68 insertions, 0 deletions
diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index e583a276b29..f2cade77fd7 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -690,6 +690,8 @@ enum { CEPH_MDS_OP_RMDIR = 0x01221, CEPH_MDS_OP_SYMLINK = 0x01222, + CEPH_MDS_OP_CREATE = 0x01230, + CEPH_MDS_OP_OPEN = 0x10302, CEPH_MDS_OP_TRUNCATE = 0x11303, CEPH_MDS_OP_LTRUNCATE = 0x01303, @@ -773,6 +775,12 @@ union ceph_mds_request_args { __le32 mode; } __attribute__ ((packed)) mkdir; struct { + __le32 uid, gid, mode, rdev; + __le64 size; + struct ceph_timespec ctime, mtime, atime; + __le32 caps, wanted; + } __attribute__ ((packed)) create; + struct { __le32 flags; __le32 mode; } __attribute__ ((packed)) open; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 5002d2c7570..0665442600d 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -962,6 +962,9 @@ void Server::dispatch_client_request(MDRequest *mdr) case CEPH_MDS_OP_SYMLINK: handle_client_symlink(mdr); break; + case CEPH_MDS_OP_CREATE: + handle_client_create(mdr); + break; // snaps @@ -2557,6 +2560,62 @@ void Server::handle_client_symlink(MDRequest *mdr) } +void Server::handle_client_create(MDRequest *mdr) +{ + MClientRequest *req = mdr->client_request; + + CDentry *dn = rdlock_path_xlock_dentry(mdr, false, false); + if (!dn) return; + + mdr->now = g_clock.real_now(); + snapid_t follows = dn->get_dir()->inode->find_snaprealm()->get_newest_seq(); + + CInode *newi = prepare_new_inode(mdr, dn->get_dir(), inodeno_t(req->head.ino)); + assert(newi); + + dn->push_projected_linkage(newi); + + newi->inode.mode = req->head.args.create.mode; + newi->inode.rdev = req->head.args.create.rdev; + newi->inode.uid = req->head.args.create.uid; + newi->inode.gid = req->head.args.create.gid; + + newi->inode.size = req->head.args.create.size; + newi->inode.mtime = req->head.args.create.mtime; + newi->inode.ctime = req->head.args.create.ctime; + newi->inode.atime = req->head.args.create.atime; + + newi->inode.rstat.rbytes = newi->inode.size; + newi->inode.rstat.rfiles = 1; + newi->inode.version = dn->pre_dirty(); + + newi->symlink = req->get_path2(); + + dn->first = newi->first = follows+1; + + // prepare finisher + mdr->ls = mdlog->get_current_segment(); + EUpdate *le = new EUpdate(mdlog, "create"); + le->metablob.add_client_req(req->get_reqid()); + journal_allocated_inos(mdr, &le->metablob); + mdcache->predirty_journal_parents(mdr, &le->metablob, newi, dn->get_dir(), PREDIRTY_PRIMARY|PREDIRTY_DIR, 1); + le->metablob.add_primary_dentry(dn, true, newi); + + int client = mdr->get_client(); + Capability *cap = newi->get_client_cap(client); + int keep = req->head.args.create.caps; + cap->set_wanted(req->head.args.create.wanted); + cap->issue(keep); + + newi->filelock.set_state((keep & CEPH_CAP_FILE_EXCL) ? LOCK_EXCL:LOCK_SYNC); + newi->authlock.set_state((keep & CEPH_CAP_AUTH_EXCL) ? LOCK_EXCL:LOCK_SYNC); + newi->linklock.set_state((keep & CEPH_CAP_LINK_EXCL) ? LOCK_EXCL:LOCK_SYNC); + newi->xattrlock.set_state((keep & CEPH_CAP_XATTR_EXCL) ? LOCK_EXCL:LOCK_SYNC); + + mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi, follows), true); +} + + diff --git a/src/mds/Server.h b/src/mds/Server.h index 8b974de5b0a..c7acdf3100f 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -133,6 +133,7 @@ public: void handle_client_mknod(MDRequest *mdr); void handle_client_mkdir(MDRequest *mdr); void handle_client_symlink(MDRequest *mdr); + void handle_client_create(MDRequest *mdr); // link void handle_client_link(MDRequest *mdr); |