~ubuntu-branches/ubuntu/wily/glusterfs/wily

« back to all changes in this revision

Viewing changes to xlators/storage/posix/src/posix.c

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Matthäi
  • Date: 2011-06-26 21:00:42 UTC
  • mfrom: (1.3.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20110626210042-ps1aim0cwz06tkx1
Tags: 3.2.1-1
* New upstream release.
  - Refresh patch 02-spelling-error.
* Wrap dependencies.
* Merge libglusterfs0 and libglusterfs-dev package to glusterfs-common.
  Closes: #630147
* Use python-module.mk and remove useless python bytecode files.
  Closes: #630146

Show diffs side-by-side

added added

removed removed

Lines of Context:
404
404
}
405
405
 
406
406
 
 
407
static int
 
408
is_fresh_file (struct stat *stat)
 
409
{
 
410
        struct timeval tv;
 
411
 
 
412
        gettimeofday (&tv, NULL);
 
413
 
 
414
        if ((stat->st_ctime >= (tv.tv_sec - 1))
 
415
            && (stat->st_ctime <= tv.tv_sec))
 
416
                return 1;
 
417
 
 
418
        return 0;
 
419
}
 
420
 
 
421
 
 
422
int
 
423
posix_gfid_heal (xlator_t *this, const char *path, dict_t *xattr_req)
 
424
{
 
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:
 
428
 
 
429
                   {create thread}       |    {lookup thread}
 
430
                                         |
 
431
                                         t0
 
432
                      mkdir ("name")     |
 
433
                                         t1
 
434
                                         |     posix_gfid_set ("name", 2);
 
435
                                         t2
 
436
             posix_gfid_set ("name", 1); |
 
437
                                         t3
 
438
                      lstat ("name");    |     lstat ("name");
 
439
 
 
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
 
443
 
 
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.
 
448
        */
 
449
 
 
450
        uuid_t       uuid_curr;
 
451
        int          ret = 0;
 
452
        struct stat  stat = {0, };
 
453
 
 
454
        if (!xattr_req)
 
455
                goto out;
 
456
 
 
457
        if (sys_lstat (path, &stat) != 0)
 
458
                goto out;
 
459
 
 
460
        ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
 
461
        if (ret != 16) {
 
462
                if (is_fresh_file (&stat)) {
 
463
                        ret = -1;
 
464
                        errno = ENOENT;
 
465
                        goto out;
 
466
                }
 
467
        }
 
468
 
 
469
        ret = posix_gfid_set (this, path, xattr_req);
 
470
out:
 
471
        return ret;
 
472
}
 
473
 
 
474
 
407
475
int32_t
408
476
posix_lookup (call_frame_t *frame, xlator_t *this,
409
477
              loc_t *loc, dict_t *xattr_req)
425
493
 
426
494
        MAKE_REAL_PATH (real_path, this, loc->path);
427
495
 
428
 
        posix_gfid_set (this, real_path, xattr_req);
 
496
        posix_gfid_heal (this, real_path, xattr_req);
429
497
 
430
498
        op_ret   = posix_lstat_with_gfid (this, real_path, &buf);
431
499
        op_errno = errno;