Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On filesystems which do not support birthtime, stats.birthtime can be greater than stats.mtime #2222

Closed
jorangreef opened this issue Jul 22, 2015 · 11 comments
Labels
doc Issues and PRs related to the documentations. fs Issues and PRs related to the fs subsystem / file system. good first issue Issues that are suitable for first-time contributors.

Comments

@jorangreef
Copy link
Contributor

stats.birthtime tracks ctime on filesystems which do not support birthtime, even if stats.ctime > stats.mtime or stats.ctime > stats.atime.

It would be better in this case if stats.birthtime be set to the earliest of all available timestamps.

Here is a test to reproduce, which should pass on OS X and fail on Ubuntu:

var fs = require('fs');
console.log('creating...');
try {
  fs.unlinkSync('testbirthtime');
} catch (error) {}
fs.writeFileSync('testbirthtime', '');
console.log('statting...');
var before = fs.statSync('testbirthtime');
if (before.mtime.getTime() === before.ctime.getTime() && before.ctime.getTime() === before.birthtime.getTime()) {
  console.log('stats.mtime===stats.ctime===stats.birthtime');
} else {
  console.log(JSON.stringify(before));
  // should never be here, unless the test is faulty.
  throw new Error('expected stats.mtime===stats.ctime===stats.birthtime after create');
}
// give enough time for filesystem timestamp granularity
console.log('waiting 3 seconds...');
setTimeout(
  function() {
    console.log('changing mode to bump ctime...');
    fs.chmodSync('testbirthtime', '777');
    console.log('statting again...');
    var after = fs.statSync('testbirthtime');
    try {
      fs.unlinkSync('testbirthtime');
    } catch (error) {}
    if (after.birthtime.getTime() === before.birthtime.getTime()) {
      console.log('===========');
      console.log('TEST PASSED');
      console.log('stats.birthtime stayed the same after chmod');
    } else {
      console.log('===========');
      console.log('TEST FAILED');
      console.log('stats.birthtime after chmod !== stats.birthtime at creation');
      if (after.birthtime.getTime() > before.birthtime.getTime()) {
        console.log('stats.birthtime has gone forward in time');
      } else {
        console.log('stats.birthtime has gone backward in time');
      }
      if (after.mtime.getTime() === before.mtime.getTime()) {
        console.log('stats.mtime stayed the same after chmod');
      }
      if (after.birthtime.getTime() === after.ctime.getTime()) {
        console.log('stats.birthtime now equals newer stats.ctime');
        console.log('where birthtime is not supported by filesystem:');
        console.log('  stats.birthtime should be earlier of stats.mtime and stats.ctime');
      }
    }
  },
  3000
);
@silverwind silverwind added the fs Issues and PRs related to the fs subsystem / file system. label Jul 22, 2015
@brendanashworth brendanashworth self-assigned this Aug 15, 2015
brendanashworth added a commit to brendanashworth/libuv that referenced this issue Aug 16, 2015
When the operating system does not support birthtime for stat,
previously behaviour was to use the ctime (last changed) time instead.

This change instead enforces that uv_fs_stat will use the oldest
available time (of ctime, atime, and mtime) rather than arbitrarily
picking ctime.

Fixes: nodejs/node#2222
brendanashworth added a commit to brendanashworth/libuv that referenced this issue Aug 16, 2015
When the operating system does not support birthtime for stat,
previously behaviour was to use the ctime (last changed) time instead.

This change instead enforces that uv_fs_stat will use the oldest
available time (of ctime, atime, and mtime) rather than arbitrarily
picking ctime.

Fixes: nodejs/node#2222
@brendanashworth
Copy link
Contributor

@jorangreef thanks for reporting this. I've submitted a patch to our upstream dependency, libuv, which will hopefully make its way into the node codebase and fix the problem for you!

@brendanashworth brendanashworth added confirmed-bug Issues with confirmed bugs. libuv Issues and PRs related to the libuv dependency or the uv binding. labels Aug 16, 2015
brendanashworth added a commit to brendanashworth/libuv that referenced this issue Aug 16, 2015
When the operating system does not support birthtime for stat,
previously behaviour was to use the ctime (last changed) time instead.

This change instead enforces that uv_fs_stat will use the oldest
available time (of ctime, atime, and mtime) rather than arbitrarily
picking ctime.

Fixes: nodejs/node#2222
@jorangreef
Copy link
Contributor Author

Thanks for the patch @brendanashworth!

@ivan
Copy link
Contributor

ivan commented Aug 16, 2015

Why is it node's business to fabricate a birthtime when one isn't available? When Linux finally gains an API to look up the birth times that are already on the filesystem, will we need a birthTimesAreRealBirthTimes() API?

@brendanashworth
Copy link
Contributor

We don't have to close it just yet - it is still pertinent! :)

Why is it node's business to fabricate a birthtime when one isn't available? When Linux finally gains an API to look up the birth times that are already on the filesystem, will we need a birthTimesAreRealBirthTimes() API?

Not quite node, but libuv wants to provide a consistent API on all platforms. You could open an issue there if you'd like.

@brendanashworth
Copy link
Contributor

The upstream patch was not accepted because it broke backwards compatibility (and because it fabricated a birthtime when one wasn't available, wink @ivan).

@jorangreef I think the best way to solve this on the node.js side is a note in the documentation of fs.Stat. Would you be interested in sending a PR?

@brendanashworth brendanashworth removed their assignment Aug 19, 2015
@jorangreef
Copy link
Contributor Author

@brendanashworth sure, I will be away till next week.

@brendanashworth brendanashworth added good first issue Issues that are suitable for first-time contributors. doc Issues and PRs related to the documentations. and removed confirmed-bug Issues with confirmed bugs. libuv Issues and PRs related to the libuv dependency or the uv binding. labels Sep 14, 2015
@kthelgason
Copy link
Contributor

@jorangreef still planing on sending a PR for this?

@jorangreef
Copy link
Contributor Author

@kthelgason if you would like to that would be appreciated, otherwise I will.

@kthelgason
Copy link
Contributor

Done. Thanks @jorangreef for raising the issue. You can view the change in #5479 and comment on whether you think this clarifies things.

@thefourtheye
Copy link
Contributor

If this is going to be accepted as expected result, then I would recommend including a test as well. Perhaps the code in this issue would do?

@jorangreef
Copy link
Contributor Author

Thanks @kthelgason !

@thefourtheye this is only a docs change for clarification, and it's possible in all environments for btime to be > than atime or mtime, so I don't think a test is needed.

evanlucas pushed a commit that referenced this issue Mar 14, 2016
Clarifies the possibility of birthtime in the fs stat
object being greater than atime or mtime when not available
in the filesystem (see issue for further info).

Fixes: #2222
PR-URL: #5479
Reviewed-By: James M Snell <jasnell@gmail.com>
rvagg pushed a commit that referenced this issue Mar 16, 2016
Clarifies the possibility of birthtime in the fs stat
object being greater than atime or mtime when not available
in the filesystem (see issue for further info).

Fixes: #2222
PR-URL: #5479
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this issue Mar 17, 2016
Clarifies the possibility of birthtime in the fs stat
object being greater than atime or mtime when not available
in the filesystem (see issue for further info).

Fixes: #2222
PR-URL: #5479
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this issue Mar 21, 2016
Clarifies the possibility of birthtime in the fs stat
object being greater than atime or mtime when not available
in the filesystem (see issue for further info).

Fixes: #2222
PR-URL: #5479
Reviewed-By: James M Snell <jasnell@gmail.com>
MylesBorins pushed a commit that referenced this issue Mar 21, 2016
Clarifies the possibility of birthtime in the fs stat
object being greater than atime or mtime when not available
in the filesystem (see issue for further info).

Fixes: #2222
PR-URL: #5479
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc Issues and PRs related to the documentations. fs Issues and PRs related to the fs subsystem / file system. good first issue Issues that are suitable for first-time contributors.
Projects
None yet
Development

No branches or pull requests

6 participants