2 * Copyright 2012-2016 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Paweł Dziepak, pdziepak@quarnos.org
10 #include "MetadataCache.h"
12 #include <NodeMonitor.h>
17 MetadataCache::MetadataCache(Inode
* inode
)
24 ASSERT(inode
!= NULL
);
25 mutex_init(&fLock
, NULL
);
29 MetadataCache::~MetadataCache()
31 mutex_destroy(&fLock
);
36 MetadataCache::GetStat(struct stat
* st
)
41 if (fForceValid
|| fExpire
> time(NULL
)) {
42 // Do not touch other members of struct stat
43 st
->st_size
= fStatCache
.st_size
;
44 st
->st_mode
= fStatCache
.st_mode
;
45 st
->st_nlink
= fStatCache
.st_nlink
;
46 st
->st_uid
= fStatCache
.st_uid
;
47 st
->st_gid
= fStatCache
.st_gid
;
48 st
->st_atim
= fStatCache
.st_atim
;
49 st
->st_ctim
= fStatCache
.st_ctim
;
50 st
->st_crtim
= fStatCache
.st_crtim
;
51 st
->st_mtim
= fStatCache
.st_mtim
;
52 st
->st_blksize
= fStatCache
.st_blksize
;
53 st
->st_blocks
= fStatCache
.st_blocks
;
62 MetadataCache::SetStat(const struct stat
& st
)
66 NotifyChanges(&fStatCache
, &st
);
69 fExpire
= time(NULL
) + kExpirationTime
;
75 MetadataCache::GrowFile(size_t newSize
)
78 off_t oldSize
= fStatCache
.st_size
;
79 fStatCache
.st_size
= max_c((off_t
)newSize
, fStatCache
.st_size
);
81 if (oldSize
!= fStatCache
.st_size
) {
82 notify_stat_changed(fInode
->GetFileSystem()->DevId(), -1, fInode
->ID(),
89 MetadataCache::GetAccess(uid_t uid
, uint32
* allowed
)
91 ASSERT(allowed
!= NULL
);
94 AVLTreeMap
<uid_t
, AccessEntry
>::Iterator it
= fAccessCache
.Find(uid
);
96 return B_ENTRY_NOT_FOUND
;
99 it
.CurrentValuePointer()->fForceValid
= false;
101 if (!it
.Current().fForceValid
&& it
.Current().fExpire
< time(NULL
)) {
106 *allowed
= it
.Current().fAllowed
;
113 MetadataCache::SetAccess(uid_t uid
, uint32 allowed
)
115 MutexLocker
_(fLock
);
116 AVLTreeMap
<uid_t
, AccessEntry
>::Iterator it
= fAccessCache
.Find(uid
);
121 entry
.fAllowed
= allowed
;
122 entry
.fExpire
= time(NULL
) + kExpirationTime
;
123 entry
.fForceValid
= fForceValid
;
125 fAccessCache
.Insert(uid
, entry
);
130 MetadataCache::LockValid()
132 MutexLocker
_(fLock
);
133 if (fForceValid
|| fExpire
> time(NULL
)) {
143 MetadataCache::UnlockValid()
145 MutexLocker
_(fLock
);
146 fExpire
= time(NULL
) + kExpirationTime
;
152 MetadataCache::NotifyChanges(const struct stat
* oldStat
,
153 const struct stat
* newStat
)
155 ASSERT(oldStat
!= NULL
);
156 ASSERT(newStat
!= NULL
);
159 if (oldStat
->st_size
!= newStat
->st_size
)
160 flags
|= B_STAT_SIZE
;
161 if (oldStat
->st_mode
!= newStat
->st_mode
)
162 flags
|= B_STAT_MODE
;
163 if (oldStat
->st_uid
!= newStat
->st_uid
)
165 if (oldStat
->st_gid
!= newStat
->st_gid
)
168 if (memcmp(&oldStat
->st_atim
, &newStat
->st_atim
,
169 sizeof(struct timespec
) == 0))
170 flags
|= B_STAT_ACCESS_TIME
;
172 if (memcmp(&oldStat
->st_ctim
, &newStat
->st_ctim
,
173 sizeof(struct timespec
) == 0))
174 flags
|= B_STAT_CHANGE_TIME
;
176 if (memcmp(&oldStat
->st_crtim
, &newStat
->st_crtim
,
177 sizeof(struct timespec
) == 0))
178 flags
|= B_STAT_CREATION_TIME
;
180 if (memcmp(&oldStat
->st_mtim
, &newStat
->st_mtim
,
181 sizeof(struct timespec
) == 0))
182 flags
|= B_STAT_MODIFICATION_TIME
;
184 notify_stat_changed(fInode
->GetFileSystem()->DevId(), -1, fInode
->ID(),