]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * | |
5 | * Copyright (C) 2012 CohortFS, LLC. | |
6 | * | |
7 | * This is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU Lesser General Public | |
9 | * License version 2.1, as published by the Free Software | |
10 | * Foundation. See file COPYING. | |
11 | * | |
12 | */ | |
13 | ||
14 | #ifndef BARRIER_H | |
15 | #define BARRIER_H | |
16 | ||
17 | #include "include/types.h" | |
18 | #include <boost/intrusive/list.hpp> | |
19 | #define BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS | |
20 | #include <boost/icl/interval_set.hpp> | |
21 | #include "common/Mutex.h" | |
22 | #include "common/Cond.h" | |
23 | ||
24 | class Client; | |
25 | ||
26 | typedef boost::icl::interval<uint64_t>::type barrier_interval; | |
27 | ||
7c673cae FG |
28 | |
29 | /* | |
30 | * we keep count of uncommitted writes on the inode, so that | |
31 | * ll_commit_blocks can do the right thing. | |
32 | * | |
33 | * This is just a hacked copy of Ceph's sync callback. | |
34 | */ | |
35 | ||
36 | enum CBlockSync_State | |
37 | { | |
38 | CBlockSync_State_None, /* initial state */ | |
39 | CBlockSync_State_Unclaimed, /* outstanding write */ | |
40 | CBlockSync_State_Committing, /* commit in progress */ | |
41 | CBlockSync_State_Completed, | |
42 | }; | |
43 | ||
44 | class BarrierContext; | |
45 | ||
46 | class C_Block_Sync; | |
47 | ||
48 | typedef boost::intrusive::list< C_Block_Sync, | |
49 | boost::intrusive::member_hook< | |
50 | C_Block_Sync, | |
51 | boost::intrusive::list_member_hook<>, | |
52 | &C_Block_Sync::intervals_hook > | |
53 | > BlockSyncList; | |
54 | ||
55 | class Barrier | |
56 | { | |
57 | private: | |
58 | Cond cond; | |
59 | boost::icl::interval_set<uint64_t> span; | |
60 | BlockSyncList write_list; | |
61 | ||
62 | public: | |
63 | boost::intrusive::list_member_hook<> active_commits_hook; | |
64 | ||
65 | Barrier(); | |
66 | ~Barrier(); | |
67 | ||
68 | friend class BarrierContext; | |
69 | }; | |
70 | ||
71 | typedef boost::intrusive::list< Barrier, | |
72 | boost::intrusive::member_hook< | |
73 | Barrier, | |
74 | boost::intrusive::list_member_hook<>, | |
75 | &Barrier::active_commits_hook > | |
76 | > BarrierList; | |
77 | ||
78 | class BarrierContext | |
79 | { | |
80 | private: | |
81 | Client *cl; | |
82 | uint64_t ino; | |
83 | Mutex lock; | |
84 | ||
85 | // writes not claimed by a commit | |
86 | BlockSyncList outstanding_writes; | |
87 | ||
88 | // commits in progress, with their claimed writes | |
89 | BarrierList active_commits; | |
90 | ||
91 | public: | |
92 | BarrierContext(Client *c, uint64_t ino); | |
93 | void write_nobarrier(C_Block_Sync &cbs); | |
94 | void write_barrier(C_Block_Sync &cbs); | |
95 | void commit_barrier(barrier_interval &civ); | |
96 | void complete(C_Block_Sync &cbs); | |
97 | ~BarrierContext(); | |
98 | }; | |
99 | ||
100 | #endif |