diff options
| author | Raghavendra G <raghavendra@gluster.com> | 2009-11-25 13:52:56 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2009-11-26 09:26:53 -0800 | 
| commit | 71eae4bd2f5384bd79c4e0bb6ac679841a8dc042 (patch) | |
| tree | cdffc314dabe223fb0179ed807e78d4694e102fe | |
| parent | fc9a8a76001b5d304d4589eb28ee903972dffcbb (diff) | |
performance/stat-prefetch: don't free the cache in readdir if the offset is not the expected one.
- cache creation is expensive operation. Also, cache will be freed in
    releasedir. Hence, just remove all entries from cache without freeing
    the cache. However this is not entirely true, since sp_cache_remove_entry
    frees the old table and reinitializes a new table if all entries are being
    removed. When rbtree based hash table provides an interface to remove all
    the entries, sp_cache_remove_entry should be modified not to destroy the
    table.
  - this patch also fixes a race condition wherein the cache being used in
    lookup getting freed in readdir if the offset is not equal to expected
    offset.
Signed-off-by: Raghavendra G <raghavendra@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 405 (Segmentation fault in stat-prefetch.)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=405
| -rw-r--r-- | xlators/performance/stat-prefetch/src/stat-prefetch.c | 7 | 
1 files changed, 2 insertions, 5 deletions
diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.c b/xlators/performance/stat-prefetch/src/stat-prefetch.c index 2261b8948fb..75a74b53112 100644 --- a/xlators/performance/stat-prefetch/src/stat-prefetch.c +++ b/xlators/performance/stat-prefetch/src/stat-prefetch.c @@ -917,10 +917,7 @@ sp_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,          cache = sp_get_cache_fd (this, fd);          if (cache) {                  if (off != cache->expected_offset) { -                        cache = sp_del_cache_fd (this, fd); -                        if (cache) { -                                sp_cache_free (cache); -                        } +                        sp_cache_remove_entry (cache, NULL, 1);                  }          } @@ -928,7 +925,7 @@ sp_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,          if (ret == -1) {                  goto unwind;          } -   +          ret = sp_cache_remove_parent_entry (frame, this, path);          if (ret < 0) {                  errno = -ret;  | 
