{"action":"created","issue":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcsfuse/issues/31","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/gcsfuse/issues/31/labels{/name}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcsfuse/issues/31/comments","events_url":"https://api.github.com/repos/GoogleCloudPlatform/gcsfuse/issues/31/events","html_url":"https://github.com/GoogleCloudPlatform/gcsfuse/issues/31","id":65563360,"number":31,"title":"Readdir unconditionally behaves like implicit directories are enabled","user":{"login":"jacobsa","id":202895,"avatar_url":"https://avatars.githubusercontent.com/u/202895?v=3","gravatar_id":"","url":"https://api.github.com/users/jacobsa","html_url":"https://github.com/jacobsa","followers_url":"https://api.github.com/users/jacobsa/followers","following_url":"https://api.github.com/users/jacobsa/following{/other_user}","gists_url":"https://api.github.com/users/jacobsa/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobsa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobsa/subscriptions","organizations_url":"https://api.github.com/users/jacobsa/orgs","repos_url":"https://api.github.com/users/jacobsa/repos","events_url":"https://api.github.com/users/jacobsa/events{/privacy}","received_events_url":"https://api.github.com/users/jacobsa/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"jacobsa","id":202895,"avatar_url":"https://avatars.githubusercontent.com/u/202895?v=3","gravatar_id":"","url":"https://api.github.com/users/jacobsa","html_url":"https://github.com/jacobsa","followers_url":"https://api.github.com/users/jacobsa/followers","following_url":"https://api.github.com/users/jacobsa/following{/other_user}","gists_url":"https://api.github.com/users/jacobsa/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobsa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobsa/subscriptions","organizations_url":"https://api.github.com/users/jacobsa/orgs","repos_url":"https://api.github.com/users/jacobsa/repos","events_url":"https://api.github.com/users/jacobsa/events{/privacy}","received_events_url":"https://api.github.com/users/jacobsa/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcsfuse/milestones/1","html_url":"https://github.com/GoogleCloudPlatform/gcsfuse/milestones/beta","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/gcsfuse/milestones/1/labels","id":1030190,"number":1,"title":"beta","description":null,"creator":{"login":"jacobsa","id":202895,"avatar_url":"https://avatars.githubusercontent.com/u/202895?v=3","gravatar_id":"","url":"https://api.github.com/users/jacobsa","html_url":"https://github.com/jacobsa","followers_url":"https://api.github.com/users/jacobsa/followers","following_url":"https://api.github.com/users/jacobsa/following{/other_user}","gists_url":"https://api.github.com/users/jacobsa/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobsa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobsa/subscriptions","organizations_url":"https://api.github.com/users/jacobsa/orgs","repos_url":"https://api.github.com/users/jacobsa/repos","events_url":"https://api.github.com/users/jacobsa/events{/privacy}","received_events_url":"https://api.github.com/users/jacobsa/received_events","type":"User","site_admin":false},"open_issues":10,"closed_issues":3,"state":"open","created_at":"2015-03-19T23:14:49Z","updated_at":"2015-03-31T22:45:09Z","due_on":null,"closed_at":null},"comments":2,"created_at":"2015-03-31T22:45:09Z","updated_at":"2015-03-31T22:58:23Z","closed_at":null,"body":"The tightening of tests in #30 revealed another problem that has been on my radar but which I haven't actually written down yet. Say the objects in a bucket are:\r\n\r\n* foo\r\n* bar/baz\r\n\r\nThen when we get a readdir op from fuse for the root inode, we call GCS's Objects.list method with a delimiter of \"/\" and a prefix of \"\". That returns an object named \"foo\" and a collapsed run named \"bar/\", so we return directory entries for a file named \"foo\" and for a directory named \"bar\".\r\n\r\nThe problem is that, unless the user is running with `--implicit_dirs` (see [semantics.md](https://github.com/GoogleCloudPlatform/gcsfuse/blob/master/docs/semantics.md)), there is no accessible directory named \"bar\". When the kernel comes back to look up such an inode, it will receive `ENOENT`.\r\n\r\nOn OS X, when `ls` encounters this situation it prints an easy to miss error and then ignores the entry (which is why the problem hasn't been in my face):\r\n\r\n```\r\n% ls -l mp\r\nls: bar: No such file or directory\r\ntotal 0\r\n-rwx------  1 jacobsa  eng  0 Apr  1 09:42 foo\r\n```\r\n\r\nOn Linux it's a bit more obvious:\r\n\r\n```\r\n% ls -l mp\r\nls: cannot access mp/bar: No such file or directory\r\ntotal 0\r\nd????????? ? ?       ?   ?            ? bar\r\n-rwx------ 1 jacobsa eng 0 Apr  1 09:42 foo\r\n```"},"comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcsfuse/issues/comments/88277789","html_url":"https://github.com/GoogleCloudPlatform/gcsfuse/issues/31#issuecomment-88277789","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/gcsfuse/issues/31","id":88277789,"user":{"login":"jacobsa","id":202895,"avatar_url":"https://avatars.githubusercontent.com/u/202895?v=3","gravatar_id":"","url":"https://api.github.com/users/jacobsa","html_url":"https://github.com/jacobsa","followers_url":"https://api.github.com/users/jacobsa/followers","following_url":"https://api.github.com/users/jacobsa/following{/other_user}","gists_url":"https://api.github.com/users/jacobsa/gists{/gist_id}","starred_url":"https://api.github.com/users/jacobsa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jacobsa/subscriptions","organizations_url":"https://api.github.com/users/jacobsa/orgs","repos_url":"https://api.github.com/users/jacobsa/repos","events_url":"https://api.github.com/users/jacobsa/events{/privacy}","received_events_url":"https://api.github.com/users/jacobsa/received_events","type":"User","site_admin":false},"created_at":"2015-03-31T22:58:23Z","updated_at":"2015-03-31T22:58:23Z","body":"I favor option (1): it seems most internally-consistent—we rely on StatObject all over the place—and it aligns well with the idea of a stat cache. If we ever got (3) from the GCS team, that would be even better."}}