#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <signal.h>
#include <linux/unistd.h>

static int have_bdflush;

 _syscall2(int,bdflush, int, func, int, data);

char * bdparam[] = {
"Maximum fraction of LRU list to examine for dirty blocks",
"Maximum number of dirty blocks to write each time bdflush activated",
"Number of clean buffers to be loaded onto free list by refill_freelist",
"Dirty block threshold for activating bdflush in refill_freelist",
"Percentage of cache to scan for free clusters",
"Time for data buffers to age before flushing",
"Time for non-data (dir, bitmap, etc) buffers to age before flushing",
"Time buffer cache load average constant",
"LAV ratio (used to determine threshold for buffer fratricide)."
};

set_param(number, value){
  int i;
  i = bdflush(2 + 1 +(number<<1) ,value);
  if(i) printf("bdflush() returned %d\n", errno);
}

void sig_alarm() {
        int i;
	signal(SIGALRM, &sig_alarm);
	if(have_bdflush) {
	  alarm(5);
	  i = bdflush(1, 0);  /* Flush expired buffers */
	  if(i) have_bdflush = 0;  /* Haven't got it.  Oh Well */
	} else {
	  alarm(30);
	  sync();
	};
}

update(){
	int i;

	signal(SIGTERM, SIG_IGN);
	signal(SIGINT, SIG_IGN);
	for (i=0 ; i < OPEN_MAX ; i++)
		close(i);
	chdir("/");

	have_bdflush = 1;

	sig_alarm();
	while (1) {
		pause();
	}
}


main(int argc, char * argv[]){
  int i, j;
  char * pnt;
  int data;

  pnt = strrchr(argv[0],'/');
  if(!pnt) pnt = argv[0];
  else pnt++;

  if(strcmp(pnt,"update") == 0) {
    if (fork())
      exit(0);
    update();
  };

  if(argc<2) {
    if (fork())
      exit(0);
    for (i = 0; i < getdtablesize(); i++)
      (void) close(i);
    i = bdflush(0,0); /* Assume we want to start bdflush */
  } else

    /* print out the current parameters */
  for(j=0; j<9; j++){
    i = bdflush(2 + (j<<1) ,(int) &data);
    printf("%d: %5d %s\n", j, data, bdparam[j]);
    if (i) break;
  };
  if(i) printf("bdflush() returned %d\n", errno);
}

