1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef __STDC_LIMIT_MACROS
6 #define __STDC_LIMIT_MACROS
9 #include "nacl_io/memfs/mem_fs_node.h"
17 #include "nacl_io/kernel_handle.h"
18 #include "nacl_io/osinttypes.h"
19 #include "nacl_io/osstat.h"
20 #include "sdk_util/auto_lock.h"
26 // The maximum size to reserve in addition to the requested size. Resize() will
27 // allocate twice as much as requested, up to this value.
28 const size_t kMaxResizeIncrement
= 16 * 1024 * 1024;
32 MemFsNode::MemFsNode(Filesystem
* filesystem
)
39 MemFsNode::~MemFsNode() {
42 Error
MemFsNode::Read(const HandleAttr
& attr
,
48 AUTO_LOCK(node_lock_
);
52 size_t size
= stat_
.st_size
;
54 if (attr
.offs
+ count
> size
) {
55 count
= size
- attr
.offs
;
58 memcpy(buf
, data_
+ attr
.offs
, count
);
59 *out_bytes
= static_cast<int>(count
);
63 Error
MemFsNode::Write(const HandleAttr
& attr
,
72 AUTO_LOCK(node_lock_
);
73 off_t new_size
= attr
.offs
+ count
;
74 if (new_size
> stat_
.st_size
) {
75 Error error
= Resize(new_size
);
77 LOG_ERROR("memfs: resize (%" PRIoff
") failed: %s", new_size
,
83 memcpy(data_
+ attr
.offs
, buf
, count
);
84 *out_bytes
= static_cast<int>(count
);
88 Error
MemFsNode::FTruncate(off_t new_size
) {
89 AUTO_LOCK(node_lock_
);
90 return Resize(new_size
);
93 Error
MemFsNode::Resize(off_t new_length
) {
96 size_t new_size
= static_cast<size_t>(new_length
);
98 if (new_size
> data_capacity_
) {
99 // While the node size is small, grow exponentially. When it starts to get
100 // larger, grow linearly.
101 size_t extra
= std::min(new_size
, kMaxResizeIncrement
);
102 data_capacity_
= new_size
+ extra
;
104 data_capacity_
= new_size
;
107 data_
= (char*)realloc(data_
, data_capacity_
);
108 if (data_capacity_
!= 0) {
109 assert(data_
!= NULL
);
112 if (new_length
> stat_
.st_size
)
113 memset(data_
+ stat_
.st_size
, 0, new_length
- stat_
.st_size
);
116 stat_
.st_size
= new_length
;
120 } // namespace nacl_io