return r;
}
+int Client::ll_lookupx(Inode *parent, const char *name, Inode **out,
+ struct ceph_statx *stx, unsigned want, unsigned flags,
+ const UserPerm& perms)
+{
+ Mutex::Locker lock(client_lock);
+ ldout(cct, 3) << "ll_lookupx " << parent << " " << name << dendl;
+ tout(cct) << "ll_lookupx" << std::endl;
+ tout(cct) << name << std::endl;
+
+ int r = 0;
+ if (!cct->_conf->fuse_default_permissions) {
+ r = may_lookup(parent, perms);
+ if (r < 0)
+ return r;
+ }
+
+ string dname(name);
+ InodeRef in;
+
+ unsigned mask = statx_to_mask(flags, want);
+ r = _lookup(parent, dname, mask, &in, perms);
+ if (r < 0) {
+ stx->stx_ino = 0;
+ stx->stx_mask = 0;
+ } else {
+ assert(in);
+ fill_statx(in, mask, stx);
+ _ll_get(in.get());
+ }
+
+ ldout(cct, 3) << "ll_lookupx " << parent << " " << name
+ << " -> " << r << " (" << hex << stx->stx_ino << dec << ")" << dendl;
+ tout(cct) << stx->stx_ino << std::endl;
+ *out = in.get();
+ return r;
+}
+
int Client::ll_walk(const char* name, Inode **out, struct stat *attr,
const UserPerm& perms)
{
Inode *ll_get_inode(vinodeno_t vino);
int ll_lookup(Inode *parent, const char *name, struct stat *attr,
Inode **out, const UserPerm& perms);
+ int ll_lookupx(Inode *parent, const char *name, Inode **out,
+ struct ceph_statx *stx, unsigned want, unsigned flags,
+ const UserPerm& perms);
bool ll_forget(Inode *in, int count);
bool ll_put(Inode *in);
int ll_getattr(Inode *in, struct stat *st, const UserPerm& perms);
#include "common/errno.h"
#include "include/assert.h"
+#include "include/cephfs/ceph_statx.h"
#define dout_subsys ceph_subsys_client
#undef dout_prefix
const char *p = prefix.c_str();
if (prefix.length()) {
client->mkdir(prefix.c_str(), 0755, perms);
- struct stat attr;
+ struct ceph_statx stx;
i1 = client->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP));
- if (client->ll_lookup(i1, prefix.c_str(), &attr, &i2, perms) == 0) {
- ll_inos[1] = attr.st_ino;
- dout(5) << "'root' ino is " << inodeno_t(attr.st_ino) << dendl;
+ if (client->ll_lookupx(i1, prefix.c_str(), &i2, &stx, CEPH_STATX_INO, 0, perms) == 0) {
+ ll_inos[1] = stx.stx_ino;
+ dout(5) << "'root' ino is " << inodeno_t(stx.stx_ino) << dendl;
client->ll_put(i1);
} else {
dout(0) << "warning: play_trace couldn't lookup up my per-client directory" << dendl;
int64_t i = t.get_int();
const char *name = t.get_string(buf, p);
int64_t r = t.get_int();
- struct stat attr;
+ struct ceph_statx stx;
if (ll_inos.count(i)) {
i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP));
- if (client->ll_lookup(i1, name, &attr, &i2, perms) == 0)
- ll_inos[r] = attr.st_ino;
+ if (client->ll_lookupx(i1, name, &i2, &stx, CEPH_STATX_INO, 0, perms) == 0)
+ ll_inos[r] = stx.stx_ino;
client->ll_put(i1);
}
} else if (strcmp(op, "ll_forget") == 0) {
*/
int ceph_ll_lookup_root(struct ceph_mount_info *cmount,
Inode **parent);
-int ceph_ll_lookup(struct ceph_mount_info *cmount, struct Inode *parent,
- const char *name, struct stat *attr,
- Inode **out, int uid, int gid);
+int ceph_ll_lookup(struct ceph_mount_info *cmount, Inode *parent,
+ const char *name, Inode **out, struct ceph_statx *stx,
+ unsigned want, unsigned flags, const UserPerm *perms);
int ceph_ll_put(struct ceph_mount_info *cmount, struct Inode *in);
int ceph_ll_forget(struct ceph_mount_info *cmount, struct Inode *in,
int count);
return 0;
}
-extern "C" int ceph_ll_lookup(class ceph_mount_info *cmount,
- struct Inode *parent, const char *name,
- struct stat *attr, Inode **out,
- int uid, int gid)
+extern "C" int ceph_ll_lookup(struct ceph_mount_info *cmount,
+ Inode *parent, const char *name, Inode **out,
+ struct ceph_statx *stx, unsigned want,
+ unsigned flags, const UserPerm *perms)
{
- UserPerm perms(uid, gid);
- return (cmount->get_client())->ll_lookup(parent, name, attr, out, perms);
+ return (cmount->get_client())->ll_lookupx(parent, name, out, stx, want,
+ flags, *perms);
}
extern "C" int ceph_ll_put(class ceph_mount_info *cmount, Inode *in)
Inode *root = NULL;
Inode *existent_file_handle = NULL;
- struct stat attr;
int res = ceph_ll_lookup_root(cmount, &root);
ASSERT_EQ(res, 0);
- res = ceph_ll_lookup(cmount, root, test_xattr_file, &attr, &existent_file_handle, 0, 0);
+
+ UserPerm *perms = ceph_mount_perms(cmount);
+ struct ceph_statx stx;
+
+ res = ceph_ll_lookup(cmount, root, test_xattr_file, &existent_file_handle,
+ &stx, 0, 0, perms);
ASSERT_EQ(res, 0);
const char *valid_name = "user.attrname";
sprintf(linkname, "nlinklink%x", getpid());
struct stat st;
+ struct ceph_statx stx;
Fh *fh;
+ UserPerm *perms = ceph_mount_perms(cmount);
ASSERT_EQ(ceph_ll_mkdir(cmount, root, dirname, 0755, &st, &dir, getuid(), getgid()), 0);
ASSERT_EQ(ceph_ll_create(cmount, dir, filename, 0666, O_RDWR|O_CREAT|O_EXCL,
ASSERT_EQ(st.st_nlink, (nlink_t)2);
ASSERT_EQ(ceph_ll_unlink(cmount, dir, linkname, getuid(), getgid()), 0);
- ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &st, &file, getuid(), getgid()), 0);
+ ASSERT_EQ(ceph_ll_lookup(cmount, dir, filename, &file, &stx,
+ CEPH_STATX_NLINK, 0, perms), 0);
ASSERT_EQ(st.st_nlink, (nlink_t)1);
ceph_shutdown(cmount);
Inode *root1, *file1, *root2, *file2;
struct stat st;
+ struct ceph_statx stx;
Fh *fh;
ASSERT_EQ(ceph_ll_lookup_root(cmount1, &root1), 0);
ASSERT_EQ(ceph_ll_lookup_root(cmount2, &root2), 0);
- ASSERT_EQ(ceph_ll_lookup(cmount2, root2, filename, &st, &file2, getuid(), getgid()), 0);
- struct timespec old_ctime = st.st_ctim;
+ UserPerm *perms = ceph_mount_perms(cmount2);
+ ASSERT_EQ(ceph_ll_lookup(cmount2, root2, filename, &file2, &stx, CEPH_STATX_CTIME, 0, perms), 0);
+
+ struct timespec old_ctime = stx.stx_ctime;
/*
* Now sleep, do a chmod on the first client and the see whether we get a
st.st_mode = 0644;
ASSERT_EQ(ceph_ll_setattr(cmount1, file1, &st, CEPH_SETATTR_MODE, getuid(), getgid()), 0);
- struct ceph_statx stx;
- ASSERT_EQ(ceph_ll_getattr(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, ceph_mount_perms(cmount2)), 0);
+ ASSERT_EQ(ceph_ll_getattr(cmount2, file2, &stx, CEPH_STATX_CTIME, AT_NO_ATTR_SYNC, perms), 0);
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_CTIME);
ASSERT_TRUE(stx.stx_ctime.tv_sec == old_ctime.tv_sec &&
stx.stx_ctime.tv_nsec == old_ctime.tv_nsec);