CacheItem.cpp revision ed909ae8db2f44ce7fe7003c6fee457f13669702
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "CacheItem.h" 18 19#include <inttypes.h> 20#include <stdint.h> 21#include <sys/xattr.h> 22 23#include <android-base/logging.h> 24#include <android-base/stringprintf.h> 25 26#include "utils.h" 27 28using android::base::StringPrintf; 29 30namespace android { 31namespace installd { 32 33CacheItem::CacheItem(FTSENT* p) { 34 level = p->fts_level; 35 directory = S_ISDIR(p->fts_statp->st_mode); 36 size = p->fts_statp->st_blocks * 512; 37 modified = p->fts_statp->st_mtime; 38 39 mParent = static_cast<CacheItem*>(p->fts_parent->fts_pointer); 40 if (mParent) { 41 group = mParent->group; 42 tombstone = mParent->tombstone; 43 mName = p->fts_name; 44 mName.insert(0, "/"); 45 } else { 46 group = false; 47 tombstone = false; 48 mName = p->fts_path; 49 } 50} 51 52CacheItem::~CacheItem() { 53} 54 55std::string CacheItem::toString() { 56 return StringPrintf("%s size=%" PRId64 " mod=%ld", buildPath().c_str(), size, modified); 57} 58 59std::string CacheItem::buildPath() { 60 std::string res = mName; 61 CacheItem* parent = mParent; 62 while (parent) { 63 res.insert(0, parent->mName); 64 parent = parent->mParent; 65 } 66 return res; 67} 68 69int CacheItem::purge() { 70 auto path = buildPath(); 71 if (directory) { 72 FTS *fts; 73 FTSENT *p; 74 char *argv[] = { (char*) path.c_str(), nullptr }; 75 if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL))) { 76 PLOG(WARNING) << "Failed to fts_open " << path; 77 return -1; 78 } 79 while ((p = fts_read(fts)) != nullptr) { 80 switch (p->fts_info) { 81 case FTS_D: 82 if (p->fts_level == 0) { 83 p->fts_number = tombstone; 84 } else { 85 p->fts_number = p->fts_parent->fts_number 86 | (getxattr(p->fts_path, kXattrCacheTombstone, nullptr, 0) >= 0); 87 } 88 break; 89 case FTS_F: 90 if (p->fts_parent->fts_number) { 91 truncate(p->fts_path, 0); 92 } else { 93 unlink(p->fts_path); 94 } 95 break; 96 case FTS_DEFAULT: 97 case FTS_SL: 98 case FTS_SLNONE: 99 unlink(p->fts_path); 100 break; 101 case FTS_DP: 102 rmdir(p->fts_path); 103 break; 104 } 105 } 106 return 0; 107 } else { 108 if (tombstone) { 109 return truncate(path.c_str(), 0); 110 } else { 111 return unlink(path.c_str()); 112 } 113 } 114} 115 116} // namespace installd 117} // namespace android 118