408
is_fresh_file (struct stat *stat)
412
gettimeofday (&tv, NULL);
414
if ((stat->st_ctime >= (tv.tv_sec - 1))
415
&& (stat->st_ctime <= tv.tv_sec))
423
posix_gfid_heal (xlator_t *this, const char *path, dict_t *xattr_req)
425
/* The purpose of this function is to prevent a race
426
where an inode creation FOP (like mkdir/mknod/create etc)
427
races with lookup in the following way:
429
{create thread} | {lookup thread}
434
| posix_gfid_set ("name", 2);
436
posix_gfid_set ("name", 1); |
438
lstat ("name"); | lstat ("name");
440
In the above case mkdir FOP would have resulted with GFID 2 while
441
it should have been GFID 1. It matters in the case where GFID would
442
have gotten set to 1 on other subvolumes of replciate/distribute
444
The "solution" here is that, if we detect lookup is attempting to
445
set a GFID on a file which is created very recently, but does not
446
yet have a GFID (i.e, between t1 and t2), then "fake" it as though
447
posix_gfid_heal was called at t0 instead.
452
struct stat stat = {0, };
457
if (sys_lstat (path, &stat) != 0)
460
ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
462
if (is_fresh_file (&stat)) {
469
ret = posix_gfid_set (this, path, xattr_req);
408
476
posix_lookup (call_frame_t *frame, xlator_t *this,
409
477
loc_t *loc, dict_t *xattr_req)
426
494
MAKE_REAL_PATH (real_path, this, loc->path);
428
posix_gfid_set (this, real_path, xattr_req);
496
posix_gfid_heal (this, real_path, xattr_req);
430
498
op_ret = posix_lstat_with_gfid (this, real_path, &buf);
431
499
op_errno = errno;