1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/*BINFMTC: -g -DILISTCREATEBENCH
* cowdancer -- a Copy-on-write data-access; No-cow-easy-replacement
*
* Copyright 2007-2000 Junichi Uekawa
* GPL v2 or later.
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "ilist.h"
/* Output error message. You need to process the error result. */
void ilist_outofmemory(const char* msg)
{
fprintf (stderr, "E: %s: %s\n", ilist_PRGNAME, msg);
}
/* return 1 on error, 0 on success */
int ilistcreate(const char* ilistpath, const char* findcommandline)
{
int i=0;
long dev, ino;
FILE* inf;
FILE* outf;
struct ilist_struct* ilist=NULL;
struct ilist_header header=
{
ILISTSIG,
ILISTREVISION,
sizeof (struct ilist_struct),
0
};
long ilist_len=0;
if(!findcommandline)
findcommandline="find . -xdev \\( -type l -o -type f \\) -a -links +1 -print0 | xargs -0 stat --format '%d %i '";
if (!(ilist=calloc(2000,sizeof(struct ilist_struct))))
{
ilist_outofmemory("memory allocation failed");
return 1;
}
ilist_len=2000;
if (NULL==(inf=popen(findcommandline, "r")))
{
ilist_outofmemory("popen find failed");
return 1;
}
while (fscanf(inf,"%li %li", &dev, &ino)>0)
{
(ilist+i)->dev=(dev_t)dev;
(ilist+i)->inode=(ino_t)ino;
if (getenv("COWDANCER_DEBUG"))
printf("%li %li \n ", (long int)dev, (long int)ino);
i++;
if (i>=ilist_len)
{
ilist=realloc(ilist, (ilist_len*=2)*sizeof(struct ilist_struct));
if (!ilist)
{
ilist_outofmemory("realloc failed");
pclose(inf);
return 1;
}
}
}
ilist_len=i;
if (pclose(inf))
{
ilist_outofmemory("pclose returned non-zero, probably the directory contains no hardlinked file, don't bother using cow-shell here.");
return 1;
}
/* sort the ilist */
qsort(ilist, ilist_len, sizeof(struct ilist_struct), compare_ilist);
/* write out the ilist file */
if (NULL==(outf=fopen(ilistpath,"w")))
{
ilist_outofmemory("cannot open .ilist file");
return 1;
}
if(1 != fwrite(&header, sizeof(struct ilist_header), 1, outf))
{
ilist_outofmemory("failed writing header to .ilist file");
return 1;
}
if (ilist_len != fwrite(ilist, sizeof(struct ilist_struct), ilist_len, outf))
{
ilist_outofmemory("failed writing to .ilist file");
return 1;
}
if (fclose (outf))
{
ilist_outofmemory("error flushing to .ilist file");
return 1;
}
return 0;
}
/* comparison function for qsort/bsearch of ilist
*/
int
compare_ilist (const void *a, const void *b)
{
const struct ilist_struct * ilista = (const struct ilist_struct*) a;
const struct ilist_struct * ilistb = (const struct ilist_struct*) b;
int ret;
ret = ilista->inode - ilistb->inode;
if (!ret)
{
ret = ilista->dev - ilistb->dev;
}
return ret;
}
#ifdef ILISTCREATEBENCH
/* test code for performance tuning */
const char* ilist_PRGNAME="testbench";
int
main()
{
int i;
if (-1==chdir("/home/dancer/shared/git/linux-2.6/"))
exit (1);
for(i=0; i<100; ++i)
ilistcreate("/home/dancer/shared/git/linux-2.6/.ilist", NULL);
exit (0);
}
#endif
|