GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/fuse_evict.h Lines: 3 3 100.0 %
Date: 2019-02-03 02:48:13 Branches: 0 0 - %

Line Branch Exec Source
1
/**
2
 * This file is part of the CernVM File System.
3
 */
4
5
#ifndef CVMFS_FUSE_EVICT_H_
6
#define CVMFS_FUSE_EVICT_H_
7
8
#include <pthread.h>
9
#include <stdint.h>
10
11
#include "atomic.h"
12
#include "bigvector.h"
13
#include "duplex_fuse.h"
14
#include "gtest/gtest_prod.h"
15
#include "shortstring.h"
16
#include "util/single_copy.h"
17
18
namespace glue {
19
class InodeTracker;
20
}
21
22
/**
23
 * This class can poke all known dentries out of the kernel caches.  This allows
24
 * for faster remount/reload of the fuse module because caches don't need to
25
 * drain out by timeout.  If the fuse library doesn't provide
26
 * fuse_lowlevel_notify_inval_entry, it falls back to waiting for drainout.
27
 *
28
 * Evicting entries from the cache must be done from a separate thread to
29
 * avoid a deadlock in the fuse callbacks (see Fuse documenatation).
30
 */
31
class FuseInvalidator : SingleCopy {
32
  FRIEND_TEST(T_FuseInvalidator, StartStop);
33
  FRIEND_TEST(T_FuseInvalidator, InvalidateTimeout);
34
  FRIEND_TEST(T_FuseInvalidator, InvalidateOps);
35
36
 public:
37
  static bool HasFuseNotifyInval();
38
39
  /**
40
   * Used to track the progress of an "invalidation" request.  The invalidator
41
   * will evict cache entries for a duration given by the timeout.  For very
42
   * large caches, active eviction can take longer than the timeout.
43
   *
44
   * The caller needs to keep Handle active until IsDone() is true;
45
   */
46
  class Handle : SingleCopy {
47
    friend class FuseInvalidator;
48
49
   public:
50
    explicit Handle(unsigned timeout_s);
51
    ~Handle();
52
21
    bool IsDone() const { return atomic_read32(status_) == 1; }
53
1
    void Reset() { atomic_write32(status_, 0); }
54
    void WaitFor();
55
56
   private:
57
5
    void SetDone() { atomic_cas32(status_, 0, 1); }
58
59
    unsigned timeout_s_;
60
    atomic_int32 *status_;
61
  };
62
63
  FuseInvalidator(glue::InodeTracker *inode_tracker,
64
                  struct fuse_chan **fuse_channel,
65
                  bool fuse_notify_invalidation);
66
  ~FuseInvalidator();
67
  void Spawn();
68
  void InvalidateInodes(Handle *handle);
69
70
 private:
71
  /**
72
   * Add one second to the caller-provided timeout to be on the safe side.
73
   */
74
  static const unsigned kTimeoutSafetyMarginSec;  // = 1;
75
  /**
76
   * If caches are drained out by timeout, set a polling interval.
77
   */
78
  static const unsigned kCheckTimeoutFreqMs;  // = 100;
79
  /**
80
   * If caches are actively drained out, check every so many operations if the
81
   * caches are anyway drained out by timeout.
82
   */
83
  static const unsigned kCheckTimeoutFreqOps;  // = 256
84
85
  static void *MainInvalidator(void *data);
86
87
  glue::InodeTracker *inode_tracker_;
88
  struct fuse_chan **fuse_channel_;
89
  bool spawned_;
90
  int pipe_ctrl_[2];
91
  pthread_t thread_invalidator_;
92
  /**
93
   * An invalidation run can take some time.  Allow for early cancelation if
94
   * thread should be shut down.
95
   */
96
  atomic_int32 terminated_;
97
  BigVector<uint64_t> evict_list_;
98
99
  static bool g_fuse_notify_invalidation_;
100
};  // class FuseInvalidator
101
102
#endif  // CVMFS_FUSE_EVICT_H_