1
2
3
4
5
6#include "protocol.h"
7#include "orangefs-kernel.h"
8#include "orangefs-dev-proto.h"
9#include "orangefs-bufmap.h"
10
11__s32 fsid_of_op(struct orangefs_kernel_op_s *op)
12{
13 __s32 fsid = ORANGEFS_FS_ID_NULL;
14
15 if (op) {
16 switch (op->upcall.type) {
17 case ORANGEFS_VFS_OP_FILE_IO:
18 fsid = op->upcall.req.io.refn.fs_id;
19 break;
20 case ORANGEFS_VFS_OP_LOOKUP:
21 fsid = op->upcall.req.lookup.parent_refn.fs_id;
22 break;
23 case ORANGEFS_VFS_OP_CREATE:
24 fsid = op->upcall.req.create.parent_refn.fs_id;
25 break;
26 case ORANGEFS_VFS_OP_GETATTR:
27 fsid = op->upcall.req.getattr.refn.fs_id;
28 break;
29 case ORANGEFS_VFS_OP_REMOVE:
30 fsid = op->upcall.req.remove.parent_refn.fs_id;
31 break;
32 case ORANGEFS_VFS_OP_MKDIR:
33 fsid = op->upcall.req.mkdir.parent_refn.fs_id;
34 break;
35 case ORANGEFS_VFS_OP_READDIR:
36 fsid = op->upcall.req.readdir.refn.fs_id;
37 break;
38 case ORANGEFS_VFS_OP_SETATTR:
39 fsid = op->upcall.req.setattr.refn.fs_id;
40 break;
41 case ORANGEFS_VFS_OP_SYMLINK:
42 fsid = op->upcall.req.sym.parent_refn.fs_id;
43 break;
44 case ORANGEFS_VFS_OP_RENAME:
45 fsid = op->upcall.req.rename.old_parent_refn.fs_id;
46 break;
47 case ORANGEFS_VFS_OP_STATFS:
48 fsid = op->upcall.req.statfs.fs_id;
49 break;
50 case ORANGEFS_VFS_OP_TRUNCATE:
51 fsid = op->upcall.req.truncate.refn.fs_id;
52 break;
53 case ORANGEFS_VFS_OP_MMAP_RA_FLUSH:
54 fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
55 break;
56 case ORANGEFS_VFS_OP_FS_UMOUNT:
57 fsid = op->upcall.req.fs_umount.fs_id;
58 break;
59 case ORANGEFS_VFS_OP_GETXATTR:
60 fsid = op->upcall.req.getxattr.refn.fs_id;
61 break;
62 case ORANGEFS_VFS_OP_SETXATTR:
63 fsid = op->upcall.req.setxattr.refn.fs_id;
64 break;
65 case ORANGEFS_VFS_OP_LISTXATTR:
66 fsid = op->upcall.req.listxattr.refn.fs_id;
67 break;
68 case ORANGEFS_VFS_OP_REMOVEXATTR:
69 fsid = op->upcall.req.removexattr.refn.fs_id;
70 break;
71 case ORANGEFS_VFS_OP_FSYNC:
72 fsid = op->upcall.req.fsync.refn.fs_id;
73 break;
74 default:
75 break;
76 }
77 }
78 return fsid;
79}
80
81static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
82{
83 int flags = 0;
84 if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
85 flags |= S_IMMUTABLE;
86 else
87 flags &= ~S_IMMUTABLE;
88 if (attrs->flags & ORANGEFS_APPEND_FL)
89 flags |= S_APPEND;
90 else
91 flags &= ~S_APPEND;
92 if (attrs->flags & ORANGEFS_NOATIME_FL)
93 flags |= S_NOATIME;
94 else
95 flags &= ~S_NOATIME;
96 return flags;
97}
98
99static 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;
130}
131
132
133
134
135
136static inline int copy_attributes_from_inode(struct inode *inode,
137 struct ORANGEFS_sys_attr_s *attrs,
138 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
152
153
154 attrs->mask = 0;
155 if (iattr->ia_valid & ATTR_UID) {
156 attrs->owner = from_kuid(current_user_ns(), iattr->ia_uid);
157 attrs->mask |= ORANGEFS_ATTR_SYS_UID;
158 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);
162 attrs->mask |= ORANGEFS_ATTR_SYS_GID;
163 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
164 }
165
166 if (iattr->ia_valid & ATTR_ATIME) {
167 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME;
168 if (iattr->ia_valid & ATTR_ATIME_SET) {
169 attrs->atime = (time64_t)iattr->ia_atime.tv_sec;
170 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET;
171 }
172 }
173 if (iattr->ia_valid & ATTR_MTIME) {
174 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME;
175 if (iattr->ia_valid & ATTR_MTIME_SET) {
176 attrs->mtime = (time64_t)iattr->ia_mtime.tv_sec;
177 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET;
178 }
179 }
180 if (iattr->ia_valid & ATTR_CTIME)
181 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
182
183
184
185
186
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
195
196
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
212 attrs->perms = ORANGEFS_util_translate_mode(tmp_mode);
213 attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
214 }
215
216 return 0;
217}
218
219static 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
231static 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
239
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
254int 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;
259 int ret, type;
260
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
276 type = orangefs_inode_type(new_op->
277 downcall.resp.getattr.attributes.objtype);
278 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;
284 }
285
286 switch (type) {
287 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:
306 inode->i_size = PAGE_SIZE;
307 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 ret = strscpy(orangefs_inode->link_target,
319 new_op->downcall.resp.getattr.link_target,
320 ORANGEFS_NAME_MAX);
321 if (ret == -E2BIG) {
322 ret = -EIO;
323 goto out;
324 }
325 inode->i_link = orangefs_inode->link_target;
326 }
327 break;
328 }
329
330 inode->i_uid = make_kuid(&init_user_ns, new_op->
331 downcall.resp.getattr.attributes.owner);
332 inode->i_gid = make_kgid(&init_user_ns, new_op->
333 downcall.resp.getattr.attributes.group);
334 inode->i_atime.tv_sec = (time64_t)new_op->
335 downcall.resp.getattr.attributes.atime;
336 inode->i_mtime.tv_sec = (time64_t)new_op->
337 downcall.resp.getattr.attributes.mtime;
338 inode->i_ctime.tv_sec = (time64_t)new_op->
339 downcall.resp.getattr.attributes.ctime;
340 inode->i_atime.tv_nsec = 0;
341 inode->i_mtime.tv_nsec = 0;
342 inode->i_ctime.tv_nsec = 0;
343
344
345 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
346 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
347
348 ret = 0;
349out:
350 op_release(new_op);
351 return ret;
352}
353
354int orangefs_inode_check_changed(struct inode *inode)
355{
356 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
357 struct orangefs_kernel_op_s *new_op;
358 int ret;
359
360 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
361 get_khandle_from_ino(inode));
362
363 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
364 if (!new_op)
365 return -ENOMEM;
366 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
367 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_TYPE |
368 ORANGEFS_ATTR_SYS_LNK_TARGET;
369
370 ret = service_operation(new_op, __func__,
371 get_interruptible_flag(inode));
372 if (ret != 0)
373 goto out;
374
375 ret = orangefs_inode_is_stale(inode, 0,
376 &new_op->downcall.resp.getattr.attributes,
377 new_op->downcall.resp.getattr.link_target);
378out:
379 op_release(new_op);
380 return ret;
381}
382
383
384
385
386
387int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
388{
389 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
390 struct orangefs_kernel_op_s *new_op;
391 int ret;
392
393 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
394 if (!new_op)
395 return -ENOMEM;
396
397 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
398 ret = copy_attributes_from_inode(inode,
399 &new_op->upcall.req.setattr.attributes,
400 iattr);
401 if (ret >= 0) {
402 ret = service_operation(new_op, __func__,
403 get_interruptible_flag(inode));
404
405 gossip_debug(GOSSIP_UTILS_DEBUG,
406 "orangefs_inode_setattr: returning %d\n",
407 ret);
408 }
409
410 op_release(new_op);
411
412
413
414
415
416 if (ret == 0) {
417 ClearAtimeFlag(orangefs_inode);
418 ClearMtimeFlag(orangefs_inode);
419 ClearCtimeFlag(orangefs_inode);
420 ClearModeFlag(orangefs_inode);
421 }
422
423 return ret;
424}
425
426int orangefs_flush_inode(struct inode *inode)
427{
428
429
430
431
432
433
434 struct iattr wbattr;
435 int ret;
436 int mtime_flag;
437 int ctime_flag;
438 int atime_flag;
439 int mode_flag;
440 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
441
442 memset(&wbattr, 0, sizeof(wbattr));
443
444
445
446
447
448
449 mtime_flag = MtimeFlag(orangefs_inode);
450 ClearMtimeFlag(orangefs_inode);
451 ctime_flag = CtimeFlag(orangefs_inode);
452 ClearCtimeFlag(orangefs_inode);
453 atime_flag = AtimeFlag(orangefs_inode);
454 ClearAtimeFlag(orangefs_inode);
455 mode_flag = ModeFlag(orangefs_inode);
456 ClearModeFlag(orangefs_inode);
457
458
459
460
461
462
463
464
465 if (mtime_flag)
466 wbattr.ia_valid |= ATTR_MTIME;
467 if (ctime_flag)
468 wbattr.ia_valid |= ATTR_CTIME;
469 if (atime_flag)
470 wbattr.ia_valid |= ATTR_ATIME;
471
472 if (mode_flag) {
473 wbattr.ia_mode = inode->i_mode;
474 wbattr.ia_valid |= ATTR_MODE;
475 }
476
477 gossip_debug(GOSSIP_UTILS_DEBUG,
478 "*********** orangefs_flush_inode: %pU "
479 "(ia_valid %d)\n",
480 get_khandle_from_ino(inode),
481 wbattr.ia_valid);
482 if (wbattr.ia_valid == 0) {
483 gossip_debug(GOSSIP_UTILS_DEBUG,
484 "orangefs_flush_inode skipping setattr()\n");
485 return 0;
486 }
487
488 gossip_debug(GOSSIP_UTILS_DEBUG,
489 "orangefs_flush_inode (%pU) writing mode %o\n",
490 get_khandle_from_ino(inode),
491 inode->i_mode);
492
493 ret = orangefs_inode_setattr(inode, &wbattr);
494
495 return ret;
496}
497
498int orangefs_unmount_sb(struct super_block *sb)
499{
500 int ret = -EINVAL;
501 struct orangefs_kernel_op_s *new_op = NULL;
502
503 gossip_debug(GOSSIP_UTILS_DEBUG,
504 "orangefs_unmount_sb called on sb %p\n",
505 sb);
506
507 new_op = op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT);
508 if (!new_op)
509 return -ENOMEM;
510 new_op->upcall.req.fs_umount.id = ORANGEFS_SB(sb)->id;
511 new_op->upcall.req.fs_umount.fs_id = ORANGEFS_SB(sb)->fs_id;
512 strncpy(new_op->upcall.req.fs_umount.orangefs_config_server,
513 ORANGEFS_SB(sb)->devname,
514 ORANGEFS_MAX_SERVER_ADDR_LEN);
515
516 gossip_debug(GOSSIP_UTILS_DEBUG,
517 "Attempting ORANGEFS Unmount via host %s\n",
518 new_op->upcall.req.fs_umount.orangefs_config_server);
519
520 ret = service_operation(new_op, "orangefs_fs_umount", 0);
521
522 gossip_debug(GOSSIP_UTILS_DEBUG,
523 "orangefs_unmount: got return value of %d\n", ret);
524 if (ret)
525 sb = ERR_PTR(ret);
526 else
527 ORANGEFS_SB(sb)->mount_pending = 1;
528
529 op_release(new_op);
530 return ret;
531}
532
533void orangefs_make_bad_inode(struct inode *inode)
534{
535 if (is_root_handle(inode)) {
536
537
538
539
540
541 gossip_debug(GOSSIP_UTILS_DEBUG,
542 "*** NOT making bad root inode %pU\n",
543 get_khandle_from_ino(inode));
544 } else {
545 gossip_debug(GOSSIP_UTILS_DEBUG,
546 "*** making bad inode %pU\n",
547 get_khandle_from_ino(inode));
548 make_bad_inode(inode);
549 }
550}
551
552
553
554
555
556
557
558static int PINT_errno_mapping[] = {
559 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM,
560 EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE,
561 EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG,
562 ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH,
563 EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM,
564 EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE,
565 ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE,
566 EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS,
567 ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY,
568 EACCES, ECONNRESET, ERANGE
569};
570
571int orangefs_normalize_to_errno(__s32 error_code)
572{
573 __u32 i;
574
575
576 if (error_code == 0) {
577 return 0;
578
579
580
581
582 } else if (error_code > 0) {
583 gossip_err("orangefs: error status receieved.\n");
584 gossip_err("orangefs: assuming error code is inverted.\n");
585 error_code = -error_code;
586 }
587
588
589
590
591
592
593
594
595
596
597 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
598 if (((-error_code) &
599 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
600 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
601
602
603
604
605 error_code = -ETIMEDOUT;
606 } else {
607
608 gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code);
609 error_code = -EINVAL;
610 }
611
612
613 } else if ((-error_code) & ORANGEFS_ERROR_BIT) {
614 i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS);
615 if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping))
616 error_code = -PINT_errno_mapping[i];
617 else
618 error_code = -EINVAL;
619
620
621
622
623
624 } else {
625 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
626 }
627 return error_code;
628}
629
630#define NUM_MODES 11
631__s32 ORANGEFS_util_translate_mode(int mode)
632{
633 int ret = 0;
634 int i = 0;
635 static int modes[NUM_MODES] = {
636 S_IXOTH, S_IWOTH, S_IROTH,
637 S_IXGRP, S_IWGRP, S_IRGRP,
638 S_IXUSR, S_IWUSR, S_IRUSR,
639 S_ISGID, S_ISUID
640 };
641 static int orangefs_modes[NUM_MODES] = {
642 ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ,
643 ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ,
644 ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ,
645 ORANGEFS_G_SGID, ORANGEFS_U_SUID
646 };
647
648 for (i = 0; i < NUM_MODES; i++)
649 if (mode & modes[i])
650 ret |= orangefs_modes[i];
651
652 return ret;
653}
654#undef NUM_MODES
655
656
657
658
659
660
661int orangefs_prepare_cdm_array(char *debug_array_string)
662{
663 int i;
664 int rc = -EINVAL;
665 char *cds_head = NULL;
666 char *cds_delimiter = NULL;
667 int keyword_len = 0;
668
669 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
670
671
672
673
674 for (i = 0; i < strlen(debug_array_string); i++)
675 if (debug_array_string[i] == '\n')
676 cdm_element_count++;
677
678 if (!cdm_element_count) {
679 pr_info("No elements in client debug array string!\n");
680 goto out;
681 }
682
683 cdm_array =
684 kzalloc(cdm_element_count * sizeof(struct client_debug_mask),
685 GFP_KERNEL);
686 if (!cdm_array) {
687 pr_info("malloc failed for cdm_array!\n");
688 rc = -ENOMEM;
689 goto out;
690 }
691
692 cds_head = debug_array_string;
693
694 for (i = 0; i < cdm_element_count; i++) {
695 cds_delimiter = strchr(cds_head, '\n');
696 *cds_delimiter = '\0';
697
698 keyword_len = strcspn(cds_head, " ");
699
700 cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL);
701 if (!cdm_array[i].keyword) {
702 rc = -ENOMEM;
703 goto out;
704 }
705
706 sscanf(cds_head,
707 "%s %llx %llx",
708 cdm_array[i].keyword,
709 (unsigned long long *)&(cdm_array[i].mask1),
710 (unsigned long long *)&(cdm_array[i].mask2));
711
712 if (!strcmp(cdm_array[i].keyword, ORANGEFS_VERBOSE))
713 client_verbose_index = i;
714
715 if (!strcmp(cdm_array[i].keyword, ORANGEFS_ALL))
716 client_all_index = i;
717
718 cds_head = cds_delimiter + 1;
719 }
720
721 rc = cdm_element_count;
722
723 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc);
724
725out:
726
727 return rc;
728
729}
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746int orangefs_prepare_debugfs_help_string(int at_boot)
747{
748 int rc = -EINVAL;
749 int i;
750 int byte_count = 0;
751 char *client_title = "Client Debug Keywords:\n";
752 char *kernel_title = "Kernel Debug Keywords:\n";
753
754 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
755
756 if (at_boot) {
757 byte_count += strlen(HELP_STRING_UNINITIALIZED);
758 client_title = HELP_STRING_UNINITIALIZED;
759 } else {
760
761
762
763
764 cdm_element_count =
765 orangefs_prepare_cdm_array(client_debug_array_string);
766 if (cdm_element_count <= 0)
767 goto out;
768
769
770 byte_count += strlen(client_title);
771
772 for (i = 0; i < cdm_element_count; i++) {
773 byte_count += strlen(cdm_array[i].keyword + 2);
774 if (byte_count >= DEBUG_HELP_STRING_SIZE) {
775 pr_info("%s: overflow 1!\n", __func__);
776 goto out;
777 }
778 }
779
780 gossip_debug(GOSSIP_UTILS_DEBUG,
781 "%s: cdm_element_count:%d:\n",
782 __func__,
783 cdm_element_count);
784 }
785
786 byte_count += strlen(kernel_title);
787 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
788 byte_count +=
789 strlen(s_kmod_keyword_mask_map[i].keyword + 2);
790 if (byte_count >= DEBUG_HELP_STRING_SIZE) {
791 pr_info("%s: overflow 2!\n", __func__);
792 goto out;
793 }
794 }
795
796
797 debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL);
798 if (!debug_help_string) {
799 rc = -ENOMEM;
800 goto out;
801 }
802
803 strcat(debug_help_string, client_title);
804
805 if (!at_boot) {
806 for (i = 0; i < cdm_element_count; i++) {
807 strcat(debug_help_string, "\t");
808 strcat(debug_help_string, cdm_array[i].keyword);
809 strcat(debug_help_string, "\n");
810 }
811 }
812
813 strcat(debug_help_string, "\n");
814 strcat(debug_help_string, kernel_title);
815
816 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
817 strcat(debug_help_string, "\t");
818 strcat(debug_help_string, s_kmod_keyword_mask_map[i].keyword);
819 strcat(debug_help_string, "\n");
820 }
821
822 rc = 0;
823
824out:
825
826 return rc;
827
828}
829
830
831
832
833
834void debug_mask_to_string(void *mask, int type)
835{
836 int i;
837 int len = 0;
838 char *debug_string;
839 int element_count = 0;
840
841 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
842
843 if (type) {
844 debug_string = client_debug_string;
845 element_count = cdm_element_count;
846 } else {
847 debug_string = kernel_debug_string;
848 element_count = num_kmod_keyword_mask_map;
849 }
850
851 memset(debug_string, 0, ORANGEFS_MAX_DEBUG_STRING_LEN);
852
853
854
855
856
857
858
859 if (check_amalgam_keyword(mask, type))
860 goto out;
861
862
863 for (i = 0; i < element_count; i++)
864 if (type)
865 do_c_string(mask, i);
866 else
867 do_k_string(mask, i);
868
869 len = strlen(debug_string);
870
871 if ((len) && (type))
872 client_debug_string[len - 1] = '\0';
873 else if (len)
874 kernel_debug_string[len - 1] = '\0';
875 else if (type)
876 strcpy(client_debug_string, "none");
877 else
878 strcpy(kernel_debug_string, "none");
879
880out:
881gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string);
882
883 return;
884
885}
886
887void do_k_string(void *k_mask, int index)
888{
889 __u64 *mask = (__u64 *) k_mask;
890
891 if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword))
892 goto out;
893
894 if (*mask & s_kmod_keyword_mask_map[index].mask_val) {
895 if ((strlen(kernel_debug_string) +
896 strlen(s_kmod_keyword_mask_map[index].keyword))
897 < ORANGEFS_MAX_DEBUG_STRING_LEN - 1) {
898 strcat(kernel_debug_string,
899 s_kmod_keyword_mask_map[index].keyword);
900 strcat(kernel_debug_string, ",");
901 } else {
902 gossip_err("%s: overflow!\n", __func__);
903 strcpy(kernel_debug_string, ORANGEFS_ALL);
904 goto out;
905 }
906 }
907
908out:
909
910 return;
911}
912
913void do_c_string(void *c_mask, int index)
914{
915 struct client_debug_mask *mask = (struct client_debug_mask *) c_mask;
916
917 if (keyword_is_amalgam(cdm_array[index].keyword))
918 goto out;
919
920 if ((mask->mask1 & cdm_array[index].mask1) ||
921 (mask->mask2 & cdm_array[index].mask2)) {
922 if ((strlen(client_debug_string) +
923 strlen(cdm_array[index].keyword) + 1)
924 < ORANGEFS_MAX_DEBUG_STRING_LEN - 2) {
925 strcat(client_debug_string,
926 cdm_array[index].keyword);
927 strcat(client_debug_string, ",");
928 } else {
929 gossip_err("%s: overflow!\n", __func__);
930 strcpy(client_debug_string, ORANGEFS_ALL);
931 goto out;
932 }
933 }
934out:
935 return;
936}
937
938int keyword_is_amalgam(char *keyword)
939{
940 int rc = 0;
941
942 if ((!strcmp(keyword, ORANGEFS_ALL)) || (!strcmp(keyword, ORANGEFS_VERBOSE)))
943 rc = 1;
944
945 return rc;
946}
947
948
949
950
951
952
953
954int check_amalgam_keyword(void *mask, int type)
955{
956 __u64 *k_mask;
957 struct client_debug_mask *c_mask;
958 int k_all_index = num_kmod_keyword_mask_map - 1;
959 int rc = 0;
960
961 if (type) {
962 c_mask = (struct client_debug_mask *) mask;
963
964 if ((c_mask->mask1 == cdm_array[client_all_index].mask1) &&
965 (c_mask->mask2 == cdm_array[client_all_index].mask2)) {
966 strcpy(client_debug_string, ORANGEFS_ALL);
967 rc = 1;
968 goto out;
969 }
970
971 if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) &&
972 (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) {
973 strcpy(client_debug_string, ORANGEFS_VERBOSE);
974 rc = 1;
975 goto out;
976 }
977
978 } else {
979 k_mask = (__u64 *) mask;
980
981 if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) {
982 strcpy(kernel_debug_string, ORANGEFS_ALL);
983 rc = 1;
984 goto out;
985 }
986 }
987
988out:
989
990 return rc;
991}
992
993
994
995
996
997void debug_string_to_mask(char *debug_string, void *mask, int type)
998{
999 char *unchecked_keyword;
1000 int i;
1001 char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL);
1002 char *original_pointer;
1003 int element_count = 0;
1004 struct client_debug_mask *c_mask;
1005 __u64 *k_mask;
1006
1007 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
1008
1009 if (type) {
1010 c_mask = (struct client_debug_mask *)mask;
1011 element_count = cdm_element_count;
1012 } else {
1013 k_mask = (__u64 *)mask;
1014 *k_mask = 0;
1015 element_count = num_kmod_keyword_mask_map;
1016 }
1017
1018 original_pointer = strsep_fodder;
1019 while ((unchecked_keyword = strsep(&strsep_fodder, ",")))
1020 if (strlen(unchecked_keyword)) {
1021 for (i = 0; i < element_count; i++)
1022 if (type)
1023 do_c_mask(i,
1024 unchecked_keyword,
1025 &c_mask);
1026 else
1027 do_k_mask(i,
1028 unchecked_keyword,
1029 &k_mask);
1030 }
1031
1032 kfree(original_pointer);
1033}
1034
1035void do_c_mask(int i,
1036 char *unchecked_keyword,
1037 struct client_debug_mask **sane_mask)
1038{
1039
1040 if (!strcmp(cdm_array[i].keyword, unchecked_keyword)) {
1041 (**sane_mask).mask1 = (**sane_mask).mask1 | cdm_array[i].mask1;
1042 (**sane_mask).mask2 = (**sane_mask).mask2 | cdm_array[i].mask2;
1043 }
1044}
1045
1046void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask)
1047{
1048
1049 if (!strcmp(s_kmod_keyword_mask_map[i].keyword, unchecked_keyword))
1050 **sane_mask = (**sane_mask) |
1051 s_kmod_keyword_mask_map[i].mask_val;
1052}
1053