]>
Commit | Line | Data |
---|---|---|
1d13e637 AF |
1 | From f2f684d4eadadeebf725b513bf4945ccf0aa7371 Mon Sep 17 00:00:00 2001 |
2 | From: Anand Avati <avati@redhat.com> | |
3 | Date: Wed, 29 May 2013 07:21:46 -0400 | |
4 | Subject: [PATCH 1/9] PATCHSET13: vfs_glusterfs: Samba VFS module for glusterfs | |
5 | ||
6 | Implement a Samba VFS plugin for glusterfs based on gluster's gfapi. | |
7 | This is a "bottom" vfs plugin (not something to be stacked on top of | |
8 | another module), and translates (most) calls into closest actions | |
9 | on gfapi. | |
10 | ||
11 | Reviewed-by: Andrew Bartlett <abartlet@samba.org> | |
12 | Reviewed-by: Simo Sorce <idra@samba.org> | |
13 | Signed-off-by: Anand Avati <avati@redhat.com> | |
14 | --- | |
15 | source3/Makefile.in | 5 + | |
16 | source3/configure.in | 23 + | |
17 | source3/modules/vfs_glusterfs.c | 1461 +++++++++++++++++++++++++++++++++++++++ | |
18 | source3/modules/wscript_build | 9 + | |
19 | source3/wscript | 22 + | |
20 | 5 files changed, 1520 insertions(+) | |
21 | create mode 100644 source3/modules/vfs_glusterfs.c | |
22 | ||
23 | diff --git a/source3/Makefile.in b/source3/Makefile.in | |
24 | index 9e8e03d..27bc43e 100644 | |
25 | --- a/source3/Makefile.in | |
26 | +++ b/source3/Makefile.in | |
27 | @@ -848,6 +848,7 @@ VFS_SCANNEDONLY_OBJ = modules/vfs_scannedonly.o | |
28 | VFS_CROSSRENAME_OBJ = modules/vfs_crossrename.o | |
29 | VFS_LINUX_XFS_SGID_OBJ = modules/vfs_linux_xfs_sgid.o | |
30 | VFS_TIME_AUDIT_OBJ = modules/vfs_time_audit.o | |
31 | +VFS_GLUSTERFS_OBJ = modules/vfs_glusterfs.o | |
32 | ||
33 | PAM_ERRORS_OBJ = ../libcli/auth/pam_errors.o | |
34 | PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o $(PAM_ERRORS_OBJ) | |
35 | @@ -3191,6 +3192,10 @@ bin/time_audit.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_TIME_AUDIT_OBJ) | |
36 | @echo "Building plugin $@" | |
37 | @$(SHLD_MODULE) $(VFS_TIME_AUDIT_OBJ) | |
38 | ||
39 | +bin/glusterfs.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_GLUSTERFS_OBJ) | |
40 | + @echo "Building plugin $@" | |
41 | + $(SHLD_MODULE) $(VFS_GLUSTERFS_OBJ) @GLUSTERFS_LIBS@ | |
42 | + | |
43 | ######################################################### | |
44 | ## IdMap NSS plugins | |
45 | ||
46 | diff --git a/source3/configure.in b/source3/configure.in | |
47 | index 42c23e3..3cc78e9 100644 | |
48 | --- a/source3/configure.in | |
49 | +++ b/source3/configure.in | |
50 | @@ -6688,6 +6688,29 @@ | |
51 | fi | |
52 | ||
53 | ||
54 | +############# | |
55 | +AC_ARG_ENABLE([glusterfs], | |
56 | + AC_HELP_STRING([--disable-glusterfs],[Do not build vfs_glusterfs module])) | |
57 | + | |
58 | +GLUTERFS_LIBS="" | |
59 | + | |
60 | +if test "x$enable_glusterfs" != "xno"; then | |
61 | + PKG_CHECK_MODULES([GLFS], [glusterfs-api >= 4], glfs_found=yes, glfs_found=no) | |
62 | +fi | |
63 | + | |
64 | +if test "x$enable_glusterfs" = "xyes" -a "x$glfs_found" != "xyes"; then | |
65 | + echo "GFAPI not found in build system" | |
66 | + exit 1 | |
67 | +fi | |
68 | + | |
69 | +if test "x$glfs_found" = "xyes"; then | |
70 | + CFLAGS="$CFLAGS $GLFS_CFLAGS" | |
71 | + GLUSTERFS_LIBS="$GLFS_LIBS" | |
72 | + default_shared_modules="$default_shared_modules vfs_glusterfs" | |
73 | +fi | |
74 | +AC_SUBST(GLUSTERFS_LIBS) | |
75 | + | |
76 | + | |
77 | ################################################# | |
78 | # Set pthread stuff | |
79 | ||
80 | @@ -7007,6 +7030,7 @@ | |
81 | SMB_MODULE(vfs_crossrename, \$(VFS_CROSSRENAME_OBJ), "bin/crossrename.$SHLIBEXT", VFS) | |
82 | SMB_MODULE(vfs_linux_xfs_sgid, \$(VFS_LINUX_XFS_SGID_OBJ), "bin/linux_xfs_sgid.$SHLIBEXT", VFS) | |
83 | SMB_MODULE(vfs_time_audit, \$(VFS_TIME_AUDIT_OBJ), "bin/time_audit.$SHLIBEXT", VFS) | |
84 | +SMB_MODULE(vfs_glusterfs, \$(VFS_GLUSTERFS_OBJ), "bin/glusterfs.$SHLIBEXT", VFS) | |
85 | ||
86 | SMB_SUBSYSTEM(VFS,smbd/vfs.o) | |
87 | ||
88 | diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c | |
89 | new file mode 100644 | |
90 | index 0000000..4beac1d | |
91 | --- /dev/null | |
92 | +++ b/source3/modules/vfs_glusterfs.c | |
93 | @@ -0,0 +1,1461 @@ | |
94 | +/* | |
95 | + Unix SMB/CIFS implementation. | |
96 | + | |
97 | + Wrap GlusterFS GFAPI calls in vfs functions. | |
98 | + | |
99 | + Copyright (c) 2013 Anand Avati <avati@redhat.com> | |
100 | + | |
101 | + This program is free software; you can redistribute it and/or modify | |
102 | + it under the terms of the GNU General Public License as published by | |
103 | + the Free Software Foundation; either version 3 of the License, or | |
104 | + (at your option) any later version. | |
105 | + | |
106 | + This program is distributed in the hope that it will be useful, | |
107 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
108 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
109 | + GNU General Public License for more details. | |
110 | + | |
111 | + You should have received a copy of the GNU General Public License | |
112 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
113 | +*/ | |
114 | + | |
115 | +#include "includes.h" | |
116 | +#include "smbd/smbd.h" | |
117 | +#include <stdio.h> | |
118 | +#include "api/glfs.h" | |
119 | + | |
120 | +#define DEFAULT_VOLFILE_SERVER "localhost" | |
121 | + | |
122 | +/* | |
123 | + TODO | |
124 | + ---- | |
125 | + Short term: | |
126 | + - AIO support | |
127 | + - sendfile/recvfile support | |
128 | +*/ | |
129 | + | |
130 | +/* Helpers to provide 'integer' fds */ | |
131 | + | |
132 | +/* This is global. gfapi's FD operations do not | |
133 | + require filesystem context. | |
134 | +*/ | |
135 | +static glfs_fd_t **glfd_fd; | |
136 | +static int glfd_fd_size; | |
137 | +static int glfd_fd_used; | |
138 | +static int glfd_fd_store(glfs_fd_t *glfd) | |
139 | +{ | |
140 | + int i; | |
141 | + void *tmp; | |
142 | + | |
143 | + if (glfd_fd_size == glfd_fd_used) { | |
144 | + if (glfd_fd_size >= INT_MAX - 1) { | |
145 | + errno = ENOMEM; | |
146 | + return -1; | |
147 | + } | |
148 | + | |
149 | + tmp = talloc_realloc(glfd_fd, glfd_fd, glfs_fd_t *, | |
150 | + glfd_fd_size + 1); | |
151 | + if (tmp == NULL) { | |
152 | + errno = ENOMEM; | |
153 | + return -1; | |
154 | + } | |
155 | + | |
156 | + glfd_fd = tmp; | |
157 | + glfd_fd[glfd_fd_size] = 0; | |
158 | + glfd_fd_size++; | |
159 | + } | |
160 | + | |
161 | + for (i = 0; i < glfd_fd_size; i++) { | |
162 | + if (!glfd_fd[i]) { | |
163 | + break; | |
164 | + } | |
165 | + } | |
166 | + glfd_fd_used++; | |
167 | + glfd_fd[i] = glfd; | |
168 | + return i; | |
169 | +} | |
170 | + | |
171 | +static glfs_fd_t *glfd_fd_get(int i) | |
172 | +{ | |
173 | + if (i < 0 || i >= glfd_fd_size) { | |
174 | + return NULL; | |
175 | + } | |
176 | + return glfd_fd[i]; | |
177 | +} | |
178 | + | |
179 | +static glfs_fd_t *glfd_fd_clear(int i) | |
180 | +{ | |
181 | + glfs_fd_t *glfd = NULL; | |
182 | + | |
183 | + if (i < 0 || i >= glfd_fd_size) { | |
184 | + return NULL; | |
185 | + } | |
186 | + | |
187 | + glfd = glfd_fd[i]; | |
188 | + glfd_fd[i] = 0; | |
189 | + glfd_fd_used--; | |
190 | + return glfd; | |
191 | +} | |
192 | + | |
193 | +/* Helper to convert stat to stat_ex */ | |
194 | + | |
195 | +static void smb_stat_ex_from_stat(struct stat_ex *dst, const struct stat *src) | |
196 | +{ | |
197 | + ZERO_STRUCTP(dst); | |
198 | + | |
199 | + dst->st_ex_dev = src->st_dev; | |
200 | + dst->st_ex_ino = src->st_ino; | |
201 | + dst->st_ex_mode = src->st_mode; | |
202 | + dst->st_ex_nlink = src->st_nlink; | |
203 | + dst->st_ex_uid = src->st_uid; | |
204 | + dst->st_ex_gid = src->st_gid; | |
205 | + dst->st_ex_rdev = src->st_rdev; | |
206 | + dst->st_ex_size = src->st_size; | |
207 | + dst->st_ex_atime.tv_sec = src->st_atime; | |
208 | +#ifdef STAT_HAVE_NSEC | |
209 | + dst->st_ex_atime.tv_nsec = src->st_atime_nsec; | |
210 | +#endif | |
211 | + dst->st_ex_mtime.tv_sec = src->st_mtime; | |
212 | +#ifdef STAT_HAVE_NSEC | |
213 | + dst->st_ex_mtime.tv_nsec = src->st_mtime_nsec; | |
214 | +#endif | |
215 | + dst->st_ex_ctime.tv_sec = src->st_ctime; | |
216 | +#ifdef STAT_HAVE_NSEC | |
217 | + dst->st_ex_ctime.tv_nsec = src->st_ctime_nsec; | |
218 | +#endif | |
219 | + dst->st_ex_btime.tv_sec = src->st_mtime; | |
220 | +#ifdef STAT_HAVE_NSEC | |
221 | + dst->st_ex_btime.tv_nsec = src->st_mtime_nsec; | |
222 | +#endif | |
223 | + dst->st_ex_blksize = src->st_blksize; | |
224 | + dst->st_ex_blocks = src->st_blocks; | |
225 | +} | |
226 | + | |
227 | +/* pre-opened glfs_t */ | |
228 | + | |
229 | +static struct glfs_preopened { | |
230 | + char *volume; | |
231 | + glfs_t *fs; | |
232 | + int ref; | |
233 | + struct glfs_preopened *next, *prev; | |
234 | +} *glfs_preopened; | |
235 | + | |
236 | + | |
237 | +int glfs_set_preopened(const char *volume, glfs_t *fs) | |
238 | +{ | |
239 | + struct glfs_preopened *entry = NULL; | |
240 | + | |
241 | + entry = talloc_zero(NULL, struct glfs_preopened); | |
242 | + if (!entry) { | |
243 | + errno = ENOMEM; | |
244 | + return -1; | |
245 | + } | |
246 | + | |
247 | + entry->volume = talloc_strdup(entry, volume); | |
248 | + if (!entry->volume) { | |
249 | + talloc_free(entry); | |
250 | + errno = ENOMEM; | |
251 | + return -1; | |
252 | + } | |
253 | + | |
254 | + entry->fs = fs; | |
255 | + entry->ref = 1; | |
256 | + | |
257 | + DLIST_ADD(glfs_preopened, entry); | |
258 | + | |
259 | + return 0; | |
260 | +} | |
261 | + | |
262 | +static glfs_t *glfs_find_preopened(const char *volume) | |
263 | +{ | |
264 | + struct glfs_preopened *entry = NULL; | |
265 | + | |
266 | + for (entry = glfs_preopened; entry; entry = entry->next) { | |
267 | + if (strcmp(entry->volume, volume) == 0) { | |
268 | + entry->ref++; | |
269 | + return entry->fs; | |
270 | + } | |
271 | + } | |
272 | + | |
273 | + return NULL; | |
274 | +} | |
275 | + | |
276 | +static void glfs_clear_preopened(glfs_t *fs) | |
277 | +{ | |
278 | + int i; | |
279 | + struct glfs_preopened *entry = NULL; | |
280 | + | |
281 | + for (entry = glfs_preopened; entry; entry = entry->next) { | |
282 | + if (entry->fs == fs) { | |
283 | + if (--entry->ref) | |
284 | + return; | |
285 | + | |
286 | + DLIST_REMOVE(glfs_preopened, entry); | |
287 | + | |
288 | + glfs_fini(entry->fs); | |
289 | + talloc_free(entry); | |
290 | + } | |
291 | + } | |
292 | +} | |
293 | + | |
294 | +/* Disk Operations */ | |
295 | + | |
296 | +static int vfs_gluster_connect(struct vfs_handle_struct *handle, | |
297 | + const char *service, const char *user) | |
298 | +{ | |
299 | + const char *volfile_server; | |
300 | + const char *volume; | |
301 | + const char *logfile; | |
302 | + int loglevel; | |
303 | + glfs_t *fs; | |
304 | + int ret; | |
305 | + | |
306 | + logfile = lp_parm_const_string(SNUM(handle->conn), "glusterfs", | |
307 | + "logfile", NULL); | |
308 | + | |
309 | + loglevel = lp_parm_int(SNUM(handle->conn), "glusterfs", "loglevel", -1); | |
310 | + | |
311 | + volfile_server = lp_parm_const_string(SNUM(handle->conn), "glusterfs", | |
312 | + "volfile_server", NULL); | |
313 | + if (volfile_server == NULL) { | |
314 | + volfile_server = DEFAULT_VOLFILE_SERVER; | |
315 | + } | |
316 | + | |
317 | + volume = lp_parm_const_string(SNUM(handle->conn), "glusterfs", "volume", | |
318 | + NULL); | |
319 | + if (volume == NULL) { | |
320 | + volume = service; | |
321 | + } | |
322 | + | |
323 | + fs = glfs_find_preopened(volume); | |
324 | + if (fs) { | |
325 | + goto found; | |
326 | + } | |
327 | + | |
328 | + fs = glfs_new(volume); | |
329 | + if (fs == NULL) { | |
330 | + return -1; | |
331 | + } | |
332 | + | |
333 | + ret = glfs_set_volfile_server(fs, "tcp", volfile_server, 0); | |
334 | + if (ret < 0) { | |
335 | + DEBUG(0, ("Failed to set volfile_server %s\n", volfile_server)); | |
336 | + glfs_fini(fs); | |
337 | + return -1; | |
338 | + } | |
339 | + | |
340 | + ret = glfs_set_xlator_option(fs, "*-md-cache", "cache-posix-acl", | |
341 | + "true"); | |
342 | + if (ret < 0) { | |
343 | + DEBUG(0, ("%s: Failed to set xlator options\n", volume)); | |
344 | + glfs_fini(fs); | |
345 | + return -1; | |
346 | + } | |
347 | + | |
348 | + ret = glfs_set_logging(fs, logfile, loglevel); | |
349 | + if (ret < 0) { | |
350 | + DEBUG(0, ("%s: Failed to set logfile %s loglevel %d\n", | |
351 | + volume, logfile, loglevel)); | |
352 | + glfs_fini(fs); | |
353 | + return -1; | |
354 | + } | |
355 | + | |
356 | + ret = glfs_init(fs); | |
357 | + if (ret < 0) { | |
358 | + DEBUG(0, ("%s: Failed to initialize volume (%s)\n", | |
359 | + volume, strerror(errno))); | |
360 | + glfs_fini(fs); | |
361 | + return -1; | |
362 | + } | |
363 | + | |
364 | + ret = glfs_set_preopened(volume, fs); | |
365 | + if (ret < 0) { | |
366 | + DEBUG(0, ("%s: Failed to register volume (%s)\n", | |
367 | + volume, strerror(errno))); | |
368 | + glfs_fini(fs); | |
369 | + return -1; | |
370 | + } | |
371 | +found: | |
372 | + DEBUG(0, ("%s: Initialized volume from server %s\n", | |
373 | + volume, volfile_server)); | |
374 | + handle->data = fs; | |
375 | + return 0; | |
376 | +} | |
377 | + | |
378 | +static void vfs_gluster_disconnect(struct vfs_handle_struct *handle) | |
379 | +{ | |
380 | + glfs_t *fs = NULL; | |
381 | + | |
382 | + fs = handle->data; | |
383 | + | |
384 | + glfs_clear_preopened(fs); | |
385 | +} | |
386 | + | |
387 | +static uint64_t | |
388 | +vfs_gluster_disk_free(struct vfs_handle_struct *handle, const char *path, | |
389 | + bool small_query, uint64_t *bsize_p, uint64_t *dfree_p, | |
390 | + uint64_t *dsize_p) | |
391 | +{ | |
392 | + struct statvfs statvfs = { 0, }; | |
393 | + uint64_t dfree = 0; | |
394 | + int ret; | |
395 | + | |
396 | + ret = glfs_statvfs(handle->data, path, &statvfs); | |
397 | + if (ret < 0) { | |
398 | + DEBUG(0, ("glfs_statvfs(%s) failed: %s\n", | |
399 | + path, strerror(errno))); | |
400 | + return -1; | |
401 | + } | |
402 | + | |
403 | + dfree = statvfs.f_bsize * statvfs.f_bavail; | |
404 | + | |
405 | + if (bsize_p) { | |
406 | + *bsize_p = statvfs.f_bsize; | |
407 | + } | |
408 | + if (dfree_p) { | |
409 | + *dfree_p = dfree; | |
410 | + } | |
411 | + if (dsize_p) { | |
412 | + *dsize_p = statvfs.f_bsize * statvfs.f_blocks; | |
413 | + } | |
414 | + | |
415 | + return dfree; | |
416 | +} | |
417 | + | |
418 | +static int | |
419 | +vfs_gluster_get_quota(struct vfs_handle_struct *handle, | |
420 | + enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) | |
421 | +{ | |
422 | + errno = ENOSYS; | |
423 | + return -1; | |
424 | +} | |
425 | + | |
426 | +static int | |
427 | +vfs_gluster_set_quota(struct vfs_handle_struct *handle, | |
428 | + enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt) | |
429 | +{ | |
430 | + errno = ENOSYS; | |
431 | + return -1; | |
432 | +} | |
433 | + | |
434 | +static int vfs_gluster_statvfs(struct vfs_handle_struct *handle, | |
435 | + const char *path, | |
436 | + struct vfs_statvfs_struct *vfs_statvfs) | |
437 | +{ | |
438 | + struct statvfs statvfs = { 0, }; | |
439 | + int ret; | |
440 | + | |
441 | + ret = glfs_statvfs(handle->data, path, &statvfs); | |
442 | + if (ret < 0) { | |
443 | + DEBUG(0, ("glfs_statvfs(%s) failed: %s\n", | |
444 | + path, strerror(errno))); | |
445 | + return -1; | |
446 | + } | |
447 | + | |
448 | + ZERO_STRUCTP(vfs_statvfs); | |
449 | + | |
450 | + vfs_statvfs->OptimalTransferSize = statvfs.f_frsize; | |
451 | + vfs_statvfs->BlockSize = statvfs.f_bsize; | |
452 | + vfs_statvfs->TotalBlocks = statvfs.f_blocks; | |
453 | + vfs_statvfs->BlocksAvail = statvfs.f_bfree; | |
454 | + vfs_statvfs->UserBlocksAvail = statvfs.f_bavail; | |
455 | + vfs_statvfs->TotalFileNodes = statvfs.f_files; | |
456 | + vfs_statvfs->FreeFileNodes = statvfs.f_ffree; | |
457 | + vfs_statvfs->FsIdentifier = statvfs.f_fsid; | |
458 | + vfs_statvfs->FsCapabilities = | |
459 | + FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES; | |
460 | + | |
461 | + return ret; | |
462 | +} | |
463 | + | |
464 | +static uint32_t vfs_gluster_fs_capabilities(struct vfs_handle_struct *handle, | |
465 | + enum timestamp_set_resolution *p_ts_res) | |
466 | +{ | |
467 | + uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES; | |
468 | + | |
469 | +#ifdef STAT_HAVE_NSEC | |
470 | + *p_ts_res = TIMESTAMP_SET_NT_OR_BETTER; | |
471 | +#endif | |
472 | + | |
473 | + return caps; | |
474 | +} | |
475 | + | |
476 | +static DIR *vfs_gluster_opendir(struct vfs_handle_struct *handle, | |
477 | + const char *path, const char *mask, | |
478 | + uint32 attributes) | |
479 | +{ | |
480 | + glfs_fd_t *fd; | |
481 | + | |
482 | + fd = glfs_opendir(handle->data, path); | |
483 | + if (fd == NULL) { | |
484 | + DEBUG(0, ("glfs_opendir(%s) failed: %s\n", | |
485 | + path, strerror(errno))); | |
486 | + } | |
487 | + | |
488 | + return (DIR *) fd; | |
489 | +} | |
490 | + | |
491 | +static DIR *vfs_gluster_fdopendir(struct vfs_handle_struct *handle, | |
492 | + files_struct *fsp, const char *mask, | |
493 | + uint32 attributes) | |
494 | +{ | |
495 | + return (DIR *) glfd_fd_get(fsp->fh->fd); | |
496 | +} | |
497 | + | |
498 | +static int vfs_gluster_closedir(struct vfs_handle_struct *handle, DIR *dirp) | |
499 | +{ | |
500 | + return glfs_closedir((void *)dirp); | |
501 | +} | |
502 | + | |
503 | +static SMB_STRUCT_DIRENT *vfs_gluster_readdir(struct vfs_handle_struct *handle, | |
504 | + SMB_STRUCT_DIR *dirp, | |
505 | + SMB_STRUCT_STAT *sbuf) | |
506 | +{ | |
507 | + char direntbuf[512]; | |
508 | + int ret; | |
509 | + struct stat stat; | |
510 | + struct dirent *dirent = 0; | |
511 | + static SMB_STRUCT_DIRENT result; | |
512 | + | |
513 | + if (sbuf != NULL) { | |
514 | + ret = glfs_readdirplus_r((void *)dirp, &stat, (void *)direntbuf, | |
515 | + &dirent); | |
516 | + } else { | |
517 | + ret = glfs_readdir_r((void *)dirp, (void *)direntbuf, &dirent); | |
518 | + } | |
519 | + | |
520 | + if (ret < 0 || (dirent == NULL)) { | |
521 | + return NULL; | |
522 | + } | |
523 | + | |
524 | + if (sbuf != NULL) { | |
525 | + smb_stat_ex_from_stat(sbuf, &stat); | |
526 | + } | |
527 | + | |
528 | + result.d_ino = dirent->d_ino; | |
529 | + result.d_off = dirent->d_off; | |
530 | + result.d_reclen = dirent->d_reclen; | |
531 | + result.d_type = dirent->d_type; | |
532 | + strncpy(result.d_name, dirent->d_name, 256); | |
533 | + | |
534 | + return &result; | |
535 | +} | |
536 | + | |
537 | +static long vfs_gluster_telldir(struct vfs_handle_struct *handle, DIR *dirp) | |
538 | +{ | |
539 | + return glfs_telldir((void *)dirp); | |
540 | +} | |
541 | + | |
542 | +static void vfs_gluster_seekdir(struct vfs_handle_struct *handle, DIR *dirp, | |
543 | + long offset) | |
544 | +{ | |
545 | + glfs_seekdir((void *)dirp, offset); | |
546 | +} | |
547 | + | |
548 | +static void vfs_gluster_rewinddir(struct vfs_handle_struct *handle, | |
549 | + DIR *dirp) | |
550 | +{ | |
551 | + glfs_seekdir((void *)dirp, 0); | |
552 | +} | |
553 | + | |
554 | +static void vfs_gluster_init_search_op(struct vfs_handle_struct *handle, | |
555 | + DIR *dirp) | |
556 | +{ | |
557 | + return; | |
558 | +} | |
559 | + | |
560 | +static int vfs_gluster_mkdir(struct vfs_handle_struct *handle, const char *path, | |
561 | + mode_t mode) | |
562 | +{ | |
563 | + return glfs_mkdir(handle->data, path, mode); | |
564 | +} | |
565 | + | |
566 | +static int vfs_gluster_rmdir(struct vfs_handle_struct *handle, const char *path) | |
567 | +{ | |
568 | + return glfs_rmdir(handle->data, path); | |
569 | +} | |
570 | + | |
571 | +static int vfs_gluster_open(struct vfs_handle_struct *handle, | |
572 | + struct smb_filename *smb_fname, files_struct *fsp, | |
573 | + int flags, mode_t mode) | |
574 | +{ | |
575 | + glfs_fd_t *glfd; | |
576 | + | |
577 | + if (flags & O_DIRECTORY) { | |
578 | + glfd = glfs_opendir(handle->data, smb_fname->base_name); | |
579 | + } else if (flags & O_CREAT) { | |
580 | + glfd = glfs_creat(handle->data, smb_fname->base_name, flags, | |
581 | + mode); | |
582 | + } else { | |
583 | + glfd = glfs_open(handle->data, smb_fname->base_name, flags); | |
584 | + } | |
585 | + | |
586 | + if (glfd == NULL) { | |
587 | + DEBUG(0, ("glfs_{open[dir],creat}(%s) failed: %s\n", | |
588 | + smb_fname->base_name, strerror(errno))); | |
589 | + return -1; | |
590 | + } | |
591 | + | |
592 | + return glfd_fd_store(glfd); | |
593 | +} | |
594 | + | |
595 | +static int vfs_gluster_close(struct vfs_handle_struct *handle, | |
596 | + files_struct *fsp) | |
597 | +{ | |
598 | + return glfs_close(glfd_fd_clear(fsp->fh->fd)); | |
599 | +} | |
600 | + | |
601 | +static ssize_t vfs_gluster_read(struct vfs_handle_struct *handle, | |
602 | + files_struct *fsp, void *data, size_t n) | |
603 | +{ | |
604 | + return glfs_read(glfd_fd_get(fsp->fh->fd), data, n, 0); | |
605 | +} | |
606 | + | |
607 | +static ssize_t vfs_gluster_pread(struct vfs_handle_struct *handle, | |
608 | + files_struct *fsp, void *data, size_t n, | |
609 | + off_t offset) | |
610 | +{ | |
611 | + return glfs_pread(glfd_fd_get(fsp->fh->fd), data, n, offset, 0); | |
612 | +} | |
613 | + | |
614 | +static ssize_t vfs_gluster_write(struct vfs_handle_struct *handle, | |
615 | + files_struct *fsp, const void *data, size_t n) | |
616 | +{ | |
617 | + return glfs_write(glfd_fd_get(fsp->fh->fd), data, n, 0); | |
618 | +} | |
619 | + | |
620 | +static ssize_t vfs_gluster_pwrite(struct vfs_handle_struct *handle, | |
621 | + files_struct *fsp, const void *data, size_t n, | |
622 | + off_t offset) | |
623 | +{ | |
624 | + return glfs_pwrite(glfd_fd_get(fsp->fh->fd), data, n, offset, 0); | |
625 | +} | |
626 | + | |
627 | +static off_t vfs_gluster_lseek(struct vfs_handle_struct *handle, | |
628 | + files_struct *fsp, off_t offset, int whence) | |
629 | +{ | |
630 | + return glfs_lseek(glfd_fd_get(fsp->fh->fd), offset, whence); | |
631 | +} | |
632 | + | |
633 | +static ssize_t vfs_gluster_sendfile(struct vfs_handle_struct *handle, int tofd, | |
634 | + files_struct *fromfsp, const DATA_BLOB *hdr, | |
635 | + off_t offset, size_t n) | |
636 | +{ | |
637 | + errno = ENOTSUP; | |
638 | + return -1; | |
639 | +} | |
640 | + | |
641 | +static ssize_t vfs_gluster_recvfile(struct vfs_handle_struct *handle, | |
642 | + int fromfd, files_struct *tofsp, | |
643 | + off_t offset, size_t n) | |
644 | +{ | |
645 | + errno = ENOTSUP; | |
646 | + return -1; | |
647 | +} | |
648 | + | |
649 | +static int vfs_gluster_rename(struct vfs_handle_struct *handle, | |
650 | + const struct smb_filename *smb_fname_src, | |
651 | + const struct smb_filename *smb_fname_dst) | |
652 | +{ | |
653 | + return glfs_rename(handle->data, smb_fname_src->base_name, | |
654 | + smb_fname_dst->base_name); | |
655 | +} | |
656 | + | |
657 | +static int vfs_gluster_fsync(struct vfs_handle_struct *handle, | |
658 | + files_struct *fsp) | |
659 | +{ | |
660 | + return glfs_fsync(glfd_fd_get(fsp->fh->fd)); | |
661 | +} | |
662 | + | |
663 | +static int vfs_gluster_stat(struct vfs_handle_struct *handle, | |
664 | + struct smb_filename *smb_fname) | |
665 | +{ | |
666 | + struct stat st; | |
667 | + int ret; | |
668 | + | |
669 | + ret = glfs_stat(handle->data, smb_fname->base_name, &st); | |
670 | + if (ret == 0) { | |
671 | + smb_stat_ex_from_stat(&smb_fname->st, &st); | |
672 | + } | |
673 | + if (ret < 0 && errno != ENOENT) { | |
674 | + DEBUG(0, ("glfs_stat(%s) failed: %s\n", | |
675 | + smb_fname->base_name, strerror(errno))); | |
676 | + } | |
677 | + return ret; | |
678 | +} | |
679 | + | |
680 | +static int vfs_gluster_fstat(struct vfs_handle_struct *handle, | |
681 | + files_struct *fsp, SMB_STRUCT_STAT *sbuf) | |
682 | +{ | |
683 | + struct stat st; | |
684 | + int ret; | |
685 | + | |
686 | + ret = glfs_fstat(glfd_fd_get(fsp->fh->fd), &st); | |
687 | + if (ret == 0) { | |
688 | + smb_stat_ex_from_stat(sbuf, &st); | |
689 | + } | |
690 | + if (ret < 0) { | |
691 | + DEBUG(0, ("glfs_ftat(%d) failed: %s\n", | |
692 | + fsp->fh->fd, strerror(errno))); | |
693 | + } | |
694 | + return ret; | |
695 | +} | |
696 | + | |
697 | +static int vfs_gluster_lstat(struct vfs_handle_struct *handle, | |
698 | + struct smb_filename *smb_fname) | |
699 | +{ | |
700 | + struct stat st; | |
701 | + int ret; | |
702 | + | |
703 | + ret = glfs_lstat(handle->data, smb_fname->base_name, &st); | |
704 | + if (ret == 0) { | |
705 | + smb_stat_ex_from_stat(&smb_fname->st, &st); | |
706 | + } | |
707 | + if (ret < 0 && errno != ENOENT) { | |
708 | + DEBUG(0, ("glfs_lstat(%s) failed: %s\n", | |
709 | + smb_fname->base_name, strerror(errno))); | |
710 | + } | |
711 | + | |
712 | + return ret; | |
713 | +} | |
714 | + | |
715 | +static uint64_t vfs_gluster_get_alloc_size(struct vfs_handle_struct *handle, | |
716 | + files_struct *fsp, | |
717 | + const SMB_STRUCT_STAT *sbuf) | |
718 | +{ | |
719 | + return sbuf->st_ex_blocks * 512; | |
720 | +} | |
721 | + | |
722 | +static int vfs_gluster_unlink(struct vfs_handle_struct *handle, | |
723 | + const struct smb_filename *smb_fname) | |
724 | +{ | |
725 | + return glfs_unlink(handle->data, smb_fname->base_name); | |
726 | +} | |
727 | + | |
728 | +static int vfs_gluster_chmod(struct vfs_handle_struct *handle, | |
729 | + const char *path, mode_t mode) | |
730 | +{ | |
731 | + return glfs_chmod(handle->data, path, mode); | |
732 | +} | |
733 | + | |
734 | +static int vfs_gluster_fchmod(struct vfs_handle_struct *handle, | |
735 | + files_struct *fsp, mode_t mode) | |
736 | +{ | |
737 | + return glfs_fchmod(glfd_fd_get(fsp->fh->fd), mode); | |
738 | +} | |
739 | + | |
740 | +static int vfs_gluster_chown(struct vfs_handle_struct *handle, | |
741 | + const char *path, uid_t uid, gid_t gid) | |
742 | +{ | |
743 | + return glfs_chown(handle->data, path, uid, gid); | |
744 | +} | |
745 | + | |
746 | +static int vfs_gluster_fchown(struct vfs_handle_struct *handle, | |
747 | + files_struct *fsp, uid_t uid, gid_t gid) | |
748 | +{ | |
749 | + return glfs_fchown(glfd_fd_get(fsp->fh->fd), uid, gid); | |
750 | +} | |
751 | + | |
752 | +static int vfs_gluster_lchown(struct vfs_handle_struct *handle, | |
753 | + const char *path, uid_t uid, gid_t gid) | |
754 | +{ | |
755 | + return glfs_lchown(handle->data, path, uid, gid); | |
756 | +} | |
757 | + | |
758 | +static int vfs_gluster_chdir(struct vfs_handle_struct *handle, const char *path) | |
759 | +{ | |
760 | + return glfs_chdir(handle->data, path); | |
761 | +} | |
762 | + | |
763 | +static char *vfs_gluster_getwd(struct vfs_handle_struct *handle, char *path) | |
764 | +{ | |
765 | + return glfs_getcwd(handle->data, path, PATH_MAX); | |
766 | +} | |
767 | + | |
768 | +static int vfs_gluster_ntimes(struct vfs_handle_struct *handle, | |
769 | + const struct smb_filename *smb_fname, | |
770 | + struct smb_file_time *ft) | |
771 | +{ | |
772 | + struct timespec times[2]; | |
773 | + | |
774 | + times[0].tv_sec = ft->atime.tv_sec; | |
775 | + times[0].tv_nsec = ft->atime.tv_nsec; | |
776 | + times[1].tv_sec = ft->mtime.tv_sec; | |
777 | + times[1].tv_nsec = ft->mtime.tv_nsec; | |
778 | + | |
779 | + return glfs_utimens(handle->data, smb_fname->base_name, times); | |
780 | +} | |
781 | + | |
782 | +static int vfs_gluster_ftruncate(struct vfs_handle_struct *handle, | |
783 | + files_struct *fsp, off_t offset) | |
784 | +{ | |
785 | + return glfs_ftruncate(glfd_fd_get(fsp->fh->fd), offset); | |
786 | +} | |
787 | + | |
788 | +static int vfs_gluster_fallocate(struct vfs_handle_struct *handle, | |
789 | + struct files_struct *fsp, | |
790 | + enum vfs_fallocate_mode mode, | |
791 | + off_t offset, off_t len) | |
792 | +{ | |
793 | + errno = ENOTSUP; | |
794 | + return -1; | |
795 | +} | |
796 | + | |
797 | +static char *vfs_gluster_realpath(struct vfs_handle_struct *handle, | |
798 | + const char *path) | |
799 | +{ | |
800 | + return glfs_realpath(handle->data, path, 0); | |
801 | +} | |
802 | + | |
803 | +static bool vfs_gluster_lock(struct vfs_handle_struct *handle, | |
804 | + files_struct *fsp, int op, off_t offset, | |
805 | + off_t count, int type) | |
806 | +{ | |
807 | + struct flock flock = { 0, }; | |
808 | + int ret; | |
809 | + | |
810 | + flock.l_type = type; | |
811 | + flock.l_whence = SEEK_SET; | |
812 | + flock.l_start = offset; | |
813 | + flock.l_len = count; | |
814 | + flock.l_pid = 0; | |
815 | + | |
816 | + ret = glfs_posix_lock(glfd_fd_get(fsp->fh->fd), op, &flock); | |
817 | + | |
818 | + if (op == F_GETLK) { | |
819 | + /* lock query, true if someone else has locked */ | |
820 | + if ((ret != -1) && | |
821 | + (flock.l_type != F_UNLCK) && | |
822 | + (flock.l_pid != 0) && (flock.l_pid != getpid())) | |
823 | + return true; | |
824 | + /* not me */ | |
825 | + return false; | |
826 | + } | |
827 | + | |
828 | + if (ret == -1) { | |
829 | + return false; | |
830 | + } | |
831 | + | |
832 | + return true; | |
833 | +} | |
834 | + | |
835 | +static int vfs_gluster_kernel_flock(struct vfs_handle_struct *handle, | |
836 | + files_struct *fsp, uint32 share_mode, | |
837 | + uint32_t access_mask) | |
838 | +{ | |
839 | + return 0; | |
840 | +} | |
841 | + | |
842 | +static int vfs_gluster_linux_setlease(struct vfs_handle_struct *handle, | |
843 | + files_struct *fsp, int leasetype) | |
844 | +{ | |
845 | + errno = ENOSYS; | |
846 | + return -1; | |
847 | +} | |
848 | + | |
849 | +static bool vfs_gluster_getlock(struct vfs_handle_struct *handle, | |
850 | + files_struct *fsp, off_t *poffset, | |
851 | + off_t *pcount, int *ptype, pid_t *ppid) | |
852 | +{ | |
853 | + struct flock flock = { 0, }; | |
854 | + int ret; | |
855 | + | |
856 | + flock.l_type = *ptype; | |
857 | + flock.l_whence = SEEK_SET; | |
858 | + flock.l_start = *poffset; | |
859 | + flock.l_len = *pcount; | |
860 | + flock.l_pid = 0; | |
861 | + | |
862 | + ret = glfs_posix_lock(glfd_fd_get(fsp->fh->fd), F_GETLK, &flock); | |
863 | + | |
864 | + if (ret == -1) { | |
865 | + return false; | |
866 | + } | |
867 | + | |
868 | + *ptype = flock.l_type; | |
869 | + *poffset = flock.l_start; | |
870 | + *pcount = flock.l_len; | |
871 | + *ppid = flock.l_pid; | |
872 | + | |
873 | + return true; | |
874 | +} | |
875 | + | |
876 | +static int vfs_gluster_symlink(struct vfs_handle_struct *handle, | |
877 | + const char *oldpath, const char *newpath) | |
878 | +{ | |
879 | + return glfs_symlink(handle->data, oldpath, newpath); | |
880 | +} | |
881 | + | |
882 | +static int vfs_gluster_readlink(struct vfs_handle_struct *handle, | |
883 | + const char *path, char *buf, size_t bufsiz) | |
884 | +{ | |
885 | + return glfs_readlink(handle->data, path, buf, bufsiz); | |
886 | +} | |
887 | + | |
888 | +static int vfs_gluster_link(struct vfs_handle_struct *handle, | |
889 | + const char *oldpath, const char *newpath) | |
890 | +{ | |
891 | + return glfs_link(handle->data, oldpath, newpath); | |
892 | +} | |
893 | + | |
894 | +static int vfs_gluster_mknod(struct vfs_handle_struct *handle, const char *path, | |
895 | + mode_t mode, SMB_DEV_T dev) | |
896 | +{ | |
897 | + return glfs_mknod(handle->data, path, mode, dev); | |
898 | +} | |
899 | + | |
900 | +static NTSTATUS vfs_gluster_notify_watch(struct vfs_handle_struct *vfs_handle, | |
901 | + struct sys_notify_context *ctx, | |
902 | + struct notify_entry *e, | |
903 | + void (*callback) (struct sys_notify_context *ctx, | |
904 | + void *private_data, | |
905 | + struct notify_event *ev), | |
906 | + void *private_data, void *handle) | |
907 | +{ | |
908 | + return NT_STATUS_NOT_IMPLEMENTED; | |
909 | +} | |
910 | + | |
911 | +static int vfs_gluster_chflags(struct vfs_handle_struct *handle, | |
912 | + const char *path, unsigned int flags) | |
913 | +{ | |
914 | + errno = ENOSYS; | |
915 | + return -1; | |
916 | +} | |
917 | + | |
918 | +static int vfs_gluster_get_real_filename(struct vfs_handle_struct *handle, | |
919 | + const char *path, const char *name, | |
920 | + TALLOC_CTX *mem_ctx, char **found_name) | |
921 | +{ | |
922 | + int ret; | |
923 | + char key_buf[NAME_MAX + 64]; | |
924 | + char val_buf[NAME_MAX + 1]; | |
925 | + | |
926 | + if (strlen(name) >= NAME_MAX) { | |
927 | + errno = ENAMETOOLONG; | |
928 | + return -1; | |
929 | + } | |
930 | + | |
931 | + snprintf(key_buf, NAME_MAX + 64, | |
932 | + "user.glusterfs.get_real_filename:%s", name); | |
933 | + | |
934 | + ret = glfs_getxattr(handle->data, path, key_buf, val_buf, NAME_MAX + 1); | |
935 | + if (ret == -1 && errno == ENODATA) { | |
936 | + errno = EOPNOTSUPP; | |
937 | + return -1; | |
938 | + } | |
939 | + | |
940 | + *found_name = talloc_strdup(mem_ctx, val_buf); | |
941 | + if (found_name[0] == NULL) { | |
942 | + errno = ENOMEM; | |
943 | + return -1; | |
944 | + } | |
945 | + return 0; | |
946 | +} | |
947 | + | |
948 | +static const char *vfs_gluster_connectpath(struct vfs_handle_struct *handle, | |
949 | + const char *filename) | |
950 | +{ | |
951 | + return handle->conn->connectpath; | |
952 | +} | |
953 | + | |
954 | +/* EA Operations */ | |
955 | + | |
956 | +static ssize_t vfs_gluster_getxattr(struct vfs_handle_struct *handle, | |
957 | + const char *path, const char *name, | |
958 | + void *value, size_t size) | |
959 | +{ | |
960 | + return glfs_getxattr(handle->data, path, name, value, size); | |
961 | +} | |
962 | + | |
963 | +static ssize_t vfs_gluster_lgetxattr(struct vfs_handle_struct *handle, | |
964 | + const char *path, const char *name, | |
965 | + void *value, size_t size) | |
966 | +{ | |
967 | + return glfs_lgetxattr(handle->data, path, name, value, size); | |
968 | +} | |
969 | + | |
970 | +static ssize_t vfs_gluster_fgetxattr(struct vfs_handle_struct *handle, | |
971 | + files_struct *fsp, const char *name, | |
972 | + void *value, size_t size) | |
973 | +{ | |
974 | + return glfs_fgetxattr(glfd_fd_get(fsp->fh->fd), name, value, size); | |
975 | +} | |
976 | + | |
977 | +static ssize_t vfs_gluster_listxattr(struct vfs_handle_struct *handle, | |
978 | + const char *path, char *list, size_t size) | |
979 | +{ | |
980 | + return glfs_listxattr(handle->data, path, list, size); | |
981 | +} | |
982 | + | |
983 | +static ssize_t vfs_gluster_llistxattr(struct vfs_handle_struct *handle, | |
984 | + const char *path, char *list, size_t size) | |
985 | +{ | |
986 | + return glfs_llistxattr(handle->data, path, list, size); | |
987 | +} | |
988 | + | |
989 | +static ssize_t vfs_gluster_flistxattr(struct vfs_handle_struct *handle, | |
990 | + files_struct *fsp, char *list, | |
991 | + size_t size) | |
992 | +{ | |
993 | + return glfs_flistxattr(glfd_fd_get(fsp->fh->fd), list, size); | |
994 | +} | |
995 | + | |
996 | +static int vfs_gluster_removexattr(struct vfs_handle_struct *handle, | |
997 | + const char *path, const char *name) | |
998 | +{ | |
999 | + return glfs_removexattr(handle->data, path, name); | |
1000 | +} | |
1001 | + | |
1002 | +static int vfs_gluster_lremovexattr(struct vfs_handle_struct *handle, | |
1003 | + const char *path, const char *name) | |
1004 | +{ | |
1005 | + return glfs_lremovexattr(handle->data, path, name); | |
1006 | +} | |
1007 | + | |
1008 | +static int vfs_gluster_fremovexattr(struct vfs_handle_struct *handle, | |
1009 | + files_struct *fsp, const char *name) | |
1010 | +{ | |
1011 | + return glfs_fremovexattr(glfd_fd_get(fsp->fh->fd), name); | |
1012 | +} | |
1013 | + | |
1014 | +static int vfs_gluster_setxattr(struct vfs_handle_struct *handle, | |
1015 | + const char *path, const char *name, | |
1016 | + const void *value, size_t size, int flags) | |
1017 | +{ | |
1018 | + return glfs_setxattr(handle->data, path, name, value, size, flags); | |
1019 | +} | |
1020 | + | |
1021 | +static int vfs_gluster_lsetxattr(struct vfs_handle_struct *handle, | |
1022 | + const char *path, const char *name, | |
1023 | + const void *value, size_t size, int flags) | |
1024 | +{ | |
1025 | + return glfs_lsetxattr(handle->data, path, name, value, size, flags); | |
1026 | +} | |
1027 | + | |
1028 | +static int vfs_gluster_fsetxattr(struct vfs_handle_struct *handle, | |
1029 | + files_struct *fsp, const char *name, | |
1030 | + const void *value, size_t size, int flags) | |
1031 | +{ | |
1032 | + return glfs_fsetxattr(glfd_fd_get(fsp->fh->fd), name, value, size, | |
1033 | + flags); | |
1034 | +} | |
1035 | + | |
1036 | +/* AIO Operations */ | |
1037 | + | |
1038 | +static bool vfs_gluster_aio_force(struct vfs_handle_struct *handle, | |
1039 | + files_struct *fsp) | |
1040 | +{ | |
1041 | + return false; | |
1042 | +} | |
1043 | + | |
1044 | +/* Offline Operations */ | |
1045 | + | |
1046 | +static bool vfs_gluster_is_offline(struct vfs_handle_struct *handle, | |
1047 | + const struct smb_filename *fname, | |
1048 | + SMB_STRUCT_STAT *sbuf) | |
1049 | +{ | |
1050 | + return false; | |
1051 | +} | |
1052 | + | |
1053 | +static int vfs_gluster_set_offline(struct vfs_handle_struct *handle, | |
1054 | + const struct smb_filename *fname) | |
1055 | +{ | |
1056 | + errno = ENOTSUP; | |
1057 | + return -1; | |
1058 | +} | |
1059 | + | |
1060 | +/* Posix ACL Operations */ | |
1061 | + | |
1062 | +#define GLUSTER_ACL_VERSION 2 | |
1063 | +#define GLUSTER_ACL_READ 0x04 | |
1064 | +#define GLUSTER_ACL_WRITE 0x02 | |
1065 | +#define GLUSTER_ACL_EXECUTE 0x01 | |
1066 | + | |
1067 | +#define GLUSTER_ACL_UNDEFINED_TAG 0x00 | |
1068 | +#define GLUSTER_ACL_USER_OBJ 0x01 | |
1069 | +#define GLUSTER_ACL_USER 0x02 | |
1070 | +#define GLUSTER_ACL_GROUP_OBJ 0x04 | |
1071 | +#define GLUSTER_ACL_GROUP 0x08 | |
1072 | +#define GLUSTER_ACL_MASK 0x10 | |
1073 | +#define GLUSTER_ACL_OTHER 0x20 | |
1074 | + | |
1075 | +#define GLUSTER_ACL_UNDEFINED_ID (-1) | |
1076 | + | |
1077 | +struct gluster_ace { | |
1078 | + uint16_t tag; | |
1079 | + uint16_t perm; | |
1080 | + uint32_t id; | |
1081 | +}; | |
1082 | + | |
1083 | +struct gluster_acl_header { | |
1084 | + uint32_t version; | |
1085 | + struct gluster_ace entries[]; | |
1086 | +}; | |
1087 | + | |
1088 | +static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size) | |
1089 | +{ | |
1090 | + int count; | |
1091 | + size_t size; | |
1092 | + struct gluster_ace *ace; | |
1093 | + struct smb_acl_entry *smb_ace; | |
1094 | + struct gluster_acl_header *hdr; | |
1095 | + struct smb_acl_t *result; | |
1096 | + int i; | |
1097 | + uint16_t tag; | |
1098 | + uint16_t perm; | |
1099 | + uint32_t id; | |
1100 | + | |
1101 | + size = xattr_size; | |
1102 | + | |
1103 | + if (size < sizeof(*hdr)) { | |
1104 | + /* ACL should be at least as big as the header */ | |
1105 | + errno = EINVAL; | |
1106 | + return NULL; | |
1107 | + } | |
1108 | + | |
1109 | + size -= sizeof(*hdr); | |
1110 | + | |
1111 | + if (size % sizeof(*ace)) { | |
1112 | + /* Size of entries must strictly be a multiple of | |
1113 | + size of an ACE | |
1114 | + */ | |
1115 | + errno = EINVAL; | |
1116 | + return NULL; | |
1117 | + } | |
1118 | + | |
1119 | + count = size / sizeof(*ace); | |
1120 | + | |
1121 | + hdr = (void *)buf; | |
1122 | + | |
1123 | + if (ntohl(hdr->version) != GLUSTER_ACL_VERSION) { | |
1124 | + DEBUG(0, ("Unknown gluster ACL version: %d\n", | |
1125 | + ntohl(hdr->version))); | |
1126 | + return NULL; | |
1127 | + } | |
1128 | + | |
1129 | + result = SMB_MALLOC(sizeof(struct smb_acl_t) + (sizeof(struct smb_acl_entry) * count)); | |
1130 | + if (!result) { | |
1131 | + errno = ENOMEM; | |
1132 | + return NULL; | |
1133 | + } | |
1134 | + | |
1135 | + result->count = count; | |
1136 | + | |
1137 | + smb_ace = result->acl; | |
1138 | + ace = hdr->entries; | |
1139 | + | |
1140 | + for (i = 0; i < count; i++) { | |
1141 | + tag = ntohs(ace->tag); | |
1142 | + | |
1143 | + switch(tag) { | |
1144 | + case GLUSTER_ACL_USER: | |
1145 | + smb_ace->a_type = SMB_ACL_USER; | |
1146 | + break; | |
1147 | + case GLUSTER_ACL_USER_OBJ: | |
1148 | + smb_ace->a_type = SMB_ACL_USER_OBJ; | |
1149 | + break; | |
1150 | + case GLUSTER_ACL_GROUP: | |
1151 | + smb_ace->a_type = SMB_ACL_GROUP; | |
1152 | + break; | |
1153 | + case GLUSTER_ACL_GROUP_OBJ: | |
1154 | + smb_ace->a_type = SMB_ACL_GROUP_OBJ; | |
1155 | + break; | |
1156 | + case GLUSTER_ACL_OTHER: | |
1157 | + smb_ace->a_type = SMB_ACL_OTHER; | |
1158 | + break; | |
1159 | + case GLUSTER_ACL_MASK: | |
1160 | + smb_ace->a_type = SMB_ACL_MASK; | |
1161 | + break; | |
1162 | + default: | |
1163 | + DEBUG(0, ("unknown tag type %d\n", (unsigned int) tag)); | |
1164 | + return NULL; | |
1165 | + } | |
1166 | + | |
1167 | + id = ntohl(ace->id); | |
1168 | + | |
1169 | + switch(smb_ace->a_type) { | |
1170 | + case SMB_ACL_USER: | |
1171 | + smb_ace->uid = id; | |
1172 | + break; | |
1173 | + case SMB_ACL_GROUP: | |
1174 | + smb_ace->gid = id; | |
1175 | + break; | |
1176 | + default: | |
1177 | + break; | |
1178 | + } | |
1179 | + | |
1180 | + perm = ntohs(ace->perm); | |
1181 | + | |
1182 | + smb_ace->a_perm = 0; | |
1183 | + smb_ace->a_perm |= | |
1184 | + ((perm & GLUSTER_ACL_READ) ? SMB_ACL_READ : 0); | |
1185 | + smb_ace->a_perm |= | |
1186 | + ((perm & GLUSTER_ACL_WRITE) ? SMB_ACL_WRITE : 0); | |
1187 | + smb_ace->a_perm |= | |
1188 | + ((perm & GLUSTER_ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0); | |
1189 | + | |
1190 | + ace++; | |
1191 | + smb_ace++; | |
1192 | + } | |
1193 | + | |
1194 | + return result; | |
1195 | +} | |
1196 | + | |
1197 | +static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len) | |
1198 | +{ | |
1199 | + ssize_t size; | |
1200 | + struct gluster_ace *ace; | |
1201 | + struct smb_acl_entry *smb_ace; | |
1202 | + struct gluster_acl_header *hdr; | |
1203 | + int i; | |
1204 | + int count; | |
1205 | + uint16_t tag; | |
1206 | + uint16_t perm; | |
1207 | + uint32_t id; | |
1208 | + | |
1209 | + count = theacl->count; | |
1210 | + | |
1211 | + size = sizeof(*hdr) + (count * sizeof(*ace)); | |
1212 | + if (!buf) { | |
1213 | + return size; | |
1214 | + } | |
1215 | + | |
1216 | + if (len < size) { | |
1217 | + errno = ERANGE; | |
1218 | + return -1; | |
1219 | + } | |
1220 | + | |
1221 | + hdr = (void *)buf; | |
1222 | + ace = hdr->entries; | |
1223 | + smb_ace = theacl->acl; | |
1224 | + | |
1225 | + hdr->version = htonl(GLUSTER_ACL_VERSION); | |
1226 | + | |
1227 | + for (i = 0; i < count; i++) { | |
1228 | + switch(smb_ace->a_type) { | |
1229 | + case SMB_ACL_USER: | |
1230 | + tag = GLUSTER_ACL_USER; | |
1231 | + break; | |
1232 | + case SMB_ACL_USER_OBJ: | |
1233 | + tag = GLUSTER_ACL_USER_OBJ; | |
1234 | + break; | |
1235 | + case SMB_ACL_GROUP: | |
1236 | + tag = GLUSTER_ACL_GROUP; | |
1237 | + break; | |
1238 | + case SMB_ACL_GROUP_OBJ: | |
1239 | + tag = GLUSTER_ACL_GROUP_OBJ; | |
1240 | + break; | |
1241 | + case SMB_ACL_OTHER: | |
1242 | + tag = GLUSTER_ACL_OTHER; | |
1243 | + break; | |
1244 | + case SMB_ACL_MASK: | |
1245 | + tag = GLUSTER_ACL_MASK; | |
1246 | + break; | |
1247 | + default: | |
1248 | + DEBUG(0, ("Unknown tag value %d\n", | |
1249 | + smb_ace->a_type)); | |
1250 | + errno = EINVAL; | |
1251 | + return -1; | |
1252 | + } | |
1253 | + | |
1254 | + ace->tag = ntohs(tag); | |
1255 | + | |
1256 | + switch(smb_ace->a_type) { | |
1257 | + case SMB_ACL_USER: | |
1258 | + id = smb_ace->uid; | |
1259 | + break; | |
1260 | + case SMB_ACL_GROUP: | |
1261 | + id = smb_ace->gid; | |
1262 | + break; | |
1263 | + default: | |
1264 | + id = GLUSTER_ACL_UNDEFINED_ID; | |
1265 | + break; | |
1266 | + } | |
1267 | + | |
1268 | + ace->id = ntohl(id); | |
1269 | + | |
1270 | + ace->perm = 0; | |
1271 | + ace->perm |= | |
1272 | + ((smb_ace->a_perm & SMB_ACL_READ) ? GLUSTER_ACL_READ : 0); | |
1273 | + ace->perm |= | |
1274 | + ((smb_ace->a_perm & SMB_ACL_WRITE) ? GLUSTER_ACL_WRITE : 0); | |
1275 | + ace->perm |= | |
1276 | + ((smb_ace->a_perm & SMB_ACL_EXECUTE) ? GLUSTER_ACL_EXECUTE : 0); | |
1277 | + | |
1278 | + ace++; | |
1279 | + smb_ace++; | |
1280 | + } | |
1281 | + | |
1282 | + return size; | |
1283 | +} | |
1284 | + | |
1285 | + | |
1286 | +static SMB_ACL_T vfs_gluster_sys_acl_get_file(struct vfs_handle_struct *handle, | |
1287 | + const char *path_p, | |
1288 | + SMB_ACL_TYPE_T type) | |
1289 | +{ | |
1290 | + struct smb_acl_t *result; | |
1291 | + char *buf; | |
1292 | + char *key; | |
1293 | + ssize_t ret; | |
1294 | + | |
1295 | + switch (type) { | |
1296 | + case SMB_ACL_TYPE_ACCESS: | |
1297 | + key = "system.posix_acl_access"; | |
1298 | + break; | |
1299 | + case SMB_ACL_TYPE_DEFAULT: | |
1300 | + key = "system.posix_acl_default"; | |
1301 | + break; | |
1302 | + default: | |
1303 | + errno = EINVAL; | |
1304 | + return NULL; | |
1305 | + } | |
1306 | + | |
1307 | + ret = glfs_getxattr(handle->data, path_p, key, 0, 0); | |
1308 | + if (ret <= 0) { | |
1309 | + return NULL; | |
1310 | + } | |
1311 | + | |
1312 | + buf = alloca(ret); | |
1313 | + ret = glfs_getxattr(handle->data, path_p, key, buf, ret); | |
1314 | + if (ret <= 0) { | |
1315 | + return NULL; | |
1316 | + } | |
1317 | + | |
1318 | + result = gluster_to_smb_acl(buf, ret); | |
1319 | + | |
1320 | + return result; | |
1321 | +} | |
1322 | + | |
1323 | +static SMB_ACL_T vfs_gluster_sys_acl_get_fd(struct vfs_handle_struct *handle, | |
1324 | + struct files_struct *fsp) | |
1325 | +{ | |
1326 | + struct smb_acl_t *result; | |
1327 | + int ret; | |
1328 | + char *buf; | |
1329 | + | |
1330 | + ret = glfs_fgetxattr(glfd_fd_get(fsp->fh->fd), | |
1331 | + "system.posix_acl_access", 0, 0); | |
1332 | + if (ret <= 0) { | |
1333 | + return NULL; | |
1334 | + } | |
1335 | + | |
1336 | + buf = alloca(ret); | |
1337 | + ret = glfs_fgetxattr(glfd_fd_get(fsp->fh->fd), | |
1338 | + "system.posix_acl_access", buf, ret); | |
1339 | + if (ret <= 0) { | |
1340 | + return NULL; | |
1341 | + } | |
1342 | + | |
1343 | + result = gluster_to_smb_acl(buf, ret); | |
1344 | + | |
1345 | + return result; | |
1346 | +} | |
1347 | + | |
1348 | +static int vfs_gluster_sys_acl_set_file(struct vfs_handle_struct *handle, | |
1349 | + const char *name, | |
1350 | + SMB_ACL_TYPE_T acltype, | |
1351 | + SMB_ACL_T theacl) | |
1352 | +{ | |
1353 | + int ret; | |
1354 | + char *key; | |
1355 | + char *buf; | |
1356 | + ssize_t size; | |
1357 | + | |
1358 | + switch (acltype) { | |
1359 | + case SMB_ACL_TYPE_ACCESS: | |
1360 | + key = "system.posix_acl_access"; | |
1361 | + break; | |
1362 | + case SMB_ACL_TYPE_DEFAULT: | |
1363 | + key = "system.posix_acl_default"; | |
1364 | + break; | |
1365 | + default: | |
1366 | + errno = EINVAL; | |
1367 | + return -1; | |
1368 | + } | |
1369 | + | |
1370 | + size = smb_to_gluster_acl(theacl, 0, 0); | |
1371 | + buf = alloca(size); | |
1372 | + | |
1373 | + size = smb_to_gluster_acl(theacl, buf, size); | |
1374 | + if (size == -1) { | |
1375 | + return -1; | |
1376 | + } | |
1377 | + | |
1378 | + ret = glfs_setxattr(handle->data, name, key, buf, size, 0); | |
1379 | + | |
1380 | + return ret; | |
1381 | +} | |
1382 | + | |
1383 | +static int vfs_gluster_sys_acl_set_fd(struct vfs_handle_struct *handle, | |
1384 | + struct files_struct *fsp, | |
1385 | + SMB_ACL_T theacl) | |
1386 | +{ | |
1387 | + int ret; | |
1388 | + char *buf; | |
1389 | + ssize_t size; | |
1390 | + | |
1391 | + size = smb_to_gluster_acl(theacl, 0, 0); | |
1392 | + buf = alloca(size); | |
1393 | + | |
1394 | + size = smb_to_gluster_acl(theacl, buf, size); | |
1395 | + if (size == -1) { | |
1396 | + return -1; | |
1397 | + } | |
1398 | + | |
1399 | + ret = glfs_fsetxattr(glfd_fd_get(fsp->fh->fd), | |
1400 | + "system.posix_acl_access", buf, size, 0); | |
1401 | + return ret; | |
1402 | +} | |
1403 | + | |
1404 | +static int vfs_gluster_sys_acl_delete_def_file(struct vfs_handle_struct *handle, | |
1405 | + const char *path) | |
1406 | +{ | |
1407 | + return glfs_removexattr(handle->data, path, "system.posix_acl_default"); | |
1408 | +} | |
1409 | + | |
1410 | +static struct vfs_fn_pointers glusterfs_fns = { | |
1411 | + | |
1412 | + /* Disk Operations */ | |
1413 | + | |
1414 | + .connect_fn = vfs_gluster_connect, | |
1415 | + .disconnect = vfs_gluster_disconnect, | |
1416 | + .disk_free = vfs_gluster_disk_free, | |
1417 | + .get_quota = vfs_gluster_get_quota, | |
1418 | + .set_quota = vfs_gluster_set_quota, | |
1419 | + .statvfs = vfs_gluster_statvfs, | |
1420 | + .fs_capabilities = vfs_gluster_fs_capabilities, | |
1421 | + | |
1422 | + /* Directory Operations */ | |
1423 | + | |
1424 | + .opendir = vfs_gluster_opendir, | |
1425 | + .fdopendir = vfs_gluster_fdopendir, | |
1426 | + .readdir = vfs_gluster_readdir, | |
1427 | + .seekdir = vfs_gluster_seekdir, | |
1428 | + .telldir = vfs_gluster_telldir, | |
1429 | + .rewind_dir = vfs_gluster_rewinddir, | |
1430 | + .mkdir = vfs_gluster_mkdir, | |
1431 | + .rmdir = vfs_gluster_rmdir, | |
1432 | + .closedir = vfs_gluster_closedir, | |
1433 | + .init_search_op = vfs_gluster_init_search_op, | |
1434 | + | |
1435 | + /* File Operations */ | |
1436 | + | |
1437 | + .open_fn = vfs_gluster_open, | |
1438 | + .create_file = NULL, | |
1439 | + .close_fn = vfs_gluster_close, | |
1440 | + .vfs_read = vfs_gluster_read, | |
1441 | + .pread = vfs_gluster_pread, | |
1442 | + .write = vfs_gluster_write, | |
1443 | + .pwrite = vfs_gluster_pwrite, | |
1444 | + .lseek = vfs_gluster_lseek, | |
1445 | + .sendfile = vfs_gluster_sendfile, | |
1446 | + .recvfile = vfs_gluster_recvfile, | |
1447 | + .rename = vfs_gluster_rename, | |
1448 | + .fsync = vfs_gluster_fsync, | |
1449 | + .stat = vfs_gluster_stat, | |
1450 | + .fstat = vfs_gluster_fstat, | |
1451 | + .lstat = vfs_gluster_lstat, | |
1452 | + .get_alloc_size = vfs_gluster_get_alloc_size, | |
1453 | + .unlink = vfs_gluster_unlink, | |
1454 | + | |
1455 | + .chmod = vfs_gluster_chmod, | |
1456 | + .fchmod = vfs_gluster_fchmod, | |
1457 | + .chown = vfs_gluster_chown, | |
1458 | + .fchown = vfs_gluster_fchown, | |
1459 | + .lchown = vfs_gluster_lchown, | |
1460 | + .chdir = vfs_gluster_chdir, | |
1461 | + .getwd = vfs_gluster_getwd, | |
1462 | + .ntimes = vfs_gluster_ntimes, | |
1463 | + .ftruncate = vfs_gluster_ftruncate, | |
1464 | + .fallocate = vfs_gluster_fallocate, | |
1465 | + .lock = vfs_gluster_lock, | |
1466 | + .kernel_flock = vfs_gluster_kernel_flock, | |
1467 | + .linux_setlease = vfs_gluster_linux_setlease, | |
1468 | + .getlock = vfs_gluster_getlock, | |
1469 | + .symlink = vfs_gluster_symlink, | |
1470 | + .vfs_readlink = vfs_gluster_readlink, | |
1471 | + .link = vfs_gluster_link, | |
1472 | + .mknod = vfs_gluster_mknod, | |
1473 | + .realpath = vfs_gluster_realpath, | |
1474 | + .notify_watch = vfs_gluster_notify_watch, | |
1475 | + .chflags = vfs_gluster_chflags, | |
1476 | + .file_id_create = NULL, | |
1477 | + .streaminfo = NULL, | |
1478 | + .get_real_filename = vfs_gluster_get_real_filename, | |
1479 | + .connectpath = vfs_gluster_connectpath, | |
1480 | + | |
1481 | + .brl_lock_windows = NULL, | |
1482 | + .brl_unlock_windows = NULL, | |
1483 | + .brl_cancel_windows = NULL, | |
1484 | + .strict_lock = NULL, | |
1485 | + .strict_unlock = NULL, | |
1486 | + .translate_name = NULL, | |
1487 | + | |
1488 | + /* NT ACL Operations */ | |
1489 | + .fget_nt_acl = NULL, | |
1490 | + .get_nt_acl = NULL, | |
1491 | + .fset_nt_acl = NULL, | |
1492 | + | |
1493 | + /* Posix ACL Operations */ | |
1494 | + .chmod_acl = NULL, /* passthrough to default */ | |
1495 | + .fchmod_acl = NULL, /* passthrough to default */ | |
1496 | + | |
1497 | + .sys_acl_get_entry = NULL, | |
1498 | + .sys_acl_get_tag_type = NULL, | |
1499 | + .sys_acl_get_permset = NULL, | |
1500 | + .sys_acl_get_qualifier = NULL, | |
1501 | + .sys_acl_get_file = vfs_gluster_sys_acl_get_file, | |
1502 | + .sys_acl_get_fd = vfs_gluster_sys_acl_get_fd, | |
1503 | + .sys_acl_clear_perms = NULL, | |
1504 | + .sys_acl_add_perm = NULL, | |
1505 | + .sys_acl_to_text = NULL, | |
1506 | + .sys_acl_init = NULL, | |
1507 | + .sys_acl_create_entry = NULL, | |
1508 | + .sys_acl_set_tag_type = NULL, | |
1509 | + .sys_acl_set_qualifier = NULL, | |
1510 | + .sys_acl_set_permset = NULL, | |
1511 | + .sys_acl_valid = NULL, | |
1512 | + .sys_acl_set_file = vfs_gluster_sys_acl_set_file, | |
1513 | + .sys_acl_set_fd = vfs_gluster_sys_acl_set_fd, | |
1514 | + .sys_acl_delete_def_file = vfs_gluster_sys_acl_delete_def_file, | |
1515 | + .sys_acl_get_perm = NULL, | |
1516 | + .sys_acl_free_text = NULL, | |
1517 | + .sys_acl_free_acl = NULL, | |
1518 | + .sys_acl_free_qualifier = NULL, | |
1519 | + | |
1520 | + /* EA Operations */ | |
1521 | + .getxattr = vfs_gluster_getxattr, | |
1522 | + .lgetxattr = vfs_gluster_lgetxattr, | |
1523 | + .fgetxattr = vfs_gluster_fgetxattr, | |
1524 | + .listxattr = vfs_gluster_listxattr, | |
1525 | + .llistxattr = vfs_gluster_llistxattr, | |
1526 | + .flistxattr = vfs_gluster_flistxattr, | |
1527 | + .removexattr = vfs_gluster_removexattr, | |
1528 | + .lremovexattr = vfs_gluster_lremovexattr, | |
1529 | + .fremovexattr = vfs_gluster_fremovexattr, | |
1530 | + .setxattr = vfs_gluster_setxattr, | |
1531 | + .lsetxattr = vfs_gluster_lsetxattr, | |
1532 | + .fsetxattr = vfs_gluster_fsetxattr, | |
1533 | + | |
1534 | + /* AIO Operations */ | |
1535 | + .aio_read = NULL, | |
1536 | + .aio_write = NULL, | |
1537 | + .aio_return_fn = NULL, | |
1538 | + .aio_cancel = NULL, | |
1539 | + .aio_error_fn = NULL, | |
1540 | + .aio_fsync = NULL, | |
1541 | + .aio_suspend = NULL, | |
1542 | + .aio_force = vfs_gluster_aio_force, | |
1543 | + | |
1544 | + /* Offline Operations */ | |
1545 | + .is_offline = vfs_gluster_is_offline, | |
1546 | + .set_offline = vfs_gluster_set_offline, | |
1547 | +}; | |
1548 | + | |
1549 | +NTSTATUS vfs_glusterfs_init(void); | |
1550 | +NTSTATUS vfs_glusterfs_init(void) | |
1551 | +{ | |
1552 | + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, | |
1553 | + "glusterfs", &glusterfs_fns); | |
1554 | +} | |
1555 | diff --git a/source3/modules/wscript_build b/source3/modules/wscript_build | |
1556 | index ff7163f..31c93be 100644 | |
1557 | --- a/source3/modules/wscript_build | |
1558 | +++ b/source3/modules/wscript_build | |
1559 | @@ -50,6 +50,7 @@ VFS_SCANNEDONLY_SRC = 'vfs_scannedonly.c' | |
1560 | VFS_CROSSRENAME_SRC = 'vfs_crossrename.c' | |
1561 | VFS_LINUX_XFS_SGID_SRC = 'vfs_linux_xfs_sgid.c' | |
1562 | VFS_TIME_AUDIT_SRC = 'vfs_time_audit.c' | |
1563 | +VFS_GLUSTERFS_SRC = 'vfs_glusterfs.c' | |
1564 | ||
1565 | ||
1566 | bld.SAMBA3_SUBSYSTEM('NFS4_ACLS', | |
1567 | @@ -408,6 +409,14 @@ bld.SAMBA3_MODULE('vfs_time_audit', | |
1568 | internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_time_audit'), | |
1569 | enabled=bld.SAMBA3_IS_ENABLED_MODULE('vfs_time_audit')) | |
1570 | ||
1571 | +bld.SAMBA3_MODULE('vfs_glusterfs', | |
1572 | + subsystem='vfs', | |
1573 | + source=VFS_GLUSTERFS_SRC, | |
1574 | + deps='samba-util gfapi', | |
1575 | + init_function='', | |
1576 | + internal_module=bld.SAMBA3_IS_STATIC_MODULE('vfs_glusterfs'), | |
1577 | + enabled=bld.SAMBA3_IS_ENABLED_MODULE('vfs_glusterfs'), | |
1578 | + allow_undefined_symbols=False) | |
1579 | ||
1580 | ||
1581 | CHARSET_WEIRD_SRC = 'weird.c' | |
1582 | diff --git a/source3/wscript b/source3/wscript | |
1583 | index bcc6ce1..7e34db5 100644 | |
1584 | --- a/source3/wscript | |
1585 | +++ b/source3/wscript | |
1586 | @@ -60,6 +60,7 @@ def set_options(opt): | |
1587 | opt.SAMBA3_ADD_OPTION('automount') | |
1588 | opt.SAMBA3_ADD_OPTION('aio-support') | |
1589 | opt.SAMBA3_ADD_OPTION('profiling-data') | |
1590 | + opt.SAMBA3_ADD_OPTION('glusterfs', with_name="enable", without_name="disable", default=True) | |
1591 | ||
1592 | opt.SAMBA3_ADD_OPTION('cluster-support') | |
1593 | ||
1594 | @@ -1701,6 +1702,24 @@ main() { | |
1595 | conf.undefine('CLUSTER_SUPPORT') | |
1596 | ||
1597 | ||
1598 | + # | |
1599 | + # Checking for GlusterFS | |
1600 | + # | |
1601 | + if Options.options.with_glusterfs: | |
1602 | + conf.check_cfg(package='glusterfs-api', args='"glusterfs-api >= 4" --cflags --libs', | |
1603 | + msg='Checking for glusterfs-api >= 4', uselib_store="GFAPI") | |
1604 | + conf.CHECK_HEADERS('api/glfs.h', lib='gfapi') | |
1605 | + conf.CHECK_LIB('gfapi', shlib=True) | |
1606 | + | |
1607 | + if conf.CONFIG_SET('HAVE_API_GLFS_H'): | |
1608 | + conf.DEFINE('HAVE_GLUSTERFS', '1') | |
1609 | + else: | |
1610 | + conf.SET_TARGET_TYPE('gfapi', 'EMPTY') | |
1611 | + conf.undefine('HAVE_GLUSTERFS') | |
1612 | + else: | |
1613 | + conf.SET_TARGET_TYPE('gfapi', 'EMPTY') | |
1614 | + conf.undefine('HAVE_GLUSTERFS') | |
1615 | + | |
1616 | ||
1617 | conf.CHECK_CODE('__attribute__((destructor)) static void cleanup(void) { }', | |
1618 | 'HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR', | |
1619 | @@ -1794,6 +1813,9 @@ main() { | |
1620 | if conf.CONFIG_SET('HAVE_GPFS'): | |
1621 | default_shared_modules.extend(TO_LIST('vfs_gpfs vfs_gpfs_hsm_notify')) | |
1622 | ||
1623 | + if conf.CONFIG_SET('HAVE_GLUSTERFS'): | |
1624 | + default_shared_modules.extend(TO_LIST('vfs_glusterfs')) | |
1625 | + | |
1626 | explicit_shared_modules = TO_LIST(Options.options.shared_modules, delimiter=',') | |
1627 | explicit_static_modules = TO_LIST(Options.options.static_modules, delimiter=',') | |
1628 | ||
1629 | -- | |
1630 | 1.9.3 | |
1631 | ||
1632 | ||
1633 | From e2b70ae1e9b072173de2b7d6140381b910d436b4 Mon Sep 17 00:00:00 2001 | |
1634 | From: Raghavendra Talur <rtalur@redhat.com> | |
1635 | Date: Thu, 20 Jun 2013 17:58:15 -0700 | |
1636 | Subject: [PATCH 2/9] PATCHSET13: vfs_glusterfs: New file creation fix. | |
1637 | ||
1638 | When a new document is created in explorer, a check for file_exist is made. | |
1639 | vfs_gluster_get_real_filename was returning 0 even when the file did not | |
1640 | exist. | |
1641 | --- | |
1642 | source3/modules/vfs_glusterfs.c | 6 ++++-- | |
1643 | 1 file changed, 4 insertions(+), 2 deletions(-) | |
1644 | ||
1645 | diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c | |
1646 | index 4beac1d..3752940 100644 | |
1647 | --- a/source3/modules/vfs_glusterfs.c | |
1648 | +++ b/source3/modules/vfs_glusterfs.c | |
1649 | @@ -839,8 +839,10 @@ static int vfs_gluster_get_real_filename(struct vfs_handle_struct *handle, | |
1650 | "user.glusterfs.get_real_filename:%s", name); | |
1651 | ||
1652 | ret = glfs_getxattr(handle->data, path, key_buf, val_buf, NAME_MAX + 1); | |
1653 | - if (ret == -1 && errno == ENODATA) { | |
1654 | - errno = EOPNOTSUPP; | |
1655 | + if (ret == -1) { | |
1656 | + if (errno == ENODATA) { | |
1657 | + errno = EOPNOTSUPP; | |
1658 | + } | |
1659 | return -1; | |
1660 | } | |
1661 | ||
1662 | -- | |
1663 | 1.9.3 | |
1664 | ||
1665 | ||
1666 | From e963ec42b17cdc7369e4b79387447bb3ddc99d2a Mon Sep 17 00:00:00 2001 | |
1667 | From: susant <spalai@redhat.com> | |
1668 | Date: Wed, 7 Aug 2013 01:00:31 -0500 | |
1669 | Subject: [PATCH 3/9] PATCHSET13: vfs_glusterfs: Volume capacity reported to | |
1670 | Windows is incorrect | |
1671 | ||
1672 | VFS plugin was sending the actual size of the volume instead of the | |
1673 | total number of block units because of which windows was getting the | |
1674 | wrong volume capacity. | |
1675 | ||
1676 | Signed-off-by: susant <spalai@redhat.com> | |
1677 | Reviewed-by: Anand Avati <avati@redhat.com> | |
1678 | --- | |
1679 | source3/modules/vfs_glusterfs.c | 11 ++++------- | |
1680 | 1 file changed, 4 insertions(+), 7 deletions(-) | |
1681 | ||
1682 | diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c | |
1683 | index 3752940..1502776 100644 | |
1684 | --- a/source3/modules/vfs_glusterfs.c | |
1685 | +++ b/source3/modules/vfs_glusterfs.c | |
1686 | @@ -297,7 +297,6 @@ vfs_gluster_disk_free(struct vfs_handle_struct *handle, const char *path, | |
1687 | uint64_t *dsize_p) | |
1688 | { | |
1689 | struct statvfs statvfs = { 0, }; | |
1690 | - uint64_t dfree = 0; | |
1691 | int ret; | |
1692 | ||
1693 | ret = glfs_statvfs(handle->data, path, &statvfs); | |
1694 | @@ -307,19 +306,17 @@ vfs_gluster_disk_free(struct vfs_handle_struct *handle, const char *path, | |
1695 | return -1; | |
1696 | } | |
1697 | ||
1698 | - dfree = statvfs.f_bsize * statvfs.f_bavail; | |
1699 | - | |
1700 | if (bsize_p) { | |
1701 | - *bsize_p = statvfs.f_bsize; | |
1702 | + *bsize_p = (uint64_t)statvfs.f_bsize; /* Block size */ | |
1703 | } | |
1704 | if (dfree_p) { | |
1705 | - *dfree_p = dfree; | |
1706 | + *dfree_p = (uint64_t)statvfs.f_bavail; /* Available Block units */ | |
1707 | } | |
1708 | if (dsize_p) { | |
1709 | - *dsize_p = statvfs.f_bsize * statvfs.f_blocks; | |
1710 | + *dsize_p = (uint64_t)statvfs.f_blocks; /* Total Block units */ | |
1711 | } | |
1712 | ||
1713 | - return dfree; | |
1714 | + return (uint64_t)statvfs.f_bavail; | |
1715 | } | |
1716 | ||
1717 | static int | |
1718 | -- | |
1719 | 1.9.3 | |
1720 | ||
1721 | ||
1722 | From 1d41227866ede7ae14857105abd6b322e8e41525 Mon Sep 17 00:00:00 2001 | |
1723 | From: Anand Avati <avati@redhat.com> | |
1724 | Date: Mon, 12 Aug 2013 14:59:24 -0500 | |
1725 | Subject: [PATCH 4/9] PATCHSET13: vfs_glusterfs: Implement proper | |
1726 | mashalling/unmarshalling of ACLs | |
1727 | ||
1728 | Use the primitives available in Samba byteorder.h for implementing | |
1729 | proper (un)marshalling of ACL xattrs. | |
1730 | ||
1731 | Signed-off-by: Anand Avati <avati@redhat.com> | |
1732 | Reviewed-by: Raghavendra Talur <rtalur@redhat.com> | |
1733 | Reviewed-by: Jeremy Allison <jra@samba.org> | |
1734 | Tested-by: "Jose A. Rivera" <jarrpa@redhat.com> | |
1735 | --- | |
1736 | source3/modules/vfs_glusterfs.c | 154 +++++++++++++++++++++++++++++----------- | |
1737 | 1 file changed, 112 insertions(+), 42 deletions(-) | |
1738 | ||
1739 | diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c | |
1740 | index 1502776..1b81d06 100644 | |
1741 | --- a/source3/modules/vfs_glusterfs.c | |
1742 | +++ b/source3/modules/vfs_glusterfs.c | |
1743 | @@ -963,13 +963,36 @@ static int vfs_gluster_set_offline(struct vfs_handle_struct *handle, | |
1744 | return -1; | |
1745 | } | |
1746 | ||
1747 | -/* Posix ACL Operations */ | |
1748 | +/* | |
1749 | + Gluster ACL Format: | |
1750 | + | |
1751 | + Size = 4 (header) + N * 8 (entry) | |
1752 | + | |
1753 | + Offset Size Field (Little Endian) | |
1754 | + ------------------------------------- | |
1755 | + 0-3 4-byte Version | |
1756 | + | |
1757 | + 4-5 2-byte Entry-1 tag | |
1758 | + 6-7 2-byte Entry-1 perm | |
1759 | + 8-11 4-byte Entry-1 id | |
1760 | + | |
1761 | + 12-13 2-byte Entry-2 tag | |
1762 | + 14-15 2-byte Entry-2 perm | |
1763 | + 16-19 4-byte Entry-2 id | |
1764 | ||
1765 | + ... | |
1766 | + | |
1767 | + */ | |
1768 | + | |
1769 | +/* header version */ | |
1770 | #define GLUSTER_ACL_VERSION 2 | |
1771 | + | |
1772 | +/* perm bits */ | |
1773 | #define GLUSTER_ACL_READ 0x04 | |
1774 | #define GLUSTER_ACL_WRITE 0x02 | |
1775 | #define GLUSTER_ACL_EXECUTE 0x01 | |
1776 | ||
1777 | +/* tag values */ | |
1778 | #define GLUSTER_ACL_UNDEFINED_TAG 0x00 | |
1779 | #define GLUSTER_ACL_USER_OBJ 0x01 | |
1780 | #define GLUSTER_ACL_USER 0x02 | |
1781 | @@ -980,57 +1003,48 @@ static int vfs_gluster_set_offline(struct vfs_handle_struct *handle, | |
1782 | ||
1783 | #define GLUSTER_ACL_UNDEFINED_ID (-1) | |
1784 | ||
1785 | -struct gluster_ace { | |
1786 | - uint16_t tag; | |
1787 | - uint16_t perm; | |
1788 | - uint32_t id; | |
1789 | -}; | |
1790 | - | |
1791 | -struct gluster_acl_header { | |
1792 | - uint32_t version; | |
1793 | - struct gluster_ace entries[]; | |
1794 | -}; | |
1795 | +#define GLUSTER_ACL_HEADER_SIZE 4 | |
1796 | +#define GLUSTER_ACL_ENTRY_SIZE 8 | |
1797 | ||
1798 | static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size) | |
1799 | { | |
1800 | int count; | |
1801 | size_t size; | |
1802 | - struct gluster_ace *ace; | |
1803 | struct smb_acl_entry *smb_ace; | |
1804 | - struct gluster_acl_header *hdr; | |
1805 | struct smb_acl_t *result; | |
1806 | int i; | |
1807 | + int offset; | |
1808 | uint16_t tag; | |
1809 | uint16_t perm; | |
1810 | uint32_t id; | |
1811 | ||
1812 | size = xattr_size; | |
1813 | ||
1814 | - if (size < sizeof(*hdr)) { | |
1815 | - /* ACL should be at least as big as the header */ | |
1816 | + if (size < GLUSTER_ACL_HEADER_SIZE) { | |
1817 | + /* ACL should be at least as big as the header (4 bytes) */ | |
1818 | errno = EINVAL; | |
1819 | return NULL; | |
1820 | } | |
1821 | ||
1822 | - size -= sizeof(*hdr); | |
1823 | + size -= GLUSTER_ACL_HEADER_SIZE; /* size of header = 4 bytes */ | |
1824 | ||
1825 | - if (size % sizeof(*ace)) { | |
1826 | + if (size % GLUSTER_ACL_ENTRY_SIZE) { | |
1827 | /* Size of entries must strictly be a multiple of | |
1828 | - size of an ACE | |
1829 | + size of an ACE (8 bytes) | |
1830 | */ | |
1831 | errno = EINVAL; | |
1832 | return NULL; | |
1833 | } | |
1834 | ||
1835 | - count = size / sizeof(*ace); | |
1836 | - | |
1837 | - hdr = (void *)buf; | |
1838 | + count = size / GLUSTER_ACL_ENTRY_SIZE; | |
1839 | ||
1840 | - if (ntohl(hdr->version) != GLUSTER_ACL_VERSION) { | |
1841 | + /* Version is the first 4 bytes of the ACL */ | |
1842 | + if (IVAL(buf, 0) != GLUSTER_ACL_VERSION) { | |
1843 | DEBUG(0, ("Unknown gluster ACL version: %d\n", | |
1844 | - ntohl(hdr->version))); | |
1845 | + IVAL(buf, 0))); | |
1846 | return NULL; | |
1847 | } | |
1848 | + offset = GLUSTER_ACL_HEADER_SIZE; | |
1849 | ||
1850 | result = SMB_MALLOC(sizeof(struct smb_acl_t) + (sizeof(struct smb_acl_entry) * count)); | |
1851 | if (!result) { | |
1852 | @@ -1041,10 +1055,19 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size) | |
1853 | result->count = count; | |
1854 | ||
1855 | smb_ace = result->acl; | |
1856 | - ace = hdr->entries; | |
1857 | ||
1858 | for (i = 0; i < count; i++) { | |
1859 | - tag = ntohs(ace->tag); | |
1860 | + /* TAG is the first 2 bytes of an entry */ | |
1861 | + tag = SVAL(buf, offset); | |
1862 | + offset += 2; | |
1863 | + | |
1864 | + /* PERM is the next 2 bytes of an entry */ | |
1865 | + perm = SVAL(buf, offset); | |
1866 | + offset += 2; | |
1867 | + | |
1868 | + /* ID is the last 4 bytes of an entry */ | |
1869 | + id = IVAL(buf, offset); | |
1870 | + offset += 4; | |
1871 | ||
1872 | switch(tag) { | |
1873 | case GLUSTER_ACL_USER: | |
1874 | @@ -1070,7 +1093,6 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size) | |
1875 | return NULL; | |
1876 | } | |
1877 | ||
1878 | - id = ntohl(ace->id); | |
1879 | ||
1880 | switch(smb_ace->a_type) { | |
1881 | case SMB_ACL_USER: | |
1882 | @@ -1083,8 +1105,6 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size) | |
1883 | break; | |
1884 | } | |
1885 | ||
1886 | - perm = ntohs(ace->perm); | |
1887 | - | |
1888 | smb_ace->a_perm = 0; | |
1889 | smb_ace->a_perm |= | |
1890 | ((perm & GLUSTER_ACL_READ) ? SMB_ACL_READ : 0); | |
1891 | @@ -1093,28 +1113,61 @@ static SMB_ACL_T gluster_to_smb_acl(const char *buf, size_t xattr_size) | |
1892 | smb_ace->a_perm |= | |
1893 | ((perm & GLUSTER_ACL_EXECUTE) ? SMB_ACL_EXECUTE : 0); | |
1894 | ||
1895 | - ace++; | |
1896 | smb_ace++; | |
1897 | } | |
1898 | ||
1899 | return result; | |
1900 | } | |
1901 | ||
1902 | + | |
1903 | +static int gluster_ace_cmp(const void *left, const void *right) | |
1904 | +{ | |
1905 | + int ret = 0; | |
1906 | + uint16_t tag_left, tag_right; | |
1907 | + uint32_t id_left, id_right; | |
1908 | + | |
1909 | + /* | |
1910 | + Sorting precedence: | |
1911 | + | |
1912 | + - Smaller TAG values must be earlier. | |
1913 | + | |
1914 | + - Within same TAG, smaller identifiers must be earlier, E.g: | |
1915 | + UID 0 entry must be earlier than UID 200 | |
1916 | + GID 17 entry must be earlier than GID 19 | |
1917 | + */ | |
1918 | + | |
1919 | + /* TAG is the first element in the entry */ | |
1920 | + tag_left = SVAL(left, 0); | |
1921 | + tag_right = SVAL(right, 0); | |
1922 | + | |
1923 | + ret = (tag_left - tag_right); | |
1924 | + if (!ret) { | |
1925 | + /* ID is the third element in the entry, after two short | |
1926 | + integers (tag and perm), i.e at offset 4. | |
1927 | + */ | |
1928 | + id_left = IVAL(left, 4); | |
1929 | + id_right = IVAL(right, 4); | |
1930 | + ret = id_left - id_right; | |
1931 | + } | |
1932 | + | |
1933 | + return ret; | |
1934 | +} | |
1935 | + | |
1936 | + | |
1937 | static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len) | |
1938 | { | |
1939 | ssize_t size; | |
1940 | - struct gluster_ace *ace; | |
1941 | struct smb_acl_entry *smb_ace; | |
1942 | - struct gluster_acl_header *hdr; | |
1943 | int i; | |
1944 | int count; | |
1945 | uint16_t tag; | |
1946 | uint16_t perm; | |
1947 | uint32_t id; | |
1948 | + int offset; | |
1949 | ||
1950 | count = theacl->count; | |
1951 | ||
1952 | - size = sizeof(*hdr) + (count * sizeof(*ace)); | |
1953 | + size = GLUSTER_ACL_HEADER_SIZE + (count * GLUSTER_ACL_ENTRY_SIZE); | |
1954 | if (!buf) { | |
1955 | return size; | |
1956 | } | |
1957 | @@ -1124,13 +1177,14 @@ static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len) | |
1958 | return -1; | |
1959 | } | |
1960 | ||
1961 | - hdr = (void *)buf; | |
1962 | - ace = hdr->entries; | |
1963 | smb_ace = theacl->acl; | |
1964 | ||
1965 | - hdr->version = htonl(GLUSTER_ACL_VERSION); | |
1966 | + /* Version is the first 4 bytes of the ACL */ | |
1967 | + SIVAL(buf, 0, GLUSTER_ACL_VERSION); | |
1968 | + offset = GLUSTER_ACL_HEADER_SIZE; | |
1969 | ||
1970 | for (i = 0; i < count; i++) { | |
1971 | + /* Calculate tag */ | |
1972 | switch(smb_ace->a_type) { | |
1973 | case SMB_ACL_USER: | |
1974 | tag = GLUSTER_ACL_USER; | |
1975 | @@ -1157,8 +1211,8 @@ static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len) | |
1976 | return -1; | |
1977 | } | |
1978 | ||
1979 | - ace->tag = ntohs(tag); | |
1980 | ||
1981 | + /* Calculate id */ | |
1982 | switch(smb_ace->a_type) { | |
1983 | case SMB_ACL_USER: | |
1984 | id = smb_ace->uid; | |
1985 | @@ -1171,20 +1225,36 @@ static ssize_t smb_to_gluster_acl(SMB_ACL_T theacl, char *buf, size_t len) | |
1986 | break; | |
1987 | } | |
1988 | ||
1989 | - ace->id = ntohl(id); | |
1990 | + /* Calculate perm */ | |
1991 | + perm = 0; | |
1992 | ||
1993 | - ace->perm = 0; | |
1994 | - ace->perm |= | |
1995 | + perm |= | |
1996 | ((smb_ace->a_perm & SMB_ACL_READ) ? GLUSTER_ACL_READ : 0); | |
1997 | - ace->perm |= | |
1998 | + perm |= | |
1999 | ((smb_ace->a_perm & SMB_ACL_WRITE) ? GLUSTER_ACL_WRITE : 0); | |
2000 | - ace->perm |= | |
2001 | + perm |= | |
2002 | ((smb_ace->a_perm & SMB_ACL_EXECUTE) ? GLUSTER_ACL_EXECUTE : 0); | |
2003 | ||
2004 | - ace++; | |
2005 | + | |
2006 | + /* TAG is the first 2 bytes of an entry */ | |
2007 | + SSVAL(buf, offset, tag); | |
2008 | + offset += 2; | |
2009 | + | |
2010 | + /* PERM is the next 2 bytes of an entry */ | |
2011 | + SSVAL(buf, offset, perm); | |
2012 | + offset += 2; | |
2013 | + | |
2014 | + /* ID is the last 4 bytes of an entry */ | |
2015 | + SIVAL(buf, offset, id); | |
2016 | + offset += 4; | |
2017 | + | |
2018 | smb_ace++; | |
2019 | } | |
2020 | ||
2021 | + /* Skip the header, sort @count number of 8-byte entries */ | |
2022 | + qsort(buf+GLUSTER_ACL_HEADER_SIZE, count, GLUSTER_ACL_ENTRY_SIZE, | |
2023 | + gluster_ace_cmp); | |
2024 | + | |
2025 | return size; | |
2026 | } | |
2027 | ||
2028 | -- | |
2029 | 1.9.3 | |
2030 | ||
2031 | ||
2032 | From 26673935299da8ce830ff9d0ea5df18f52092092 Mon Sep 17 00:00:00 2001 | |
2033 | From: "Christopher R. Hertel" <crh@redhat.com> | |
2034 | Date: Thu, 29 Aug 2013 11:01:24 -0500 | |
2035 | Subject: [PATCH 5/9] PATCHSET13: vfs_glusterfs: Fix excessive debug output | |
2036 | from vfs_gluster_open(). | |
2037 | ||
2038 | The vfs_gluster_open() function generates a debug message (at level 0) | |
2039 | for every failed attempt to open a pathname. This includes cases in | |
2040 | which attempts are made to open a directory as a file (those attempts | |
2041 | are retried calling vfs_gluster_opendir()). The result is that the log | |
2042 | file fills with messages about failed attempts to open directories, | |
2043 | because they are directories. This patch ensures that failed attempts | |
2044 | to open directories as files are logged at log level 4, not 0. In | |
2045 | addition, other failed open attempts are logged at level 1, not 0. | |
2046 | ||
2047 | Signed-off-by: Christopher R. Hertel <crh@redhat.com> | |
2048 | Reviewed-by : Susant Palai <spalai@redhat.com> | |
2049 | Reviewed-by : Raghavendra Talur <rtalur@redhat.com> | |
2050 | Reviewed-by : Jose A. Rivera <jarrpa@redhat.com> | |
2051 | --- | |
2052 | source3/modules/vfs_glusterfs.c | 3 --- | |
2053 | 1 file changed, 3 deletions(-) | |
2054 | ||
2055 | diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c | |
2056 | index 1b81d06..b92c7fd 100644 | |
2057 | --- a/source3/modules/vfs_glusterfs.c | |
2058 | +++ b/source3/modules/vfs_glusterfs.c | |
2059 | @@ -488,11 +488,8 @@ static int vfs_gluster_open(struct vfs_handle_struct *handle, | |
2060 | } | |
2061 | ||
2062 | if (glfd == NULL) { | |
2063 | - DEBUG(0, ("glfs_{open[dir],creat}(%s) failed: %s\n", | |
2064 | - smb_fname->base_name, strerror(errno))); | |
2065 | return -1; | |
2066 | } | |
2067 | - | |
2068 | return glfd_fd_store(glfd); | |
2069 | } | |
2070 | ||
2071 | -- | |
2072 | 1.9.3 | |
2073 | ||
2074 | ||
2075 | From f396be725dd8e8f93b0eed1b23fcf0a0f61303a9 Mon Sep 17 00:00:00 2001 | |
2076 | From: Andreas Schneider <asn@samba.org> | |
2077 | Date: Mon, 4 Nov 2013 12:32:05 +0100 | |
2078 | Subject: [PATCH 6/9] PATCHSET13: vfs: Fix some build warnings in glusterfs. | |
2079 | ||
2080 | Signed-off-by: Andreas Schneider <asn@samba.org> | |
2081 | Reviewed-by: David Disseldorp <ddiss@samba.org> | |
2082 | --- | |
2083 | source3/modules/vfs_glusterfs.c | 4 ++-- | |
2084 | 1 file changed, 2 insertions(+), 2 deletions(-) | |
2085 | ||
2086 | diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c | |
2087 | index b92c7fd..4b8da4a 100644 | |
2088 | --- a/source3/modules/vfs_glusterfs.c | |
2089 | +++ b/source3/modules/vfs_glusterfs.c | |
2090 | @@ -1262,7 +1262,7 @@ static SMB_ACL_T vfs_gluster_sys_acl_get_file(struct vfs_handle_struct *handle, | |
2091 | { | |
2092 | struct smb_acl_t *result; | |
2093 | char *buf; | |
2094 | - char *key; | |
2095 | + const char *key; | |
2096 | ssize_t ret; | |
2097 | ||
2098 | switch (type) { | |
2099 | @@ -1324,7 +1324,7 @@ static int vfs_gluster_sys_acl_set_file(struct vfs_handle_struct *handle, | |
2100 | SMB_ACL_T theacl) | |
2101 | { | |
2102 | int ret; | |
2103 | - char *key; | |
2104 | + const char *key; | |
2105 | char *buf; | |
2106 | ssize_t size; | |
2107 | ||
2108 | -- | |
2109 | 1.9.3 | |
2110 | ||
2111 | ||
2112 | From 2b136f8999e171d15736d0a532353799b7251ae2 Mon Sep 17 00:00:00 2001 | |
2113 | From: Andreas Schneider <asn@samba.org> | |
2114 | Date: Fri, 15 Nov 2013 17:02:19 +0100 | |
2115 | Subject: [PATCH 7/9] PATCHSET13: s3-vfs: Make glfs_set_preopened() static. | |
2116 | ||
2117 | Signed-off-by: Andreas Schneider <asn@samba.org> | |
2118 | Reviewed-by: Jeremy Allison <jra@samba.org> | |
2119 | --- | |
2120 | source3/modules/vfs_glusterfs.c | 2 +- | |
2121 | 1 file changed, 1 insertion(+), 1 deletion(-) | |
2122 | ||
2123 | diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c | |
2124 | index 4b8da4a..ef505a3 100644 | |
2125 | --- a/source3/modules/vfs_glusterfs.c | |
2126 | +++ b/source3/modules/vfs_glusterfs.c | |
2127 | @@ -141,7 +141,7 @@ static struct glfs_preopened { | |
2128 | } *glfs_preopened; | |
2129 | ||
2130 | ||
2131 | -int glfs_set_preopened(const char *volume, glfs_t *fs) | |
2132 | +static int glfs_set_preopened(const char *volume, glfs_t *fs) | |
2133 | { | |
2134 | struct glfs_preopened *entry = NULL; | |
2135 | ||
2136 | -- | |
2137 | 1.9.3 | |
2138 | ||
2139 | ||
2140 | From 9b2c8854a5a27e4fdbe5191abf174d3152b0edfd Mon Sep 17 00:00:00 2001 | |
2141 | From: Poornima Gurusiddaiah <pgurusid@redhat.com> | |
2142 | Date: Sun, 24 Nov 2013 21:37:53 +0000 | |
2143 | Subject: [PATCH 8/9] PATCHSET13: vfs_glusterfs: Enable per client log file | |
2144 | ||
2145 | In Samba configuration file, one of the options of gluster type is | |
2146 | log file, the value of this option was not allowed to contain any | |
2147 | variables, as a result all the clients would have a single log file, | |
2148 | which complicated debugging. | |
2149 | In this patch, variable substitution is performed for gluster log file. | |
2150 | Hence allowing user to customise the gluster log file name. | |
2151 | ||
2152 | Signed-off-by: Poornima Gurusiddaiah <pgurusid@redhat.com> | |
2153 | Reviewed-by: Ira Cooper <ira@samba.org> | |
2154 | --- | |
2155 | source3/modules/vfs_glusterfs.c | 41 ++++++++++++++++++++++------------------- | |
2156 | 1 file changed, 22 insertions(+), 19 deletions(-) | |
2157 | ||
2158 | diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c | |
2159 | index ef505a3..3757968 100644 | |
2160 | --- a/source3/modules/vfs_glusterfs.c | |
2161 | +++ b/source3/modules/vfs_glusterfs.c | |
2162 | @@ -205,12 +205,12 @@ static int vfs_gluster_connect(struct vfs_handle_struct *handle, | |
2163 | { | |
2164 | const char *volfile_server; | |
2165 | const char *volume; | |
2166 | - const char *logfile; | |
2167 | + char *logfile; | |
2168 | int loglevel; | |
2169 | glfs_t *fs; | |
2170 | - int ret; | |
2171 | + int ret = 0; | |
2172 | ||
2173 | - logfile = lp_parm_const_string(SNUM(handle->conn), "glusterfs", | |
2174 | + logfile = lp_parm_talloc_string(SNUM(handle->conn), "glusterfs", | |
2175 | "logfile", NULL); | |
2176 | ||
2177 | loglevel = lp_parm_int(SNUM(handle->conn), "glusterfs", "loglevel", -1); | |
2178 | @@ -229,57 +229,60 @@ static int vfs_gluster_connect(struct vfs_handle_struct *handle, | |
2179 | ||
2180 | fs = glfs_find_preopened(volume); | |
2181 | if (fs) { | |
2182 | - goto found; | |
2183 | + goto done; | |
2184 | } | |
2185 | ||
2186 | fs = glfs_new(volume); | |
2187 | if (fs == NULL) { | |
2188 | - return -1; | |
2189 | + ret = -1; | |
2190 | + goto done; | |
2191 | } | |
2192 | ||
2193 | ret = glfs_set_volfile_server(fs, "tcp", volfile_server, 0); | |
2194 | if (ret < 0) { | |
2195 | DEBUG(0, ("Failed to set volfile_server %s\n", volfile_server)); | |
2196 | - glfs_fini(fs); | |
2197 | - return -1; | |
2198 | + goto done; | |
2199 | } | |
2200 | ||
2201 | ret = glfs_set_xlator_option(fs, "*-md-cache", "cache-posix-acl", | |
2202 | "true"); | |
2203 | if (ret < 0) { | |
2204 | DEBUG(0, ("%s: Failed to set xlator options\n", volume)); | |
2205 | - glfs_fini(fs); | |
2206 | - return -1; | |
2207 | + goto done; | |
2208 | } | |
2209 | ||
2210 | ret = glfs_set_logging(fs, logfile, loglevel); | |
2211 | if (ret < 0) { | |
2212 | DEBUG(0, ("%s: Failed to set logfile %s loglevel %d\n", | |
2213 | volume, logfile, loglevel)); | |
2214 | - glfs_fini(fs); | |
2215 | - return -1; | |
2216 | + goto done; | |
2217 | } | |
2218 | ||
2219 | ret = glfs_init(fs); | |
2220 | if (ret < 0) { | |
2221 | DEBUG(0, ("%s: Failed to initialize volume (%s)\n", | |
2222 | volume, strerror(errno))); | |
2223 | - glfs_fini(fs); | |
2224 | - return -1; | |
2225 | + goto done; | |
2226 | } | |
2227 | ||
2228 | ret = glfs_set_preopened(volume, fs); | |
2229 | if (ret < 0) { | |
2230 | DEBUG(0, ("%s: Failed to register volume (%s)\n", | |
2231 | volume, strerror(errno))); | |
2232 | - glfs_fini(fs); | |
2233 | + goto done; | |
2234 | + } | |
2235 | +done: | |
2236 | + talloc_free(logfile); | |
2237 | + if (ret < 0) { | |
2238 | + if (fs) | |
2239 | + glfs_fini(fs); | |
2240 | return -1; | |
2241 | + } else { | |
2242 | + DEBUG(0, ("%s: Initialized volume from server %s\n", | |
2243 | + volume, volfile_server)); | |
2244 | + handle->data = fs; | |
2245 | + return 0; | |
2246 | } | |
2247 | -found: | |
2248 | - DEBUG(0, ("%s: Initialized volume from server %s\n", | |
2249 | - volume, volfile_server)); | |
2250 | - handle->data = fs; | |
2251 | - return 0; | |
2252 | } | |
2253 | ||
2254 | static void vfs_gluster_disconnect(struct vfs_handle_struct *handle) | |
2255 | -- | |
2256 | 1.9.3 | |
2257 | ||
2258 | ||
2259 | From 8577c573dcd44e26579a6594b83a6d582faef14c Mon Sep 17 00:00:00 2001 | |
2260 | From: Niels de Vos <ndevos@redhat.com> | |
2261 | Date: Fri, 10 Jan 2014 16:26:18 +0100 | |
2262 | Subject: [PATCH 9/9] PATCHSET13: vfs/glusterfs: in case atime is not passed, | |
2263 | set it to the current atime | |
2264 | ||
2265 | The Linux CIFS client does not pass an updated atime when a write() is | |
2266 | done. This causes the vfs/glusterfs module to set the atime to -1 on the | |
2267 | Gluster backend, resulting in an atime far in the future (year 2106). | |
2268 | ||
2269 | Signed-off-by: Niels de Vos <ndevos@redhat.com> | |
2270 | Reviewed-by: Ira Cooper <ira@samba.org> | |
2271 | Reviewed-by: Jeremy Allison <jra@samba.org> | |
2272 | ||
2273 | Autobuild-User(master): Jeremy Allison <jra@samba.org> | |
2274 | Autobuild-Date(master): Wed Jan 15 21:31:30 CET 2014 on sn-devel-104 | |
2275 | --- | |
2276 | source3/modules/vfs_glusterfs.c | 26 ++++++++++++++++++++++---- | |
2277 | 1 file changed, 22 insertions(+), 4 deletions(-) | |
2278 | ||
2279 | diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c | |
2280 | index 3757968..24f80dd 100644 | |
2281 | --- a/source3/modules/vfs_glusterfs.c | |
2282 | +++ b/source3/modules/vfs_glusterfs.c | |
2283 | @@ -675,10 +675,28 @@ static int vfs_gluster_ntimes(struct vfs_handle_struct *handle, | |
2284 | { | |
2285 | struct timespec times[2]; | |
2286 | ||
2287 | - times[0].tv_sec = ft->atime.tv_sec; | |
2288 | - times[0].tv_nsec = ft->atime.tv_nsec; | |
2289 | - times[1].tv_sec = ft->mtime.tv_sec; | |
2290 | - times[1].tv_nsec = ft->mtime.tv_nsec; | |
2291 | + if (null_timespec(ft->atime)) { | |
2292 | + times[0].tv_sec = smb_fname->st.st_ex_atime.tv_sec; | |
2293 | + times[0].tv_nsec = smb_fname->st.st_ex_atime.tv_nsec; | |
2294 | + } else { | |
2295 | + times[0].tv_sec = ft->atime.tv_sec; | |
2296 | + times[0].tv_nsec = ft->atime.tv_nsec; | |
2297 | + } | |
2298 | + | |
2299 | + if (null_timespec(ft->mtime)) { | |
2300 | + times[1].tv_sec = smb_fname->st.st_ex_mtime.tv_sec; | |
2301 | + times[1].tv_nsec = smb_fname->st.st_ex_mtime.tv_nsec; | |
2302 | + } else { | |
2303 | + times[1].tv_sec = ft->mtime.tv_sec; | |
2304 | + times[1].tv_nsec = ft->mtime.tv_nsec; | |
2305 | + } | |
2306 | + | |
2307 | + if ((timespec_compare(×[0], | |
2308 | + &smb_fname->st.st_ex_atime) == 0) && | |
2309 | + (timespec_compare(×[1], | |
2310 | + &smb_fname->st.st_ex_mtime) == 0)) { | |
2311 | + return 0; | |
2312 | + } | |
2313 | ||
2314 | return glfs_utimens(handle->data, smb_fname->base_name, times); | |
2315 | } | |
2316 | -- | |
2317 | 1.9.3 | |
2318 |