From: Greg Farnum Date: Tue, 12 Jul 2016 00:31:17 +0000 (-0700) Subject: client: always pass a UserPerm to mkdir and mksnap functions X-Git-Tag: v11.0.1~36^2~90 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=affddbca453748445b76eb59640e339fc647a674;p=ceph.git client: always pass a UserPerm to mkdir and mksnap functions Signed-off-by: Greg Farnum --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 2f0c3aeb5cc4..dd21a26deda0 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -6211,7 +6211,7 @@ out: // dirs -int Client::mkdir(const char *relpath, mode_t mode) +int Client::mkdir(const char *relpath, mode_t mode, const UserPerm& perm) { Mutex::Locker lock(client_lock); tout(cct) << "mkdir" << std::endl; @@ -6223,15 +6223,15 @@ int Client::mkdir(const char *relpath, mode_t mode) string name = path.last_dentry(); path.pop_dentry(); InodeRef dir; - int r = path_walk(path, &dir); + int r = path_walk(path, &dir, perm); if (r < 0) return r; if (cct->_conf->client_permissions) { - r = may_create(dir.get()); + r = may_create(dir.get(), perm); if (r < 0) return r; } - return _mkdir(dir.get(), name.c_str(), mode); + return _mkdir(dir.get(), name.c_str(), mode, perm); } int Client::mkdirs(const char *relpath, mode_t mode) @@ -6242,8 +6242,7 @@ int Client::mkdirs(const char *relpath, mode_t mode) tout(cct) << relpath << std::endl; tout(cct) << mode << std::endl; - uid_t uid = get_uid(); - gid_t gid = get_gid(); + UserPerm perms = pick_my_perms(); //get through existing parts of path filepath path(relpath); @@ -6253,12 +6252,12 @@ int Client::mkdirs(const char *relpath, mode_t mode) cur = cwd; for (i=0; i_conf->client_permissions) { - r = may_lookup(cur.get(), uid, gid); + r = may_lookup(cur.get(), perms); if (r < 0) break; caps = CEPH_CAP_AUTH_SHARED; } - r = _lookup(cur.get(), path[i].c_str(), caps, &next, uid, gid); + r = _lookup(cur.get(), path[i].c_str(), caps, &next, perms); if (r < 0) break; cur.swap(next); @@ -6270,12 +6269,12 @@ int Client::mkdirs(const char *relpath, mode_t mode) //make new directory at each level for (; i_conf->client_permissions) { - r = may_create(cur.get(), uid, gid); + r = may_create(cur.get(), perms); if (r < 0) return r; } //make new dir - r = _mkdir(cur.get(), path[i].c_str(), mode, uid, gid, &next); + r = _mkdir(cur.get(), path[i].c_str(), mode, perms, &next); //check proper creation/existence if (r < 0) return r; //move to new dir and continue @@ -9417,21 +9416,21 @@ int Client::lazyio_synchronize(int fd, loff_t offset, size_t count) // ============================= // snaps -int Client::mksnap(const char *relpath, const char *name) +int Client::mksnap(const char *relpath, const char *name, const UserPerm& perm) { Mutex::Locker l(client_lock); filepath path(relpath); InodeRef in; - int r = path_walk(path, &in); + int r = path_walk(path, &in, perm); if (r < 0) return r; if (cct->_conf->client_permissions) { - r = may_create(in.get()); + r = may_create(in.get(), perm); if (r < 0) return r; } Inode *snapdir = open_snapdir(in.get()); - return _mkdir(snapdir, name, 0); + return _mkdir(snapdir, name, 0, perm); } int Client::rmsnap(const char *relpath, const char *name) { @@ -10656,12 +10655,12 @@ int Client::_create(Inode *dir, const char *name, int flags, mode_t mode, } -int Client::_mkdir(Inode *dir, const char *name, mode_t mode, int uid, int gid, +int Client::_mkdir(Inode *dir, const char *name, mode_t mode, const UserPerm& perm, InodeRef *inp) { ldout(cct, 3) << "_mkdir(" << dir->ino << " " << name << ", 0" << oct - << mode << dec << ", uid " << uid << ", gid " << gid << ")" - << dendl; + << mode << dec << ", uid " << perm.uid() + << ", gid " << perm.gid() << ")" << dendl; if (strlen(name) > NAME_MAX) return -ENAMETOOLONG; @@ -10685,7 +10684,7 @@ int Client::_mkdir(Inode *dir, const char *name, mode_t mode, int uid, int gid, mode |= S_IFDIR; bufferlist xattrs_bl; - int res = _posix_acl_create(dir, &mode, xattrs_bl, uid, gid); + int res = _posix_acl_create(dir, &mode, xattrs_bl, perm.uid(), perm.gid()); if (res < 0) goto fail; req->head.args.mkdir.mode = mode; @@ -10699,7 +10698,7 @@ int Client::_mkdir(Inode *dir, const char *name, mode_t mode, int uid, int gid, req->set_dentry(de); ldout(cct, 10) << "_mkdir: making request" << dendl; - res = make_request(req, uid, gid, inp); + res = make_request(req, perm, inp); ldout(cct, 10) << "_mkdir result is " << res << dendl; trim_cache(); @@ -10713,7 +10712,7 @@ int Client::_mkdir(Inode *dir, const char *name, mode_t mode, int uid, int gid, } int Client::ll_mkdir(Inode *parent, const char *name, mode_t mode, - struct stat *attr, Inode **out, int uid, int gid) + struct stat *attr, Inode **out, const UserPerm& perm) { Mutex::Locker lock(client_lock); @@ -10726,13 +10725,13 @@ int Client::ll_mkdir(Inode *parent, const char *name, mode_t mode, tout(cct) << mode << std::endl; if (!cct->_conf->fuse_default_permissions) { - int r = may_create(parent, uid, gid); + int r = may_create(parent, perm); if (r < 0) return r; } InodeRef in; - int r = _mkdir(parent, name, mode, uid, gid, &in); + int r = _mkdir(parent, name, mode, perm, &in); if (r == 0) { fill_stat(in, attr); _ll_get(in.get()); diff --git a/src/client/Client.h b/src/client/Client.h index 137586b28ef6..977bdc454889 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -789,7 +789,8 @@ private: InodeRef *inp = 0); int _unlink(Inode *dir, const char *name, const UserPerm& perm); int _rename(Inode *olddir, const char *oname, Inode *ndir, const char *nname, const UserPerm& perm); - int _mkdir(Inode *dir, const char *name, mode_t mode, int uid=-1, int gid=-1, InodeRef *inp = 0); + int _mkdir(Inode *dir, const char *name, mode_t mode, const UserPerm& perm, + InodeRef *inp = 0); int _rmdir(Inode *dir, const char *name, int uid=-1, int gid=-1); int _symlink(Inode *dir, const char *name, const char *target, int uid=-1, int gid=-1, InodeRef *inp = 0); int _mknod(Inode *dir, const char *name, mode_t mode, dev_t rdev, int uid=-1, int gid=-1, InodeRef *inp = 0); @@ -1030,7 +1031,7 @@ public: int rename(const char *from, const char *to, const UserPerm& perm); // dirs - int mkdir(const char *path, mode_t mode); + int mkdir(const char *path, mode_t mode, const UserPerm& perm); int mkdirs(const char *path, mode_t mode); int rmdir(const char *path); @@ -1115,7 +1116,7 @@ public: int enumerate_layout(int fd, vector& result, loff_t length, loff_t offset); - int mksnap(const char *path, const char *name); + int mksnap(const char *path, const char *name, const UserPerm& perm); int rmsnap(const char *path, const char *name); // expose caps @@ -1156,7 +1157,7 @@ public: int ll_mknod(Inode *in, const char *name, mode_t mode, dev_t rdev, struct stat *attr, Inode **out, int uid = -1, int gid = -1); int ll_mkdir(Inode *in, const char *name, mode_t mode, struct stat *attr, - Inode **out, int uid = -1, int gid = -1); + Inode **out, const UserPerm& perm); int ll_symlink(Inode *in, const char *name, const char *value, struct stat *attr, Inode **out, int uid = -1, int gid = -1); int ll_unlink(Inode *in, const char *name, const UserPerm& perm); diff --git a/src/client/SyntheticClient.cc b/src/client/SyntheticClient.cc index 355bb4d70f6e..ca18cc0ba182 100644 --- a/src/client/SyntheticClient.cc +++ b/src/client/SyntheticClient.cc @@ -328,6 +328,8 @@ int SyntheticClient::run() int seq = 0; + UserPerm perms = client->pick_my_perms(); + for (list::iterator it = modes.begin(); it != modes.end(); ++it) { @@ -896,7 +898,7 @@ int SyntheticClient::run() string base = get_sarg(0); string name = get_sarg(0); if (run_me()) - mksnap(base.c_str(), name.c_str()); + mksnap(base.c_str(), name.c_str(), perms); did_run_me(); } break; @@ -997,6 +999,7 @@ void SyntheticClient::up() int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) { dout(4) << "play trace prefix '" << prefix << "'" << dendl; + UserPerm perms = client->pick_my_perms(); t.start(); char buf[1024]; @@ -1018,7 +1021,7 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) // prefix? const char *p = prefix.c_str(); if (prefix.length()) { - client->mkdir(prefix.c_str(), 0755); + client->mkdir(prefix.c_str(), 0755, perms); struct stat attr; i1 = client->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP)); if (client->ll_lookup(i1, prefix.c_str(), &attr, &i2) == 0) { @@ -1083,7 +1086,7 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) } else if (strcmp(op, "mkdir") == 0) { const char *a = t.get_string(buf, p); int64_t b = t.get_int(); - client->mkdir(a, b); + client->mkdir(a, b, perms); } else if (strcmp(op, "rmdir") == 0) { const char *a = t.get_string(buf, p); client->rmdir(a); @@ -1290,7 +1293,7 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) struct stat attr; if (ll_inos.count(i)) { i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - if (client->ll_mkdir(i1, n, m, &attr, &i2) == 0) + if (client->ll_mkdir(i1, n, m, &attr, &i2, perms) == 0) ll_inos[ri] = attr.st_ino; client->ll_put(i1); } @@ -1742,8 +1745,9 @@ int SyntheticClient::make_dirs(const char *basedir, int dirs, int files, int dep { if (time_to_stop()) return 0; + UserPerm perms = client->pick_my_perms(); // make sure base dir exists - int r = client->mkdir(basedir, 0755); + int r = client->mkdir(basedir, 0755, perms); if (r != 0) { dout(1) << "can't make base dir? " << basedir << dendl; //return -1; @@ -1847,14 +1851,14 @@ int SyntheticClient::make_files(int num, int count, int priv, bool more) if (priv) { for (int c=0; cmkdir(d, 0755); + client->mkdir(d, 0755, perms); } } else { // shared if (true || whoami == 0) { for (int c=0; cmkdir(d, 0755); + client->mkdir(d, 0755, perms); } } else { sleep(2); @@ -1897,8 +1901,8 @@ int SyntheticClient::link_test() // create files int num = 200; - client->mkdir("orig", 0755); - client->mkdir("copy", 0755); + client->mkdir("orig", 0755, perms); + client->mkdir("copy", 0755, perms); utime_t start = ceph_clock_now(client->cct); for (int i=0; ipick_my_perms(); char d[255]; - client->mkdir("test", 0755); + client->mkdir("test", 0755, perms); for (int n=0; nmknod(d, 0644); @@ -2702,7 +2707,7 @@ int SyntheticClient::random_walk(int num_req) } if (op == CEPH_MDS_OP_MKDIR) { - r = client->mkdir( make_sub("mkdir"), 0755); + r = client->mkdir(make_sub("mkdir"), 0755, perms); } if (op == CEPH_MDS_OP_RMDIR) { @@ -2834,12 +2839,13 @@ int SyntheticClient::random_walk(int num_req) void SyntheticClient::make_dir_mess(const char *basedir, int n) { + UserPerm perms = client->pick_my_perms(); vector dirs; dirs.push_back(basedir); dirs.push_back(basedir); - client->mkdir(basedir, 0755); + client->mkdir(basedir, 0755, perms); // motivation: // P(dir) ~ subdirs_of(dir) + 2 @@ -2862,7 +2868,7 @@ void SyntheticClient::make_dir_mess(const char *basedir, int n) dirs.push_back(dir); // do it - client->mkdir(dir.c_str(), 0755); + client->mkdir(dir.c_str(), 0755, perms); } @@ -2877,8 +2883,8 @@ void SyntheticClient::foo() if (1) { // make 2 parallel dirs, link/unlink between them. char a[100], b[100]; - client->mkdir("/a", 0755); - client->mkdir("/b", 0755); + client->mkdir("/a", 0755, perms); + client->mkdir("/b", 0755, perms); for (int i=0; i<10; i++) { snprintf(a, sizeof(a), "/a/%d", i); client->mknod(a, 0644); @@ -3007,7 +3013,7 @@ void SyntheticClient::foo() client->mknod("one", 0755); client->mknod("two", 0755); client->link("one", "three", perms); - client->mkdir("dir", 0755); + client->mkdir("dir", 0755, perms); client->link("two", "/dir/twolink", perms); client->link("dir/twolink", "four", perms); @@ -3017,7 +3023,7 @@ void SyntheticClient::foo() client->mknod("b", 0644); client->link("b", "c", perms); client->unlink("c", perms); - client->mkdir("d", 0755); + client->mkdir("d", 0755, perms); client->unlink("d", perms); client->rmdir("d"); @@ -3029,8 +3035,8 @@ void SyntheticClient::foo() client->rename("p3","p4", perms); // check dest dir ambiguity thing - client->mkdir("dir1", 0755); - client->mkdir("dir2", 0755); + client->mkdir("dir1", 0755, perms); + client->mkdir("dir2", 0755, perms); client->rename("p2", "dir1/p2", perms); client->rename("dir1/p2", "dir2/p2", perms); client->rename("dir2/p2", "/p2", perms); @@ -3052,10 +3058,10 @@ void SyntheticClient::foo() client->rename("da2", "da3", perms); // check directory renames - client->mkdir("dir3", 0755); + client->mkdir("dir3", 0755, perms); client->mknod("dir3/asdf", 0644); - client->mkdir("dir4", 0755); - client->mkdir("dir5", 0755); + client->mkdir("dir4", 0755, perms); + client->mkdir("dir5", 0755, perms); client->mknod("dir5/asdf", 0644); client->rename("dir3", "dir4", perms); // ok client->rename("dir4", "dir5", perms); // fail @@ -3205,7 +3211,7 @@ void SyntheticClient::import_find(const char *base, const char *find, bool data) */ if (base[0] != '-') - client->mkdir(base, 0755); + client->mkdir(base, 0755, client->pick_my_perms()); ifstream f(find); assert(f.is_open()); @@ -3231,6 +3237,7 @@ void SyntheticClient::import_find(const char *base, const char *find, bool data) f >> mtime; f.seekg(1, ios::cur); getline(f, filename); + UserPerm perms(uid, gid); // ignore "." if (filename == ".") continue; @@ -3298,7 +3305,7 @@ void SyntheticClient::import_find(const char *base, const char *find, bool data) } f += filename; if (S_ISDIR(mode)) { - client->mkdir(f.c_str(), mode); + client->mkdir(f.c_str(), mode, perms); } else { int fd = client->open(f.c_str(), O_WRONLY|O_CREAT, mode & 0777); assert(fd > 0); @@ -3402,9 +3409,9 @@ int SyntheticClient::chunk_file(string &filename) -void SyntheticClient::mksnap(const char *base, const char *name) +void SyntheticClient::mksnap(const char *base, const char *name, const UserPerm& perms) { - client->mksnap(base, name); + client->mksnap(base, name, perms); } void SyntheticClient::rmsnap(const char *base, const char *name) @@ -3414,7 +3421,8 @@ void SyntheticClient::rmsnap(const char *base, const char *name) void SyntheticClient::mksnapfile(const char *dir) { - client->mkdir(dir, 0755); + UserPerm perms = client->pick_my_perms(); + client->mkdir(dir, 0755, perms); string f = dir; f += "/foo"; @@ -3427,7 +3435,7 @@ void SyntheticClient::mksnapfile(const char *dir) string s = dir; s += "/.snap/1"; - client->mkdir(s.c_str(), 0755); + client->mkdir(s.c_str(), 0755, perms); fd = client->open(f.c_str(), O_WRONLY); client->write(fd, buf, 1048576*2, 1048576); diff --git a/src/client/SyntheticClient.h b/src/client/SyntheticClient.h index e0687b403f49..83d70fb144f2 100644 --- a/src/client/SyntheticClient.h +++ b/src/client/SyntheticClient.h @@ -270,7 +270,7 @@ class SyntheticClient { int chunk_file(string &filename); - void mksnap(const char *base, const char *name); + void mksnap(const char *base, const char *name, const UserPerm& perms); void rmsnap(const char *base, const char *name); void mksnapfile(const char *dir); diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index 31783af40008..e08b73a34456 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -334,7 +334,7 @@ static void fuse_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name, struct fuse_entry_param fe; memset(&fe, 0, sizeof(fe)); - + UserPerm perm(ctx->uid, ctx->gid); #ifdef HAVE_SYS_SYNCFS if (cfuse->fino_snap(parent) == CEPH_SNAPDIR && cfuse->client->cct->_conf->fuse_multithreaded && @@ -357,8 +357,7 @@ static void fuse_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name, #endif i1 = cfuse->iget(parent); - int r = cfuse->client->ll_mkdir(i1, name, mode, &fe.attr, &i2, ctx->uid, - ctx->gid); + int r = cfuse->client->ll_mkdir(i1, name, mode, &fe.attr, &i2, perm); if (r == 0) { fe.ino = cfuse->make_fake_ino(fe.attr.st_ino, fe.attr.st_dev); fe.attr.st_rdev = new_encode_dev(fe.attr.st_rdev); diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 9e728543240b..dd50890e2e72 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -571,7 +571,8 @@ extern "C" int ceph_mkdir(struct ceph_mount_info *cmount, const char *path, mode { if (!cmount->is_mounted()) return -ENOTCONN; - return cmount->get_client()->mkdir(path, mode); + UserPerm perms = cmount->get_client()->pick_my_perms(); + return cmount->get_client()->mkdir(path, mode, perms); } extern "C" int ceph_mkdirs(struct ceph_mount_info *cmount, const char *path, mode_t mode) @@ -1533,8 +1534,8 @@ extern "C" int ceph_ll_mkdir(class ceph_mount_info *cmount, mode_t mode, struct stat *attr, Inode **out, int uid, int gid) { - return (cmount->get_client()->ll_mkdir(parent, name, mode, attr, out, uid, - gid)); + UserPerm perms(uid, gid); + return (cmount->get_client()->ll_mkdir(parent, name, mode, attr, out, perms)); } extern "C" int ceph_ll_link(class ceph_mount_info *cmount,