2 Copyright (C) 2011 Proxmox Server Solutions GmbH
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Affero General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Affero General Public License for more details.
14 You should have received a copy of the GNU Affero General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Author: Dietmar Maurer <dietmar@proxmox.com>
23 #endif /* HAVE_CONFIG_H */
30 #include <sys/types.h>
37 #include "cfs-utils.h"
40 static struct cfs_operations cfs_ops
;
42 static cfs_plug_t
*cfs_plug_func_lookup_plug(cfs_plug_t
*plug
, char **path
)
44 g_return_val_if_fail(plug
!= NULL
, NULL
);
45 g_return_val_if_fail(plug
->ops
== &cfs_ops
, NULL
);
47 return (!*path
|| !(*path
)[0]) ? plug
: NULL
;
50 static void cfs_plug_func_destroy(cfs_plug_t
*plug
)
52 g_return_if_fail(plug
!= NULL
);
53 g_return_if_fail(plug
->ops
== &cfs_ops
);
55 cfs_plug_func_t
*fplug
= (cfs_plug_func_t
*)plug
;
57 cfs_debug("enter cfs_plug_func_destroy %s", plug
->name
);
68 cfs_plug_func_getattr(
73 g_return_val_if_fail(plug
!= NULL
, PARAM_CHECK_ERRNO
);
74 g_return_val_if_fail(plug
->ops
== &cfs_ops
, PARAM_CHECK_ERRNO
);
75 g_return_val_if_fail(path
!= NULL
, PARAM_CHECK_ERRNO
);
76 g_return_val_if_fail(stbuf
!= NULL
, PARAM_CHECK_ERRNO
);
78 cfs_debug("enter cfs_plug_func_getattr %s", path
);
80 cfs_plug_func_t
*fplug
= (cfs_plug_func_t
*)plug
;
82 memset(stbuf
, 0, sizeof(struct stat
));
84 g_rw_lock_writer_lock(&fplug
->data_rw_lock
);
88 fplug
->data
= fplug
->update_callback(plug
);
90 stbuf
->st_size
= fplug
->data
? strlen(fplug
->data
) : 0;
92 g_rw_lock_writer_unlock(&fplug
->data_rw_lock
);
94 stbuf
->st_mode
= fplug
->mode
;
107 struct fuse_file_info
*fi
)
111 g_return_val_if_fail(plug
!= NULL
, PARAM_CHECK_ERRNO
);
112 g_return_val_if_fail(plug
->ops
== &cfs_ops
, PARAM_CHECK_ERRNO
);
113 g_return_val_if_fail(path
!= NULL
, PARAM_CHECK_ERRNO
);
114 g_return_val_if_fail(buf
!= NULL
, PARAM_CHECK_ERRNO
);
116 cfs_plug_func_t
*fplug
= (cfs_plug_func_t
*)plug
;
118 g_rw_lock_reader_lock(&fplug
->data_rw_lock
);
119 char *data
= fplug
->data
;
121 cfs_debug("enter cfs_plug_func_read %s", data
);
124 g_rw_lock_reader_unlock(&fplug
->data_rw_lock
);
128 int len
= strlen(data
);
131 if (offset
+ size
> len
)
133 memcpy(buf
, data
+ offset
, size
);
137 g_rw_lock_reader_unlock(&fplug
->data_rw_lock
);
149 struct fuse_file_info
*fi
)
153 g_return_val_if_fail(plug
!= NULL
, PARAM_CHECK_ERRNO
);
154 g_return_val_if_fail(plug
->ops
== &cfs_ops
, PARAM_CHECK_ERRNO
);
155 g_return_val_if_fail(path
!= NULL
, PARAM_CHECK_ERRNO
);
156 g_return_val_if_fail(buf
!= NULL
, PARAM_CHECK_ERRNO
);
158 cfs_debug("enter cfs_plug_func_write");
160 cfs_plug_func_t
*fplug
= (cfs_plug_func_t
*)plug
;
162 if (offset
!= 0 || !fplug
->write_callback
)
165 return fplug
->write_callback(plug
, buf
, size
);
169 cfs_plug_func_truncate(
174 g_return_val_if_fail(plug
!= NULL
, PARAM_CHECK_ERRNO
);
175 g_return_val_if_fail(plug
->ops
== &cfs_ops
, PARAM_CHECK_ERRNO
);
176 g_return_val_if_fail(path
!= NULL
, PARAM_CHECK_ERRNO
);
178 cfs_plug_func_t
*fplug
= (cfs_plug_func_t
*)plug
;
180 if (fplug
->write_callback
)
190 struct fuse_file_info
*fi
)
192 g_return_val_if_fail(plug
!= NULL
, PARAM_CHECK_ERRNO
);
193 g_return_val_if_fail(plug
->ops
== &cfs_ops
, PARAM_CHECK_ERRNO
);
194 g_return_val_if_fail(path
!= NULL
, PARAM_CHECK_ERRNO
);
195 g_return_val_if_fail(fi
!= NULL
, PARAM_CHECK_ERRNO
);
197 cfs_debug("enter cfs_plug_func_open %s", path
);
202 static struct cfs_operations cfs_ops
= {
203 .getattr
= cfs_plug_func_getattr
,
204 .read
= cfs_plug_func_read
,
205 .write
= cfs_plug_func_write
,
206 .truncate
= cfs_plug_func_truncate
,
207 .open
= cfs_plug_func_open
,
215 cfs_plug_func_udpate_data_fn_t update_callback
,
216 cfs_plug_func_write_data_fn_t write_callback
)
218 g_return_val_if_fail(name
!= NULL
, NULL
);
219 g_return_val_if_fail(update_callback
!= NULL
, NULL
);
221 cfs_plug_func_t
*fplug
= g_new0(cfs_plug_func_t
, 1);
223 fplug
->plug
.ops
= &cfs_ops
;
225 fplug
->plug
.lookup_plug
= cfs_plug_func_lookup_plug
;
226 fplug
->plug
.destroy_plug
= cfs_plug_func_destroy
;
228 fplug
->plug
.name
= g_strdup(name
);
230 fplug
->update_callback
= update_callback
;
231 fplug
->write_callback
= write_callback
;
235 fplug
->mode
= S_IFREG
| mode
;