From 588af9c0b283c20ce1d02604b47dc3251bebd3e6 Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Fri, 23 Dec 2011 18:01:49 +0400 Subject: [PATCH] Make lookup/readdir operations lockless --- fs/pohmelfs/dir.c | 101 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 49 deletions(-) diff --git a/fs/pohmelfs/dir.c b/fs/pohmelfs/dir.c index 1e80a4e9b38..a7aa093f0a7 100644 --- a/fs/pohmelfs/dir.c +++ b/fs/pohmelfs/dir.c @@ -87,6 +87,54 @@ static void pohmelfs_send_inode_info_destroy(struct pohmelfs_trans *t) pohmelfs_wait_put(wait); } +static int pohmelfs_lookup_complete(struct pohmelfs_trans *t, struct pohmelfs_state *recv) +{ + struct pohmelfs_inode *parent = pohmelfs_inode(t->inode); + struct pohmelfs_wait *wait = t->priv; + struct dnet_cmd *cmd = &recv->cmd; + unsigned long long trans = cmd->trans & ~DNET_TRANS_REPLY; + int err = cmd->status; + + if (err) + goto err_out_exit; + + if (cmd->flags & DNET_FLAGS_MORE) { + struct pohmelfs_inode_info *info; + struct pohmelfs_inode *pi; + + if (cmd->size != sizeof(struct dnet_attr) + sizeof(struct pohmelfs_inode_info)) { + err = -ENOENT; + goto err_out_exit; + } + + pr_debug("pohmelfs: %s: pohmelfs_lookup_complete: %llu, size: %llu, min size: %zu, flags: %x, status: %d\n", + pohmelfs_dump_id(parent->id.id), trans, cmd->size, + sizeof(struct dnet_attr) + sizeof(struct pohmelfs_inode_info), cmd->flags, cmd->status); + + + info = t->recv_data + sizeof(struct dnet_attr); + pohmelfs_convert_inode_info(info); + + pi = pohmelfs_existing_inode(pohmelfs_sb(t->inode->i_sb), info); + if (IS_ERR(pi)) { + err = PTR_ERR(pi); + goto err_out_exit; + } + + pi->parent_id = parent->id; + pi->received = 1; + wait->ret = pi; + } + +err_out_exit: + if (err) + wait->condition = err; + else + wait->condition = 1; + + return 0; +} + static int pohmelfs_send_script_request(struct pohmelfs_inode *parent, struct pohmelfs_script_req *req) { struct pohmelfs_sb *psb = pohmelfs_sb(parent->vfs_inode.i_sb); @@ -135,6 +183,9 @@ static int pohmelfs_send_script_request(struct pohmelfs_inode *parent, struct po pio->id = req->id; pio->group_id = req->group_id; pio->cflags = DNET_FLAGS_NEED_ACK; + if (req->complete == pohmelfs_lookup_complete) + pio->cflags |= DNET_FLAGS_NOLOCK; + pio->cmd = DNET_CMD_EXEC; pio->size = sizeof(struct dnet_exec) + req->script_namelen + script_len + req->binary_size; pio->data = e; @@ -620,7 +671,7 @@ static int pohmelfs_warm_dir_group(struct inode *dir, int group_id) io->pi = parent; io->id = &parent->id; - io->cflags = DNET_FLAGS_NEED_ACK; + io->cflags = DNET_FLAGS_NEED_ACK | DNET_FLAGS_NOLOCK; io->cmd = DNET_CMD_READ; io->cb.recv_reply = pohmelfs_readdir_recv_reply; io->cb.complete = pohmelfs_readdir_complete; @@ -675,54 +726,6 @@ static int pohmelfs_warm_dir(struct inode *dir) return err; } -static int pohmelfs_lookup_complete(struct pohmelfs_trans *t, struct pohmelfs_state *recv) -{ - struct pohmelfs_inode *parent = pohmelfs_inode(t->inode); - struct pohmelfs_wait *wait = t->priv; - struct dnet_cmd *cmd = &recv->cmd; - unsigned long long trans = cmd->trans & ~DNET_TRANS_REPLY; - int err = cmd->status; - - if (err) - goto err_out_exit; - - if (cmd->flags & DNET_FLAGS_MORE) { - struct pohmelfs_inode_info *info; - struct pohmelfs_inode *pi; - - if (cmd->size != sizeof(struct dnet_attr) + sizeof(struct pohmelfs_inode_info)) { - err = -ENOENT; - goto err_out_exit; - } - - pr_debug("pohmelfs: %s: pohmelfs_lookup_complete: %llu, size: %llu, min size: %zu, flags: %x, status: %d\n", - pohmelfs_dump_id(parent->id.id), trans, cmd->size, - sizeof(struct dnet_attr) + sizeof(struct pohmelfs_inode_info), cmd->flags, cmd->status); - - - info = t->recv_data + sizeof(struct dnet_attr); - pohmelfs_convert_inode_info(info); - - pi = pohmelfs_existing_inode(pohmelfs_sb(t->inode->i_sb), info); - if (IS_ERR(pi)) { - err = PTR_ERR(pi); - goto err_out_exit; - } - - pi->parent_id = parent->id; - pi->received = 1; - wait->ret = pi; - } - -err_out_exit: - if (err) - wait->condition = err; - else - wait->condition = 1; - - return 0; -} - static struct pohmelfs_inode *pohmelfs_lookup_group(struct inode *dir, struct dentry *dentry, int group_id) { struct pohmelfs_inode *parent = pohmelfs_inode(dir); -- 2.11.4.GIT