// namespace ops
-int Client::link(const char *relexisting, const char *relpath)
+int Client::link(const char *relexisting, const char *relpath, const UserPerm& perm)
{
Mutex::Locker lock(client_lock);
tout(cct) << "link" << std::endl;
path.pop_dentry();
InodeRef in, dir;
- int r = path_walk(existing, &in);
+ int r = path_walk(existing, &in, perm, true);
if (r < 0)
goto out;
- r = path_walk(path, &dir);
+ r = path_walk(path, &dir, perm, true);
if (r < 0)
goto out;
if (cct->_conf->client_permissions) {
r = -EPERM;
goto out;
}
- r = may_hardlink(in.get());
+ r = may_hardlink(in.get(), perm);
if (r < 0)
goto out;
- r = may_create(dir.get());
+ r = may_create(dir.get(), perm);
if (r < 0)
goto out;
}
- r = _link(in.get(), dir.get(), name.c_str());
+ r = _link(in.get(), dir.get(), name.c_str(), perm);
out:
return r;
}
return _rename(parent, name, newparent, newname, uid, gid);
}
-int Client::_link(Inode *in, Inode *dir, const char *newname, int uid, int gid, InodeRef *inp)
+int Client::_link(Inode *in, Inode *dir, const char *newname, const UserPerm& perm, InodeRef *inp)
{
ldout(cct, 3) << "_link(" << in->ino << " to " << dir->ino << " " << newname
- << " uid " << uid << " gid " << gid << ")" << dendl;
+ << " uid " << perm.uid() << " gid " << perm.gid() << ")" << dendl;
if (strlen(newname) > NAME_MAX)
return -ENAMETOOLONG;
goto fail;
req->set_dentry(de);
- res = make_request(req, uid, gid, inp);
+ res = make_request(req, perm.uid(), perm.gid(), inp);
ldout(cct, 10) << "link result is " << res << dendl;
trim_cache();
}
int Client::ll_link(Inode *in, Inode *newparent, const char *newname,
- struct stat *attr, int uid, int gid)
+ struct stat *attr, const UserPerm& perm)
{
Mutex::Locker lock(client_lock);
r = -EPERM;
goto out;
}
- r = may_hardlink(in, uid, gid);
+ r = may_hardlink(in, perm);
if (r < 0)
goto out;
- r = may_create(newparent, uid, gid);
+ r = may_create(newparent, perm);
if (r < 0)
goto out;
}
- r = _link(in, newparent, newname, uid, gid, &target);
+ r = _link(in, newparent, newname, perm, &target);
if (r == 0) {
assert(target);
fill_stat(target, attr);
int _do_lookup(Inode *dir, const string& name, int mask, InodeRef *target, int uid, int gid);
int _lookup(Inode *dir, const string& dname, int mask, InodeRef *target, int uid, int gid);
- int _link(Inode *in, Inode *dir, const char *name, int uid=-1, int gid=-1, InodeRef *inp = 0);
+ int _link(Inode *in, Inode *dir, const char *name, const UserPerm& perm,
+ InodeRef *inp = 0);
int _unlink(Inode *dir, const char *name, int uid=-1, int gid=-1);
int _rename(Inode *olddir, const char *oname, Inode *ndir, const char *nname, int uid=-1, int gid=-1);
int _mkdir(Inode *dir, const char *name, mode_t mode, int uid=-1, int gid=-1, InodeRef *inp = 0);
loff_t telldir(dir_result_t *dirp);
void seekdir(dir_result_t *dirp, loff_t offset);
- int link(const char *existing, const char *newname);
+ int link(const char *existing, const char *newname, const UserPerm& perm);
int unlink(const char *path);
int rename(const char *from, const char *to);
int ll_rename(Inode *parent, const char *name, Inode *newparent,
const char *newname, int uid = -1, int gid = -1);
int ll_link(Inode *in, Inode *newparent, const char *newname,
- struct stat *attr, int uid = -1, int gid = -1);
+ struct stat *attr, const UserPerm& perm);
int ll_open(Inode *in, int flags, Fh **fh, int uid = -1, int gid = -1);
int ll_create(Inode *parent, const char *name, mode_t mode, int flags,
struct stat *attr, Inode **out, Fh **fhp, int uid = -1,
if (strcmp(op, "link") == 0) {
const char *a = t.get_string(buf, p);
const char *b = t.get_string(buf2, p);
- client->link(a,b);
+ client->link(a, b, perms);
} else if (strcmp(op, "unlink") == 0) {
const char *a = t.get_string(buf, p);
client->unlink(a);
ll_inos.count(ni)) {
i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP));
i2 = client->ll_get_inode(vinodeno_t(ll_inos[ni],CEPH_NOSNAP));
- client->ll_link(i1, i2, nn, &attr);
+ client->ll_link(i1, i2, nn, &attr, perms);
client->ll_put(i1);
client->ll_put(i2);
}
char d[255];
char e[255];
+ UserPerm perms = client->pick_my_perms();
+
// create files
int num = 200;
for (int i=0; i<num; i++) {
snprintf(d, sizeof(d), "orig/file.%d", i);
snprintf(e, sizeof(e), "copy/file.%d", i);
- client->link(d, e);
+ client->link(d, e, perms);
}
end = ceph_clock_now(client->cct);
end -= start;
void SyntheticClient::foo()
{
+ UserPerm perms = client->pick_my_perms();
+
if (1) {
// make 2 parallel dirs, link/unlink between them.
char a[100], b[100];
for (int i=0; i<10; i++) {
snprintf(a, sizeof(a), "/a/%d", i);
snprintf(b, sizeof(b), "/b/%d", i);
- client->link(a, b);
+ client->link(a, b, perms);
}
for (int i=0; i<10; i++) {
snprintf(b, sizeof(b), "/b/%d", i);
char dst[80];
snprintf(src, sizeof(src), "syn.0.0/dir.%d/dir.%d/file.%d", a, b, c);
snprintf(dst, sizeof(dst), "syn.0.0/dir.%d/dir.%d/newlink.%d", d, e, f);
- client->link(src, dst);
+ client->link(src, dst, perms);
}
srand(0);
for (int i=0; i<100; i++) {
// link fun
client->mknod("one", 0755);
client->mknod("two", 0755);
- client->link("one", "three");
+ client->link("one", "three", perms);
client->mkdir("dir", 0755);
- client->link("two", "/dir/twolink");
- client->link("dir/twolink", "four");
+ client->link("two", "/dir/twolink", perms);
+ client->link("dir/twolink", "four", perms);
// unlink fun
client->mknod("a", 0644);
client->unlink("a");
client->mknod("b", 0644);
- client->link("b", "c");
+ client->link("b", "c", perms);
client->unlink("c");
client->mkdir("d", 0755);
client->unlink("d");
client->rename("dir2/p2","/p2");
// check primary+remote link merging
- client->link("p2","p2.l");
- client->link("p4","p4.l");
+ client->link("p2","p2.l", perms);
+ client->link("p4","p4.l", perms);
client->rename("p2.l","p2");
client->rename("p4","p4.l");
// check anchor updates
client->mknod("dir1/a", 0644);
- client->link("dir1/a", "da1");
- client->link("dir1/a", "da2");
- client->link("da2","da3");
+ client->link("dir1/a", "da1", perms);
+ client->link("dir1/a", "da2", perms);
+ client->link("da2","da3", perms);
client->rename("dir1/a","dir2/a");
client->rename("dir2/a","da2");
client->rename("da1","da2");
if (time_to_stop()) return 0;
+ UserPerm perms = client->pick_my_perms();
+
srand(0);
if (1) {
bool renames = true; // thrash renames too?
case 1:
client->mknod(src.c_str(), 0755);
client->unlink(dst.c_str());
- client->link(src.c_str(), dst.c_str());
+ client->link(src.c_str(), dst.c_str(), perms);
break;
case 2: client->unlink(src.c_str()); break;
case 3: client->unlink(dst.c_str()); break;
snprintf(f, sizeof(f), "/ln.%d", i);
ln += f;
- client->link(file.c_str(), ln.c_str());
+ client->link(file.c_str(), ln.c_str(), perms);
}
}
return 0;
struct fuse_entry_param fe;
memset(&fe, 0, sizeof(fe));
+ UserPerm perm(ctx->uid, ctx->gid);
- int r = cfuse->client->ll_link(in, nin, newname, &fe.attr, ctx->uid,
- ctx->gid);
+ int r = cfuse->client->ll_link(in, nin, newname, &fe.attr, 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);
{
if (!cmount->is_mounted())
return -ENOTCONN;
- return cmount->get_client()->link(existing, newname);
+ UserPerm perms = cmount->get_client()->pick_my_perms();
+ return cmount->get_client()->link(existing, newname, perms);
}
extern "C" int ceph_unlink(struct ceph_mount_info *cmount, const char *path)
const char *name, struct stat *attr, int uid,
int gid)
{
- return (cmount->get_client()->ll_link(in, newparent, name, attr, uid,
- gid));
+ UserPerm perms(uid, gid);
+ return (cmount->get_client()->ll_link(in, newparent, name, attr, perms));
}
extern "C" int ceph_ll_truncate(class ceph_mount_info *cmount,