fuse.cpp 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482
  1. /*
  2. * Copyright (C) 2010 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. #include <errno.h>
  17. #include <string.h>
  18. #include <unistd.h>
  19. #define LOG_TAG "sdcard"
  20. #include "fuse.h"
  21. #include <android-base/logging.h>
  22. /* FUSE_CANONICAL_PATH is not currently upstreamed */
  23. #define FUSE_CANONICAL_PATH 2016
  24. #define FUSE_UNKNOWN_INO 0xffffffff
  25. /* Pseudo-error constant used to indicate that no fuse status is needed
  26. * or that a reply has already been written. */
  27. #define NO_STATUS 1
  28. static inline void *id_to_ptr(__u64 nid)
  29. {
  30. return (void *) (uintptr_t) nid;
  31. }
  32. static inline __u64 ptr_to_id(void *ptr)
  33. {
  34. return (__u64) (uintptr_t) ptr;
  35. }
  36. static void acquire_node_locked(struct node* node)
  37. {
  38. node->refcount++;
  39. DLOG(INFO) << "ACQUIRE " << std::hex << node << std::dec
  40. << " (" << node->name << ") rc=" << node->refcount;
  41. }
  42. static void remove_node_from_parent_locked(struct node* node);
  43. static void release_node_locked(struct node* node)
  44. {
  45. DLOG(INFO) << "RELEASE " << std::hex << node << std::dec
  46. << " (" << node->name << ") rc=" << node->refcount;
  47. if (node->refcount > 0) {
  48. node->refcount--;
  49. if (!node->refcount) {
  50. DLOG(INFO) << "DESTROY " << std::hex << node << std::dec << " (" << node->name << ")";
  51. remove_node_from_parent_locked(node);
  52. /* TODO: remove debugging - poison memory */
  53. memset(node->name, 0xef, node->namelen);
  54. free(node->name);
  55. free(node->actual_name);
  56. memset(node, 0xfc, sizeof(*node));
  57. free(node);
  58. }
  59. } else {
  60. LOG(ERROR) << std::hex << node << std::dec << " refcount=0";
  61. }
  62. }
  63. static void add_node_to_parent_locked(struct node *node, struct node *parent) {
  64. node->parent = parent;
  65. node->next = parent->child;
  66. parent->child = node;
  67. acquire_node_locked(parent);
  68. }
  69. static void remove_node_from_parent_locked(struct node* node)
  70. {
  71. if (node->parent) {
  72. if (node->parent->child == node) {
  73. node->parent->child = node->parent->child->next;
  74. } else {
  75. struct node *node2;
  76. node2 = node->parent->child;
  77. while (node2->next != node)
  78. node2 = node2->next;
  79. node2->next = node->next;
  80. }
  81. release_node_locked(node->parent);
  82. node->parent = NULL;
  83. node->next = NULL;
  84. }
  85. }
  86. /* Gets the absolute path to a node into the provided buffer.
  87. *
  88. * Populates 'buf' with the path and returns the length of the path on success,
  89. * or returns -1 if the path is too long for the provided buffer.
  90. */
  91. static ssize_t get_node_path_locked(struct node* node, char* buf, size_t bufsize) {
  92. const char* name;
  93. size_t namelen;
  94. if (node->graft_path) {
  95. name = node->graft_path;
  96. namelen = node->graft_pathlen;
  97. } else if (node->actual_name) {
  98. name = node->actual_name;
  99. namelen = node->namelen;
  100. } else {
  101. name = node->name;
  102. namelen = node->namelen;
  103. }
  104. if (bufsize < namelen + 1) {
  105. return -1;
  106. }
  107. ssize_t pathlen = 0;
  108. if (node->parent && node->graft_path == NULL) {
  109. pathlen = get_node_path_locked(node->parent, buf, bufsize - namelen - 1);
  110. if (pathlen < 0) {
  111. return -1;
  112. }
  113. buf[pathlen++] = '/';
  114. }
  115. memcpy(buf + pathlen, name, namelen + 1); /* include trailing \0 */
  116. return pathlen + namelen;
  117. }
  118. /* Finds the absolute path of a file within a given directory.
  119. * Performs a case-insensitive search for the file and sets the buffer to the path
  120. * of the first matching file. If 'search' is zero or if no match is found, sets
  121. * the buffer to the path that the file would have, assuming the name were case-sensitive.
  122. *
  123. * Populates 'buf' with the path and returns the actual name (within 'buf') on success,
  124. * or returns NULL if the path is too long for the provided buffer.
  125. */
  126. static char* find_file_within(const char* path, const char* name,
  127. char* buf, size_t bufsize, int search)
  128. {
  129. size_t pathlen = strlen(path);
  130. size_t namelen = strlen(name);
  131. size_t childlen = pathlen + namelen + 1;
  132. char* actual;
  133. if (bufsize <= childlen) {
  134. return NULL;
  135. }
  136. memcpy(buf, path, pathlen);
  137. buf[pathlen] = '/';
  138. actual = buf + pathlen + 1;
  139. memcpy(actual, name, namelen + 1);
  140. if (search && access(buf, F_OK)) {
  141. struct dirent* entry;
  142. DIR* dir = opendir(path);
  143. if (!dir) {
  144. PLOG(ERROR) << "opendir(" << path << ") failed";
  145. return actual;
  146. }
  147. while ((entry = readdir(dir))) {
  148. if (!strcasecmp(entry->d_name, name)) {
  149. /* we have a match - replace the name, don't need to copy the null again */
  150. memcpy(actual, entry->d_name, namelen);
  151. break;
  152. }
  153. }
  154. closedir(dir);
  155. }
  156. return actual;
  157. }
  158. static void attr_from_stat(struct fuse* fuse, struct fuse_attr *attr,
  159. const struct stat *s, const struct node* node) {
  160. attr->ino = node->ino;
  161. attr->size = s->st_size;
  162. attr->blocks = s->st_blocks;
  163. attr->atime = s->st_atim.tv_sec;
  164. attr->mtime = s->st_mtim.tv_sec;
  165. attr->ctime = s->st_ctim.tv_sec;
  166. attr->atimensec = s->st_atim.tv_nsec;
  167. attr->mtimensec = s->st_mtim.tv_nsec;
  168. attr->ctimensec = s->st_ctim.tv_nsec;
  169. attr->mode = s->st_mode;
  170. attr->nlink = s->st_nlink;
  171. attr->uid = node->uid;
  172. if (fuse->gid == AID_SDCARD_RW) {
  173. /* As an optimization, certain trusted system components only run
  174. * as owner but operate across all users. Since we're now handing
  175. * out the sdcard_rw GID only to trusted apps, we're okay relaxing
  176. * the user boundary enforcement for the default view. The UIDs
  177. * assigned to app directories are still multiuser aware. */
  178. attr->gid = AID_SDCARD_RW;
  179. } else {
  180. attr->gid = multiuser_get_uid(node->userid, fuse->gid);
  181. }
  182. int visible_mode = 0775 & ~fuse->mask;
  183. if (node->perm == PERM_PRE_ROOT) {
  184. /* Top of multi-user view should always be visible to ensure
  185. * secondary users can traverse inside. */
  186. visible_mode = 0711;
  187. } else if (node->under_android) {
  188. /* Block "other" access to Android directories, since only apps
  189. * belonging to a specific user should be in there; we still
  190. * leave +x open for the default view. */
  191. if (fuse->gid == AID_SDCARD_RW) {
  192. visible_mode = visible_mode & ~0006;
  193. } else {
  194. visible_mode = visible_mode & ~0007;
  195. }
  196. }
  197. int owner_mode = s->st_mode & 0700;
  198. int filtered_mode = visible_mode & (owner_mode | (owner_mode >> 3) | (owner_mode >> 6));
  199. attr->mode = (attr->mode & S_IFMT) | filtered_mode;
  200. }
  201. static int touch(char* path, mode_t mode) {
  202. int fd = TEMP_FAILURE_RETRY(open(path, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW | O_CLOEXEC,
  203. mode));
  204. if (fd == -1) {
  205. if (errno == EEXIST) {
  206. return 0;
  207. } else {
  208. PLOG(ERROR) << "open(" << path << ") failed";
  209. return -1;
  210. }
  211. }
  212. close(fd);
  213. return 0;
  214. }
  215. static void derive_permissions_locked(struct fuse* fuse, struct node *parent,
  216. struct node *node) {
  217. appid_t appid;
  218. /* By default, each node inherits from its parent */
  219. node->perm = PERM_INHERIT;
  220. node->userid = parent->userid;
  221. node->uid = parent->uid;
  222. node->under_android = parent->under_android;
  223. /* Derive custom permissions based on parent and current node */
  224. switch (parent->perm) {
  225. case PERM_INHERIT:
  226. /* Already inherited above */
  227. break;
  228. case PERM_PRE_ROOT:
  229. /* Legacy internal layout places users at top level */
  230. node->perm = PERM_ROOT;
  231. node->userid = strtoul(node->name, NULL, 10);
  232. break;
  233. case PERM_ROOT:
  234. /* Assume masked off by default. */
  235. if (!strcasecmp(node->name, "Android")) {
  236. /* App-specific directories inside; let anyone traverse */
  237. node->perm = PERM_ANDROID;
  238. node->under_android = true;
  239. }
  240. break;
  241. case PERM_ANDROID:
  242. if (!strcasecmp(node->name, "data")) {
  243. /* App-specific directories inside; let anyone traverse */
  244. node->perm = PERM_ANDROID_DATA;
  245. } else if (!strcasecmp(node->name, "obb")) {
  246. /* App-specific directories inside; let anyone traverse */
  247. node->perm = PERM_ANDROID_OBB;
  248. /* Single OBB directory is always shared */
  249. node->graft_path = fuse->global->obb_path;
  250. node->graft_pathlen = strlen(fuse->global->obb_path);
  251. } else if (!strcasecmp(node->name, "media")) {
  252. /* App-specific directories inside; let anyone traverse */
  253. node->perm = PERM_ANDROID_MEDIA;
  254. }
  255. break;
  256. case PERM_ANDROID_DATA:
  257. case PERM_ANDROID_OBB:
  258. case PERM_ANDROID_MEDIA:
  259. const auto& iter = fuse->global->package_to_appid->find(node->name);
  260. if (iter != fuse->global->package_to_appid->end()) {
  261. appid = iter->second;
  262. node->uid = multiuser_get_uid(parent->userid, appid);
  263. }
  264. break;
  265. }
  266. }
  267. void derive_permissions_recursive_locked(struct fuse* fuse, struct node *parent) {
  268. struct node *node;
  269. for (node = parent->child; node; node = node->next) {
  270. derive_permissions_locked(fuse, parent, node);
  271. if (node->child) {
  272. derive_permissions_recursive_locked(fuse, node);
  273. }
  274. }
  275. }
  276. /* Kernel has already enforced everything we returned through
  277. * derive_permissions_locked(), so this is used to lock down access
  278. * even further, such as enforcing that apps hold sdcard_rw. */
  279. static bool check_caller_access_to_name(struct fuse* fuse,
  280. const struct fuse_in_header *hdr, const struct node* parent_node,
  281. const char* name, int mode) {
  282. /* Always block security-sensitive files at root */
  283. if (parent_node && parent_node->perm == PERM_ROOT) {
  284. if (!strcasecmp(name, "autorun.inf")
  285. || !strcasecmp(name, ".android_secure")
  286. || !strcasecmp(name, "android_secure")) {
  287. return false;
  288. }
  289. }
  290. /* Root always has access; access for any other UIDs should always
  291. * be controlled through packages.list. */
  292. if (hdr->uid == 0) {
  293. return true;
  294. }
  295. /* No extra permissions to enforce */
  296. return true;
  297. }
  298. static bool check_caller_access_to_node(struct fuse* fuse,
  299. const struct fuse_in_header *hdr, const struct node* node, int mode) {
  300. return check_caller_access_to_name(fuse, hdr, node->parent, node->name, mode);
  301. }
  302. struct node *create_node_locked(struct fuse* fuse,
  303. struct node *parent, const char *name, const char* actual_name)
  304. {
  305. struct node *node;
  306. size_t namelen = strlen(name);
  307. // Detect overflows in the inode counter. "4 billion nodes should be enough
  308. // for everybody".
  309. if (fuse->global->inode_ctr == 0) {
  310. LOG(ERROR) << "No more inode numbers available";
  311. return NULL;
  312. }
  313. node = static_cast<struct node*>(calloc(1, sizeof(struct node)));
  314. if (!node) {
  315. return NULL;
  316. }
  317. node->name = static_cast<char*>(malloc(namelen + 1));
  318. if (!node->name) {
  319. free(node);
  320. return NULL;
  321. }
  322. memcpy(node->name, name, namelen + 1);
  323. if (strcmp(name, actual_name)) {
  324. node->actual_name = static_cast<char*>(malloc(namelen + 1));
  325. if (!node->actual_name) {
  326. free(node->name);
  327. free(node);
  328. return NULL;
  329. }
  330. memcpy(node->actual_name, actual_name, namelen + 1);
  331. }
  332. node->namelen = namelen;
  333. node->nid = ptr_to_id(node);
  334. node->ino = fuse->global->inode_ctr++;
  335. node->gen = fuse->global->next_generation++;
  336. node->deleted = false;
  337. derive_permissions_locked(fuse, parent, node);
  338. acquire_node_locked(node);
  339. add_node_to_parent_locked(node, parent);
  340. return node;
  341. }
  342. static int rename_node_locked(struct node *node, const char *name,
  343. const char* actual_name)
  344. {
  345. size_t namelen = strlen(name);
  346. int need_actual_name = strcmp(name, actual_name);
  347. /* make the storage bigger without actually changing the name
  348. * in case an error occurs part way */
  349. if (namelen > node->namelen) {
  350. char* new_name = static_cast<char*>(realloc(node->name, namelen + 1));
  351. if (!new_name) {
  352. return -ENOMEM;
  353. }
  354. node->name = new_name;
  355. if (need_actual_name && node->actual_name) {
  356. char* new_actual_name = static_cast<char*>(realloc(node->actual_name, namelen + 1));
  357. if (!new_actual_name) {
  358. return -ENOMEM;
  359. }
  360. node->actual_name = new_actual_name;
  361. }
  362. }
  363. /* update the name, taking care to allocate storage before overwriting the old name */
  364. if (need_actual_name) {
  365. if (!node->actual_name) {
  366. node->actual_name = static_cast<char*>(malloc(namelen + 1));
  367. if (!node->actual_name) {
  368. return -ENOMEM;
  369. }
  370. }
  371. memcpy(node->actual_name, actual_name, namelen + 1);
  372. } else {
  373. free(node->actual_name);
  374. node->actual_name = NULL;
  375. }
  376. memcpy(node->name, name, namelen + 1);
  377. node->namelen = namelen;
  378. return 0;
  379. }
  380. static struct node *lookup_node_by_id_locked(struct fuse *fuse, __u64 nid)
  381. {
  382. if (nid == FUSE_ROOT_ID) {
  383. return &fuse->global->root;
  384. } else {
  385. return static_cast<struct node*>(id_to_ptr(nid));
  386. }
  387. }
  388. static struct node* lookup_node_and_path_by_id_locked(struct fuse* fuse, __u64 nid,
  389. char* buf, size_t bufsize)
  390. {
  391. struct node* node = lookup_node_by_id_locked(fuse, nid);
  392. if (node && get_node_path_locked(node, buf, bufsize) < 0) {
  393. node = NULL;
  394. }
  395. return node;
  396. }
  397. static struct node *lookup_child_by_name_locked(struct node *node, const char *name)
  398. {
  399. for (node = node->child; node; node = node->next) {
  400. /* use exact string comparison, nodes that differ by case
  401. * must be considered distinct even if they refer to the same
  402. * underlying file as otherwise operations such as "mv x x"
  403. * will not work because the source and target nodes are the same. */
  404. if (!strcmp(name, node->name) && !node->deleted) {
  405. return node;
  406. }
  407. }
  408. return 0;
  409. }
  410. static struct node* acquire_or_create_child_locked(
  411. struct fuse* fuse, struct node* parent,
  412. const char* name, const char* actual_name)
  413. {
  414. struct node* child = lookup_child_by_name_locked(parent, name);
  415. if (child) {
  416. acquire_node_locked(child);
  417. } else {
  418. child = create_node_locked(fuse, parent, name, actual_name);
  419. }
  420. return child;
  421. }
  422. static void fuse_status(struct fuse *fuse, __u64 unique, int err)
  423. {
  424. struct fuse_out_header hdr;
  425. hdr.len = sizeof(hdr);
  426. hdr.error = err;
  427. hdr.unique = unique;
  428. ssize_t ret = TEMP_FAILURE_RETRY(write(fuse->fd, &hdr, sizeof(hdr)));
  429. if (ret == -1) {
  430. PLOG(ERROR) << "*** STATUS FAILED ***";
  431. } else if (static_cast<size_t>(ret) != sizeof(hdr)) {
  432. LOG(ERROR) << "*** STATUS FAILED: written " << ret << " expected "
  433. << sizeof(hdr) << " ***";
  434. }
  435. }
  436. static void fuse_reply(struct fuse *fuse, __u64 unique, void *data, int len)
  437. {
  438. struct fuse_out_header hdr;
  439. hdr.len = len + sizeof(hdr);
  440. hdr.error = 0;
  441. hdr.unique = unique;
  442. struct iovec vec[2];
  443. vec[0].iov_base = &hdr;
  444. vec[0].iov_len = sizeof(hdr);
  445. vec[1].iov_base = data;
  446. vec[1].iov_len = len;
  447. ssize_t ret = TEMP_FAILURE_RETRY(writev(fuse->fd, vec, 2));
  448. if (ret == -1) {
  449. PLOG(ERROR) << "*** REPLY FAILED ***";
  450. } else if (static_cast<size_t>(ret) != sizeof(hdr) + len) {
  451. LOG(ERROR) << "*** REPLY FAILED: written " << ret << " expected "
  452. << sizeof(hdr) + len << " ***";
  453. }
  454. }
  455. static int fuse_reply_entry(struct fuse* fuse, __u64 unique,
  456. struct node* parent, const char* name, const char* actual_name,
  457. const char* path)
  458. {
  459. struct node* node;
  460. struct fuse_entry_out out;
  461. struct stat s;
  462. if (lstat(path, &s) == -1) {
  463. return -errno;
  464. }
  465. pthread_mutex_lock(&fuse->global->lock);
  466. node = acquire_or_create_child_locked(fuse, parent, name, actual_name);
  467. if (!node) {
  468. pthread_mutex_unlock(&fuse->global->lock);
  469. return -ENOMEM;
  470. }
  471. memset(&out, 0, sizeof(out));
  472. attr_from_stat(fuse, &out.attr, &s, node);
  473. out.attr_valid = 10;
  474. out.entry_valid = 10;
  475. out.nodeid = node->nid;
  476. out.generation = node->gen;
  477. pthread_mutex_unlock(&fuse->global->lock);
  478. fuse_reply(fuse, unique, &out, sizeof(out));
  479. return NO_STATUS;
  480. }
  481. static int fuse_reply_attr(struct fuse* fuse, __u64 unique, const struct node* node,
  482. const char* path)
  483. {
  484. struct fuse_attr_out out;
  485. struct stat s;
  486. if (lstat(path, &s) == -1) {
  487. return -errno;
  488. }
  489. memset(&out, 0, sizeof(out));
  490. attr_from_stat(fuse, &out.attr, &s, node);
  491. out.attr_valid = 10;
  492. fuse_reply(fuse, unique, &out, sizeof(out));
  493. return NO_STATUS;
  494. }
  495. static void fuse_notify_delete(struct fuse* fuse, const __u64 parent,
  496. const __u64 child, const char* name) {
  497. struct fuse_out_header hdr;
  498. struct fuse_notify_delete_out data;
  499. size_t namelen = strlen(name);
  500. hdr.len = sizeof(hdr) + sizeof(data) + namelen + 1;
  501. hdr.error = FUSE_NOTIFY_DELETE;
  502. hdr.unique = 0;
  503. data.parent = parent;
  504. data.child = child;
  505. data.namelen = namelen;
  506. data.padding = 0;
  507. struct iovec vec[3];
  508. vec[0].iov_base = &hdr;
  509. vec[0].iov_len = sizeof(hdr);
  510. vec[1].iov_base = &data;
  511. vec[1].iov_len = sizeof(data);
  512. vec[2].iov_base = (void*) name;
  513. vec[2].iov_len = namelen + 1;
  514. ssize_t ret = TEMP_FAILURE_RETRY(writev(fuse->fd, vec, 3));
  515. /* Ignore ENOENT, since other views may not have seen the entry */
  516. if (ret == -1) {
  517. if (errno != ENOENT) {
  518. PLOG(ERROR) << "*** NOTIFY FAILED ***";
  519. }
  520. } else if (static_cast<size_t>(ret) != sizeof(hdr) + sizeof(data) + namelen + 1) {
  521. LOG(ERROR) << "*** NOTIFY FAILED: written " << ret << " expected "
  522. << sizeof(hdr) + sizeof(data) + namelen + 1 << " ***";
  523. }
  524. }
  525. static int handle_lookup(struct fuse* fuse, struct fuse_handler* handler,
  526. const struct fuse_in_header *hdr, const char* name)
  527. {
  528. struct node* parent_node;
  529. char parent_path[PATH_MAX];
  530. char child_path[PATH_MAX];
  531. const char* actual_name;
  532. pthread_mutex_lock(&fuse->global->lock);
  533. parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
  534. parent_path, sizeof(parent_path));
  535. DLOG(INFO) << "[" << handler->token << "] LOOKUP " << name << " @ " << hdr->nodeid
  536. << " (" << (parent_node ? parent_node->name : "?") << ")";
  537. pthread_mutex_unlock(&fuse->global->lock);
  538. if (!parent_node || !(actual_name = find_file_within(parent_path, name,
  539. child_path, sizeof(child_path), 1))) {
  540. return -ENOENT;
  541. }
  542. if (!check_caller_access_to_name(fuse, hdr, parent_node, name, R_OK)) {
  543. return -EACCES;
  544. }
  545. return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
  546. }
  547. static int handle_forget(struct fuse* fuse, struct fuse_handler* handler,
  548. const struct fuse_in_header *hdr, const struct fuse_forget_in *req)
  549. {
  550. struct node* node;
  551. pthread_mutex_lock(&fuse->global->lock);
  552. node = lookup_node_by_id_locked(fuse, hdr->nodeid);
  553. DLOG(INFO) << "[" << handler->token << "] FORGET #" << req->nlookup
  554. << " @ " << std::hex << hdr->nodeid
  555. << " (" << (node ? node->name : "?") << ")";
  556. if (node) {
  557. __u64 n = req->nlookup;
  558. while (n) {
  559. n--;
  560. release_node_locked(node);
  561. }
  562. }
  563. pthread_mutex_unlock(&fuse->global->lock);
  564. return NO_STATUS; /* no reply */
  565. }
  566. static int handle_getattr(struct fuse* fuse, struct fuse_handler* handler,
  567. const struct fuse_in_header *hdr, const struct fuse_getattr_in *req)
  568. {
  569. struct node* node;
  570. char path[PATH_MAX];
  571. pthread_mutex_lock(&fuse->global->lock);
  572. node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
  573. DLOG(INFO) << "[" << handler->token << "] GETATTR flags=" << req->getattr_flags
  574. << " fh=" << std::hex << req->fh << " @ " << hdr->nodeid << std::dec
  575. << " (" << (node ? node->name : "?") << ")";
  576. pthread_mutex_unlock(&fuse->global->lock);
  577. if (!node) {
  578. return -ENOENT;
  579. }
  580. if (!check_caller_access_to_node(fuse, hdr, node, R_OK)) {
  581. return -EACCES;
  582. }
  583. return fuse_reply_attr(fuse, hdr->unique, node, path);
  584. }
  585. static int handle_setattr(struct fuse* fuse, struct fuse_handler* handler,
  586. const struct fuse_in_header *hdr, const struct fuse_setattr_in *req)
  587. {
  588. struct node* node;
  589. char path[PATH_MAX];
  590. struct timespec times[2];
  591. pthread_mutex_lock(&fuse->global->lock);
  592. node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
  593. DLOG(INFO) << "[" << handler->token << "] SETATTR fh=" << std::hex << req->fh
  594. << " valid=" << std::hex << req->valid << " @ " << hdr->nodeid << std::dec
  595. << " (" << (node ? node->name : "?") << ")";
  596. pthread_mutex_unlock(&fuse->global->lock);
  597. if (!node) {
  598. return -ENOENT;
  599. }
  600. if (!(req->valid & FATTR_FH) &&
  601. !check_caller_access_to_node(fuse, hdr, node, W_OK)) {
  602. return -EACCES;
  603. }
  604. /* XXX: incomplete implementation on purpose.
  605. * chmod/chown should NEVER be implemented.*/
  606. if ((req->valid & FATTR_SIZE) && TEMP_FAILURE_RETRY(truncate64(path, req->size)) == -1) {
  607. return -errno;
  608. }
  609. /* Handle changing atime and mtime. If FATTR_ATIME_and FATTR_ATIME_NOW
  610. * are both set, then set it to the current time. Else, set it to the
  611. * time specified in the request. Same goes for mtime. Use utimensat(2)
  612. * as it allows ATIME and MTIME to be changed independently, and has
  613. * nanosecond resolution which fuse also has.
  614. */
  615. if (req->valid & (FATTR_ATIME | FATTR_MTIME)) {
  616. times[0].tv_nsec = UTIME_OMIT;
  617. times[1].tv_nsec = UTIME_OMIT;
  618. if (req->valid & FATTR_ATIME) {
  619. if (req->valid & FATTR_ATIME_NOW) {
  620. times[0].tv_nsec = UTIME_NOW;
  621. } else {
  622. times[0].tv_sec = req->atime;
  623. times[0].tv_nsec = req->atimensec;
  624. }
  625. }
  626. if (req->valid & FATTR_MTIME) {
  627. if (req->valid & FATTR_MTIME_NOW) {
  628. times[1].tv_nsec = UTIME_NOW;
  629. } else {
  630. times[1].tv_sec = req->mtime;
  631. times[1].tv_nsec = req->mtimensec;
  632. }
  633. }
  634. DLOG(INFO) << "[" << handler->token << "] Calling utimensat on " << path
  635. << " with atime " << times[0].tv_sec << ", mtime=" << times[1].tv_sec;
  636. if (utimensat(-1, path, times, 0) < 0) {
  637. return -errno;
  638. }
  639. }
  640. return fuse_reply_attr(fuse, hdr->unique, node, path);
  641. }
  642. static int handle_mknod(struct fuse* fuse, struct fuse_handler* handler,
  643. const struct fuse_in_header* hdr, const struct fuse_mknod_in* req, const char* name)
  644. {
  645. struct node* parent_node;
  646. char parent_path[PATH_MAX];
  647. char child_path[PATH_MAX];
  648. const char* actual_name;
  649. pthread_mutex_lock(&fuse->global->lock);
  650. parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
  651. parent_path, sizeof(parent_path));
  652. DLOG(INFO) << "[" << handler->token << "] MKNOD " << name << " 0" << std::oct << req->mode
  653. << " @ " << std::hex << hdr->nodeid
  654. << " (" << (parent_node ? parent_node->name : "?") << ")";
  655. pthread_mutex_unlock(&fuse->global->lock);
  656. if (!parent_node || !(actual_name = find_file_within(parent_path, name,
  657. child_path, sizeof(child_path), 1))) {
  658. return -ENOENT;
  659. }
  660. if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK)) {
  661. return -EACCES;
  662. }
  663. __u32 mode = (req->mode & (~0777)) | 0664;
  664. if (mknod(child_path, mode, req->rdev) == -1) {
  665. return -errno;
  666. }
  667. return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
  668. }
  669. static int handle_mkdir(struct fuse* fuse, struct fuse_handler* handler,
  670. const struct fuse_in_header* hdr, const struct fuse_mkdir_in* req, const char* name)
  671. {
  672. struct node* parent_node;
  673. char parent_path[PATH_MAX];
  674. char child_path[PATH_MAX];
  675. const char* actual_name;
  676. pthread_mutex_lock(&fuse->global->lock);
  677. parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
  678. parent_path, sizeof(parent_path));
  679. DLOG(INFO) << "[" << handler->token << "] MKDIR " << name << " 0" << std::oct << req->mode
  680. << " @ " << std::hex << hdr->nodeid
  681. << " (" << (parent_node ? parent_node->name : "?") << ")";
  682. pthread_mutex_unlock(&fuse->global->lock);
  683. if (!parent_node || !(actual_name = find_file_within(parent_path, name,
  684. child_path, sizeof(child_path), 1))) {
  685. return -ENOENT;
  686. }
  687. if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK)) {
  688. return -EACCES;
  689. }
  690. __u32 mode = (req->mode & (~0777)) | 0775;
  691. if (mkdir(child_path, mode) == -1) {
  692. return -errno;
  693. }
  694. /* When creating /Android/data and /Android/obb, mark them as .nomedia */
  695. if (parent_node->perm == PERM_ANDROID && !strcasecmp(name, "data")) {
  696. char nomedia[PATH_MAX];
  697. snprintf(nomedia, PATH_MAX, "%s/.nomedia", child_path);
  698. if (touch(nomedia, 0664) != 0) {
  699. PLOG(ERROR) << "touch(" << nomedia << ") failed";
  700. return -ENOENT;
  701. }
  702. }
  703. if (parent_node->perm == PERM_ANDROID && !strcasecmp(name, "obb")) {
  704. char nomedia[PATH_MAX];
  705. snprintf(nomedia, PATH_MAX, "%s/.nomedia", fuse->global->obb_path);
  706. if (touch(nomedia, 0664) != 0) {
  707. PLOG(ERROR) << "touch(" << nomedia << ") failed";
  708. return -ENOENT;
  709. }
  710. }
  711. return fuse_reply_entry(fuse, hdr->unique, parent_node, name, actual_name, child_path);
  712. }
  713. static int handle_unlink(struct fuse* fuse, struct fuse_handler* handler,
  714. const struct fuse_in_header* hdr, const char* name)
  715. {
  716. struct node* parent_node;
  717. struct node* child_node;
  718. char parent_path[PATH_MAX];
  719. char child_path[PATH_MAX];
  720. pthread_mutex_lock(&fuse->global->lock);
  721. parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
  722. parent_path, sizeof(parent_path));
  723. DLOG(INFO) << "[" << handler->token << "] UNLINK " << name << " @ " << std::hex << hdr->nodeid
  724. << " (" << (parent_node ? parent_node->name : "?") << ")";
  725. pthread_mutex_unlock(&fuse->global->lock);
  726. if (!parent_node || !find_file_within(parent_path, name,
  727. child_path, sizeof(child_path), 1)) {
  728. return -ENOENT;
  729. }
  730. if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK)) {
  731. return -EACCES;
  732. }
  733. if (unlink(child_path) == -1) {
  734. return -errno;
  735. }
  736. pthread_mutex_lock(&fuse->global->lock);
  737. child_node = lookup_child_by_name_locked(parent_node, name);
  738. if (child_node) {
  739. child_node->deleted = true;
  740. }
  741. pthread_mutex_unlock(&fuse->global->lock);
  742. if (parent_node && child_node) {
  743. /* Tell all other views that node is gone */
  744. DLOG(INFO) << "[" << handler->token << "] fuse_notify_delete"
  745. << " parent=" << std::hex << parent_node->nid
  746. << ", child=" << std::hex << child_node->nid << std::dec
  747. << ", name=" << name;
  748. if (fuse != fuse->global->fuse_default) {
  749. fuse_notify_delete(fuse->global->fuse_default, parent_node->nid, child_node->nid, name);
  750. }
  751. if (fuse != fuse->global->fuse_read) {
  752. fuse_notify_delete(fuse->global->fuse_read, parent_node->nid, child_node->nid, name);
  753. }
  754. if (fuse != fuse->global->fuse_write) {
  755. fuse_notify_delete(fuse->global->fuse_write, parent_node->nid, child_node->nid, name);
  756. }
  757. if (fuse != fuse->global->fuse_full) {
  758. fuse_notify_delete(fuse->global->fuse_full, parent_node->nid, child_node->nid, name);
  759. }
  760. }
  761. return 0;
  762. }
  763. static int handle_rmdir(struct fuse* fuse, struct fuse_handler* handler,
  764. const struct fuse_in_header* hdr, const char* name)
  765. {
  766. struct node* child_node;
  767. struct node* parent_node;
  768. char parent_path[PATH_MAX];
  769. char child_path[PATH_MAX];
  770. pthread_mutex_lock(&fuse->global->lock);
  771. parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
  772. parent_path, sizeof(parent_path));
  773. DLOG(INFO) << "[" << handler->token << "] UNLINK " << name << " @ " << std::hex << hdr->nodeid
  774. << " (" << (parent_node ? parent_node->name : "?") << ")";
  775. pthread_mutex_unlock(&fuse->global->lock);
  776. if (!parent_node || !find_file_within(parent_path, name,
  777. child_path, sizeof(child_path), 1)) {
  778. return -ENOENT;
  779. }
  780. if (!check_caller_access_to_name(fuse, hdr, parent_node, name, W_OK)) {
  781. return -EACCES;
  782. }
  783. if (rmdir(child_path) == -1) {
  784. return -errno;
  785. }
  786. pthread_mutex_lock(&fuse->global->lock);
  787. child_node = lookup_child_by_name_locked(parent_node, name);
  788. if (child_node) {
  789. child_node->deleted = true;
  790. }
  791. pthread_mutex_unlock(&fuse->global->lock);
  792. if (parent_node && child_node) {
  793. /* Tell all other views that node is gone */
  794. DLOG(INFO) << "[" << handler->token << "] fuse_notify_delete"
  795. << " parent=" << std::hex << parent_node->nid
  796. << ", child=" << std::hex << child_node->nid << std::dec
  797. << ", name=" << name;
  798. if (fuse != fuse->global->fuse_default) {
  799. fuse_notify_delete(fuse->global->fuse_default, parent_node->nid, child_node->nid, name);
  800. }
  801. if (fuse != fuse->global->fuse_read) {
  802. fuse_notify_delete(fuse->global->fuse_read, parent_node->nid, child_node->nid, name);
  803. }
  804. if (fuse != fuse->global->fuse_write) {
  805. fuse_notify_delete(fuse->global->fuse_write, parent_node->nid, child_node->nid, name);
  806. }
  807. if (fuse != fuse->global->fuse_full) {
  808. fuse_notify_delete(fuse->global->fuse_full, parent_node->nid, child_node->nid, name);
  809. }
  810. }
  811. return 0;
  812. }
  813. static int handle_rename(struct fuse* fuse, struct fuse_handler* handler,
  814. const struct fuse_in_header* hdr, const struct fuse_rename_in* req,
  815. const char* old_name, const char* new_name)
  816. {
  817. struct node* old_parent_node;
  818. struct node* new_parent_node;
  819. struct node* child_node;
  820. char old_parent_path[PATH_MAX];
  821. char new_parent_path[PATH_MAX];
  822. char old_child_path[PATH_MAX];
  823. char new_child_path[PATH_MAX];
  824. const char* new_actual_name;
  825. int search;
  826. int res;
  827. pthread_mutex_lock(&fuse->global->lock);
  828. old_parent_node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
  829. old_parent_path, sizeof(old_parent_path));
  830. new_parent_node = lookup_node_and_path_by_id_locked(fuse, req->newdir,
  831. new_parent_path, sizeof(new_parent_path));
  832. DLOG(INFO) << "[" << handler->token << "] RENAME " << old_name << "->" << new_name
  833. << " @ " << std::hex << hdr->nodeid
  834. << " (" << (old_parent_node ? old_parent_node->name : "?") << ") -> "
  835. << std::hex << req->newdir
  836. << " (" << (new_parent_node ? new_parent_node->name : "?") << ")";
  837. if (!old_parent_node || !new_parent_node) {
  838. res = -ENOENT;
  839. goto lookup_error;
  840. }
  841. if (!check_caller_access_to_name(fuse, hdr, old_parent_node, old_name, W_OK)) {
  842. res = -EACCES;
  843. goto lookup_error;
  844. }
  845. if (!check_caller_access_to_name(fuse, hdr, new_parent_node, new_name, W_OK)) {
  846. res = -EACCES;
  847. goto lookup_error;
  848. }
  849. child_node = lookup_child_by_name_locked(old_parent_node, old_name);
  850. if (!child_node || get_node_path_locked(child_node,
  851. old_child_path, sizeof(old_child_path)) < 0) {
  852. res = -ENOENT;
  853. goto lookup_error;
  854. }
  855. acquire_node_locked(child_node);
  856. pthread_mutex_unlock(&fuse->global->lock);
  857. /* Special case for renaming a file where destination is same path
  858. * differing only by case. In this case we don't want to look for a case
  859. * insensitive match. This allows commands like "mv foo FOO" to work as expected.
  860. */
  861. search = old_parent_node != new_parent_node
  862. || strcasecmp(old_name, new_name);
  863. if (!(new_actual_name = find_file_within(new_parent_path, new_name,
  864. new_child_path, sizeof(new_child_path), search))) {
  865. res = -ENOENT;
  866. goto io_error;
  867. }
  868. DLOG(INFO) << "[" << handler->token << "] RENAME " << old_child_path << "->" << new_child_path;
  869. res = rename(old_child_path, new_child_path);
  870. if (res == -1) {
  871. res = -errno;
  872. goto io_error;
  873. }
  874. pthread_mutex_lock(&fuse->global->lock);
  875. res = rename_node_locked(child_node, new_name, new_actual_name);
  876. if (!res) {
  877. remove_node_from_parent_locked(child_node);
  878. derive_permissions_locked(fuse, new_parent_node, child_node);
  879. derive_permissions_recursive_locked(fuse, child_node);
  880. add_node_to_parent_locked(child_node, new_parent_node);
  881. }
  882. goto done;
  883. io_error:
  884. pthread_mutex_lock(&fuse->global->lock);
  885. done:
  886. release_node_locked(child_node);
  887. lookup_error:
  888. pthread_mutex_unlock(&fuse->global->lock);
  889. return res;
  890. }
  891. static int open_flags_to_access_mode(int open_flags) {
  892. if ((open_flags & O_ACCMODE) == O_RDONLY) {
  893. return R_OK;
  894. } else if ((open_flags & O_ACCMODE) == O_WRONLY) {
  895. return W_OK;
  896. } else {
  897. /* Probably O_RDRW, but treat as default to be safe */
  898. return R_OK | W_OK;
  899. }
  900. }
  901. static int handle_open(struct fuse* fuse, struct fuse_handler* handler,
  902. const struct fuse_in_header* hdr, const struct fuse_open_in* req)
  903. {
  904. struct node* node;
  905. char path[PATH_MAX];
  906. struct fuse_open_out out = {};
  907. struct handle *h;
  908. pthread_mutex_lock(&fuse->global->lock);
  909. node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
  910. DLOG(INFO) << "[" << handler->token << "] OPEN 0" << std::oct << req->flags
  911. << " @ " << std::hex << hdr->nodeid << std::dec
  912. << " (" << (node ? node->name : "?") << ")";
  913. pthread_mutex_unlock(&fuse->global->lock);
  914. if (!node) {
  915. return -ENOENT;
  916. }
  917. if (!check_caller_access_to_node(fuse, hdr, node,
  918. open_flags_to_access_mode(req->flags))) {
  919. return -EACCES;
  920. }
  921. h = static_cast<struct handle*>(malloc(sizeof(*h)));
  922. if (!h) {
  923. return -ENOMEM;
  924. }
  925. DLOG(INFO) << "[" << handler->token << "] OPEN " << path;
  926. h->fd = TEMP_FAILURE_RETRY(open(path, req->flags));
  927. if (h->fd == -1) {
  928. free(h);
  929. return -errno;
  930. }
  931. out.fh = ptr_to_id(h);
  932. out.open_flags = 0;
  933. fuse_reply(fuse, hdr->unique, &out, sizeof(out));
  934. return NO_STATUS;
  935. }
  936. static int handle_read(struct fuse* fuse, struct fuse_handler* handler,
  937. const struct fuse_in_header* hdr, const struct fuse_read_in* req)
  938. {
  939. struct handle *h = static_cast<struct handle*>(id_to_ptr(req->fh));
  940. __u64 unique = hdr->unique;
  941. __u32 size = req->size;
  942. __u64 offset = req->offset;
  943. int res;
  944. __u8 *read_buffer = (__u8 *) ((uintptr_t)(handler->read_buffer + PAGE_SIZE) & ~((uintptr_t)PAGE_SIZE-1));
  945. /* Don't access any other fields of hdr or req beyond this point, the read buffer
  946. * overlaps the request buffer and will clobber data in the request. This
  947. * saves us 128KB per request handler thread at the cost of this scary comment. */
  948. DLOG(INFO) << "[" << handler->token << "] READ " << std::hex << h << std::dec
  949. << "(" << h->fd << ") " << size << "@" << offset;
  950. if (size > MAX_READ) {
  951. return -EINVAL;
  952. }
  953. res = TEMP_FAILURE_RETRY(pread64(h->fd, read_buffer, size, offset));
  954. if (res == -1) {
  955. return -errno;
  956. }
  957. fuse_reply(fuse, unique, read_buffer, res);
  958. return NO_STATUS;
  959. }
  960. static int handle_write(struct fuse* fuse, struct fuse_handler* handler,
  961. const struct fuse_in_header* hdr, const struct fuse_write_in* req,
  962. const void* buffer)
  963. {
  964. struct fuse_write_out out;
  965. struct handle *h = static_cast<struct handle*>(id_to_ptr(req->fh));
  966. int res;
  967. __u8 aligned_buffer[req->size] __attribute__((__aligned__(PAGE_SIZE)));
  968. if (req->flags & O_DIRECT) {
  969. memcpy(aligned_buffer, buffer, req->size);
  970. buffer = (const __u8*) aligned_buffer;
  971. }
  972. DLOG(INFO) << "[" << handler->token << "] WRITE " << std::hex << h << std::dec
  973. << "(" << h->fd << ") " << req->size << "@" << req->offset;
  974. res = TEMP_FAILURE_RETRY(pwrite64(h->fd, buffer, req->size, req->offset));
  975. if (res == -1) {
  976. return -errno;
  977. }
  978. out.size = res;
  979. out.padding = 0;
  980. fuse_reply(fuse, hdr->unique, &out, sizeof(out));
  981. return NO_STATUS;
  982. }
  983. static int handle_statfs(struct fuse* fuse, struct fuse_handler* handler,
  984. const struct fuse_in_header* hdr)
  985. {
  986. char path[PATH_MAX];
  987. struct statfs stat;
  988. struct fuse_statfs_out out;
  989. int res;
  990. pthread_mutex_lock(&fuse->global->lock);
  991. DLOG(INFO) << "[" << handler->token << "] STATFS";
  992. res = get_node_path_locked(&fuse->global->root, path, sizeof(path));
  993. pthread_mutex_unlock(&fuse->global->lock);
  994. if (res < 0) {
  995. return -ENOENT;
  996. }
  997. if (TEMP_FAILURE_RETRY(statfs(fuse->global->root.name, &stat)) == -1) {
  998. return -errno;
  999. }
  1000. memset(&out, 0, sizeof(out));
  1001. out.st.blocks = stat.f_blocks;
  1002. out.st.bfree = stat.f_bfree;
  1003. out.st.bavail = stat.f_bavail;
  1004. out.st.files = stat.f_files;
  1005. out.st.ffree = stat.f_ffree;
  1006. out.st.bsize = stat.f_bsize;
  1007. out.st.namelen = stat.f_namelen;
  1008. out.st.frsize = stat.f_frsize;
  1009. fuse_reply(fuse, hdr->unique, &out, sizeof(out));
  1010. return NO_STATUS;
  1011. }
  1012. static int handle_release(struct fuse* fuse, struct fuse_handler* handler,
  1013. const struct fuse_in_header* hdr, const struct fuse_release_in* req)
  1014. {
  1015. struct handle *h = static_cast<struct handle*>(id_to_ptr(req->fh));
  1016. DLOG(INFO) << "[" << handler->token << "] RELEASE " << std::hex << h << std::dec
  1017. << "(" << h->fd << ")";
  1018. close(h->fd);
  1019. free(h);
  1020. return 0;
  1021. }
  1022. static int handle_fsync(struct fuse* fuse, struct fuse_handler* handler,
  1023. const struct fuse_in_header* hdr, const struct fuse_fsync_in* req)
  1024. {
  1025. bool is_dir = (hdr->opcode == FUSE_FSYNCDIR);
  1026. bool is_data_sync = req->fsync_flags & 1;
  1027. int fd = -1;
  1028. if (is_dir) {
  1029. struct dirhandle *dh = static_cast<struct dirhandle*>(id_to_ptr(req->fh));
  1030. fd = dirfd(dh->d);
  1031. } else {
  1032. struct handle *h = static_cast<struct handle*>(id_to_ptr(req->fh));
  1033. fd = h->fd;
  1034. }
  1035. DLOG(INFO) << "[" << handler->token << "] " << (is_dir ? "FSYNCDIR" : "FSYNC") << " "
  1036. << std::hex << req->fh << std::dec << "(" << fd << ") is_data_sync=" << is_data_sync;
  1037. int res = is_data_sync ? fdatasync(fd) : fsync(fd);
  1038. if (res == -1) {
  1039. return -errno;
  1040. }
  1041. return 0;
  1042. }
  1043. static int handle_flush(struct fuse* fuse, struct fuse_handler* handler,
  1044. const struct fuse_in_header* hdr)
  1045. {
  1046. DLOG(INFO) << "[" << handler->token << "] FLUSH";
  1047. return 0;
  1048. }
  1049. static int handle_opendir(struct fuse* fuse, struct fuse_handler* handler,
  1050. const struct fuse_in_header* hdr, const struct fuse_open_in* req)
  1051. {
  1052. struct node* node;
  1053. char path[PATH_MAX];
  1054. struct fuse_open_out out = {};
  1055. struct dirhandle *h;
  1056. pthread_mutex_lock(&fuse->global->lock);
  1057. node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid, path, sizeof(path));
  1058. DLOG(INFO) << "[" << handler->token << "] OPENDIR @ " << std::hex << hdr->nodeid
  1059. << " (" << (node ? node->name : "?") << ")";
  1060. pthread_mutex_unlock(&fuse->global->lock);
  1061. if (!node) {
  1062. return -ENOENT;
  1063. }
  1064. if (!check_caller_access_to_node(fuse, hdr, node, R_OK)) {
  1065. return -EACCES;
  1066. }
  1067. h = static_cast<struct dirhandle*>(malloc(sizeof(*h)));
  1068. if (!h) {
  1069. return -ENOMEM;
  1070. }
  1071. DLOG(INFO) << "[" << handler->token << "] OPENDIR " << path;
  1072. h->d = opendir(path);
  1073. if (!h->d) {
  1074. free(h);
  1075. return -errno;
  1076. }
  1077. out.fh = ptr_to_id(h);
  1078. out.open_flags = 0;
  1079. fuse_reply(fuse, hdr->unique, &out, sizeof(out));
  1080. return NO_STATUS;
  1081. }
  1082. static int handle_readdir(struct fuse* fuse, struct fuse_handler* handler,
  1083. const struct fuse_in_header* hdr, const struct fuse_read_in* req)
  1084. {
  1085. char buffer[8192];
  1086. struct fuse_dirent *fde = (struct fuse_dirent*) buffer;
  1087. struct dirent *de;
  1088. struct dirhandle *h = static_cast<struct dirhandle*>(id_to_ptr(req->fh));
  1089. DLOG(INFO) << "[" << handler->token << "] READDIR " << h;
  1090. if (req->offset == 0) {
  1091. /* rewinddir() might have been called above us, so rewind here too */
  1092. DLOG(INFO) << "[" << handler->token << "] calling rewinddir()";
  1093. rewinddir(h->d);
  1094. }
  1095. de = readdir(h->d);
  1096. if (!de) {
  1097. return 0;
  1098. }
  1099. fde->ino = FUSE_UNKNOWN_INO;
  1100. /* increment the offset so we can detect when rewinddir() seeks back to the beginning */
  1101. fde->off = req->offset + 1;
  1102. fde->type = de->d_type;
  1103. fde->namelen = strlen(de->d_name);
  1104. memcpy(fde->name, de->d_name, fde->namelen + 1);
  1105. fuse_reply(fuse, hdr->unique, fde,
  1106. FUSE_DIRENT_ALIGN(sizeof(struct fuse_dirent) + fde->namelen));
  1107. return NO_STATUS;
  1108. }
  1109. static int handle_releasedir(struct fuse* fuse, struct fuse_handler* handler,
  1110. const struct fuse_in_header* hdr, const struct fuse_release_in* req)
  1111. {
  1112. struct dirhandle *h = static_cast<struct dirhandle*>(id_to_ptr(req->fh));
  1113. DLOG(INFO) << "[" << handler->token << "] RELEASEDIR " << h;
  1114. closedir(h->d);
  1115. free(h);
  1116. return 0;
  1117. }
  1118. static int handle_init(struct fuse* fuse, struct fuse_handler* handler,
  1119. const struct fuse_in_header* hdr, const struct fuse_init_in* req)
  1120. {
  1121. struct fuse_init_out out;
  1122. size_t fuse_struct_size;
  1123. DLOG(INFO) << "[" << handler->token << "] INIT ver=" << req->major << "." << req->minor
  1124. << " maxread=" << req->max_readahead << " flags=" << std::hex << req->flags;
  1125. /* Kernel 2.6.16 is the first stable kernel with struct fuse_init_out
  1126. * defined (fuse version 7.6). The structure is the same from 7.6 through
  1127. * 7.22. Beginning with 7.23, the structure increased in size and added
  1128. * new parameters.
  1129. */
  1130. if (req->major != FUSE_KERNEL_VERSION || req->minor < 6) {
  1131. LOG(ERROR) << "Fuse kernel version mismatch: Kernel version "
  1132. << req->major << "." << req->minor
  1133. << ", Expected at least " << FUSE_KERNEL_VERSION << ".6";
  1134. return -1;
  1135. }
  1136. /* We limit ourselves to 15 because we don't handle BATCH_FORGET yet */
  1137. out.minor = MIN(req->minor, 15);
  1138. fuse_struct_size = sizeof(out);
  1139. #if defined(FUSE_COMPAT_22_INIT_OUT_SIZE)
  1140. /* FUSE_KERNEL_VERSION >= 23. */
  1141. /* Since we return minor version 15, the kernel does not accept the latest
  1142. * fuse_init_out size. We need to use FUSE_COMPAT_22_INIT_OUT_SIZE always.*/
  1143. fuse_struct_size = FUSE_COMPAT_22_INIT_OUT_SIZE;
  1144. #endif
  1145. out.major = FUSE_KERNEL_VERSION;
  1146. out.max_readahead = req->max_readahead;
  1147. out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
  1148. out.max_background = 32;
  1149. out.congestion_threshold = 32;
  1150. out.max_write = MAX_WRITE;
  1151. fuse_reply(fuse, hdr->unique, &out, fuse_struct_size);
  1152. return NO_STATUS;
  1153. }
  1154. static int handle_canonical_path(struct fuse* fuse, struct fuse_handler* handler,
  1155. const struct fuse_in_header *hdr)
  1156. {
  1157. struct node* node;
  1158. char path[PATH_MAX];
  1159. int len;
  1160. pthread_mutex_lock(&fuse->global->lock);
  1161. node = lookup_node_and_path_by_id_locked(fuse, hdr->nodeid,
  1162. path, sizeof(path));
  1163. DLOG(INFO) << "[" << handler->token << "] CANONICAL_PATH @ " << std::hex << hdr->nodeid
  1164. << std::dec << " (" << (node ? node->name : "?") << ")";
  1165. pthread_mutex_unlock(&fuse->global->lock);
  1166. if (!node) {
  1167. return -ENOENT;
  1168. }
  1169. if (!check_caller_access_to_node(fuse, hdr, node, R_OK)) {
  1170. return -EACCES;
  1171. }
  1172. len = strlen(path);
  1173. if (len + 1 > PATH_MAX)
  1174. len = PATH_MAX - 1;
  1175. path[PATH_MAX - 1] = 0;
  1176. fuse_reply(fuse, hdr->unique, path, len + 1);
  1177. return NO_STATUS;
  1178. }
  1179. static int handle_fuse_request(struct fuse *fuse, struct fuse_handler* handler,
  1180. const struct fuse_in_header *hdr, const void *data, size_t data_len)
  1181. {
  1182. switch (hdr->opcode) {
  1183. case FUSE_LOOKUP: { /* bytez[] -> entry_out */
  1184. const char *name = static_cast<const char*>(data);
  1185. return handle_lookup(fuse, handler, hdr, name);
  1186. }
  1187. case FUSE_FORGET: {
  1188. const struct fuse_forget_in *req = static_cast<const struct fuse_forget_in*>(data);
  1189. return handle_forget(fuse, handler, hdr, req);
  1190. }
  1191. case FUSE_GETATTR: { /* getattr_in -> attr_out */
  1192. const struct fuse_getattr_in *req = static_cast<const struct fuse_getattr_in*>(data);
  1193. return handle_getattr(fuse, handler, hdr, req);
  1194. }
  1195. case FUSE_SETATTR: { /* setattr_in -> attr_out */
  1196. const struct fuse_setattr_in *req = static_cast<const struct fuse_setattr_in*>(data);
  1197. return handle_setattr(fuse, handler, hdr, req);
  1198. }
  1199. // case FUSE_READLINK:
  1200. // case FUSE_SYMLINK:
  1201. case FUSE_MKNOD: { /* mknod_in, bytez[] -> entry_out */
  1202. const struct fuse_mknod_in *req = static_cast<const struct fuse_mknod_in*>(data);
  1203. const char *name = ((const char*) data) + sizeof(*req);
  1204. return handle_mknod(fuse, handler, hdr, req, name);
  1205. }
  1206. case FUSE_MKDIR: { /* mkdir_in, bytez[] -> entry_out */
  1207. const struct fuse_mkdir_in *req = static_cast<const struct fuse_mkdir_in*>(data);
  1208. const char *name = ((const char*) data) + sizeof(*req);
  1209. return handle_mkdir(fuse, handler, hdr, req, name);
  1210. }
  1211. case FUSE_UNLINK: { /* bytez[] -> */
  1212. const char *name = static_cast<const char*>(data);
  1213. return handle_unlink(fuse, handler, hdr, name);
  1214. }
  1215. case FUSE_RMDIR: { /* bytez[] -> */
  1216. const char *name = static_cast<const char*>(data);
  1217. return handle_rmdir(fuse, handler, hdr, name);
  1218. }
  1219. case FUSE_RENAME: { /* rename_in, oldname, newname -> */
  1220. const struct fuse_rename_in *req = static_cast<const struct fuse_rename_in*>(data);
  1221. const char *old_name = ((const char*) data) + sizeof(*req);
  1222. const char *new_name = old_name + strlen(old_name) + 1;
  1223. return handle_rename(fuse, handler, hdr, req, old_name, new_name);
  1224. }
  1225. // case FUSE_LINK:
  1226. case FUSE_OPEN: { /* open_in -> open_out */
  1227. const struct fuse_open_in *req = static_cast<const struct fuse_open_in*>(data);
  1228. return handle_open(fuse, handler, hdr, req);
  1229. }
  1230. case FUSE_READ: { /* read_in -> byte[] */
  1231. const struct fuse_read_in *req = static_cast<const struct fuse_read_in*>(data);
  1232. return handle_read(fuse, handler, hdr, req);
  1233. }
  1234. case FUSE_WRITE: { /* write_in, byte[write_in.size] -> write_out */
  1235. const struct fuse_write_in *req = static_cast<const struct fuse_write_in*>(data);
  1236. const void* buffer = (const __u8*)data + sizeof(*req);
  1237. return handle_write(fuse, handler, hdr, req, buffer);
  1238. }
  1239. case FUSE_STATFS: { /* getattr_in -> attr_out */
  1240. return handle_statfs(fuse, handler, hdr);
  1241. }
  1242. case FUSE_RELEASE: { /* release_in -> */
  1243. const struct fuse_release_in *req = static_cast<const struct fuse_release_in*>(data);
  1244. return handle_release(fuse, handler, hdr, req);
  1245. }
  1246. case FUSE_FSYNC:
  1247. case FUSE_FSYNCDIR: {
  1248. const struct fuse_fsync_in *req = static_cast<const struct fuse_fsync_in*>(data);
  1249. return handle_fsync(fuse, handler, hdr, req);
  1250. }
  1251. // case FUSE_SETXATTR:
  1252. // case FUSE_GETXATTR:
  1253. // case FUSE_LISTXATTR:
  1254. // case FUSE_REMOVEXATTR:
  1255. case FUSE_FLUSH: {
  1256. return handle_flush(fuse, handler, hdr);
  1257. }
  1258. case FUSE_OPENDIR: { /* open_in -> open_out */
  1259. const struct fuse_open_in *req = static_cast<const struct fuse_open_in*>(data);
  1260. return handle_opendir(fuse, handler, hdr, req);
  1261. }
  1262. case FUSE_READDIR: {
  1263. const struct fuse_read_in *req = static_cast<const struct fuse_read_in*>(data);
  1264. return handle_readdir(fuse, handler, hdr, req);
  1265. }
  1266. case FUSE_RELEASEDIR: { /* release_in -> */
  1267. const struct fuse_release_in *req = static_cast<const struct fuse_release_in*>(data);
  1268. return handle_releasedir(fuse, handler, hdr, req);
  1269. }
  1270. case FUSE_INIT: { /* init_in -> init_out */
  1271. const struct fuse_init_in *req = static_cast<const struct fuse_init_in*>(data);
  1272. return handle_init(fuse, handler, hdr, req);
  1273. }
  1274. case FUSE_CANONICAL_PATH: { /* nodeid -> bytez[] */
  1275. return handle_canonical_path(fuse, handler, hdr);
  1276. }
  1277. default: {
  1278. DLOG(INFO) << "[" << handler->token << "] NOTIMPL op=" << hdr->opcode
  1279. << "uniq=" << std::hex << hdr->unique << "nid=" << hdr->nodeid << std::dec;
  1280. return -ENOSYS;
  1281. }
  1282. }
  1283. }
  1284. void handle_fuse_requests(struct fuse_handler* handler)
  1285. {
  1286. struct fuse* fuse = handler->fuse;
  1287. for (;;) {
  1288. ssize_t len = TEMP_FAILURE_RETRY(read(fuse->fd,
  1289. handler->request_buffer, sizeof(handler->request_buffer)));
  1290. if (len == -1) {
  1291. if (errno == ENODEV) {
  1292. LOG(ERROR) << "[" << handler->token << "] someone stole our marbles!";
  1293. exit(2);
  1294. }
  1295. PLOG(ERROR) << "[" << handler->token << "] handle_fuse_requests";
  1296. continue;
  1297. }
  1298. if (static_cast<size_t>(len) < sizeof(struct fuse_in_header)) {
  1299. LOG(ERROR) << "[" << handler->token << "] request too short: len=" << len;
  1300. continue;
  1301. }
  1302. const struct fuse_in_header* hdr =
  1303. reinterpret_cast<const struct fuse_in_header*>(handler->request_buffer);
  1304. if (hdr->len != static_cast<size_t>(len)) {
  1305. LOG(ERROR) << "[" << handler->token << "] malformed header: len=" << len
  1306. << ", hdr->len=" << hdr->len;
  1307. continue;
  1308. }
  1309. const void *data = handler->request_buffer + sizeof(struct fuse_in_header);
  1310. size_t data_len = len - sizeof(struct fuse_in_header);
  1311. __u64 unique = hdr->unique;
  1312. int res = handle_fuse_request(fuse, handler, hdr, data, data_len);
  1313. /* We do not access the request again after this point because the underlying
  1314. * buffer storage may have been reused while processing the request. */
  1315. if (res != NO_STATUS) {
  1316. if (res) {
  1317. DLOG(INFO) << "[" << handler->token << "] ERROR " << res;
  1318. }
  1319. fuse_status(fuse, unique, res);
  1320. }
  1321. }
  1322. }