Skip to content

Commit

Permalink
client: use thread local data to track fuse request
Browse files Browse the repository at this point in the history
When handling an operation, libcephfs code may want to access fuse
request for extra information. by tracking fuse request in thread
local data, we can avoid adding extra parameter to Client::ll_foo
functions.

Signed-off-by: Yan, Zheng <zyan@redhat.com>
  • Loading branch information
ukernel committed Jan 12, 2016
1 parent cc9f739 commit a9f91d7
Showing 1 changed file with 66 additions and 36 deletions.
102 changes: 66 additions & 36 deletions src/client/fuse_ll.cc
Expand Up @@ -92,12 +92,23 @@ class CephFuse::Handle {
ceph::unordered_map<uint64_t,int> snap_stag_map;
ceph::unordered_map<int,uint64_t> stag_snap_map;

pthread_key_t fuse_req_key;
void set_fuse_req(fuse_req_t);
fuse_req_t get_fuse_req();

struct fuse_args args;
};

static void fuse_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
static CephFuse::Handle *fuse_ll_req_prepare(fuse_req_t req)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
cfuse->set_fuse_req(req);
return cfuse;
}

static void fuse_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
{
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
struct fuse_entry_param fe;
Inode *i2, *i1 = cfuse->iget(parent); // see below
Expand All @@ -121,15 +132,15 @@ static void fuse_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
static void fuse_ll_forget(fuse_req_t req, fuse_ino_t ino,
long unsigned nlookup)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
cfuse->client->ll_forget(cfuse->iget(ino), nlookup+1);
fuse_reply_none(req);
}

static void fuse_ll_getattr(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
struct stat stbuf;
Expand All @@ -150,7 +161,7 @@ static void fuse_ll_getattr(fuse_req_t req, fuse_ino_t ino,
static void fuse_ll_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set, struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);

Expand Down Expand Up @@ -181,7 +192,7 @@ static void fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
#endif
)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);

Expand All @@ -194,7 +205,7 @@ static void fuse_ll_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,

static void fuse_ll_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
char buf[size];
Expand All @@ -217,7 +228,7 @@ static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
#endif
)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
char buf[size];
Expand All @@ -236,7 +247,7 @@ static void fuse_ll_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
static void fuse_ll_removexattr(fuse_req_t req, fuse_ino_t ino,
const char *name)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);

Expand All @@ -250,13 +261,13 @@ static void fuse_ll_removexattr(fuse_req_t req, fuse_ino_t ino,
static void fuse_ll_opendir(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
void *dirp;

int r = cfuse->client->ll_opendir(in, (dir_result_t **) &dirp, ctx->uid,
ctx->gid);
int r = cfuse->client->ll_opendir(in, (dir_result_t **)&dirp,
ctx->uid, ctx->gid);
if (r >= 0) {
fi->fh = (long)dirp;
fuse_reply_open(req, fi);
Expand All @@ -269,7 +280,7 @@ static void fuse_ll_opendir(fuse_req_t req, fuse_ino_t ino,

static void fuse_ll_readlink(fuse_req_t req, fuse_ino_t ino)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
char buf[PATH_MAX + 1]; // leave room for a null terminator
Expand All @@ -288,7 +299,7 @@ static void fuse_ll_readlink(fuse_req_t req, fuse_ino_t ino)
static void fuse_ll_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode, dev_t rdev)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *i2, *i1 = cfuse->iget(parent);
struct fuse_entry_param fe;
Expand All @@ -313,7 +324,7 @@ static void fuse_ll_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
static void fuse_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *i2, *i1 = cfuse->iget(parent);
struct fuse_entry_param fe;
Expand All @@ -337,7 +348,7 @@ static void fuse_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,

static void fuse_ll_unlink(fuse_req_t req, fuse_ino_t parent, const char *name)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(parent);

Expand All @@ -349,7 +360,7 @@ static void fuse_ll_unlink(fuse_req_t req, fuse_ino_t parent, const char *name)

static void fuse_ll_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(parent);

Expand All @@ -362,7 +373,7 @@ static void fuse_ll_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
static void fuse_ll_symlink(fuse_req_t req, const char *existing,
fuse_ino_t parent, const char *name)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *i2, *i1 = cfuse->iget(parent);
struct fuse_entry_param fe;
Expand All @@ -387,7 +398,7 @@ static void fuse_ll_symlink(fuse_req_t req, const char *existing,
static void fuse_ll_rename(fuse_req_t req, fuse_ino_t parent, const char *name,
fuse_ino_t newparent, const char *newname)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(parent);
Inode *nin = cfuse->iget(newparent);
Expand All @@ -402,7 +413,7 @@ static void fuse_ll_rename(fuse_req_t req, fuse_ino_t parent, const char *name,
static void fuse_ll_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
const char *newname)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
Inode *nin = cfuse->iget(newparent);
Expand All @@ -427,7 +438,7 @@ static void fuse_ll_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
static void fuse_ll_open(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *in = cfuse->iget(ino);
Fh *fh = NULL;
Expand All @@ -450,7 +461,7 @@ static void fuse_ll_open(fuse_req_t req, fuse_ino_t ino,
static void fuse_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Fh *fh = reinterpret_cast<Fh*>(fi->fh);
bufferlist bl;
int r = cfuse->client->ll_read(fh, off, size, &bl);
Expand All @@ -463,7 +474,7 @@ static void fuse_ll_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
static void fuse_ll_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
size_t size, off_t off, struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Fh *fh = reinterpret_cast<Fh*>(fi->fh);
int r = cfuse->client->ll_write(fh, off, size, buf);
if (r >= 0)
Expand All @@ -475,7 +486,7 @@ static void fuse_ll_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
static void fuse_ll_flush(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Fh *fh = reinterpret_cast<Fh*>(fi->fh);
int r = cfuse->client->ll_flush(fh);
fuse_reply_err(req, -r);
Expand All @@ -485,7 +496,7 @@ static void fuse_ll_flush(fuse_req_t req, fuse_ino_t ino,
static void fuse_ll_ioctl(fuse_req_t req, fuse_ino_t ino, int cmd, void *arg, struct fuse_file_info *fi,
unsigned flags, const void *in_buf, size_t in_bufsz, size_t out_bufsz)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);

if (flags & FUSE_IOCTL_COMPAT) {
fuse_reply_err(req, ENOSYS);
Expand Down Expand Up @@ -517,7 +528,7 @@ static void fuse_ll_fallocate(fuse_req_t req, fuse_ino_t ino, int mode,
off_t offset, off_t length,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Fh *fh = (Fh*)fi->fh;
int r = cfuse->client->ll_fallocate(fh, mode, offset, length);
fuse_reply_err(req, -r);
Expand All @@ -528,7 +539,7 @@ static void fuse_ll_fallocate(fuse_req_t req, fuse_ino_t ino, int mode,
static void fuse_ll_release(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Fh *fh = reinterpret_cast<Fh*>(fi->fh);
int r = cfuse->client->ll_release(fh);
fuse_reply_err(req, -r);
Expand All @@ -537,7 +548,7 @@ static void fuse_ll_release(fuse_req_t req, fuse_ino_t ino,
static void fuse_ll_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Fh *fh = reinterpret_cast<Fh*>(fi->fh);
int r = cfuse->client->ll_fsync(fh, datasync);
fuse_reply_err(req, -r);
Expand Down Expand Up @@ -578,7 +589,7 @@ static int fuse_ll_add_dirent(void *p, struct dirent *de, struct stat *st,
static void fuse_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
off_t off, struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);

dir_result_t *dirp = reinterpret_cast<dir_result_t*>(fi->fh);
cfuse->client->seekdir(dirp, off);
Expand All @@ -601,7 +612,7 @@ static void fuse_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
static void fuse_ll_releasedir(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
dir_result_t *dirp = reinterpret_cast<dir_result_t*>(fi->fh);
cfuse->client->ll_releasedir(dirp);
fuse_reply_err(req, 0);
Expand All @@ -610,7 +621,7 @@ static void fuse_ll_releasedir(fuse_req_t req, fuse_ino_t ino,
static void fuse_ll_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
dir_result_t *dirp = reinterpret_cast<dir_result_t*>(fi->fh);
int r = cfuse->client->ll_fsyncdir(dirp);
fuse_reply_err(req, -r);
Expand All @@ -624,7 +635,7 @@ static void fuse_ll_access(fuse_req_t req, fuse_ino_t ino, int mask)
static void fuse_ll_create(fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode, struct fuse_file_info *fi)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
const struct fuse_ctx *ctx = fuse_req_ctx(req);
Inode *i1 = cfuse->iget(parent), *i2;
struct fuse_entry_param fe;
Expand All @@ -649,7 +660,7 @@ static void fuse_ll_create(fuse_req_t req, fuse_ino_t parent, const char *name,
static void fuse_ll_statfs(fuse_req_t req, fuse_ino_t ino)
{
struct statvfs stbuf;
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Inode *in = cfuse->iget(ino);

int r = cfuse->client->ll_statfs(in, &stbuf);
Expand All @@ -664,7 +675,7 @@ static void fuse_ll_statfs(fuse_req_t req, fuse_ino_t ino)
static void fuse_ll_getlk(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi, struct flock *lock)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Fh *fh = reinterpret_cast<Fh*>(fi->fh);

int r = cfuse->client->ll_getlk(fh, lock, fi->lock_owner);
Expand All @@ -677,7 +688,7 @@ static void fuse_ll_getlk(fuse_req_t req, fuse_ino_t ino,
static void fuse_ll_setlk(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi, struct flock *lock, int sleep)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Fh *fh = reinterpret_cast<Fh*>(fi->fh);

// must use multithread if operation may block
Expand All @@ -693,7 +704,7 @@ static void fuse_ll_setlk(fuse_req_t req, fuse_ino_t ino,

static void fuse_ll_interrupt(fuse_req_t req, void* data)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
cfuse->client->ll_interrupt(data);
}

Expand All @@ -709,7 +720,7 @@ static void switch_interrupt_cb(void *req, void* data)
static void fuse_ll_flock(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi, int cmd)
{
CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
Fh *fh = (Fh*)fi->fh;

// must use multithread if operation may block
Expand Down Expand Up @@ -898,10 +909,18 @@ void CephFuse::Handle::finalize()
if (ch)
fuse_unmount(mountpoint, ch);

pthread_key_delete(fuse_req_key);
}

int CephFuse::Handle::init(int argc, const char *argv[])
{

int r = pthread_key_create(&fuse_req_key, NULL);
if (r) {
derr << "pthread_key_create failed." << dendl;
return r;
}

// set up fuse argc/argv
int newargc = 0;
const char **newargv = (const char **) malloc((argc + 10) * sizeof(char *));
Expand Down Expand Up @@ -1059,6 +1078,17 @@ uint64_t CephFuse::Handle::make_fake_ino(inodeno_t ino, snapid_t snapid)
}
}

void CephFuse::Handle::set_fuse_req(fuse_req_t req)
{
pthread_setspecific(fuse_req_key, (void*)req);
}

fuse_req_t CephFuse::Handle::get_fuse_req()
{
return (fuse_req_t) pthread_getspecific(fuse_req_key);
}


CephFuse::CephFuse(Client *c, int fd) : _handle(new CephFuse::Handle(c, fd))
{
}
Expand Down

0 comments on commit a9f91d7

Please sign in to comment.