1 Source: Oracle Solaris (based on VFS module written by [email protected]) |
|
2 Shared with community as Samba.org bug #5780 : |
|
3 https://bugzilla.samba.org/show_bug.cgi?id=5780 |
|
4 |
|
5 diff --git a/source3/Makefile.in b/source3/Makefile.in |
|
6 index 425aa2b..db1d809 100644 |
|
7 --- a/source3/Makefile.in |
|
8 +++ b/source3/Makefile.in |
|
9 @@ -715,6 +715,7 @@ VFS_AIXACL_OBJ = modules/vfs_aixacl.o modules/vfs_aixacl_util.o |
|
10 VFS_AIXACL2_OBJ = modules/vfs_aixacl2.o modules/vfs_aixacl_util.o modules/nfs4_acls.o |
|
11 VFS_SOLARISACL_OBJ = modules/vfs_solarisacl.o |
|
12 VFS_ZFSACL_OBJ = modules/vfs_zfsacl.o modules/nfs4_acls.o |
|
13 +VFS_SAMFS_OBJ = modules/vfs_samfs.o |
|
14 VFS_HPUXACL_OBJ = modules/vfs_hpuxacl.o |
|
15 VFS_IRIXACL_OBJ = modules/vfs_irixacl.o |
|
16 VFS_TRU64ACL_OBJ = modules/vfs_tru64acl.o |
|
17 @@ -2741,6 +2742,10 @@ bin/zfsacl.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ZFSACL_OBJ) |
|
18 @echo "Building plugin $@" |
|
19 @$(SHLD_MODULE) $(VFS_ZFSACL_OBJ) |
|
20 |
|
21 +bin/samfs.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SAMFS_OBJ) |
|
22 + @echo "Building plugin $@" |
|
23 + @$(SHLD_MODULE) $(VFS_SAMFS_OBJ) @SAMFS_LIBS@ |
|
24 + |
|
25 bin/irixacl.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_IRIXACL_OBJ) |
|
26 @echo "Building plugin $@" |
|
27 @$(SHLD_MODULE) $(VFS_IRIXACL_OBJ) |
|
28 diff --git a/source3/configure.in b/source3/configure.in |
|
29 index 2494593..8daa53f 100644 |
|
30 --- a/source3/configure.in |
|
31 +++ b/source3/configure.in |
|
32 @@ -6653,6 +6653,8 @@ SMB_MODULE(vfs_aio_fork, \$(VFS_AIO_FORK_OBJ), "bin/aio_fork.$SHLIBEXT", VFS) |
|
33 SMB_MODULE(vfs_preopen, \$(VFS_PREOPEN_OBJ), "bin/preopen.$SHLIBEXT", VFS) |
|
34 SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS) |
|
35 SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS) |
|
36 +AC_SUBST(SAMFS_LIBS) |
|
37 +SMB_MODULE(vfs_samfs, \$(VFS_SAMFS_OBJ), "bin/samfs.$SHLIBEXT", VFS) |
|
38 SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", VFS) |
|
39 SMB_MODULE(vfs_acl_xattr, \$(VFS_ACL_XATTR_OBJ), "bin/acl_xattr.$SHLIBEXT", VFS) |
|
40 SMB_MODULE(vfs_acl_tdb, \$(VFS_ACL_TDB_OBJ), "bin/acl_tdb.$SHLIBEXT", VFS) |
|
41 diff --git a/source3/modules/vfs_samfs.c b/source3/modules/vfs_samfs.c |
|
42 new file mode 100644 |
|
43 index 0000000..9370768 |
|
44 --- /dev/null 2012-07-16 09:13:54.000000000 -0700 |
|
45 +++ b/source3/modules/vfs_samfs.c 2012-07-16 09:21:00.168046000 -0700 |
|
46 @@ -0,0 +1,179 @@ |
|
47 +/* |
|
48 + * Support for offline files with Sun SAM-QFS |
|
49 + * |
|
50 + * Copyright (C) Dirk Nitschke, 2009 |
|
51 + * |
|
52 + * Modified by Jiri Sasek, 2010 |
|
53 + * To conform the samba-vfs api |
|
54 + * |
|
55 + * This program is free software; you can redistribute it and/or modify |
|
56 + * it under the terms of the GNU General Public License as published by |
|
57 + * the Free Software Foundation; either version 3 of the License, or |
|
58 + * (at your option) any later version. |
|
59 + * |
|
60 + * This program is distributed in the hope that it will be useful, |
|
61 + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
62 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
63 + * GNU General Public License for more details. |
|
64 + * |
|
65 + * You should have received a copy of the GNU General Public License |
|
66 + * along with this program; if not, see <http://www.gnu.org/licenses/>. |
|
67 + * |
|
68 + */ |
|
69 + |
|
70 +#include "includes.h" |
|
71 +#include "smbd/smbd.h" |
|
72 +/* |
|
73 + * Include files for Sun SAM-QFS |
|
74 + * |
|
75 + */ |
|
76 +#include <samfs/stat.h> |
|
77 +#include <samfs/lib.h> |
|
78 + |
|
79 +#undef DBGC_CLASS |
|
80 +#define DBGC_CLASS DBGC_VFS |
|
81 + |
|
82 +#define SAMFS_MODULE_NAME "samfs" |
|
83 + |
|
84 +NTSTATUS vfs_samfs_init(void); |
|
85 + |
|
86 +/* |
|
87 + * samfs_is_offline() |
|
88 + * check if the local file is offline in the sense of SAM-QFS |
|
89 + * |
|
90 + * A segmented file is offline if the file's index inode is |
|
91 + * offline or at least one of it's segments is offline. |
|
92 + * |
|
93 + * See sam_stat(3) and sam_segment_stat(3) for details. |
|
94 + * |
|
95 + * If something goes wrong we assume that the file is offline. |
|
96 + */ |
|
97 +static bool samfs_is_offline(struct vfs_handle_struct *handle, const struct smb_filename *fname, SMB_STRUCT_STAT *sbuf) |
|
98 +{ |
|
99 + struct sam_stat file_info; |
|
100 + struct sam_stat *seg_info_ptr; |
|
101 + int number_of_segments, number_of_segments_offline = 0; |
|
102 + int result; |
|
103 + int i; |
|
104 + NTSTATUS status; |
|
105 + char *path; |
|
106 + |
|
107 + status = get_full_smb_filename(talloc_tos(), fname, &path); |
|
108 + if (!NT_STATUS_IS_OK(status)) { |
|
109 + errno = map_errno_from_nt_status(status); |
|
110 + return false; |
|
111 + } |
|
112 + |
|
113 + if (ISDOT(path) || ISDOTDOT(path)) { |
|
114 + return false; |
|
115 + } |
|
116 + |
|
117 + /* |
|
118 + * Initialize file_info to be all zero bits |
|
119 + */ |
|
120 + memset((void *)&file_info, 0, sizeof(struct sam_stat)); |
|
121 + |
|
122 + /* |
|
123 + * Stat the file using the regular sam_stat function |
|
124 + */ |
|
125 + result = sam_stat(path, &file_info, sizeof(struct sam_stat)); |
|
126 + |
|
127 + if (result != 0) { |
|
128 + DEBUG(10,("samfs_is_offline: cannot sam_stat %s, %s\nAssuming file is offline.\n", \ |
|
129 + path, strerror(errno))); |
|
130 + return true; |
|
131 + } |
|
132 + |
|
133 + /* |
|
134 + * Check if file is offline |
|
135 + */ |
|
136 + if (SS_ISOFFLINE(file_info.attr)) { |
|
137 + DEBUG(10,("samfs_is_offline: file %s is offline.\n", path)); |
|
138 + return true; |
|
139 + } |
|
140 + |
|
141 + /* |
|
142 + * Check for segmented file |
|
143 + */ |
|
144 + if (SS_ISSEGMENT_F(file_info.attr)) { |
|
145 + number_of_segments = NUM_SEGS(&file_info); |
|
146 + seg_info_ptr = (struct sam_stat *)TALLOC_ZERO_ARRAY(talloc_tos(), |
|
147 + struct sam_stat, number_of_segments); |
|
148 + if (seg_info_ptr == NULL) { |
|
149 + DEBUG(10,("samfs_is_offline: cannot talloc for " |
|
150 + "segment stat info %s\nAssuming file is offline.\n", |
|
151 + path)); |
|
152 + return true; |
|
153 + } |
|
154 + |
|
155 + /* |
|
156 + * Stat all segments |
|
157 + */ |
|
158 + result = sam_segment_stat(path, seg_info_ptr, |
|
159 + number_of_segments * sizeof(struct sam_stat)); |
|
160 + if (result != 0) { |
|
161 + DEBUG(10,("samfs_is_offline: cannot sam_segment_stat %s, " |
|
162 + "%s\nAssuming file is offline.\n", |
|
163 + path, strerror(errno))); |
|
164 + TALLOC_FREE(seg_info_ptr); |
|
165 + return true; |
|
166 + } |
|
167 + /* |
|
168 + * Loop over segments until we have checked all segments |
|
169 + * or found one which is offline. |
|
170 + */ |
|
171 + for (i = 0; i < number_of_segments; i++) { |
|
172 + if (SS_ISOFFLINE(seg_info_ptr[i].attr)) { |
|
173 + number_of_segments_offline++; |
|
174 + } |
|
175 + } |
|
176 + DEBUG(10,("samfs_is_offline: file %s has %d offline segments\n" |
|
177 + , path, number_of_segments_offline)); |
|
178 + TALLOC_FREE(seg_info_ptr); |
|
179 + } |
|
180 + return (number_of_segments_offline) ? true : false ; |
|
181 +} |
|
182 + |
|
183 +/* |
|
184 + * samfs_set_offline() |
|
185 + * |
|
186 + * Release the local file in the sense of SAM-QFS. |
|
187 + * See sam_release(3) for details. |
|
188 + * |
|
189 + */ |
|
190 +static int samfs_set_offline(struct vfs_handle_struct *handle, const struct smb_filename *fname) |
|
191 +{ |
|
192 + int result; |
|
193 + NTSTATUS status; |
|
194 + char *path; |
|
195 + |
|
196 + status = get_full_smb_filename(talloc_tos(), fname, &path); |
|
197 + if (!NT_STATUS_IS_OK(status)) { |
|
198 + errno = map_errno_from_nt_status(status); |
|
199 + return false; |
|
200 + } |
|
201 + |
|
202 + /* |
|
203 + * release a file-command to SAM-stager |
|
204 + */ |
|
205 + result = sam_release(path, "i"); |
|
206 + if (result != 0) { |
|
207 + DEBUG(10,("samfs_set_offline: sam_release %s returned %s\n", |
|
208 + path, strerror(errno))); |
|
209 + return -1; |
|
210 + } |
|
211 + return 0; |
|
212 +} |
|
213 + |
|
214 +/* VFS operations structure */ |
|
215 + |
|
216 +static struct vfs_fn_pointers samfs_fns = { |
|
217 + .is_offline = samfs_is_offline, |
|
218 + .set_offline = samfs_set_offline |
|
219 +}; |
|
220 + |
|
221 +NTSTATUS vfs_samfs_init(void) |
|
222 +{ |
|
223 + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, SAMFS_MODULE_NAME, |
|
224 + &samfs_fns); |
|
225 +} |
|