Plan 9 from Bell Labs’s /usr/web/sources/contrib/de0u/root/sys/src/cmd/divergefs/holemanager.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <String.h>
#include <bio.h>
#include "common.h"
#include "debug.h"
#include "string.h"
#include "collection.h"
#include "function.h"
#include "array.h"
#include "set.h"
#include "file.h"
#include "filepath.h"
#include "holemanager.h"

enum 
{ 
  DEBUG_HOLEMANAGER = false,
  HOLEMANAGER_DUMPFILE_PERM = 0755L
};

struct HoleManager
{
  Set *holes;
  char *holefile;
  bool isdirty;
};

static collection_do_ret holemanager_dump_holes_each(void *p, void *arg)
{
  int result;
  char *filename = (char *)p;
  Biobuf *biohole = (Biobuf *)arg;

  assert_valid(filename);
  assert(strlen(filename) > 0);
  assert_valid(biohole);
  
  result = Bprint(biohole, "%s\n", filename);
  if(result == Beof)
  {
    WARNING(DEBUG_HOLEMANAGER, 
      "holemanager_dump_holes_each failed to write to file");
  }

  // NOISE(DEBUG_HOLEMANAGER, "holemanager_dump_holes_each dumping %s", filename);
  return COLLECTION_DO_CONTINUE;
}

static void holemanager_dump_holes(HoleManager *self)
{
  int result;
  Biobuf *biohole;
  assert_valid(self);
  
  biohole = Bopen(self->holefile, OWRITE);
  if(biohole == nil)
  {
    WARNING(DEBUG_HOLEMANAGER, 
      "holemanager_dump_holes unable to open dump file");
    return;
  }

  set_do(self->holes, holemanager_dump_holes_each, biohole);
  result = Bterm(biohole);
  NOISE(DEBUG_HOLEMANAGER, "holemanager_dump_holes total: %ud Bterm returns %d",
    set_size(self->holes), result);
  NOISE(DEBUG_HOLEMANAGER, "holemanager_dump_holes unsetting dirty bit");
  self->isdirty = false;
}

static void holemanager_read_holes(HoleManager *self)
{
  int result;
  int fd;
  char *filename;
  Biobuf biohole;
  assert_valid(self);

  fd = file_open(self->holefile, OREAD);
  if(!fd_isopen(fd))
  {
    NOISE(DEBUG_HOLEMANAGER, 
      "holemanager_read_holes unable to open hole file %s for reading",
      self->holefile);
    return;
  }

  result = Binit(&biohole, fd, OREAD);
  NOISE(DEBUG_HOLEMANAGER, "holemanager_read_holes Binit returns %s", result);
  
  while((filename = Brdstr(&biohole, '\n', 1)) != nil)
  {
    NOISE(DEBUG_HOLEMANAGER, 
      "holemanager_read_holes reading filename: %s len: %d", 
      filename, strlen(filename));
    set_add(self->holes, filename);
  }

  result = Bterm(&biohole);
  file_close(fd);
  NOISE(DEBUG_HOLEMANAGER, "holemanager_dump_holes Bterm returns %d", result);

  self->isdirty = false;
}

HoleManager *holemanager_new(char *holefile)
{
  HoleManager *result = (HoleManager *)emalloc_fs(sizeof(*result));
  result->holes = set_new(string_isequal, string_hash);
  result->isdirty = false;

  if(holefile != nil)
  {
    result->holefile = filepath_make_absolute_cstr(holefile);
    holemanager_read_holes(result);
  }
  else
  {
    result->holefile = estrdup_fs("/tmp/holes");
  }

  NOISE(DEBUG_HOLEMANAGER, "holemanager_new holefile: %s", result->holefile);
  return result;
}

void holemanager_free(HoleManager *self)
{
  if(self == nil)
  {
    return;
  }

  free(self->holefile);
  set_free_with(self->holes, free);
  free(self);
}

void holemanager_add(HoleManager *self, char *holepath)
{
  assert_valid(self);
  assert_valid(holepath);
  NOISE(DEBUG_HOLEMANAGER, "holemanager_add adding hole: %s", holepath);

  set_add(self->holes, estrdup_fs(holepath));
  NOISE(DEBUG_HOLEMANAGER, "holemanager_add setting dirty bit");
  self->isdirty = true;

  holemanager_dump_holes(self);
}

bool holemanager_includes(HoleManager *self, char *holepath)
{
  bool result;
  assert_valid(self);
  assert_valid(holepath);

  result = set_includes(self->holes, holepath);
  NOISE(DEBUG_HOLEMANAGER, "holemanager_includes path: %s result: %d", 
    holepath, result);
  return result;
}

void holemanager_remove(HoleManager *self, char *holepath)
{
  bool result;
  assert_valid(self);
  assert_valid(holepath);

  result = set_remove(self->holes, holepath);
  NOISE(DEBUG_HOLEMANAGER, 
    "holemanager_remove removing: %s with result: %d", holepath, result);

  self->isdirty = true;
  NOISE(DEBUG_HOLEMANAGER, "holemanager_add setting dirty bit");

  holemanager_dump_holes(self);
}



Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].