]>
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> | |
9f95a23c | 21 | #include "common/ceph_mutex.h" |
7c673cae FG |
22 | |
23 | class Client; | |
24 | ||
25 | typedef boost::icl::interval<uint64_t>::type barrier_interval; | |
26 | ||
7c673cae FG |
27 | |
28 | /* | |
29 | * we keep count of uncommitted writes on the inode, so that | |
30 | * ll_commit_blocks can do the right thing. | |
31 | * | |
32 | * This is just a hacked copy of Ceph's sync callback. | |
33 | */ | |
34 | ||
35 | enum CBlockSync_State | |
36 | { | |
37 | CBlockSync_State_None, /* initial state */ | |
38 | CBlockSync_State_Unclaimed, /* outstanding write */ | |
39 | CBlockSync_State_Committing, /* commit in progress */ | |
40 | CBlockSync_State_Completed, | |
41 | }; | |
42 | ||
43 | class BarrierContext; | |
44 | ||
45 | class C_Block_Sync; | |
46 | ||
47 | typedef boost::intrusive::list< C_Block_Sync, | |
48 | boost::intrusive::member_hook< | |
49 | C_Block_Sync, | |
50 | boost::intrusive::list_member_hook<>, | |
51 | &C_Block_Sync::intervals_hook > | |
52 | > BlockSyncList; | |
53 | ||
54 | class Barrier | |
55 | { | |
56 | private: | |
9f95a23c | 57 | ceph::condition_variable cond; |
7c673cae FG |
58 | boost::icl::interval_set<uint64_t> span; |
59 | BlockSyncList write_list; | |
60 | ||
61 | public: | |
62 | boost::intrusive::list_member_hook<> active_commits_hook; | |
63 | ||
64 | Barrier(); | |
65 | ~Barrier(); | |
66 | ||
67 | friend class BarrierContext; | |
68 | }; | |
69 | ||
70 | typedef boost::intrusive::list< Barrier, | |
71 | boost::intrusive::member_hook< | |
72 | Barrier, | |
73 | boost::intrusive::list_member_hook<>, | |
74 | &Barrier::active_commits_hook > | |
75 | > BarrierList; | |
76 | ||
77 | class BarrierContext | |
78 | { | |
79 | private: | |
80 | Client *cl; | |
81 | uint64_t ino; | |
9f95a23c | 82 | ceph::mutex lock = ceph::make_mutex("BarrierContext"); |
7c673cae FG |
83 | |
84 | // writes not claimed by a commit | |
85 | BlockSyncList outstanding_writes; | |
86 | ||
87 | // commits in progress, with their claimed writes | |
88 | BarrierList active_commits; | |
89 | ||
90 | public: | |
91 | BarrierContext(Client *c, uint64_t ino); | |
92 | void write_nobarrier(C_Block_Sync &cbs); | |
93 | void write_barrier(C_Block_Sync &cbs); | |
94 | void commit_barrier(barrier_interval &civ); | |
95 | void complete(C_Block_Sync &cbs); | |
96 | ~BarrierContext(); | |
97 | }; | |
98 | ||
99 | #endif |