2 * (C) 2001 Clemson University and The University of Chicago
4 * See COPYING in top-level directory.
7 #include "orangefs-kernel.h"
8 #include "orangefs-dev-proto.h"
9 #include "orangefs-bufmap.h"
11 __s32
fsid_of_op(struct orangefs_kernel_op_s
*op
)
13 __s32 fsid
= ORANGEFS_FS_ID_NULL
;
16 switch (op
->upcall
.type
) {
17 case ORANGEFS_VFS_OP_FILE_IO
:
18 fsid
= op
->upcall
.req
.io
.refn
.fs_id
;
20 case ORANGEFS_VFS_OP_LOOKUP
:
21 fsid
= op
->upcall
.req
.lookup
.parent_refn
.fs_id
;
23 case ORANGEFS_VFS_OP_CREATE
:
24 fsid
= op
->upcall
.req
.create
.parent_refn
.fs_id
;
26 case ORANGEFS_VFS_OP_GETATTR
:
27 fsid
= op
->upcall
.req
.getattr
.refn
.fs_id
;
29 case ORANGEFS_VFS_OP_REMOVE
:
30 fsid
= op
->upcall
.req
.remove
.parent_refn
.fs_id
;
32 case ORANGEFS_VFS_OP_MKDIR
:
33 fsid
= op
->upcall
.req
.mkdir
.parent_refn
.fs_id
;
35 case ORANGEFS_VFS_OP_READDIR
:
36 fsid
= op
->upcall
.req
.readdir
.refn
.fs_id
;
38 case ORANGEFS_VFS_OP_SETATTR
:
39 fsid
= op
->upcall
.req
.setattr
.refn
.fs_id
;
41 case ORANGEFS_VFS_OP_SYMLINK
:
42 fsid
= op
->upcall
.req
.sym
.parent_refn
.fs_id
;
44 case ORANGEFS_VFS_OP_RENAME
:
45 fsid
= op
->upcall
.req
.rename
.old_parent_refn
.fs_id
;
47 case ORANGEFS_VFS_OP_STATFS
:
48 fsid
= op
->upcall
.req
.statfs
.fs_id
;
50 case ORANGEFS_VFS_OP_TRUNCATE
:
51 fsid
= op
->upcall
.req
.truncate
.refn
.fs_id
;
53 case ORANGEFS_VFS_OP_MMAP_RA_FLUSH
:
54 fsid
= op
->upcall
.req
.ra_cache_flush
.refn
.fs_id
;
56 case ORANGEFS_VFS_OP_FS_UMOUNT
:
57 fsid
= op
->upcall
.req
.fs_umount
.fs_id
;
59 case ORANGEFS_VFS_OP_GETXATTR
:
60 fsid
= op
->upcall
.req
.getxattr
.refn
.fs_id
;
62 case ORANGEFS_VFS_OP_SETXATTR
:
63 fsid
= op
->upcall
.req
.setxattr
.refn
.fs_id
;
65 case ORANGEFS_VFS_OP_LISTXATTR
:
66 fsid
= op
->upcall
.req
.listxattr
.refn
.fs_id
;
68 case ORANGEFS_VFS_OP_REMOVEXATTR
:
69 fsid
= op
->upcall
.req
.removexattr
.refn
.fs_id
;
71 case ORANGEFS_VFS_OP_FSYNC
:
72 fsid
= op
->upcall
.req
.fsync
.refn
.fs_id
;
81 static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s
*attrs
)
84 if (attrs
->flags
& ORANGEFS_IMMUTABLE_FL
)
87 flags
&= ~S_IMMUTABLE
;
88 if (attrs
->flags
& ORANGEFS_APPEND_FL
)
92 if (attrs
->flags
& ORANGEFS_NOATIME_FL
)
99 static int orangefs_inode_perms(struct ORANGEFS_sys_attr_s
*attrs
)
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
;
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
;
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
;
124 if (attrs
->perms
& ORANGEFS_G_SGID
)
125 perm_mode
|= S_ISGID
;
126 if (attrs
->perms
& ORANGEFS_U_SUID
)
127 perm_mode
|= S_ISUID
;
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.
136 static inline int copy_attributes_from_inode(struct inode
*inode
,
137 struct ORANGEFS_sys_attr_s
*attrs
,
142 if (!iattr
|| !inode
|| !attrs
) {
143 gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
144 "in copy_attributes_from_inode!\n",
151 * We need to be careful to only copy the attributes out of the
152 * iattr object that we know are valid.
155 if (iattr
->ia_valid
& ATTR_UID
) {
156 attrs
->owner
= from_kuid(&init_user_ns
, iattr
->ia_uid
);
157 attrs
->mask
|= ORANGEFS_ATTR_SYS_UID
;
158 gossip_debug(GOSSIP_UTILS_DEBUG
, "(UID) %d\n", attrs
->owner
);
160 if (iattr
->ia_valid
& ATTR_GID
) {
161 attrs
->group
= from_kgid(&init_user_ns
, iattr
->ia_gid
);
162 attrs
->mask
|= ORANGEFS_ATTR_SYS_GID
;
163 gossip_debug(GOSSIP_UTILS_DEBUG
, "(GID) %d\n", attrs
->group
);
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
;
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
;
180 if (iattr
->ia_valid
& ATTR_CTIME
)
181 attrs
->mask
|= ORANGEFS_ATTR_SYS_CTIME
;
184 * ORANGEFS cannot set size with a setattr operation. Probably not likely
185 * to be requested through the VFS, but just in case, don't worry about
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
)) {
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
200 gossip_debug(GOSSIP_UTILS_DEBUG
,
201 "User attempted to set sticky bit on non-root directory; returning EINVAL.\n");
206 if (tmp_mode
& (S_ISUID
)) {
207 gossip_debug(GOSSIP_UTILS_DEBUG
,
208 "Attempting to set setuid bit (not supported); returning EINVAL.\n");
212 attrs
->perms
= ORANGEFS_util_translate_mode(tmp_mode
);
213 attrs
->mask
|= ORANGEFS_ATTR_SYS_PERM
;
219 static int orangefs_inode_type(enum orangefs_ds_type objtype
)
221 if (objtype
== ORANGEFS_TYPE_METAFILE
)
223 else if (objtype
== ORANGEFS_TYPE_DIRECTORY
)
225 else if (objtype
== ORANGEFS_TYPE_SYMLINK
)
231 static int orangefs_inode_is_stale(struct inode
*inode
, int new,
232 struct ORANGEFS_sys_attr_s
*attrs
, char *link_target
)
234 struct orangefs_inode_s
*orangefs_inode
= ORANGEFS_I(inode
);
235 int type
= orangefs_inode_type(attrs
->objtype
);
238 * If the inode type or symlink target have changed then this
241 if (type
== -1 || !(inode
->i_mode
& type
)) {
242 orangefs_make_bad_inode(inode
);
245 if (type
== S_IFLNK
&& strncmp(orangefs_inode
->link_target
,
246 link_target
, ORANGEFS_NAME_MAX
)) {
247 orangefs_make_bad_inode(inode
);
254 int orangefs_inode_getattr(struct inode
*inode
, int new, int bypass
)
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
;
261 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: called on inode %pU\n", __func__
,
262 get_khandle_from_ino(inode
));
264 if (!new && !bypass
) {
265 if (time_before(jiffies
, orangefs_inode
->getattr_time
))
269 new_op
= op_alloc(ORANGEFS_VFS_OP_GETATTR
);
272 new_op
->upcall
.req
.getattr
.refn
= orangefs_inode
->refn
;
273 new_op
->upcall
.req
.getattr
.mask
= ORANGEFS_ATTR_SYS_ALL_NOHINT
;
275 ret
= service_operation(new_op
, __func__
,
276 get_interruptible_flag(inode
));
280 type
= orangefs_inode_type(new_op
->
281 downcall
.resp
.getattr
.attributes
.objtype
);
282 ret
= orangefs_inode_is_stale(inode
, new,
283 &new_op
->downcall
.resp
.getattr
.attributes
,
284 new_op
->downcall
.resp
.getattr
.link_target
);
292 inode
->i_flags
= orangefs_inode_flags(&new_op
->
293 downcall
.resp
.getattr
.attributes
);
294 inode_size
= (loff_t
)new_op
->
295 downcall
.resp
.getattr
.attributes
.size
;
297 (inode_size
+ (4096 - (inode_size
% 4096)));
298 inode
->i_size
= inode_size
;
299 orangefs_inode
->blksize
=
300 new_op
->downcall
.resp
.getattr
.attributes
.blksize
;
301 spin_lock(&inode
->i_lock
);
302 inode
->i_bytes
= inode_size
;
304 (unsigned long)(rounded_up_size
/ 512);
305 spin_unlock(&inode
->i_lock
);
308 inode
->i_size
= PAGE_SIZE
;
309 orangefs_inode
->blksize
= (1 << inode
->i_blkbits
);
310 spin_lock(&inode
->i_lock
);
311 inode_set_bytes(inode
, inode
->i_size
);
312 spin_unlock(&inode
->i_lock
);
317 inode
->i_size
= (loff_t
)strlen(new_op
->
318 downcall
.resp
.getattr
.link_target
);
319 orangefs_inode
->blksize
= (1 << inode
->i_blkbits
);
320 ret
= strscpy(orangefs_inode
->link_target
,
321 new_op
->downcall
.resp
.getattr
.link_target
,
327 inode
->i_link
= orangefs_inode
->link_target
;
332 inode
->i_uid
= make_kuid(&init_user_ns
, new_op
->
333 downcall
.resp
.getattr
.attributes
.owner
);
334 inode
->i_gid
= make_kgid(&init_user_ns
, new_op
->
335 downcall
.resp
.getattr
.attributes
.group
);
336 inode
->i_atime
.tv_sec
= (time64_t
)new_op
->
337 downcall
.resp
.getattr
.attributes
.atime
;
338 inode
->i_mtime
.tv_sec
= (time64_t
)new_op
->
339 downcall
.resp
.getattr
.attributes
.mtime
;
340 inode
->i_ctime
.tv_sec
= (time64_t
)new_op
->
341 downcall
.resp
.getattr
.attributes
.ctime
;
342 inode
->i_atime
.tv_nsec
= 0;
343 inode
->i_mtime
.tv_nsec
= 0;
344 inode
->i_ctime
.tv_nsec
= 0;
346 /* special case: mark the root inode as sticky */
347 inode
->i_mode
= type
| (is_root_handle(inode
) ? S_ISVTX
: 0) |
348 orangefs_inode_perms(&new_op
->downcall
.resp
.getattr
.attributes
);
350 orangefs_inode
->getattr_time
= jiffies
+ getattr_timeout_msecs
*HZ
/1000;
357 int orangefs_inode_check_changed(struct inode
*inode
)
359 struct orangefs_inode_s
*orangefs_inode
= ORANGEFS_I(inode
);
360 struct orangefs_kernel_op_s
*new_op
;
363 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: called on inode %pU\n", __func__
,
364 get_khandle_from_ino(inode
));
366 new_op
= op_alloc(ORANGEFS_VFS_OP_GETATTR
);
369 new_op
->upcall
.req
.getattr
.refn
= orangefs_inode
->refn
;
370 new_op
->upcall
.req
.getattr
.mask
= ORANGEFS_ATTR_SYS_TYPE
|
371 ORANGEFS_ATTR_SYS_LNK_TARGET
;
373 ret
= service_operation(new_op
, __func__
,
374 get_interruptible_flag(inode
));
378 ret
= orangefs_inode_is_stale(inode
, 0,
379 &new_op
->downcall
.resp
.getattr
.attributes
,
380 new_op
->downcall
.resp
.getattr
.link_target
);
387 * issues a orangefs setattr request to make sure the new attribute values
388 * take effect if successful. returns 0 on success; -errno otherwise
390 int orangefs_inode_setattr(struct inode
*inode
, struct iattr
*iattr
)
392 struct orangefs_inode_s
*orangefs_inode
= ORANGEFS_I(inode
);
393 struct orangefs_kernel_op_s
*new_op
;
396 new_op
= op_alloc(ORANGEFS_VFS_OP_SETATTR
);
400 new_op
->upcall
.req
.setattr
.refn
= orangefs_inode
->refn
;
401 ret
= copy_attributes_from_inode(inode
,
402 &new_op
->upcall
.req
.setattr
.attributes
,
405 ret
= service_operation(new_op
, __func__
,
406 get_interruptible_flag(inode
));
408 gossip_debug(GOSSIP_UTILS_DEBUG
,
409 "orangefs_inode_setattr: returning %d\n",
416 * successful setattr should clear the atime, mtime and
420 ClearAtimeFlag(orangefs_inode
);
421 ClearMtimeFlag(orangefs_inode
);
422 ClearCtimeFlag(orangefs_inode
);
423 ClearModeFlag(orangefs_inode
);
424 orangefs_inode
->getattr_time
= jiffies
- 1;
430 int orangefs_flush_inode(struct inode
*inode
)
433 * If it is a dirty inode, this function gets called.
434 * Gather all the information that needs to be setattr'ed
435 * Right now, this will only be used for mode, atime, mtime
444 struct orangefs_inode_s
*orangefs_inode
= ORANGEFS_I(inode
);
446 memset(&wbattr
, 0, sizeof(wbattr
));
449 * check inode flags up front, and clear them if they are set. This
450 * will prevent multiple processes from all trying to flush the same
451 * inode if they call close() simultaneously
453 mtime_flag
= MtimeFlag(orangefs_inode
);
454 ClearMtimeFlag(orangefs_inode
);
455 ctime_flag
= CtimeFlag(orangefs_inode
);
456 ClearCtimeFlag(orangefs_inode
);
457 atime_flag
= AtimeFlag(orangefs_inode
);
458 ClearAtimeFlag(orangefs_inode
);
459 mode_flag
= ModeFlag(orangefs_inode
);
460 ClearModeFlag(orangefs_inode
);
462 /* -- Lazy atime,mtime and ctime update --
463 * Note: all times are dictated by server in the new scheme
464 * and not by the clients
466 * Also mode updates are being handled now..
470 wbattr
.ia_valid
|= ATTR_MTIME
;
472 wbattr
.ia_valid
|= ATTR_CTIME
;
474 wbattr
.ia_valid
|= ATTR_ATIME
;
477 wbattr
.ia_mode
= inode
->i_mode
;
478 wbattr
.ia_valid
|= ATTR_MODE
;
481 gossip_debug(GOSSIP_UTILS_DEBUG
,
482 "*********** orangefs_flush_inode: %pU "
484 get_khandle_from_ino(inode
),
486 if (wbattr
.ia_valid
== 0) {
487 gossip_debug(GOSSIP_UTILS_DEBUG
,
488 "orangefs_flush_inode skipping setattr()\n");
492 gossip_debug(GOSSIP_UTILS_DEBUG
,
493 "orangefs_flush_inode (%pU) writing mode %o\n",
494 get_khandle_from_ino(inode
),
497 ret
= orangefs_inode_setattr(inode
, &wbattr
);
502 int orangefs_unmount_sb(struct super_block
*sb
)
505 struct orangefs_kernel_op_s
*new_op
= NULL
;
507 gossip_debug(GOSSIP_UTILS_DEBUG
,
508 "orangefs_unmount_sb called on sb %p\n",
511 new_op
= op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT
);
514 new_op
->upcall
.req
.fs_umount
.id
= ORANGEFS_SB(sb
)->id
;
515 new_op
->upcall
.req
.fs_umount
.fs_id
= ORANGEFS_SB(sb
)->fs_id
;
516 strncpy(new_op
->upcall
.req
.fs_umount
.orangefs_config_server
,
517 ORANGEFS_SB(sb
)->devname
,
518 ORANGEFS_MAX_SERVER_ADDR_LEN
);
520 gossip_debug(GOSSIP_UTILS_DEBUG
,
521 "Attempting ORANGEFS Unmount via host %s\n",
522 new_op
->upcall
.req
.fs_umount
.orangefs_config_server
);
524 ret
= service_operation(new_op
, "orangefs_fs_umount", 0);
526 gossip_debug(GOSSIP_UTILS_DEBUG
,
527 "orangefs_unmount: got return value of %d\n", ret
);
531 ORANGEFS_SB(sb
)->mount_pending
= 1;
537 void orangefs_make_bad_inode(struct inode
*inode
)
539 if (is_root_handle(inode
)) {
541 * if this occurs, the pvfs2-client-core was killed but we
542 * can't afford to lose the inode operations and such
543 * associated with the root handle in any case.
545 gossip_debug(GOSSIP_UTILS_DEBUG
,
546 "*** NOT making bad root inode %pU\n",
547 get_khandle_from_ino(inode
));
549 gossip_debug(GOSSIP_UTILS_DEBUG
,
550 "*** making bad inode %pU\n",
551 get_khandle_from_ino(inode
));
552 make_bad_inode(inode
);
557 * The following is a very dirty hack that is now a permanent part of the
558 * ORANGEFS protocol. See protocol.h for more error definitions.
561 /* The order matches include/orangefs-types.h in the OrangeFS source. */
562 static int PINT_errno_mapping
[] = {
563 0, EPERM
, ENOENT
, EINTR
, EIO
, ENXIO
, EBADF
, EAGAIN
, ENOMEM
,
564 EFAULT
, EBUSY
, EEXIST
, ENODEV
, ENOTDIR
, EISDIR
, EINVAL
, EMFILE
,
565 EFBIG
, ENOSPC
, EROFS
, EMLINK
, EPIPE
, EDEADLK
, ENAMETOOLONG
,
566 ENOLCK
, ENOSYS
, ENOTEMPTY
, ELOOP
, EWOULDBLOCK
, ENOMSG
, EUNATCH
,
567 EBADR
, EDEADLOCK
, ENODATA
, ETIME
, ENONET
, EREMOTE
, ECOMM
,
568 EPROTO
, EBADMSG
, EOVERFLOW
, ERESTART
, EMSGSIZE
, EPROTOTYPE
,
569 ENOPROTOOPT
, EPROTONOSUPPORT
, EOPNOTSUPP
, EADDRINUSE
,
570 EADDRNOTAVAIL
, ENETDOWN
, ENETUNREACH
, ENETRESET
, ENOBUFS
,
571 ETIMEDOUT
, ECONNREFUSED
, EHOSTDOWN
, EHOSTUNREACH
, EALREADY
,
572 EACCES
, ECONNRESET
, ERANGE
575 int orangefs_normalize_to_errno(__s32 error_code
)
580 if (error_code
== 0) {
583 * This shouldn't ever happen. If it does it should be fixed on the
586 } else if (error_code
> 0) {
587 gossip_err("orangefs: error status receieved.\n");
588 gossip_err("orangefs: assuming error code is inverted.\n");
589 error_code
= -error_code
;
593 * XXX: This is very bad since error codes from ORANGEFS may not be
594 * suitable for return into userspace.
598 * Convert ORANGEFS error values into errno values suitable for return
601 if ((-error_code
) & ORANGEFS_NON_ERRNO_ERROR_BIT
) {
603 (ORANGEFS_ERROR_NUMBER_BITS
|ORANGEFS_NON_ERRNO_ERROR_BIT
|
604 ORANGEFS_ERROR_BIT
)) == ORANGEFS_ECANCEL
) {
606 * cancellation error codes generally correspond to
607 * a timeout from the client's perspective
609 error_code
= -ETIMEDOUT
;
611 /* assume a default error code */
612 gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code
);
613 error_code
= -EINVAL
;
616 /* Convert ORANGEFS encoded errno values into regular errno values. */
617 } else if ((-error_code
) & ORANGEFS_ERROR_BIT
) {
618 i
= (-error_code
) & ~(ORANGEFS_ERROR_BIT
|ORANGEFS_ERROR_CLASS_BITS
);
619 if (i
< sizeof(PINT_errno_mapping
)/sizeof(*PINT_errno_mapping
))
620 error_code
= -PINT_errno_mapping
[i
];
622 error_code
= -EINVAL
;
625 * Only ORANGEFS protocol error codes should ever come here. Otherwise
626 * there is a bug somewhere.
629 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
635 __s32
ORANGEFS_util_translate_mode(int mode
)
639 static int modes
[NUM_MODES
] = {
640 S_IXOTH
, S_IWOTH
, S_IROTH
,
641 S_IXGRP
, S_IWGRP
, S_IRGRP
,
642 S_IXUSR
, S_IWUSR
, S_IRUSR
,
645 static int orangefs_modes
[NUM_MODES
] = {
646 ORANGEFS_O_EXECUTE
, ORANGEFS_O_WRITE
, ORANGEFS_O_READ
,
647 ORANGEFS_G_EXECUTE
, ORANGEFS_G_WRITE
, ORANGEFS_G_READ
,
648 ORANGEFS_U_EXECUTE
, ORANGEFS_U_WRITE
, ORANGEFS_U_READ
,
649 ORANGEFS_G_SGID
, ORANGEFS_U_SUID
652 for (i
= 0; i
< NUM_MODES
; i
++)
654 ret
|= orangefs_modes
[i
];
661 * After obtaining a string representation of the client's debug
662 * keywords and their associated masks, this function is called to build an
663 * array of these values.
665 int orangefs_prepare_cdm_array(char *debug_array_string
)
669 char *cds_head
= NULL
;
670 char *cds_delimiter
= NULL
;
673 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: start\n", __func__
);
676 * figure out how many elements the cdm_array needs.
678 for (i
= 0; i
< strlen(debug_array_string
); i
++)
679 if (debug_array_string
[i
] == '\n')
682 if (!cdm_element_count
) {
683 pr_info("No elements in client debug array string!\n");
688 kzalloc(cdm_element_count
* sizeof(struct client_debug_mask
),
691 pr_info("malloc failed for cdm_array!\n");
696 cds_head
= debug_array_string
;
698 for (i
= 0; i
< cdm_element_count
; i
++) {
699 cds_delimiter
= strchr(cds_head
, '\n');
700 *cds_delimiter
= '\0';
702 keyword_len
= strcspn(cds_head
, " ");
704 cdm_array
[i
].keyword
= kzalloc(keyword_len
+ 1, GFP_KERNEL
);
705 if (!cdm_array
[i
].keyword
) {
712 cdm_array
[i
].keyword
,
713 (unsigned long long *)&(cdm_array
[i
].mask1
),
714 (unsigned long long *)&(cdm_array
[i
].mask2
));
716 if (!strcmp(cdm_array
[i
].keyword
, ORANGEFS_VERBOSE
))
717 client_verbose_index
= i
;
719 if (!strcmp(cdm_array
[i
].keyword
, ORANGEFS_ALL
))
720 client_all_index
= i
;
722 cds_head
= cds_delimiter
+ 1;
725 rc
= cdm_element_count
;
727 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: rc:%d:\n", __func__
, rc
);
736 * /sys/kernel/debug/orangefs/debug-help can be catted to
737 * see all the available kernel and client debug keywords.
739 * When the kernel boots, we have no idea what keywords the
740 * client supports, nor their associated masks.
742 * We pass through this function once at boot and stamp a
743 * boilerplate "we don't know" message for the client in the
744 * debug-help file. We pass through here again when the client
745 * starts and then we can fill out the debug-help file fully.
747 * The client might be restarted any number of times between
748 * reboots, we only build the debug-help file the first time.
750 int orangefs_prepare_debugfs_help_string(int at_boot
)
755 char *client_title
= "Client Debug Keywords:\n";
756 char *kernel_title
= "Kernel Debug Keywords:\n";
758 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: start\n", __func__
);
761 byte_count
+= strlen(HELP_STRING_UNINITIALIZED
);
762 client_title
= HELP_STRING_UNINITIALIZED
;
765 * fill the client keyword/mask array and remember
766 * how many elements there were.
769 orangefs_prepare_cdm_array(client_debug_array_string
);
770 if (cdm_element_count
<= 0)
773 /* Count the bytes destined for debug_help_string. */
774 byte_count
+= strlen(client_title
);
776 for (i
= 0; i
< cdm_element_count
; i
++) {
777 byte_count
+= strlen(cdm_array
[i
].keyword
+ 2);
778 if (byte_count
>= DEBUG_HELP_STRING_SIZE
) {
779 pr_info("%s: overflow 1!\n", __func__
);
784 gossip_debug(GOSSIP_UTILS_DEBUG
,
785 "%s: cdm_element_count:%d:\n",
790 byte_count
+= strlen(kernel_title
);
791 for (i
= 0; i
< num_kmod_keyword_mask_map
; i
++) {
793 strlen(s_kmod_keyword_mask_map
[i
].keyword
+ 2);
794 if (byte_count
>= DEBUG_HELP_STRING_SIZE
) {
795 pr_info("%s: overflow 2!\n", __func__
);
800 /* build debug_help_string. */
801 debug_help_string
= kzalloc(DEBUG_HELP_STRING_SIZE
, GFP_KERNEL
);
802 if (!debug_help_string
) {
807 strcat(debug_help_string
, client_title
);
810 for (i
= 0; i
< cdm_element_count
; i
++) {
811 strcat(debug_help_string
, "\t");
812 strcat(debug_help_string
, cdm_array
[i
].keyword
);
813 strcat(debug_help_string
, "\n");
817 strcat(debug_help_string
, "\n");
818 strcat(debug_help_string
, kernel_title
);
820 for (i
= 0; i
< num_kmod_keyword_mask_map
; i
++) {
821 strcat(debug_help_string
, "\t");
822 strcat(debug_help_string
, s_kmod_keyword_mask_map
[i
].keyword
);
823 strcat(debug_help_string
, "\n");
838 void debug_mask_to_string(void *mask
, int type
)
843 int element_count
= 0;
845 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: start\n", __func__
);
848 debug_string
= client_debug_string
;
849 element_count
= cdm_element_count
;
851 debug_string
= kernel_debug_string
;
852 element_count
= num_kmod_keyword_mask_map
;
855 memset(debug_string
, 0, ORANGEFS_MAX_DEBUG_STRING_LEN
);
858 * Some keywords, like "all" or "verbose", are amalgams of
859 * numerous other keywords. Make a special check for those
860 * before grinding through the whole mask only to find out
863 if (check_amalgam_keyword(mask
, type
))
866 /* Build the debug string. */
867 for (i
= 0; i
< element_count
; i
++)
869 do_c_string(mask
, i
);
871 do_k_string(mask
, i
);
873 len
= strlen(debug_string
);
876 client_debug_string
[len
- 1] = '\0';
878 kernel_debug_string
[len
- 1] = '\0';
880 strcpy(client_debug_string
, "none");
882 strcpy(kernel_debug_string
, "none");
885 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: string:%s:\n", __func__
, debug_string
);
891 void do_k_string(void *k_mask
, int index
)
893 __u64
*mask
= (__u64
*) k_mask
;
895 if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map
[index
].keyword
))
898 if (*mask
& s_kmod_keyword_mask_map
[index
].mask_val
) {
899 if ((strlen(kernel_debug_string
) +
900 strlen(s_kmod_keyword_mask_map
[index
].keyword
))
901 < ORANGEFS_MAX_DEBUG_STRING_LEN
- 1) {
902 strcat(kernel_debug_string
,
903 s_kmod_keyword_mask_map
[index
].keyword
);
904 strcat(kernel_debug_string
, ",");
906 gossip_err("%s: overflow!\n", __func__
);
907 strcpy(kernel_debug_string
, ORANGEFS_ALL
);
917 void do_c_string(void *c_mask
, int index
)
919 struct client_debug_mask
*mask
= (struct client_debug_mask
*) c_mask
;
921 if (keyword_is_amalgam(cdm_array
[index
].keyword
))
924 if ((mask
->mask1
& cdm_array
[index
].mask1
) ||
925 (mask
->mask2
& cdm_array
[index
].mask2
)) {
926 if ((strlen(client_debug_string
) +
927 strlen(cdm_array
[index
].keyword
) + 1)
928 < ORANGEFS_MAX_DEBUG_STRING_LEN
- 2) {
929 strcat(client_debug_string
,
930 cdm_array
[index
].keyword
);
931 strcat(client_debug_string
, ",");
933 gossip_err("%s: overflow!\n", __func__
);
934 strcpy(client_debug_string
, ORANGEFS_ALL
);
942 int keyword_is_amalgam(char *keyword
)
946 if ((!strcmp(keyword
, ORANGEFS_ALL
)) || (!strcmp(keyword
, ORANGEFS_VERBOSE
)))
956 * return 1 if we found an amalgam.
958 int check_amalgam_keyword(void *mask
, int type
)
961 struct client_debug_mask
*c_mask
;
962 int k_all_index
= num_kmod_keyword_mask_map
- 1;
966 c_mask
= (struct client_debug_mask
*) mask
;
968 if ((c_mask
->mask1
== cdm_array
[client_all_index
].mask1
) &&
969 (c_mask
->mask2
== cdm_array
[client_all_index
].mask2
)) {
970 strcpy(client_debug_string
, ORANGEFS_ALL
);
975 if ((c_mask
->mask1
== cdm_array
[client_verbose_index
].mask1
) &&
976 (c_mask
->mask2
== cdm_array
[client_verbose_index
].mask2
)) {
977 strcpy(client_debug_string
, ORANGEFS_VERBOSE
);
983 k_mask
= (__u64
*) mask
;
985 if (*k_mask
>= s_kmod_keyword_mask_map
[k_all_index
].mask_val
) {
986 strcpy(kernel_debug_string
, ORANGEFS_ALL
);
1001 void debug_string_to_mask(char *debug_string
, void *mask
, int type
)
1003 char *unchecked_keyword
;
1005 char *strsep_fodder
= kstrdup(debug_string
, GFP_KERNEL
);
1006 char *original_pointer
;
1007 int element_count
= 0;
1008 struct client_debug_mask
*c_mask
;
1011 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: start\n", __func__
);
1014 c_mask
= (struct client_debug_mask
*)mask
;
1015 element_count
= cdm_element_count
;
1017 k_mask
= (__u64
*)mask
;
1019 element_count
= num_kmod_keyword_mask_map
;
1022 original_pointer
= strsep_fodder
;
1023 while ((unchecked_keyword
= strsep(&strsep_fodder
, ",")))
1024 if (strlen(unchecked_keyword
)) {
1025 for (i
= 0; i
< element_count
; i
++)
1036 kfree(original_pointer
);
1039 void do_c_mask(int i
,
1040 char *unchecked_keyword
,
1041 struct client_debug_mask
**sane_mask
)
1044 if (!strcmp(cdm_array
[i
].keyword
, unchecked_keyword
)) {
1045 (**sane_mask
).mask1
= (**sane_mask
).mask1
| cdm_array
[i
].mask1
;
1046 (**sane_mask
).mask2
= (**sane_mask
).mask2
| cdm_array
[i
].mask2
;
1050 void do_k_mask(int i
, char *unchecked_keyword
, __u64
**sane_mask
)
1053 if (!strcmp(s_kmod_keyword_mask_map
[i
].keyword
, unchecked_keyword
))
1054 **sane_mask
= (**sane_mask
) |
1055 s_kmod_keyword_mask_map
[i
].mask_val
;