]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/fs/rock/RockIoState.cc
4 * DEBUG: section 79 Disk IO Routines
10 #include "DiskIO/DiskIOModule.h"
11 #include "DiskIO/DiskIOStrategy.h"
12 #include "DiskIO/WriteRequest.h"
13 #include "fs/rock/RockIoState.h"
14 #include "fs/rock/RockIoRequests.h"
15 #include "fs/rock/RockSwapDir.h"
18 Rock::IoState::IoState(SwapDir
*dir
,
20 StoreIOState::STFNCB
*cbFile
,
21 StoreIOState::STIOCB
*cbIo
,
28 // swap_filen, swap_dirn, diskOffset, and payloadEnd are set by the caller
29 slotSize
= dir
->max_objsize
;
30 file_callback
= cbFile
;
32 callback_data
= cbdataReference(data
);
33 ++store_open_disk_fd
; // TODO: use a dedicated counter?
34 //theFile is set by SwapDir because it depends on DiskIOStrategy
37 Rock::IoState::~IoState()
41 cbdataReferenceDone(callback_data
);
46 Rock::IoState::file(const RefCount
<DiskFile
> &aFile
)
49 assert(aFile
!= NULL
);
54 Rock::IoState::read_(char *buf
, size_t len
, off_t coreOff
, STRCB
*cb
, void *data
)
56 assert(theFile
!= NULL
);
60 // we skip our cell header; it is only read when building the map
61 const int64_t cellOffset
= sizeof(DbCellHeader
) +
62 static_cast<int64_t>(coreOff
);
63 assert(cellOffset
<= payloadEnd
);
65 // Core specifies buffer length, but we must not exceed stored entry size
66 if (cellOffset
+ (int64_t)len
> payloadEnd
)
67 len
= payloadEnd
- cellOffset
;
69 assert(read
.callback
== NULL
);
70 assert(read
.callback_data
== NULL
);
72 read
.callback_data
= cbdataReference(data
);
74 theFile
->read(new ReadRequest(
75 ::ReadRequest(buf
, diskOffset
+ cellOffset
, len
), this));
78 // We only buffer data here; we actually write when close() is called.
79 // We buffer, in part, to avoid forcing OS to _read_ old unwritten portions
80 // of the slot when the write does not end at the page or sector boundary.
82 Rock::IoState::write(char const *buf
, size_t size
, off_t coreOff
, FREE
*dtor
)
84 // TODO: move to create?
86 assert(theBuf
.isNull());
87 assert(payloadEnd
<= slotSize
);
88 theBuf
.init(min(payloadEnd
, slotSize
), slotSize
);
89 // start with our header; TODO: consider making it a trailer
91 assert(static_cast<int64_t>(sizeof(header
)) <= payloadEnd
);
92 header
.payloadSize
= payloadEnd
- sizeof(header
);
93 theBuf
.append(reinterpret_cast<const char*>(&header
), sizeof(header
));
95 // Core uses -1 offset as "append". Sigh.
96 assert(coreOff
== -1);
97 assert(!theBuf
.isNull());
100 theBuf
.append(buf
, size
);
101 offset_
+= size
; // so that Core thinks we wrote it
104 (dtor
)(const_cast<char*>(buf
)); // cast due to a broken API?
107 // write what was buffered during write() calls
109 Rock::IoState::startWriting()
111 assert(theFile
!= NULL
);
112 assert(!theBuf
.isNull());
114 // TODO: if DiskIO module is mmap-based, we should be writing whole pages
115 // to avoid triggering read-page;new_head+old_tail;write-page overheads
117 debugs(79, 5, HERE
<< swap_filen
<< " at " << diskOffset
<< '+' <<
118 theBuf
.contentSize());
120 assert(theBuf
.contentSize() <= slotSize
);
121 // theFile->write may call writeCompleted immediatelly
122 theFile
->write(new WriteRequest(::WriteRequest(theBuf
.content(),
123 diskOffset
, theBuf
.contentSize(), theBuf
.freeFunc()), this));
128 Rock::IoState::finishedWriting(const int errFlag
)
130 // we incremented offset_ while accumulating data in write()
135 Rock::IoState::close(int how
)
137 debugs(79, 3, HERE
<< swap_filen
<< " accumulated: " << offset_
<<
139 if (how
== wroteAll
&& !theBuf
.isNull())
142 callBack(how
== writerGone
? DISK_ERROR
: 0); // TODO: add DISK_CALLER_GONE
145 /// close callback (STIOCB) dialer: breaks dependencies and
146 /// counts IOState concurrency level
147 class StoreIOStateCb
: public CallDialer
150 StoreIOStateCb(StoreIOState::STIOCB
*cb
, void *data
, int err
, const Rock::IoState::Pointer
&anSio
):
157 callback_data
= cbdataReference(data
);
160 StoreIOStateCb(const StoreIOStateCb
&cb
):
166 callback
= cb
.callback
;
167 callback_data
= cbdataReference(cb
.callback_data
);
170 virtual ~StoreIOStateCb() {
171 cbdataReferenceDone(callback_data
); // may be nil already
174 void dial(AsyncCall
&call
) {
176 if (cbdataReferenceValidDone(callback_data
, &cbd
) && callback
)
177 callback(cbd
, errflag
, sio
.getRaw());
180 bool canDial(AsyncCall
&call
) const {
181 return cbdataReferenceValid(callback_data
) && callback
;
184 virtual void print(std::ostream
&os
) const {
185 os
<< '(' << callback_data
<< ", err=" << errflag
<< ')';
189 StoreIOStateCb
&operator =(const StoreIOStateCb
&cb
); // not defined
191 StoreIOState::STIOCB
*callback
;
194 Rock::IoState::Pointer sio
;
198 Rock::IoState::callBack(int errflag
)
200 debugs(79,3, HERE
<< "errflag=" << errflag
);
203 AsyncCall::Pointer call
= asyncCall(79,3, "SomeIoStateCloseCb",
204 StoreIOStateCb(callback
, callback_data
, errflag
, this));
205 ScheduleCallHere(call
);
208 cbdataReferenceDone(callback_data
);