Beispiel #1
0
/* checks an individual file for hard links and updates its cicrular linked
 * list, also updates the sizes of the parent dirs */
static void hlink_check(struct dir *d) {
    struct dir *t, *pt, *par;
    int i;

    /* add to links table */
    khiter_t k = kh_put(hl, links, d, &i);

    /* found in the table? update hlnk */
    if(!i) {
        t = d->hlnk = kh_key(links, k);
        if(t->hlnk != NULL)
            for(t=t->hlnk; t->hlnk!=d->hlnk; t=t->hlnk)
                ;
        t->hlnk = d;
    }

    /* now update the sizes of the parent directories,
     * This works by only counting this file in the parent directories where this
     * file hasn't been counted yet, which can be determined from the hlnk list.
     * XXX: This may not be the most efficient algorithm to do this */
    for(i=1,par=d->parent; i&∥ par=par->parent) {
        if(d->hlnk)
            for(t=d->hlnk; i&&t!=d; t=t->hlnk)
                for(pt=t->parent; i&&pt; pt=pt->parent)
                    if(pt==par)
                        i=0;
        if(i) {
            par->size = adds64(par->size, d->size);
            par->asize = adds64(par->size, d->asize);
        }
    }
}
Beispiel #2
0
/* removes item from the hlnk circular linked list and size counts of the parents */
static void freedir_hlnk(struct dir *d) {
  struct dir *t, *par, *pt;
  int i;

  if(!(d->flags & FF_HLNKC))
    return;

  /* remove size from parents.
   * This works the same as with adding: only the parents in which THIS is the
   * only occurence of the hard link will be modified, if the same file still
   * exists within the parent it shouldn't get removed from the count.
   * XXX: Same note as for dir_mem.c / hlink_check():
   *      this is probably not the most efficient algorithm */
  for(i=1,par=d->parent; i&∥ par=par->parent) {
    if(d->hlnk)
      for(t=d->hlnk; i&&t!=d; t=t->hlnk)
        for(pt=t->parent; i&&pt; pt=pt->parent)
          if(pt==par)
            i=0;
    if(i) {
      par->size = adds64(par->size, -d->size);
      par->asize = adds64(par->size, -d->asize);
    }
  }

  /* remove from hlnk */
  if(d->hlnk) {
    for(t=d->hlnk; t->hlnk!=d; t=t->hlnk)
      ;
    t->hlnk = d->hlnk;
  }
}
Beispiel #3
0
void addparentstats(struct dir *d, int64_t size, int64_t asize, int items) {
  while(d) {
    d->size = adds64(d->size, size);
    d->asize = adds64(d->asize, asize);
    d->items += items;
    d = d->parent;
  }
}