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
;
132 /* NOTE: symname is ignored unless the inode is a sym link */
133 static int copy_attributes_to_inode(struct inode
*inode
,
134 struct ORANGEFS_sys_attr_s
*attrs
,
138 struct orangefs_inode_s
*orangefs_inode
= ORANGEFS_I(inode
);
139 loff_t inode_size
= 0;
140 loff_t rounded_up_size
= 0;
144 * arbitrarily set the inode block size; FIXME: we need to
145 * resolve the difference between the reported inode blocksize
146 * and the PAGE_CACHE_SIZE, since our block count will always
149 * For now, we're setting the block count to be the proper
150 * number assuming the block size is 512 bytes, and the size is
151 * rounded up to the nearest 4K. This is apparently required
152 * to get proper size reports from the 'du' shell utility.
154 * changing the inode->i_blkbits to something other than
155 * PAGE_CACHE_SHIFT breaks mmap/execution as we depend on that.
157 gossip_debug(GOSSIP_UTILS_DEBUG
,
158 "attrs->mask = %x (objtype = %s)\n",
160 attrs
->objtype
== ORANGEFS_TYPE_METAFILE
? "file" :
161 attrs
->objtype
== ORANGEFS_TYPE_DIRECTORY
? "directory" :
162 attrs
->objtype
== ORANGEFS_TYPE_SYMLINK
? "symlink" :
165 switch (attrs
->objtype
) {
166 case ORANGEFS_TYPE_METAFILE
:
167 inode
->i_flags
= orangefs_inode_flags(attrs
);
168 if (attrs
->mask
& ORANGEFS_ATTR_SYS_SIZE
) {
169 inode_size
= (loff_t
) attrs
->size
;
171 (inode_size
+ (4096 - (inode_size
% 4096)));
173 orangefs_lock_inode(inode
);
174 inode
->i_bytes
= inode_size
;
176 (unsigned long)(rounded_up_size
/ 512);
177 orangefs_unlock_inode(inode
);
180 * NOTE: make sure all the places we're called
181 * from have the inode->i_sem lock. We're fine
182 * in 99% of the cases since we're mostly
183 * called from a lookup.
185 inode
->i_size
= inode_size
;
188 case ORANGEFS_TYPE_SYMLINK
:
189 if (symname
!= NULL
) {
190 inode
->i_size
= (loff_t
) strlen(symname
);
195 inode
->i_size
= PAGE_CACHE_SIZE
;
197 orangefs_lock_inode(inode
);
198 inode_set_bytes(inode
, inode
->i_size
);
199 orangefs_unlock_inode(inode
);
203 inode
->i_uid
= make_kuid(&init_user_ns
, attrs
->owner
);
204 inode
->i_gid
= make_kgid(&init_user_ns
, attrs
->group
);
205 inode
->i_atime
.tv_sec
= (time_t) attrs
->atime
;
206 inode
->i_mtime
.tv_sec
= (time_t) attrs
->mtime
;
207 inode
->i_ctime
.tv_sec
= (time_t) attrs
->ctime
;
208 inode
->i_atime
.tv_nsec
= 0;
209 inode
->i_mtime
.tv_nsec
= 0;
210 inode
->i_ctime
.tv_nsec
= 0;
212 inode
->i_mode
= orangefs_inode_perms(attrs
);
214 if (is_root_handle(inode
)) {
215 /* special case: mark the root inode as sticky */
216 inode
->i_mode
|= S_ISVTX
;
217 gossip_debug(GOSSIP_UTILS_DEBUG
,
218 "Marking inode %pU as sticky\n",
219 get_khandle_from_ino(inode
));
222 switch (attrs
->objtype
) {
223 case ORANGEFS_TYPE_METAFILE
:
224 inode
->i_mode
|= S_IFREG
;
227 case ORANGEFS_TYPE_DIRECTORY
:
228 inode
->i_mode
|= S_IFDIR
;
229 /* NOTE: we have no good way to keep nlink consistent
230 * for directories across clients; keep constant at 1.
231 * Why 1? If we go with 2, then find(1) gets confused
232 * and won't work properly withouth the -noleaf option
237 case ORANGEFS_TYPE_SYMLINK
:
238 inode
->i_mode
|= S_IFLNK
;
240 /* copy link target to inode private data */
241 if (orangefs_inode
&& symname
) {
242 strncpy(orangefs_inode
->link_target
,
245 gossip_debug(GOSSIP_UTILS_DEBUG
,
246 "Copied attr link target %s\n",
247 orangefs_inode
->link_target
);
249 gossip_debug(GOSSIP_UTILS_DEBUG
,
255 gossip_err("orangefs: copy_attributes_to_inode: got invalid attribute type %x\n",
259 gossip_debug(GOSSIP_UTILS_DEBUG
,
260 "orangefs: copy_attributes_to_inode: setting i_mode to %o, i_size to %lu\n",
262 (unsigned long)i_size_read(inode
));
268 * NOTE: in kernel land, we never use the sys_attr->link_target for
269 * anything, so don't bother copying it into the sys_attr object here.
271 static inline int copy_attributes_from_inode(struct inode
*inode
,
272 struct ORANGEFS_sys_attr_s
*attrs
,
277 if (!iattr
|| !inode
|| !attrs
) {
278 gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
279 "in copy_attributes_from_inode!\n",
286 * We need to be careful to only copy the attributes out of the
287 * iattr object that we know are valid.
290 if (iattr
->ia_valid
& ATTR_UID
) {
291 attrs
->owner
= from_kuid(current_user_ns(), iattr
->ia_uid
);
292 attrs
->mask
|= ORANGEFS_ATTR_SYS_UID
;
293 gossip_debug(GOSSIP_UTILS_DEBUG
, "(UID) %d\n", attrs
->owner
);
295 if (iattr
->ia_valid
& ATTR_GID
) {
296 attrs
->group
= from_kgid(current_user_ns(), iattr
->ia_gid
);
297 attrs
->mask
|= ORANGEFS_ATTR_SYS_GID
;
298 gossip_debug(GOSSIP_UTILS_DEBUG
, "(GID) %d\n", attrs
->group
);
301 if (iattr
->ia_valid
& ATTR_ATIME
) {
302 attrs
->mask
|= ORANGEFS_ATTR_SYS_ATIME
;
303 if (iattr
->ia_valid
& ATTR_ATIME_SET
) {
305 orangefs_convert_time_field(&iattr
->ia_atime
);
306 attrs
->mask
|= ORANGEFS_ATTR_SYS_ATIME_SET
;
309 if (iattr
->ia_valid
& ATTR_MTIME
) {
310 attrs
->mask
|= ORANGEFS_ATTR_SYS_MTIME
;
311 if (iattr
->ia_valid
& ATTR_MTIME_SET
) {
313 orangefs_convert_time_field(&iattr
->ia_mtime
);
314 attrs
->mask
|= ORANGEFS_ATTR_SYS_MTIME_SET
;
317 if (iattr
->ia_valid
& ATTR_CTIME
)
318 attrs
->mask
|= ORANGEFS_ATTR_SYS_CTIME
;
321 * ORANGEFS cannot set size with a setattr operation. Probably not likely
322 * to be requested through the VFS, but just in case, don't worry about
326 if (iattr
->ia_valid
& ATTR_MODE
) {
327 tmp_mode
= iattr
->ia_mode
;
328 if (tmp_mode
& (S_ISVTX
)) {
329 if (is_root_handle(inode
)) {
331 * allow sticky bit to be set on root (since
332 * it shows up that way by default anyhow),
333 * but don't show it to the server
337 gossip_debug(GOSSIP_UTILS_DEBUG
,
338 "User attempted to set sticky bit on non-root directory; returning EINVAL.\n");
343 if (tmp_mode
& (S_ISUID
)) {
344 gossip_debug(GOSSIP_UTILS_DEBUG
,
345 "Attempting to set setuid bit (not supported); returning EINVAL.\n");
349 attrs
->perms
= ORANGEFS_util_translate_mode(tmp_mode
);
350 attrs
->mask
|= ORANGEFS_ATTR_SYS_PERM
;
356 static int compare_attributes_to_inode(struct inode
*inode
,
357 struct ORANGEFS_sys_attr_s
*attrs
,
361 struct orangefs_inode_s
*orangefs_inode
= ORANGEFS_I(inode
);
362 loff_t inode_size
, rounded_up_size
;
364 /* Much of what happens below relies on the type being around. */
365 if (!(mask
& ORANGEFS_ATTR_SYS_TYPE
))
368 if (attrs
->objtype
== ORANGEFS_TYPE_METAFILE
&&
369 inode
->i_flags
!= orangefs_inode_flags(attrs
))
372 /* Compare file size. */
374 switch (attrs
->objtype
) {
375 case ORANGEFS_TYPE_METAFILE
:
376 if (mask
& ORANGEFS_ATTR_SYS_SIZE
) {
377 inode_size
= attrs
->size
;
378 rounded_up_size
= inode_size
+
379 (4096 - (inode_size
% 4096));
380 if (inode
->i_bytes
!= inode_size
||
381 inode
->i_blocks
!= rounded_up_size
/512)
385 case ORANGEFS_TYPE_SYMLINK
:
386 if (mask
& ORANGEFS_ATTR_SYS_SIZE
)
387 if (symname
&& strlen(symname
) != inode
->i_size
)
391 if (inode
->i_size
!= PAGE_CACHE_SIZE
&&
392 inode_get_bytes(inode
) != PAGE_CACHE_SIZE
)
396 /* Compare general attributes. */
398 if (mask
& ORANGEFS_ATTR_SYS_UID
&&
399 !uid_eq(inode
->i_uid
, make_kuid(&init_user_ns
, attrs
->owner
)))
401 if (mask
& ORANGEFS_ATTR_SYS_GID
&&
402 !gid_eq(inode
->i_gid
, make_kgid(&init_user_ns
, attrs
->group
)))
404 if (mask
& ORANGEFS_ATTR_SYS_ATIME
&&
405 inode
->i_atime
.tv_sec
!= attrs
->atime
)
407 if (mask
& ORANGEFS_ATTR_SYS_MTIME
&&
408 inode
->i_atime
.tv_sec
!= attrs
->mtime
)
410 if (mask
& ORANGEFS_ATTR_SYS_CTIME
&&
411 inode
->i_atime
.tv_sec
!= attrs
->ctime
)
413 if (inode
->i_atime
.tv_nsec
!= 0 ||
414 inode
->i_mtime
.tv_nsec
!= 0 ||
415 inode
->i_ctime
.tv_nsec
!= 0)
418 if (mask
& ORANGEFS_ATTR_SYS_PERM
&&
419 (inode
->i_mode
& ~(S_ISVTX
|S_IFREG
|S_IFDIR
|S_IFLNK
)) !=
420 orangefs_inode_perms(attrs
))
423 if (is_root_handle(inode
))
424 if (!(inode
->i_mode
& S_ISVTX
))
427 /* Compare file type. */
429 switch (attrs
->objtype
) {
430 case ORANGEFS_TYPE_METAFILE
:
431 if (!(inode
->i_mode
& S_IFREG
))
434 case ORANGEFS_TYPE_DIRECTORY
:
435 if (!(inode
->i_mode
& S_IFDIR
))
437 if (inode
->i_nlink
!= 1)
440 case ORANGEFS_TYPE_SYMLINK
:
441 if (!(inode
->i_mode
& S_IFLNK
))
443 if (orangefs_inode
&& symname
&&
444 mask
& ORANGEFS_ATTR_SYS_LNK_TARGET
)
445 if (strcmp(orangefs_inode
->link_target
, symname
))
449 gossip_err("orangefs: compare_attributes_to_inode: got invalid attribute type %x\n",
458 * Issues a orangefs getattr request and fills in the appropriate inode
459 * attributes if successful. When check is 0, returns 0 on success and -errno
460 * otherwise. When check is 1, returns 1 on success where the inode is valid
461 * and 0 on success where the inode is stale and -errno otherwise.
463 int orangefs_inode_getattr(struct inode
*inode
, __u32 getattr_mask
, int check
)
465 struct orangefs_inode_s
*orangefs_inode
= ORANGEFS_I(inode
);
466 struct orangefs_kernel_op_s
*new_op
;
469 gossip_debug(GOSSIP_UTILS_DEBUG
,
470 "%s: called on inode %pU\n",
472 get_khandle_from_ino(inode
));
474 new_op
= op_alloc(ORANGEFS_VFS_OP_GETATTR
);
477 new_op
->upcall
.req
.getattr
.refn
= orangefs_inode
->refn
;
478 new_op
->upcall
.req
.getattr
.mask
= getattr_mask
;
480 ret
= service_operation(new_op
, __func__
,
481 get_interruptible_flag(inode
));
486 ret
= compare_attributes_to_inode(inode
,
487 &new_op
->downcall
.resp
.getattr
.attributes
,
488 new_op
->downcall
.resp
.getattr
.link_target
,
491 if (new_op
->downcall
.resp
.getattr
.attributes
.objtype
==
492 ORANGEFS_TYPE_METAFILE
) {
493 if (orangefs_inode
->blksize
!=
494 new_op
->downcall
.resp
.getattr
.attributes
.blksize
)
497 if (orangefs_inode
->blksize
!= 1 << inode
->i_blkbits
)
501 if (copy_attributes_to_inode(inode
,
502 &new_op
->downcall
.resp
.getattr
.attributes
,
503 new_op
->downcall
.resp
.getattr
.link_target
)) {
504 gossip_err("%s: failed to copy attributes\n", __func__
);
510 * Store blksize in orangefs specific part of inode structure;
511 * we are only going to use this to report to stat to make sure
512 * it doesn't perturb any inode related code paths.
514 if (new_op
->downcall
.resp
.getattr
.attributes
.objtype
==
515 ORANGEFS_TYPE_METAFILE
) {
516 orangefs_inode
->blksize
= new_op
->downcall
.resp
.
517 getattr
.attributes
.blksize
;
520 * mimic behavior of generic_fillattr() for other file
523 orangefs_inode
->blksize
= (1 << inode
->i_blkbits
);
529 gossip_debug(GOSSIP_UTILS_DEBUG
,
530 "Getattr on handle %pU, "
531 "fsid %d\n (inode ct = %d) returned %d\n",
532 &orangefs_inode
->refn
.khandle
,
533 orangefs_inode
->refn
.fs_id
,
534 (int)atomic_read(&inode
->i_count
),
542 * issues a orangefs setattr request to make sure the new attribute values
543 * take effect if successful. returns 0 on success; -errno otherwise
545 int orangefs_inode_setattr(struct inode
*inode
, struct iattr
*iattr
)
547 struct orangefs_inode_s
*orangefs_inode
= ORANGEFS_I(inode
);
548 struct orangefs_kernel_op_s
*new_op
;
551 new_op
= op_alloc(ORANGEFS_VFS_OP_SETATTR
);
555 new_op
->upcall
.req
.setattr
.refn
= orangefs_inode
->refn
;
556 ret
= copy_attributes_from_inode(inode
,
557 &new_op
->upcall
.req
.setattr
.attributes
,
560 ret
= service_operation(new_op
, __func__
,
561 get_interruptible_flag(inode
));
563 gossip_debug(GOSSIP_UTILS_DEBUG
,
564 "orangefs_inode_setattr: returning %d\n",
571 * successful setattr should clear the atime, mtime and
575 ClearAtimeFlag(orangefs_inode
);
576 ClearMtimeFlag(orangefs_inode
);
577 ClearCtimeFlag(orangefs_inode
);
578 ClearModeFlag(orangefs_inode
);
584 int orangefs_flush_inode(struct inode
*inode
)
587 * If it is a dirty inode, this function gets called.
588 * Gather all the information that needs to be setattr'ed
589 * Right now, this will only be used for mode, atime, mtime
598 struct orangefs_inode_s
*orangefs_inode
= ORANGEFS_I(inode
);
600 memset(&wbattr
, 0, sizeof(wbattr
));
603 * check inode flags up front, and clear them if they are set. This
604 * will prevent multiple processes from all trying to flush the same
605 * inode if they call close() simultaneously
607 mtime_flag
= MtimeFlag(orangefs_inode
);
608 ClearMtimeFlag(orangefs_inode
);
609 ctime_flag
= CtimeFlag(orangefs_inode
);
610 ClearCtimeFlag(orangefs_inode
);
611 atime_flag
= AtimeFlag(orangefs_inode
);
612 ClearAtimeFlag(orangefs_inode
);
613 mode_flag
= ModeFlag(orangefs_inode
);
614 ClearModeFlag(orangefs_inode
);
616 /* -- Lazy atime,mtime and ctime update --
617 * Note: all times are dictated by server in the new scheme
618 * and not by the clients
620 * Also mode updates are being handled now..
624 wbattr
.ia_valid
|= ATTR_MTIME
;
626 wbattr
.ia_valid
|= ATTR_CTIME
;
628 wbattr
.ia_valid
|= ATTR_ATIME
;
631 wbattr
.ia_mode
= inode
->i_mode
;
632 wbattr
.ia_valid
|= ATTR_MODE
;
635 gossip_debug(GOSSIP_UTILS_DEBUG
,
636 "*********** orangefs_flush_inode: %pU "
638 get_khandle_from_ino(inode
),
640 if (wbattr
.ia_valid
== 0) {
641 gossip_debug(GOSSIP_UTILS_DEBUG
,
642 "orangefs_flush_inode skipping setattr()\n");
646 gossip_debug(GOSSIP_UTILS_DEBUG
,
647 "orangefs_flush_inode (%pU) writing mode %o\n",
648 get_khandle_from_ino(inode
),
651 ret
= orangefs_inode_setattr(inode
, &wbattr
);
656 int orangefs_unmount_sb(struct super_block
*sb
)
659 struct orangefs_kernel_op_s
*new_op
= NULL
;
661 gossip_debug(GOSSIP_UTILS_DEBUG
,
662 "orangefs_unmount_sb called on sb %p\n",
665 new_op
= op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT
);
668 new_op
->upcall
.req
.fs_umount
.id
= ORANGEFS_SB(sb
)->id
;
669 new_op
->upcall
.req
.fs_umount
.fs_id
= ORANGEFS_SB(sb
)->fs_id
;
670 strncpy(new_op
->upcall
.req
.fs_umount
.orangefs_config_server
,
671 ORANGEFS_SB(sb
)->devname
,
672 ORANGEFS_MAX_SERVER_ADDR_LEN
);
674 gossip_debug(GOSSIP_UTILS_DEBUG
,
675 "Attempting ORANGEFS Unmount via host %s\n",
676 new_op
->upcall
.req
.fs_umount
.orangefs_config_server
);
678 ret
= service_operation(new_op
, "orangefs_fs_umount", 0);
680 gossip_debug(GOSSIP_UTILS_DEBUG
,
681 "orangefs_unmount: got return value of %d\n", ret
);
685 ORANGEFS_SB(sb
)->mount_pending
= 1;
691 void orangefs_make_bad_inode(struct inode
*inode
)
693 if (is_root_handle(inode
)) {
695 * if this occurs, the pvfs2-client-core was killed but we
696 * can't afford to lose the inode operations and such
697 * associated with the root handle in any case.
699 gossip_debug(GOSSIP_UTILS_DEBUG
,
700 "*** NOT making bad root inode %pU\n",
701 get_khandle_from_ino(inode
));
703 gossip_debug(GOSSIP_UTILS_DEBUG
,
704 "*** making bad inode %pU\n",
705 get_khandle_from_ino(inode
));
706 make_bad_inode(inode
);
710 /* Block all blockable signals... */
711 void orangefs_block_signals(sigset_t
*orig_sigset
)
716 * Initialize all entries in the signal set to the
717 * inverse of the given mask.
719 siginitsetinv(&mask
, sigmask(SIGKILL
));
721 /* Block 'em Danno... */
722 sigprocmask(SIG_BLOCK
, &mask
, orig_sigset
);
725 /* set the signal mask to the given template... */
726 void orangefs_set_signals(sigset_t
*sigset
)
728 sigprocmask(SIG_SETMASK
, sigset
, NULL
);
732 * The following is a very dirty hack that is now a permanent part of the
733 * ORANGEFS protocol. See protocol.h for more error definitions.
736 /* The order matches include/orangefs-types.h in the OrangeFS source. */
737 static int PINT_errno_mapping
[] = {
738 0, EPERM
, ENOENT
, EINTR
, EIO
, ENXIO
, EBADF
, EAGAIN
, ENOMEM
,
739 EFAULT
, EBUSY
, EEXIST
, ENODEV
, ENOTDIR
, EISDIR
, EINVAL
, EMFILE
,
740 EFBIG
, ENOSPC
, EROFS
, EMLINK
, EPIPE
, EDEADLK
, ENAMETOOLONG
,
741 ENOLCK
, ENOSYS
, ENOTEMPTY
, ELOOP
, EWOULDBLOCK
, ENOMSG
, EUNATCH
,
742 EBADR
, EDEADLOCK
, ENODATA
, ETIME
, ENONET
, EREMOTE
, ECOMM
,
743 EPROTO
, EBADMSG
, EOVERFLOW
, ERESTART
, EMSGSIZE
, EPROTOTYPE
,
744 ENOPROTOOPT
, EPROTONOSUPPORT
, EOPNOTSUPP
, EADDRINUSE
,
745 EADDRNOTAVAIL
, ENETDOWN
, ENETUNREACH
, ENETRESET
, ENOBUFS
,
746 ETIMEDOUT
, ECONNREFUSED
, EHOSTDOWN
, EHOSTUNREACH
, EALREADY
,
747 EACCES
, ECONNRESET
, ERANGE
750 int orangefs_normalize_to_errno(__s32 error_code
)
755 if (error_code
== 0) {
758 * This shouldn't ever happen. If it does it should be fixed on the
761 } else if (error_code
> 0) {
762 gossip_err("orangefs: error status receieved.\n");
763 gossip_err("orangefs: assuming error code is inverted.\n");
764 error_code
= -error_code
;
768 * XXX: This is very bad since error codes from ORANGEFS may not be
769 * suitable for return into userspace.
773 * Convert ORANGEFS error values into errno values suitable for return
776 if ((-error_code
) & ORANGEFS_NON_ERRNO_ERROR_BIT
) {
778 (ORANGEFS_ERROR_NUMBER_BITS
|ORANGEFS_NON_ERRNO_ERROR_BIT
|
779 ORANGEFS_ERROR_BIT
)) == ORANGEFS_ECANCEL
) {
781 * cancellation error codes generally correspond to
782 * a timeout from the client's perspective
784 error_code
= -ETIMEDOUT
;
786 /* assume a default error code */
787 gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code
);
788 error_code
= -EINVAL
;
791 /* Convert ORANGEFS encoded errno values into regular errno values. */
792 } else if ((-error_code
) & ORANGEFS_ERROR_BIT
) {
793 i
= (-error_code
) & ~(ORANGEFS_ERROR_BIT
|ORANGEFS_ERROR_CLASS_BITS
);
794 if (i
< sizeof(PINT_errno_mapping
)/sizeof(*PINT_errno_mapping
))
795 error_code
= -PINT_errno_mapping
[i
];
797 error_code
= -EINVAL
;
800 * Only ORANGEFS protocol error codes should ever come here. Otherwise
801 * there is a bug somewhere.
804 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
810 __s32
ORANGEFS_util_translate_mode(int mode
)
814 static int modes
[NUM_MODES
] = {
815 S_IXOTH
, S_IWOTH
, S_IROTH
,
816 S_IXGRP
, S_IWGRP
, S_IRGRP
,
817 S_IXUSR
, S_IWUSR
, S_IRUSR
,
820 static int orangefs_modes
[NUM_MODES
] = {
821 ORANGEFS_O_EXECUTE
, ORANGEFS_O_WRITE
, ORANGEFS_O_READ
,
822 ORANGEFS_G_EXECUTE
, ORANGEFS_G_WRITE
, ORANGEFS_G_READ
,
823 ORANGEFS_U_EXECUTE
, ORANGEFS_U_WRITE
, ORANGEFS_U_READ
,
824 ORANGEFS_G_SGID
, ORANGEFS_U_SUID
827 for (i
= 0; i
< NUM_MODES
; i
++)
829 ret
|= orangefs_modes
[i
];
836 * After obtaining a string representation of the client's debug
837 * keywords and their associated masks, this function is called to build an
838 * array of these values.
840 int orangefs_prepare_cdm_array(char *debug_array_string
)
844 char *cds_head
= NULL
;
845 char *cds_delimiter
= NULL
;
848 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: start\n", __func__
);
851 * figure out how many elements the cdm_array needs.
853 for (i
= 0; i
< strlen(debug_array_string
); i
++)
854 if (debug_array_string
[i
] == '\n')
857 if (!cdm_element_count
) {
858 pr_info("No elements in client debug array string!\n");
863 kzalloc(cdm_element_count
* sizeof(struct client_debug_mask
),
866 pr_info("malloc failed for cdm_array!\n");
871 cds_head
= debug_array_string
;
873 for (i
= 0; i
< cdm_element_count
; i
++) {
874 cds_delimiter
= strchr(cds_head
, '\n');
875 *cds_delimiter
= '\0';
877 keyword_len
= strcspn(cds_head
, " ");
879 cdm_array
[i
].keyword
= kzalloc(keyword_len
+ 1, GFP_KERNEL
);
880 if (!cdm_array
[i
].keyword
) {
887 cdm_array
[i
].keyword
,
888 (unsigned long long *)&(cdm_array
[i
].mask1
),
889 (unsigned long long *)&(cdm_array
[i
].mask2
));
891 if (!strcmp(cdm_array
[i
].keyword
, ORANGEFS_VERBOSE
))
892 client_verbose_index
= i
;
894 if (!strcmp(cdm_array
[i
].keyword
, ORANGEFS_ALL
))
895 client_all_index
= i
;
897 cds_head
= cds_delimiter
+ 1;
900 rc
= cdm_element_count
;
902 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: rc:%d:\n", __func__
, rc
);
911 * /sys/kernel/debug/orangefs/debug-help can be catted to
912 * see all the available kernel and client debug keywords.
914 * When the kernel boots, we have no idea what keywords the
915 * client supports, nor their associated masks.
917 * We pass through this function once at boot and stamp a
918 * boilerplate "we don't know" message for the client in the
919 * debug-help file. We pass through here again when the client
920 * starts and then we can fill out the debug-help file fully.
922 * The client might be restarted any number of times between
923 * reboots, we only build the debug-help file the first time.
925 int orangefs_prepare_debugfs_help_string(int at_boot
)
930 char *client_title
= "Client Debug Keywords:\n";
931 char *kernel_title
= "Kernel Debug Keywords:\n";
933 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: start\n", __func__
);
936 byte_count
+= strlen(HELP_STRING_UNINITIALIZED
);
937 client_title
= HELP_STRING_UNINITIALIZED
;
940 * fill the client keyword/mask array and remember
941 * how many elements there were.
944 orangefs_prepare_cdm_array(client_debug_array_string
);
945 if (cdm_element_count
<= 0)
948 /* Count the bytes destined for debug_help_string. */
949 byte_count
+= strlen(client_title
);
951 for (i
= 0; i
< cdm_element_count
; i
++) {
952 byte_count
+= strlen(cdm_array
[i
].keyword
+ 2);
953 if (byte_count
>= DEBUG_HELP_STRING_SIZE
) {
954 pr_info("%s: overflow 1!\n", __func__
);
959 gossip_debug(GOSSIP_UTILS_DEBUG
,
960 "%s: cdm_element_count:%d:\n",
965 byte_count
+= strlen(kernel_title
);
966 for (i
= 0; i
< num_kmod_keyword_mask_map
; i
++) {
968 strlen(s_kmod_keyword_mask_map
[i
].keyword
+ 2);
969 if (byte_count
>= DEBUG_HELP_STRING_SIZE
) {
970 pr_info("%s: overflow 2!\n", __func__
);
975 /* build debug_help_string. */
976 debug_help_string
= kzalloc(DEBUG_HELP_STRING_SIZE
, GFP_KERNEL
);
977 if (!debug_help_string
) {
982 strcat(debug_help_string
, client_title
);
985 for (i
= 0; i
< cdm_element_count
; i
++) {
986 strcat(debug_help_string
, "\t");
987 strcat(debug_help_string
, cdm_array
[i
].keyword
);
988 strcat(debug_help_string
, "\n");
992 strcat(debug_help_string
, "\n");
993 strcat(debug_help_string
, kernel_title
);
995 for (i
= 0; i
< num_kmod_keyword_mask_map
; i
++) {
996 strcat(debug_help_string
, "\t");
997 strcat(debug_help_string
, s_kmod_keyword_mask_map
[i
].keyword
);
998 strcat(debug_help_string
, "\n");
1013 void debug_mask_to_string(void *mask
, int type
)
1018 int element_count
= 0;
1020 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: start\n", __func__
);
1023 debug_string
= client_debug_string
;
1024 element_count
= cdm_element_count
;
1026 debug_string
= kernel_debug_string
;
1027 element_count
= num_kmod_keyword_mask_map
;
1030 memset(debug_string
, 0, ORANGEFS_MAX_DEBUG_STRING_LEN
);
1033 * Some keywords, like "all" or "verbose", are amalgams of
1034 * numerous other keywords. Make a special check for those
1035 * before grinding through the whole mask only to find out
1038 if (check_amalgam_keyword(mask
, type
))
1041 /* Build the debug string. */
1042 for (i
= 0; i
< element_count
; i
++)
1044 do_c_string(mask
, i
);
1046 do_k_string(mask
, i
);
1048 len
= strlen(debug_string
);
1050 if ((len
) && (type
))
1051 client_debug_string
[len
- 1] = '\0';
1053 kernel_debug_string
[len
- 1] = '\0';
1055 strcpy(client_debug_string
, "none");
1057 strcpy(kernel_debug_string
, "none");
1060 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: string:%s:\n", __func__
, debug_string
);
1066 void do_k_string(void *k_mask
, int index
)
1068 __u64
*mask
= (__u64
*) k_mask
;
1070 if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map
[index
].keyword
))
1073 if (*mask
& s_kmod_keyword_mask_map
[index
].mask_val
) {
1074 if ((strlen(kernel_debug_string
) +
1075 strlen(s_kmod_keyword_mask_map
[index
].keyword
))
1076 < ORANGEFS_MAX_DEBUG_STRING_LEN
- 1) {
1077 strcat(kernel_debug_string
,
1078 s_kmod_keyword_mask_map
[index
].keyword
);
1079 strcat(kernel_debug_string
, ",");
1081 gossip_err("%s: overflow!\n", __func__
);
1082 strcpy(kernel_debug_string
, ORANGEFS_ALL
);
1092 void do_c_string(void *c_mask
, int index
)
1094 struct client_debug_mask
*mask
= (struct client_debug_mask
*) c_mask
;
1096 if (keyword_is_amalgam(cdm_array
[index
].keyword
))
1099 if ((mask
->mask1
& cdm_array
[index
].mask1
) ||
1100 (mask
->mask2
& cdm_array
[index
].mask2
)) {
1101 if ((strlen(client_debug_string
) +
1102 strlen(cdm_array
[index
].keyword
) + 1)
1103 < ORANGEFS_MAX_DEBUG_STRING_LEN
- 2) {
1104 strcat(client_debug_string
,
1105 cdm_array
[index
].keyword
);
1106 strcat(client_debug_string
, ",");
1108 gossip_err("%s: overflow!\n", __func__
);
1109 strcpy(client_debug_string
, ORANGEFS_ALL
);
1117 int keyword_is_amalgam(char *keyword
)
1121 if ((!strcmp(keyword
, ORANGEFS_ALL
)) || (!strcmp(keyword
, ORANGEFS_VERBOSE
)))
1131 * return 1 if we found an amalgam.
1133 int check_amalgam_keyword(void *mask
, int type
)
1136 struct client_debug_mask
*c_mask
;
1137 int k_all_index
= num_kmod_keyword_mask_map
- 1;
1141 c_mask
= (struct client_debug_mask
*) mask
;
1143 if ((c_mask
->mask1
== cdm_array
[client_all_index
].mask1
) &&
1144 (c_mask
->mask2
== cdm_array
[client_all_index
].mask2
)) {
1145 strcpy(client_debug_string
, ORANGEFS_ALL
);
1150 if ((c_mask
->mask1
== cdm_array
[client_verbose_index
].mask1
) &&
1151 (c_mask
->mask2
== cdm_array
[client_verbose_index
].mask2
)) {
1152 strcpy(client_debug_string
, ORANGEFS_VERBOSE
);
1158 k_mask
= (__u64
*) mask
;
1160 if (*k_mask
>= s_kmod_keyword_mask_map
[k_all_index
].mask_val
) {
1161 strcpy(kernel_debug_string
, ORANGEFS_ALL
);
1176 void debug_string_to_mask(char *debug_string
, void *mask
, int type
)
1178 char *unchecked_keyword
;
1180 char *strsep_fodder
= kstrdup(debug_string
, GFP_KERNEL
);
1181 char *original_pointer
;
1182 int element_count
= 0;
1183 struct client_debug_mask
*c_mask
;
1186 gossip_debug(GOSSIP_UTILS_DEBUG
, "%s: start\n", __func__
);
1189 c_mask
= (struct client_debug_mask
*)mask
;
1190 element_count
= cdm_element_count
;
1192 k_mask
= (__u64
*)mask
;
1194 element_count
= num_kmod_keyword_mask_map
;
1197 original_pointer
= strsep_fodder
;
1198 while ((unchecked_keyword
= strsep(&strsep_fodder
, ",")))
1199 if (strlen(unchecked_keyword
)) {
1200 for (i
= 0; i
< element_count
; i
++)
1211 kfree(original_pointer
);
1214 void do_c_mask(int i
,
1215 char *unchecked_keyword
,
1216 struct client_debug_mask
**sane_mask
)
1219 if (!strcmp(cdm_array
[i
].keyword
, unchecked_keyword
)) {
1220 (**sane_mask
).mask1
= (**sane_mask
).mask1
| cdm_array
[i
].mask1
;
1221 (**sane_mask
).mask2
= (**sane_mask
).mask2
| cdm_array
[i
].mask2
;
1225 void do_k_mask(int i
, char *unchecked_keyword
, __u64
**sane_mask
)
1228 if (!strcmp(s_kmod_keyword_mask_map
[i
].keyword
, unchecked_keyword
))
1229 **sane_mask
= (**sane_mask
) |
1230 s_kmod_keyword_mask_map
[i
].mask_val
;