blob: 8277aba65e87447086c96b0f4b741752aa8a4875 [file] [log] [blame]
Mike Marshallf7be4ee2015-07-17 10:38:14 -04001/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6#include "protocol.h"
Mike Marshall575e9462015-12-04 12:56:14 -05007#include "orangefs-kernel.h"
8#include "orangefs-dev-proto.h"
9#include "orangefs-bufmap.h"
Mike Marshallf7be4ee2015-07-17 10:38:14 -040010
Yi Liu8bb8aef2015-11-24 15:12:14 -050011__s32 fsid_of_op(struct orangefs_kernel_op_s *op)
Mike Marshallf7be4ee2015-07-17 10:38:14 -040012{
Yi Liu8bb8aef2015-11-24 15:12:14 -050013 __s32 fsid = ORANGEFS_FS_ID_NULL;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040014
15 if (op) {
16 switch (op->upcall.type) {
Yi Liu8bb8aef2015-11-24 15:12:14 -050017 case ORANGEFS_VFS_OP_FILE_IO:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040018 fsid = op->upcall.req.io.refn.fs_id;
19 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050020 case ORANGEFS_VFS_OP_LOOKUP:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040021 fsid = op->upcall.req.lookup.parent_refn.fs_id;
22 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050023 case ORANGEFS_VFS_OP_CREATE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040024 fsid = op->upcall.req.create.parent_refn.fs_id;
25 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050026 case ORANGEFS_VFS_OP_GETATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040027 fsid = op->upcall.req.getattr.refn.fs_id;
28 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050029 case ORANGEFS_VFS_OP_REMOVE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040030 fsid = op->upcall.req.remove.parent_refn.fs_id;
31 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050032 case ORANGEFS_VFS_OP_MKDIR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040033 fsid = op->upcall.req.mkdir.parent_refn.fs_id;
34 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050035 case ORANGEFS_VFS_OP_READDIR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040036 fsid = op->upcall.req.readdir.refn.fs_id;
37 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050038 case ORANGEFS_VFS_OP_SETATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040039 fsid = op->upcall.req.setattr.refn.fs_id;
40 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050041 case ORANGEFS_VFS_OP_SYMLINK:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040042 fsid = op->upcall.req.sym.parent_refn.fs_id;
43 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050044 case ORANGEFS_VFS_OP_RENAME:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040045 fsid = op->upcall.req.rename.old_parent_refn.fs_id;
46 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050047 case ORANGEFS_VFS_OP_STATFS:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040048 fsid = op->upcall.req.statfs.fs_id;
49 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050050 case ORANGEFS_VFS_OP_TRUNCATE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040051 fsid = op->upcall.req.truncate.refn.fs_id;
52 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050053 case ORANGEFS_VFS_OP_MMAP_RA_FLUSH:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040054 fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
55 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050056 case ORANGEFS_VFS_OP_FS_UMOUNT:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040057 fsid = op->upcall.req.fs_umount.fs_id;
58 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050059 case ORANGEFS_VFS_OP_GETXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040060 fsid = op->upcall.req.getxattr.refn.fs_id;
61 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050062 case ORANGEFS_VFS_OP_SETXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040063 fsid = op->upcall.req.setxattr.refn.fs_id;
64 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050065 case ORANGEFS_VFS_OP_LISTXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040066 fsid = op->upcall.req.listxattr.refn.fs_id;
67 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050068 case ORANGEFS_VFS_OP_REMOVEXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040069 fsid = op->upcall.req.removexattr.refn.fs_id;
70 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050071 case ORANGEFS_VFS_OP_FSYNC:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040072 fsid = op->upcall.req.fsync.refn.fs_id;
73 break;
74 default:
75 break;
76 }
77 }
78 return fsid;
79}
80
Martin Brandenburg394f6472016-01-25 15:33:39 -050081static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
Mike Marshallf7be4ee2015-07-17 10:38:14 -040082{
Martin Brandenburg394f6472016-01-25 15:33:39 -050083 int flags = 0;
Yi Liu8bb8aef2015-11-24 15:12:14 -050084 if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050085 flags |= S_IMMUTABLE;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040086 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050087 flags &= ~S_IMMUTABLE;
Yi Liu8bb8aef2015-11-24 15:12:14 -050088 if (attrs->flags & ORANGEFS_APPEND_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050089 flags |= S_APPEND;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040090 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050091 flags &= ~S_APPEND;
Yi Liu8bb8aef2015-11-24 15:12:14 -050092 if (attrs->flags & ORANGEFS_NOATIME_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050093 flags |= S_NOATIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040094 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050095 flags &= ~S_NOATIME;
96 return flags;
97}
Mike Marshallf7be4ee2015-07-17 10:38:14 -040098
Martin Brandenburg394f6472016-01-25 15:33:39 -050099static int orangefs_inode_perms(struct ORANGEFS_sys_attr_s *attrs)
100{
101 int perm_mode = 0;
102
103 if (attrs->perms & ORANGEFS_O_EXECUTE)
104 perm_mode |= S_IXOTH;
105 if (attrs->perms & ORANGEFS_O_WRITE)
106 perm_mode |= S_IWOTH;
107 if (attrs->perms & ORANGEFS_O_READ)
108 perm_mode |= S_IROTH;
109
110 if (attrs->perms & ORANGEFS_G_EXECUTE)
111 perm_mode |= S_IXGRP;
112 if (attrs->perms & ORANGEFS_G_WRITE)
113 perm_mode |= S_IWGRP;
114 if (attrs->perms & ORANGEFS_G_READ)
115 perm_mode |= S_IRGRP;
116
117 if (attrs->perms & ORANGEFS_U_EXECUTE)
118 perm_mode |= S_IXUSR;
119 if (attrs->perms & ORANGEFS_U_WRITE)
120 perm_mode |= S_IWUSR;
121 if (attrs->perms & ORANGEFS_U_READ)
122 perm_mode |= S_IRUSR;
123
124 if (attrs->perms & ORANGEFS_G_SGID)
125 perm_mode |= S_ISGID;
126 if (attrs->perms & ORANGEFS_U_SUID)
127 perm_mode |= S_ISUID;
128
129 return perm_mode;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400130}
131
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400132/*
133 * NOTE: in kernel land, we never use the sys_attr->link_target for
134 * anything, so don't bother copying it into the sys_attr object here.
135 */
136static inline int copy_attributes_from_inode(struct inode *inode,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500137 struct ORANGEFS_sys_attr_s *attrs,
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400138 struct iattr *iattr)
139{
140 umode_t tmp_mode;
141
142 if (!iattr || !inode || !attrs) {
143 gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
144 "in copy_attributes_from_inode!\n",
145 iattr,
146 inode,
147 attrs);
148 return -EINVAL;
149 }
150 /*
151 * We need to be careful to only copy the attributes out of the
152 * iattr object that we know are valid.
153 */
154 attrs->mask = 0;
155 if (iattr->ia_valid & ATTR_UID) {
156 attrs->owner = from_kuid(current_user_ns(), iattr->ia_uid);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500157 attrs->mask |= ORANGEFS_ATTR_SYS_UID;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400158 gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
159 }
160 if (iattr->ia_valid & ATTR_GID) {
161 attrs->group = from_kgid(current_user_ns(), iattr->ia_gid);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500162 attrs->mask |= ORANGEFS_ATTR_SYS_GID;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400163 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
164 }
165
166 if (iattr->ia_valid & ATTR_ATIME) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500167 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400168 if (iattr->ia_valid & ATTR_ATIME_SET) {
Arnd Bergmannbe81ce42016-02-26 13:54:10 +0100169 attrs->atime = (time64_t)iattr->ia_atime.tv_sec;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500170 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400171 }
172 }
173 if (iattr->ia_valid & ATTR_MTIME) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500174 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400175 if (iattr->ia_valid & ATTR_MTIME_SET) {
Arnd Bergmannbe81ce42016-02-26 13:54:10 +0100176 attrs->mtime = (time64_t)iattr->ia_mtime.tv_sec;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500177 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400178 }
179 }
180 if (iattr->ia_valid & ATTR_CTIME)
Yi Liu8bb8aef2015-11-24 15:12:14 -0500181 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400182
183 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500184 * ORANGEFS cannot set size with a setattr operation. Probably not likely
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400185 * to be requested through the VFS, but just in case, don't worry about
186 * ATTR_SIZE
187 */
188
189 if (iattr->ia_valid & ATTR_MODE) {
190 tmp_mode = iattr->ia_mode;
191 if (tmp_mode & (S_ISVTX)) {
192 if (is_root_handle(inode)) {
193 /*
194 * allow sticky bit to be set on root (since
195 * it shows up that way by default anyhow),
196 * but don't show it to the server
197 */
198 tmp_mode -= S_ISVTX;
199 } else {
200 gossip_debug(GOSSIP_UTILS_DEBUG,
201 "User attempted to set sticky bit on non-root directory; returning EINVAL.\n");
202 return -EINVAL;
203 }
204 }
205
206 if (tmp_mode & (S_ISUID)) {
207 gossip_debug(GOSSIP_UTILS_DEBUG,
208 "Attempting to set setuid bit (not supported); returning EINVAL.\n");
209 return -EINVAL;
210 }
211
Yi Liu8bb8aef2015-11-24 15:12:14 -0500212 attrs->perms = ORANGEFS_util_translate_mode(tmp_mode);
213 attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400214 }
215
216 return 0;
217}
218
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400219static int orangefs_inode_type(enum orangefs_ds_type objtype)
220{
221 if (objtype == ORANGEFS_TYPE_METAFILE)
222 return S_IFREG;
223 else if (objtype == ORANGEFS_TYPE_DIRECTORY)
224 return S_IFDIR;
225 else if (objtype == ORANGEFS_TYPE_SYMLINK)
226 return S_IFLNK;
227 else
228 return -1;
229}
230
Martin Brandenburg26662632016-03-17 16:01:52 -0400231static int orangefs_inode_is_stale(struct inode *inode, int new,
232 struct ORANGEFS_sys_attr_s *attrs, char *link_target)
233{
234 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
235 int type = orangefs_inode_type(attrs->objtype);
236 if (!new) {
237 /*
238 * If the inode type or symlink target have changed then this
239 * inode is stale.
240 */
241 if (type == -1 || !(inode->i_mode & type)) {
242 orangefs_make_bad_inode(inode);
243 return 1;
244 }
245 if (type == S_IFLNK && strncmp(orangefs_inode->link_target,
246 link_target, ORANGEFS_NAME_MAX)) {
247 orangefs_make_bad_inode(inode);
248 return 1;
249 }
250 }
251 return 0;
252}
253
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400254int orangefs_inode_getattr(struct inode *inode, int new, int size)
255{
256 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
257 struct orangefs_kernel_op_s *new_op;
258 loff_t inode_size, rounded_up_size;
Martin Brandenburg26662632016-03-17 16:01:52 -0400259 int ret, type;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400260
261 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
262 get_khandle_from_ino(inode));
263
264 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
265 if (!new_op)
266 return -ENOMEM;
267 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
268 new_op->upcall.req.getattr.mask = size ?
269 ORANGEFS_ATTR_SYS_ALL_NOHINT : ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE;
270
271 ret = service_operation(new_op, __func__,
272 get_interruptible_flag(inode));
273 if (ret != 0)
274 goto out;
275
Martin Brandenburg26662632016-03-17 16:01:52 -0400276 type = orangefs_inode_type(new_op->
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400277 downcall.resp.getattr.attributes.objtype);
Martin Brandenburg26662632016-03-17 16:01:52 -0400278 ret = orangefs_inode_is_stale(inode, new,
279 &new_op->downcall.resp.getattr.attributes,
280 new_op->downcall.resp.getattr.link_target);
281 if (ret) {
282 ret = -ESTALE;
283 goto out;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400284 }
285
Martin Brandenburg26662632016-03-17 16:01:52 -0400286 switch (type) {
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400287 case S_IFREG:
288 inode->i_flags = orangefs_inode_flags(&new_op->
289 downcall.resp.getattr.attributes);
290 if (size) {
291 inode_size = (loff_t)new_op->
292 downcall.resp.getattr.attributes.size;
293 rounded_up_size =
294 (inode_size + (4096 - (inode_size % 4096)));
295 inode->i_size = inode_size;
296 orangefs_inode->blksize =
297 new_op->downcall.resp.getattr.attributes.blksize;
298 spin_lock(&inode->i_lock);
299 inode->i_bytes = inode_size;
300 inode->i_blocks =
301 (unsigned long)(rounded_up_size / 512);
302 spin_unlock(&inode->i_lock);
303 }
304 break;
305 case S_IFDIR:
Kirill A. Shutemov09cbfea2016-04-01 15:29:47 +0300306 inode->i_size = PAGE_SIZE;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400307 orangefs_inode->blksize = (1 << inode->i_blkbits);
308 spin_lock(&inode->i_lock);
309 inode_set_bytes(inode, inode->i_size);
310 spin_unlock(&inode->i_lock);
311 set_nlink(inode, 1);
312 break;
313 case S_IFLNK:
314 if (new) {
315 inode->i_size = (loff_t)strlen(new_op->
316 downcall.resp.getattr.link_target);
317 orangefs_inode->blksize = (1 << inode->i_blkbits);
318 strlcpy(orangefs_inode->link_target,
319 new_op->downcall.resp.getattr.link_target,
320 ORANGEFS_NAME_MAX);
Martin Brandenburge8da2542016-03-18 14:20:15 -0400321 inode->i_link = orangefs_inode->link_target;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400322 }
323 break;
324 }
325
326 inode->i_uid = make_kuid(&init_user_ns, new_op->
327 downcall.resp.getattr.attributes.owner);
328 inode->i_gid = make_kgid(&init_user_ns, new_op->
329 downcall.resp.getattr.attributes.group);
330 inode->i_atime.tv_sec = (time64_t)new_op->
331 downcall.resp.getattr.attributes.atime;
332 inode->i_mtime.tv_sec = (time64_t)new_op->
333 downcall.resp.getattr.attributes.mtime;
334 inode->i_ctime.tv_sec = (time64_t)new_op->
335 downcall.resp.getattr.attributes.ctime;
336 inode->i_atime.tv_nsec = 0;
337 inode->i_mtime.tv_nsec = 0;
338 inode->i_ctime.tv_nsec = 0;
339
340 /* special case: mark the root inode as sticky */
Martin Brandenburg26662632016-03-17 16:01:52 -0400341 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400342 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
343
344 ret = 0;
345out:
346 op_release(new_op);
347 return ret;
348}
349
Martin Brandenburg5859d772016-03-17 15:15:16 -0400350int orangefs_inode_check_changed(struct inode *inode)
351{
352 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
353 struct orangefs_kernel_op_s *new_op;
354 int ret;
355
356 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
357 get_khandle_from_ino(inode));
358
359 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
360 if (!new_op)
361 return -ENOMEM;
362 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
363 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_TYPE |
364 ORANGEFS_ATTR_SYS_LNK_TARGET;
365
366 ret = service_operation(new_op, __func__,
367 get_interruptible_flag(inode));
368 if (ret != 0)
369 goto out;
370
Martin Brandenburg26662632016-03-17 16:01:52 -0400371 ret = orangefs_inode_is_stale(inode, 0,
372 &new_op->downcall.resp.getattr.attributes,
373 new_op->downcall.resp.getattr.link_target);
Martin Brandenburg5859d772016-03-17 15:15:16 -0400374out:
375 op_release(new_op);
376 return ret;
377}
378
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400379/*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500380 * issues a orangefs setattr request to make sure the new attribute values
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400381 * take effect if successful. returns 0 on success; -errno otherwise
382 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500383int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400384{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500385 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
386 struct orangefs_kernel_op_s *new_op;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400387 int ret;
388
Yi Liu8bb8aef2015-11-24 15:12:14 -0500389 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400390 if (!new_op)
391 return -ENOMEM;
392
Yi Liu8bb8aef2015-11-24 15:12:14 -0500393 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400394 ret = copy_attributes_from_inode(inode,
395 &new_op->upcall.req.setattr.attributes,
396 iattr);
Al Viroed42fe02016-01-22 19:47:47 -0500397 if (ret >= 0) {
398 ret = service_operation(new_op, __func__,
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400399 get_interruptible_flag(inode));
400
Al Viroed42fe02016-01-22 19:47:47 -0500401 gossip_debug(GOSSIP_UTILS_DEBUG,
402 "orangefs_inode_setattr: returning %d\n",
403 ret);
404 }
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400405
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400406 op_release(new_op);
407
408 /*
409 * successful setattr should clear the atime, mtime and
410 * ctime flags.
411 */
412 if (ret == 0) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500413 ClearAtimeFlag(orangefs_inode);
414 ClearMtimeFlag(orangefs_inode);
415 ClearCtimeFlag(orangefs_inode);
416 ClearModeFlag(orangefs_inode);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400417 }
418
419 return ret;
420}
421
Yi Liu8bb8aef2015-11-24 15:12:14 -0500422int orangefs_flush_inode(struct inode *inode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400423{
424 /*
425 * If it is a dirty inode, this function gets called.
426 * Gather all the information that needs to be setattr'ed
427 * Right now, this will only be used for mode, atime, mtime
428 * and/or ctime.
429 */
430 struct iattr wbattr;
431 int ret;
432 int mtime_flag;
433 int ctime_flag;
434 int atime_flag;
435 int mode_flag;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500436 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400437
438 memset(&wbattr, 0, sizeof(wbattr));
439
440 /*
441 * check inode flags up front, and clear them if they are set. This
442 * will prevent multiple processes from all trying to flush the same
443 * inode if they call close() simultaneously
444 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500445 mtime_flag = MtimeFlag(orangefs_inode);
446 ClearMtimeFlag(orangefs_inode);
447 ctime_flag = CtimeFlag(orangefs_inode);
448 ClearCtimeFlag(orangefs_inode);
449 atime_flag = AtimeFlag(orangefs_inode);
450 ClearAtimeFlag(orangefs_inode);
451 mode_flag = ModeFlag(orangefs_inode);
452 ClearModeFlag(orangefs_inode);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400453
454 /* -- Lazy atime,mtime and ctime update --
455 * Note: all times are dictated by server in the new scheme
456 * and not by the clients
457 *
458 * Also mode updates are being handled now..
459 */
460
461 if (mtime_flag)
462 wbattr.ia_valid |= ATTR_MTIME;
463 if (ctime_flag)
464 wbattr.ia_valid |= ATTR_CTIME;
465 if (atime_flag)
466 wbattr.ia_valid |= ATTR_ATIME;
467
468 if (mode_flag) {
469 wbattr.ia_mode = inode->i_mode;
470 wbattr.ia_valid |= ATTR_MODE;
471 }
472
473 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500474 "*********** orangefs_flush_inode: %pU "
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400475 "(ia_valid %d)\n",
476 get_khandle_from_ino(inode),
477 wbattr.ia_valid);
478 if (wbattr.ia_valid == 0) {
479 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500480 "orangefs_flush_inode skipping setattr()\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400481 return 0;
482 }
483
484 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500485 "orangefs_flush_inode (%pU) writing mode %o\n",
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400486 get_khandle_from_ino(inode),
487 inode->i_mode);
488
Yi Liu8bb8aef2015-11-24 15:12:14 -0500489 ret = orangefs_inode_setattr(inode, &wbattr);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400490
491 return ret;
492}
493
Yi Liu8bb8aef2015-11-24 15:12:14 -0500494int orangefs_unmount_sb(struct super_block *sb)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400495{
496 int ret = -EINVAL;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500497 struct orangefs_kernel_op_s *new_op = NULL;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400498
499 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500500 "orangefs_unmount_sb called on sb %p\n",
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400501 sb);
502
Yi Liu8bb8aef2015-11-24 15:12:14 -0500503 new_op = op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400504 if (!new_op)
505 return -ENOMEM;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500506 new_op->upcall.req.fs_umount.id = ORANGEFS_SB(sb)->id;
507 new_op->upcall.req.fs_umount.fs_id = ORANGEFS_SB(sb)->fs_id;
508 strncpy(new_op->upcall.req.fs_umount.orangefs_config_server,
509 ORANGEFS_SB(sb)->devname,
510 ORANGEFS_MAX_SERVER_ADDR_LEN);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400511
512 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500513 "Attempting ORANGEFS Unmount via host %s\n",
514 new_op->upcall.req.fs_umount.orangefs_config_server);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400515
Yi Liu8bb8aef2015-11-24 15:12:14 -0500516 ret = service_operation(new_op, "orangefs_fs_umount", 0);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400517
518 gossip_debug(GOSSIP_UTILS_DEBUG,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500519 "orangefs_unmount: got return value of %d\n", ret);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400520 if (ret)
521 sb = ERR_PTR(ret);
522 else
Yi Liu8bb8aef2015-11-24 15:12:14 -0500523 ORANGEFS_SB(sb)->mount_pending = 1;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400524
525 op_release(new_op);
526 return ret;
527}
528
Yi Liu8bb8aef2015-11-24 15:12:14 -0500529void orangefs_make_bad_inode(struct inode *inode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400530{
531 if (is_root_handle(inode)) {
532 /*
533 * if this occurs, the pvfs2-client-core was killed but we
534 * can't afford to lose the inode operations and such
535 * associated with the root handle in any case.
536 */
537 gossip_debug(GOSSIP_UTILS_DEBUG,
538 "*** NOT making bad root inode %pU\n",
539 get_khandle_from_ino(inode));
540 } else {
541 gossip_debug(GOSSIP_UTILS_DEBUG,
542 "*** making bad inode %pU\n",
543 get_khandle_from_ino(inode));
544 make_bad_inode(inode);
545 }
546}
547
Mike Marshall54804942015-10-05 13:44:24 -0400548/*
549 * The following is a very dirty hack that is now a permanent part of the
Yi Liu8bb8aef2015-11-24 15:12:14 -0500550 * ORANGEFS protocol. See protocol.h for more error definitions.
Mike Marshall54804942015-10-05 13:44:24 -0400551 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400552
Yi Liu8bb8aef2015-11-24 15:12:14 -0500553/* The order matches include/orangefs-types.h in the OrangeFS source. */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400554static int PINT_errno_mapping[] = {
Mike Marshall54804942015-10-05 13:44:24 -0400555 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM,
556 EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE,
557 EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG,
558 ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH,
559 EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM,
560 EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE,
561 ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE,
562 EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS,
563 ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY,
564 EACCES, ECONNRESET, ERANGE
Martin Brandenburg894ac432015-10-02 12:11:19 -0400565};
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400566
Yi Liu8bb8aef2015-11-24 15:12:14 -0500567int orangefs_normalize_to_errno(__s32 error_code)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400568{
Mike Marshall54804942015-10-05 13:44:24 -0400569 __u32 i;
570
Martin Brandenburg894ac432015-10-02 12:11:19 -0400571 /* Success */
572 if (error_code == 0) {
573 return 0;
Mike Marshall54804942015-10-05 13:44:24 -0400574 /*
575 * This shouldn't ever happen. If it does it should be fixed on the
576 * server.
577 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400578 } else if (error_code > 0) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500579 gossip_err("orangefs: error status receieved.\n");
580 gossip_err("orangefs: assuming error code is inverted.\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400581 error_code = -error_code;
582 }
583
Mike Marshall54804942015-10-05 13:44:24 -0400584 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500585 * XXX: This is very bad since error codes from ORANGEFS may not be
Mike Marshall54804942015-10-05 13:44:24 -0400586 * suitable for return into userspace.
587 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400588
Mike Marshall54804942015-10-05 13:44:24 -0400589 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500590 * Convert ORANGEFS error values into errno values suitable for return
Mike Marshall54804942015-10-05 13:44:24 -0400591 * from the kernel.
592 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500593 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
Martin Brandenburg894ac432015-10-02 12:11:19 -0400594 if (((-error_code) &
Yi Liu8bb8aef2015-11-24 15:12:14 -0500595 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
596 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400597 /*
598 * cancellation error codes generally correspond to
599 * a timeout from the client's perspective
600 */
601 error_code = -ETIMEDOUT;
602 } else {
603 /* assume a default error code */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500604 gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400605 error_code = -EINVAL;
606 }
Martin Brandenburg894ac432015-10-02 12:11:19 -0400607
Yi Liu8bb8aef2015-11-24 15:12:14 -0500608 /* Convert ORANGEFS encoded errno values into regular errno values. */
609 } else if ((-error_code) & ORANGEFS_ERROR_BIT) {
610 i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS);
Mike Marshall54804942015-10-05 13:44:24 -0400611 if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping))
Martin Brandenburg894ac432015-10-02 12:11:19 -0400612 error_code = -PINT_errno_mapping[i];
613 else
614 error_code = -EINVAL;
615
Mike Marshall54804942015-10-05 13:44:24 -0400616 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500617 * Only ORANGEFS protocol error codes should ever come here. Otherwise
Mike Marshall54804942015-10-05 13:44:24 -0400618 * there is a bug somewhere.
619 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400620 } else {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500621 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400622 }
623 return error_code;
624}
625
626#define NUM_MODES 11
Yi Liu8bb8aef2015-11-24 15:12:14 -0500627__s32 ORANGEFS_util_translate_mode(int mode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400628{
629 int ret = 0;
630 int i = 0;
631 static int modes[NUM_MODES] = {
632 S_IXOTH, S_IWOTH, S_IROTH,
633 S_IXGRP, S_IWGRP, S_IRGRP,
634 S_IXUSR, S_IWUSR, S_IRUSR,
635 S_ISGID, S_ISUID
636 };
Yi Liu8bb8aef2015-11-24 15:12:14 -0500637 static int orangefs_modes[NUM_MODES] = {
638 ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ,
639 ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ,
640 ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ,
641 ORANGEFS_G_SGID, ORANGEFS_U_SUID
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400642 };
643
644 for (i = 0; i < NUM_MODES; i++)
645 if (mode & modes[i])
Yi Liu8bb8aef2015-11-24 15:12:14 -0500646 ret |= orangefs_modes[i];
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400647
648 return ret;
649}
650#undef NUM_MODES
651
652/*
653 * After obtaining a string representation of the client's debug
654 * keywords and their associated masks, this function is called to build an
655 * array of these values.
656 */
657int orangefs_prepare_cdm_array(char *debug_array_string)
658{
659 int i;
660 int rc = -EINVAL;
661 char *cds_head = NULL;
662 char *cds_delimiter = NULL;
663 int keyword_len = 0;
664
665 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
666
667 /*
668 * figure out how many elements the cdm_array needs.
669 */
670 for (i = 0; i < strlen(debug_array_string); i++)
671 if (debug_array_string[i] == '\n')
672 cdm_element_count++;
673
674 if (!cdm_element_count) {
675 pr_info("No elements in client debug array string!\n");
676 goto out;
677 }
678
679 cdm_array =
680 kzalloc(cdm_element_count * sizeof(struct client_debug_mask),
681 GFP_KERNEL);
682 if (!cdm_array) {
683 pr_info("malloc failed for cdm_array!\n");
684 rc = -ENOMEM;
685 goto out;
686 }
687
688 cds_head = debug_array_string;
689
690 for (i = 0; i < cdm_element_count; i++) {
691 cds_delimiter = strchr(cds_head, '\n');
692 *cds_delimiter = '\0';
693
694 keyword_len = strcspn(cds_head, " ");
695
696 cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL);
697 if (!cdm_array[i].keyword) {
698 rc = -ENOMEM;
699 goto out;
700 }
701
702 sscanf(cds_head,
703 "%s %llx %llx",
704 cdm_array[i].keyword,
705 (unsigned long long *)&(cdm_array[i].mask1),
706 (unsigned long long *)&(cdm_array[i].mask2));
707
Yi Liu8bb8aef2015-11-24 15:12:14 -0500708 if (!strcmp(cdm_array[i].keyword, ORANGEFS_VERBOSE))
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400709 client_verbose_index = i;
710
Yi Liu8bb8aef2015-11-24 15:12:14 -0500711 if (!strcmp(cdm_array[i].keyword, ORANGEFS_ALL))
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400712 client_all_index = i;
713
714 cds_head = cds_delimiter + 1;
715 }
716
717 rc = cdm_element_count;
718
719 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc);
720
721out:
722
723 return rc;
724
725}
726
727/*
728 * /sys/kernel/debug/orangefs/debug-help can be catted to
729 * see all the available kernel and client debug keywords.
730 *
731 * When the kernel boots, we have no idea what keywords the
732 * client supports, nor their associated masks.
733 *
734 * We pass through this function once at boot and stamp a
735 * boilerplate "we don't know" message for the client in the
736 * debug-help file. We pass through here again when the client
737 * starts and then we can fill out the debug-help file fully.
738 *
739 * The client might be restarted any number of times between
740 * reboots, we only build the debug-help file the first time.
741 */
742int orangefs_prepare_debugfs_help_string(int at_boot)
743{
744 int rc = -EINVAL;
745 int i;
746 int byte_count = 0;
747 char *client_title = "Client Debug Keywords:\n";
748 char *kernel_title = "Kernel Debug Keywords:\n";
749
750 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
751
752 if (at_boot) {
753 byte_count += strlen(HELP_STRING_UNINITIALIZED);
754 client_title = HELP_STRING_UNINITIALIZED;
755 } else {
756 /*
757 * fill the client keyword/mask array and remember
758 * how many elements there were.
759 */
760 cdm_element_count =
761 orangefs_prepare_cdm_array(client_debug_array_string);
762 if (cdm_element_count <= 0)
763 goto out;
764
765 /* Count the bytes destined for debug_help_string. */
766 byte_count += strlen(client_title);
767
768 for (i = 0; i < cdm_element_count; i++) {
769 byte_count += strlen(cdm_array[i].keyword + 2);
770 if (byte_count >= DEBUG_HELP_STRING_SIZE) {
771 pr_info("%s: overflow 1!\n", __func__);
772 goto out;
773 }
774 }
775
776 gossip_debug(GOSSIP_UTILS_DEBUG,
777 "%s: cdm_element_count:%d:\n",
778 __func__,
779 cdm_element_count);
780 }
781
782 byte_count += strlen(kernel_title);
783 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
784 byte_count +=
785 strlen(s_kmod_keyword_mask_map[i].keyword + 2);
786 if (byte_count >= DEBUG_HELP_STRING_SIZE) {
787 pr_info("%s: overflow 2!\n", __func__);
788 goto out;
789 }
790 }
791
792 /* build debug_help_string. */
793 debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL);
794 if (!debug_help_string) {
795 rc = -ENOMEM;
796 goto out;
797 }
798
799 strcat(debug_help_string, client_title);
800
801 if (!at_boot) {
802 for (i = 0; i < cdm_element_count; i++) {
803 strcat(debug_help_string, "\t");
804 strcat(debug_help_string, cdm_array[i].keyword);
805 strcat(debug_help_string, "\n");
806 }
807 }
808
809 strcat(debug_help_string, "\n");
810 strcat(debug_help_string, kernel_title);
811
812 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
813 strcat(debug_help_string, "\t");
814 strcat(debug_help_string, s_kmod_keyword_mask_map[i].keyword);
815 strcat(debug_help_string, "\n");
816 }
817
818 rc = 0;
819
820out:
821
822 return rc;
823
824}
825
826/*
827 * kernel = type 0
828 * client = type 1
829 */
830void debug_mask_to_string(void *mask, int type)
831{
832 int i;
833 int len = 0;
834 char *debug_string;
835 int element_count = 0;
836
837 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
838
839 if (type) {
840 debug_string = client_debug_string;
841 element_count = cdm_element_count;
842 } else {
843 debug_string = kernel_debug_string;
844 element_count = num_kmod_keyword_mask_map;
845 }
846
Yi Liu8bb8aef2015-11-24 15:12:14 -0500847 memset(debug_string, 0, ORANGEFS_MAX_DEBUG_STRING_LEN);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400848
849 /*
850 * Some keywords, like "all" or "verbose", are amalgams of
851 * numerous other keywords. Make a special check for those
852 * before grinding through the whole mask only to find out
853 * later...
854 */
855 if (check_amalgam_keyword(mask, type))
856 goto out;
857
858 /* Build the debug string. */
859 for (i = 0; i < element_count; i++)
860 if (type)
861 do_c_string(mask, i);
862 else
863 do_k_string(mask, i);
864
865 len = strlen(debug_string);
866
867 if ((len) && (type))
868 client_debug_string[len - 1] = '\0';
869 else if (len)
870 kernel_debug_string[len - 1] = '\0';
871 else if (type)
872 strcpy(client_debug_string, "none");
873 else
874 strcpy(kernel_debug_string, "none");
875
876out:
877gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string);
878
879 return;
880
881}
882
883void do_k_string(void *k_mask, int index)
884{
885 __u64 *mask = (__u64 *) k_mask;
886
887 if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword))
Mike Marshall54804942015-10-05 13:44:24 -0400888 goto out;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400889
890 if (*mask & s_kmod_keyword_mask_map[index].mask_val) {
891 if ((strlen(kernel_debug_string) +
892 strlen(s_kmod_keyword_mask_map[index].keyword))
Yi Liu8bb8aef2015-11-24 15:12:14 -0500893 < ORANGEFS_MAX_DEBUG_STRING_LEN - 1) {
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400894 strcat(kernel_debug_string,
895 s_kmod_keyword_mask_map[index].keyword);
896 strcat(kernel_debug_string, ",");
897 } else {
898 gossip_err("%s: overflow!\n", __func__);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500899 strcpy(kernel_debug_string, ORANGEFS_ALL);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400900 goto out;
901 }
902 }
903
904out:
905
906 return;
907}
908
909void do_c_string(void *c_mask, int index)
910{
911 struct client_debug_mask *mask = (struct client_debug_mask *) c_mask;
912
913 if (keyword_is_amalgam(cdm_array[index].keyword))
914 goto out;
915
916 if ((mask->mask1 & cdm_array[index].mask1) ||
917 (mask->mask2 & cdm_array[index].mask2)) {
918 if ((strlen(client_debug_string) +
919 strlen(cdm_array[index].keyword) + 1)
Yi Liu8bb8aef2015-11-24 15:12:14 -0500920 < ORANGEFS_MAX_DEBUG_STRING_LEN - 2) {
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400921 strcat(client_debug_string,
922 cdm_array[index].keyword);
923 strcat(client_debug_string, ",");
924 } else {
925 gossip_err("%s: overflow!\n", __func__);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500926 strcpy(client_debug_string, ORANGEFS_ALL);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400927 goto out;
928 }
929 }
930out:
931 return;
932}
933
934int keyword_is_amalgam(char *keyword)
935{
936 int rc = 0;
937
Yi Liu8bb8aef2015-11-24 15:12:14 -0500938 if ((!strcmp(keyword, ORANGEFS_ALL)) || (!strcmp(keyword, ORANGEFS_VERBOSE)))
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400939 rc = 1;
940
941 return rc;
942}
943
944/*
945 * kernel = type 0
946 * client = type 1
947 *
948 * return 1 if we found an amalgam.
949 */
950int check_amalgam_keyword(void *mask, int type)
951{
952 __u64 *k_mask;
953 struct client_debug_mask *c_mask;
954 int k_all_index = num_kmod_keyword_mask_map - 1;
955 int rc = 0;
956
957 if (type) {
958 c_mask = (struct client_debug_mask *) mask;
959
960 if ((c_mask->mask1 == cdm_array[client_all_index].mask1) &&
961 (c_mask->mask2 == cdm_array[client_all_index].mask2)) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500962 strcpy(client_debug_string, ORANGEFS_ALL);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400963 rc = 1;
964 goto out;
965 }
966
967 if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) &&
968 (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500969 strcpy(client_debug_string, ORANGEFS_VERBOSE);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400970 rc = 1;
971 goto out;
972 }
973
974 } else {
975 k_mask = (__u64 *) mask;
976
977 if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500978 strcpy(kernel_debug_string, ORANGEFS_ALL);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400979 rc = 1;
980 goto out;
981 }
982 }
983
984out:
985
986 return rc;
987}
988
989/*
990 * kernel = type 0
991 * client = type 1
992 */
993void debug_string_to_mask(char *debug_string, void *mask, int type)
994{
995 char *unchecked_keyword;
996 int i;
997 char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL);
Mike Marshalleeaa3d42015-07-29 13:36:37 -0400998 char *original_pointer;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400999 int element_count = 0;
1000 struct client_debug_mask *c_mask;
1001 __u64 *k_mask;
1002
1003 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
1004
1005 if (type) {
1006 c_mask = (struct client_debug_mask *)mask;
1007 element_count = cdm_element_count;
1008 } else {
1009 k_mask = (__u64 *)mask;
1010 *k_mask = 0;
1011 element_count = num_kmod_keyword_mask_map;
1012 }
1013
Mike Marshalleeaa3d42015-07-29 13:36:37 -04001014 original_pointer = strsep_fodder;
Mike Marshallf7be4ee2015-07-17 10:38:14 -04001015 while ((unchecked_keyword = strsep(&strsep_fodder, ",")))
1016 if (strlen(unchecked_keyword)) {
1017 for (i = 0; i < element_count; i++)
1018 if (type)
1019 do_c_mask(i,
1020 unchecked_keyword,
1021 &c_mask);
1022 else
1023 do_k_mask(i,
1024 unchecked_keyword,
1025 &k_mask);
1026 }
1027
Mike Marshalleeaa3d42015-07-29 13:36:37 -04001028 kfree(original_pointer);
Mike Marshallf7be4ee2015-07-17 10:38:14 -04001029}
1030
1031void do_c_mask(int i,
1032 char *unchecked_keyword,
1033 struct client_debug_mask **sane_mask)
1034{
1035
1036 if (!strcmp(cdm_array[i].keyword, unchecked_keyword)) {
1037 (**sane_mask).mask1 = (**sane_mask).mask1 | cdm_array[i].mask1;
1038 (**sane_mask).mask2 = (**sane_mask).mask2 | cdm_array[i].mask2;
1039 }
1040}
1041
1042void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask)
1043{
1044
1045 if (!strcmp(s_kmod_keyword_mask_map[i].keyword, unchecked_keyword))
1046 **sane_mask = (**sane_mask) |
1047 s_kmod_keyword_mask_map[i].mask_val;
1048}