diff options
author | Raghavendra G <raghavendra@gluster.com> | 2011-04-24 22:52:46 +0000 |
---|---|---|
committer | Anand Avati <avati@gluster.com> | 2011-05-31 21:54:09 -0700 |
commit | 38b5f930f05b4291af0609f3babc7f48d7a29f22 (patch) | |
tree | 2ad5664dbd67e3e69e51a4103608765634b8beb4 | |
parent | 7cc8a41744eae66765ce475b0374d2d77920a98b (diff) |
performance/write-behind: initialize lock in wb-file before wb-file is set in fd-ctx.
- Consider a combination of fuse->quick-read->read-ahead->wb->client.
quick-read can do open-behind (open is returned as success even
before it is issued to backend) and hence the fd can already be
in the list of open fds of the inode. A flush call on some other
fd opened on the same inode, will result in ra_flush issuing flush
calls to all the fds opened on the same inode. This can result in
wb_flush trying to hold a lock on non-initialized lock there by causing
memory corruption.
Signed-off-by: Raghavendra G <raghavendra@gluster.com>
Signed-off-by: Anand Avati <avati@gluster.com>
BUG: 2679 (Crash in GlusterFS 3.0.5 in GSP)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2679
-rw-r--r-- | xlators/performance/write-behind/src/write-behind.c | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c index 43956a920..952de57b7 100644 --- a/xlators/performance/write-behind/src/write-behind.c +++ b/xlators/performance/write-behind/src/write-behind.c @@ -297,7 +297,7 @@ wb_file_t * wb_file_create (xlator_t *this, fd_t *fd, int32_t flags) { wb_file_t *file = NULL; - wb_conf_t *conf = this->private; + wb_conf_t *conf = this->private; file = GF_CALLOC (1, sizeof (*file), gf_wb_mt_wb_file_t); if (file == NULL) { @@ -307,7 +307,7 @@ wb_file_create (xlator_t *this, fd_t *fd, int32_t flags) INIT_LIST_HEAD (&file->request); INIT_LIST_HEAD (&file->passive_requests); - /* + /* fd_ref() not required, file should never decide the existance of an fd */ @@ -318,6 +318,8 @@ wb_file_create (xlator_t *this, fd_t *fd, int32_t flags) file->window_conf = conf->window_size; file->flags = flags; + LOCK_INIT (&file->lock); + fd_ctx_set (fd, this, (uint64_t)(long)file); out: @@ -1325,21 +1327,23 @@ wb_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, goto out; } - /* If O_DIRECT then, we disable chaching */ - if (((flags & O_DIRECT) == O_DIRECT) - || ((flags & O_ACCMODE) == O_RDONLY) - || (((flags & O_SYNC) == O_SYNC) - && conf->enable_O_SYNC == _gf_true)) { - file->window_conf = 0; - } + LOCK (&file->lock); + { + /* If O_DIRECT then, we disable chaching */ + if (((flags & O_DIRECT) == O_DIRECT) + || ((flags & O_ACCMODE) == O_RDONLY) + || (((flags & O_SYNC) == O_SYNC) + && conf->enable_O_SYNC == _gf_true)) { + file->window_conf = 0; + } - if (wbflags & GF_OPEN_NOWB) { - file->disabled = 1; + if (wbflags & GF_OPEN_NOWB) { + file->disabled = 1; + } } - - LOCK_INIT (&file->lock); + UNLOCK (&file->lock); } - + out: STACK_UNWIND_STRICT (open, frame, op_ret, op_errno, fd); return 0; @@ -1400,22 +1404,24 @@ wb_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, goto out; } - /* If O_DIRECT then, we disable chaching */ - if (frame->local) { - if (((flags & O_DIRECT) == O_DIRECT) - || ((flags & O_ACCMODE) == O_RDONLY) - || (((flags & O_SYNC) == O_SYNC) - && (conf->enable_O_SYNC == _gf_true))) { - file->window_conf = 0; + LOCK (&file->lock); + { + /* If O_DIRECT then, we disable chaching */ + if (frame->local) { + if (((flags & O_DIRECT) == O_DIRECT) + || ((flags & O_ACCMODE) == O_RDONLY) + || (((flags & O_SYNC) == O_SYNC) + && (conf->enable_O_SYNC == _gf_true))) { + file->window_conf = 0; + } } } - - LOCK_INIT (&file->lock); + UNLOCK (&file->lock); } - + frame->local = NULL; -out: +out: STACK_UNWIND_STRICT (create, frame, op_ret, op_errno, fd, inode, buf, preparent, postparent); return 0; |