14 #include <treefiles.h>
15 #include <nbd-debug.h>
18 * Tree structure helper functions
20 void construct_path(char* name,int lenmax,off_t size, off_t pos, off_t * ppos) {
22 err("Char buffer overflow. This is likely a bug.");
24 if (size<TREEDIRSIZE*TREEPAGESIZE) {
25 // we are done, add filename
26 snprintf(name,lenmax,"/FILE%04" PRIX64,(pos/TREEPAGESIZE) % TREEDIRSIZE);
27 *ppos = pos / (TREEPAGESIZE*TREEDIRSIZE);
29 construct_path(name+9,lenmax-9,size/TREEDIRSIZE,pos,ppos);
31 snprintf(buffer,sizeof(buffer),"/TREE%04jX",(intmax_t)(*ppos % TREEDIRSIZE));
32 memcpy(name,buffer,9); // copy into string without trailing zero
37 void delete_treefile(char* name,off_t size,off_t pos) {
38 char filename[PATH_MAX];
41 strncpy(filename,name,PATH_MAX-1);
42 filename[PATH_MAX-1] = '\0';
43 construct_path(filename+strlen(name),PATH_MAX-strlen(name)-1,size,pos,&ppos);
45 DEBUG("Deleting treefile: %s",filename);
47 if (unlink(filename)==-1)
48 DEBUG("Deleting failed : %s",strerror(errno));
51 void mkdir_path(char * path) {
53 while ((subpath=strchr(subpath,'/'))) {
54 *subpath='\0'; // path is modified in place with terminating null char instead of slash
55 if (mkdir(path,0700)==-1) {
57 err("Path access error! %m");
64 int open_treefile(char* name,mode_t mode,off_t size,off_t pos, pthread_mutex_t *mutex) {
65 char filename[PATH_MAX];
68 strncpy(filename,name,PATH_MAX-1);
69 filename[PATH_MAX - 1] = '\0';
70 construct_path(filename+strlen(name),PATH_MAX-strlen(name)-1,size,pos,&ppos);
72 DEBUG("Accessing treefile %s ( offset %llu of %llu)",filename,(unsigned long long)pos,(unsigned long long)size);
74 pthread_mutex_lock(mutex);
75 int handle=open(filename, mode, 0600);
76 if (handle<0 && errno==ENOENT) {
79 DEBUG("Creating new treepath");
82 handle=open(filename, O_RDWR|O_CREAT, 0600);
84 err("Error opening tree block file %m");
88 DEBUG("Creating a dummy tempfile for reading");
90 tmpname = g_strdup_printf("dummy-XXXXXX");
91 mode_t oldmode = umask(77);
92 handle = mkstemp(tmpname);
95 unlink(tmpname); /* File will stick around whilst FD open */
97 err("Error opening tree block file %m");
102 if(lseek(handle,TREEPAGESIZE-1, SEEK_SET) < 0) {
103 err("Could not create tree file!\n");
105 ssize_t c = write(handle,n,1);
107 err("Error setting tree block file size %m");
110 pthread_mutex_unlock(mutex);