2 #include <limits.h> // for PATH_MAX
11 #include "treefiles.h"
12 #include "nbd-debug.h"
15 * Tree structure helper functions
17 void construct_path(char* name
, int lenmax
, off_t size
, off_t pos
, off_t
* ppos
) {
19 err("Char buffer overflow. This is likely a bug.");
21 if (size
<TREEDIRSIZE
*TREEPAGESIZE
) {
22 // we are done, add filename
23 snprintf(name
,lenmax
,"/FILE%04" PRIX64
,(pos
/TREEPAGESIZE
) % TREEDIRSIZE
);
24 *ppos
= pos
/ (TREEPAGESIZE
*TREEDIRSIZE
);
26 construct_path(name
+9,lenmax
-9,size
/TREEDIRSIZE
,pos
,ppos
);
28 snprintf(buffer
,sizeof(buffer
),"/TREE%04jX",(intmax_t)(*ppos
% TREEDIRSIZE
));
29 memcpy(name
,buffer
,9); // copy into string without trailing zero
34 void delete_treefile(char* name
, off_t size
, off_t pos
) {
35 char filename
[PATH_MAX
];
38 strncpy(filename
,name
,PATH_MAX
-1);
39 filename
[PATH_MAX
-1] = '\0';
40 construct_path(filename
+strlen(name
),PATH_MAX
-strlen(name
)-1,size
,pos
,&ppos
);
42 DEBUG("Deleting treefile: %s",filename
);
44 if (unlink(filename
)==-1)
45 DEBUG("Deleting failed : %s",strerror(errno
));
48 void mkdir_path(char* path
) {
50 while ((subpath
=strchr(subpath
,'/'))) {
51 *subpath
='\0'; // path is modified in place with terminating null char instead of slash
52 if (mkdir(path
,0700)==-1) {
54 err("Path access error! %m");
61 int open_treefile(char* name
, mode_t mode
, off_t size
, off_t pos
, pthread_mutex_t
* mutex
) {
62 char filename
[PATH_MAX
];
65 strncpy(filename
,name
,PATH_MAX
-1);
66 filename
[PATH_MAX
- 1] = '\0';
67 construct_path(filename
+strlen(name
),PATH_MAX
-strlen(name
)-1,size
,pos
,&ppos
);
69 DEBUG("Accessing treefile %s (offset %llu of %llu)",filename
,(unsigned long long)pos
,(unsigned long long)size
);
71 pthread_mutex_lock(mutex
);
72 int handle
=open(filename
, mode
, 0600);
73 if (handle
<0 && errno
==ENOENT
) {
76 DEBUG("Creating new treepath");
79 handle
=open(filename
, O_RDWR
|O_CREAT
, 0600);
81 err("Error opening tree block file %m");
85 DEBUG("Creating a dummy tempfile for reading");
86 char tmpname
[] = "dummy-XXXXXX";
87 mode_t oldmode
= umask(077);
88 handle
= mkstemp(tmpname
);
91 unlink(tmpname
); /* File will stick around whilst FD open */
93 err("Error opening tree block file %m");
97 if(lseek(handle
,TREEPAGESIZE
-1, SEEK_SET
) < 0) {
98 err("Could not create tree file!\n");
100 ssize_t c
= write(handle
,n
,1);
102 err("Error setting tree block file size %m");
105 pthread_mutex_unlock(mutex
);