]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - fs/orangefs/pvfs2-utils.c
Orangefs: fix some checkpatch.pl complaints that had creeped in.
[karo-tx-linux.git] / fs / orangefs / pvfs2-utils.c
1 /*
2  * (C) 2001 Clemson University and The University of Chicago
3  *
4  * See COPYING in top-level directory.
5  */
6 #include "protocol.h"
7 #include "pvfs2-kernel.h"
8 #include "pvfs2-dev-proto.h"
9 #include "pvfs2-bufmap.h"
10
11 __s32 fsid_of_op(struct pvfs2_kernel_op_s *op)
12 {
13         __s32 fsid = PVFS_FS_ID_NULL;
14
15         if (op) {
16                 switch (op->upcall.type) {
17                 case PVFS2_VFS_OP_FILE_IO:
18                         fsid = op->upcall.req.io.refn.fs_id;
19                         break;
20                 case PVFS2_VFS_OP_LOOKUP:
21                         fsid = op->upcall.req.lookup.parent_refn.fs_id;
22                         break;
23                 case PVFS2_VFS_OP_CREATE:
24                         fsid = op->upcall.req.create.parent_refn.fs_id;
25                         break;
26                 case PVFS2_VFS_OP_GETATTR:
27                         fsid = op->upcall.req.getattr.refn.fs_id;
28                         break;
29                 case PVFS2_VFS_OP_REMOVE:
30                         fsid = op->upcall.req.remove.parent_refn.fs_id;
31                         break;
32                 case PVFS2_VFS_OP_MKDIR:
33                         fsid = op->upcall.req.mkdir.parent_refn.fs_id;
34                         break;
35                 case PVFS2_VFS_OP_READDIR:
36                         fsid = op->upcall.req.readdir.refn.fs_id;
37                         break;
38                 case PVFS2_VFS_OP_SETATTR:
39                         fsid = op->upcall.req.setattr.refn.fs_id;
40                         break;
41                 case PVFS2_VFS_OP_SYMLINK:
42                         fsid = op->upcall.req.sym.parent_refn.fs_id;
43                         break;
44                 case PVFS2_VFS_OP_RENAME:
45                         fsid = op->upcall.req.rename.old_parent_refn.fs_id;
46                         break;
47                 case PVFS2_VFS_OP_STATFS:
48                         fsid = op->upcall.req.statfs.fs_id;
49                         break;
50                 case PVFS2_VFS_OP_TRUNCATE:
51                         fsid = op->upcall.req.truncate.refn.fs_id;
52                         break;
53                 case PVFS2_VFS_OP_MMAP_RA_FLUSH:
54                         fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
55                         break;
56                 case PVFS2_VFS_OP_FS_UMOUNT:
57                         fsid = op->upcall.req.fs_umount.fs_id;
58                         break;
59                 case PVFS2_VFS_OP_GETXATTR:
60                         fsid = op->upcall.req.getxattr.refn.fs_id;
61                         break;
62                 case PVFS2_VFS_OP_SETXATTR:
63                         fsid = op->upcall.req.setxattr.refn.fs_id;
64                         break;
65                 case PVFS2_VFS_OP_LISTXATTR:
66                         fsid = op->upcall.req.listxattr.refn.fs_id;
67                         break;
68                 case PVFS2_VFS_OP_REMOVEXATTR:
69                         fsid = op->upcall.req.removexattr.refn.fs_id;
70                         break;
71                 case PVFS2_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
81 static void pvfs2_set_inode_flags(struct inode *inode,
82                                   struct PVFS_sys_attr_s *attrs)
83 {
84         if (attrs->flags & PVFS_IMMUTABLE_FL)
85                 inode->i_flags |= S_IMMUTABLE;
86         else
87                 inode->i_flags &= ~S_IMMUTABLE;
88
89         if (attrs->flags & PVFS_APPEND_FL)
90                 inode->i_flags |= S_APPEND;
91         else
92                 inode->i_flags &= ~S_APPEND;
93
94         if (attrs->flags & PVFS_NOATIME_FL)
95                 inode->i_flags |= S_NOATIME;
96         else
97                 inode->i_flags &= ~S_NOATIME;
98
99 }
100
101 /* NOTE: symname is ignored unless the inode is a sym link */
102 static int copy_attributes_to_inode(struct inode *inode,
103                                     struct PVFS_sys_attr_s *attrs,
104                                     char *symname)
105 {
106         int ret = -1;
107         int perm_mode = 0;
108         struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
109         loff_t inode_size = 0;
110         loff_t rounded_up_size = 0;
111
112
113         /*
114          * arbitrarily set the inode block size; FIXME: we need to
115          * resolve the difference between the reported inode blocksize
116          * and the PAGE_CACHE_SIZE, since our block count will always
117          * be wrong.
118          *
119          * For now, we're setting the block count to be the proper
120          * number assuming the block size is 512 bytes, and the size is
121          * rounded up to the nearest 4K.  This is apparently required
122          * to get proper size reports from the 'du' shell utility.
123          *
124          * changing the inode->i_blkbits to something other than
125          * PAGE_CACHE_SHIFT breaks mmap/execution as we depend on that.
126          */
127         gossip_debug(GOSSIP_UTILS_DEBUG,
128                      "attrs->mask = %x (objtype = %s)\n",
129                      attrs->mask,
130                      attrs->objtype == PVFS_TYPE_METAFILE ? "file" :
131                      attrs->objtype == PVFS_TYPE_DIRECTORY ? "directory" :
132                      attrs->objtype == PVFS_TYPE_SYMLINK ? "symlink" :
133                         "invalid/unknown");
134
135         switch (attrs->objtype) {
136         case PVFS_TYPE_METAFILE:
137                 pvfs2_set_inode_flags(inode, attrs);
138                 if (attrs->mask & PVFS_ATTR_SYS_SIZE) {
139                         inode_size = (loff_t) attrs->size;
140                         rounded_up_size =
141                             (inode_size + (4096 - (inode_size % 4096)));
142
143                         pvfs2_lock_inode(inode);
144                         inode->i_bytes = inode_size;
145                         inode->i_blocks =
146                             (unsigned long)(rounded_up_size / 512);
147                         pvfs2_unlock_inode(inode);
148
149                         /*
150                          * NOTE: make sure all the places we're called
151                          * from have the inode->i_sem lock. We're fine
152                          * in 99% of the cases since we're mostly
153                          * called from a lookup.
154                          */
155                         inode->i_size = inode_size;
156                 }
157                 break;
158         case PVFS_TYPE_SYMLINK:
159                 if (symname != NULL) {
160                         inode->i_size = (loff_t) strlen(symname);
161                         break;
162                 }
163                 /*FALLTHRU*/
164         default:
165                 inode->i_size = PAGE_CACHE_SIZE;
166
167                 pvfs2_lock_inode(inode);
168                 inode_set_bytes(inode, inode->i_size);
169                 pvfs2_unlock_inode(inode);
170                 break;
171         }
172
173         inode->i_uid = make_kuid(&init_user_ns, attrs->owner);
174         inode->i_gid = make_kgid(&init_user_ns, attrs->group);
175         inode->i_atime.tv_sec = (time_t) attrs->atime;
176         inode->i_mtime.tv_sec = (time_t) attrs->mtime;
177         inode->i_ctime.tv_sec = (time_t) attrs->ctime;
178         inode->i_atime.tv_nsec = 0;
179         inode->i_mtime.tv_nsec = 0;
180         inode->i_ctime.tv_nsec = 0;
181
182         if (attrs->perms & PVFS_O_EXECUTE)
183                 perm_mode |= S_IXOTH;
184         if (attrs->perms & PVFS_O_WRITE)
185                 perm_mode |= S_IWOTH;
186         if (attrs->perms & PVFS_O_READ)
187                 perm_mode |= S_IROTH;
188
189         if (attrs->perms & PVFS_G_EXECUTE)
190                 perm_mode |= S_IXGRP;
191         if (attrs->perms & PVFS_G_WRITE)
192                 perm_mode |= S_IWGRP;
193         if (attrs->perms & PVFS_G_READ)
194                 perm_mode |= S_IRGRP;
195
196         if (attrs->perms & PVFS_U_EXECUTE)
197                 perm_mode |= S_IXUSR;
198         if (attrs->perms & PVFS_U_WRITE)
199                 perm_mode |= S_IWUSR;
200         if (attrs->perms & PVFS_U_READ)
201                 perm_mode |= S_IRUSR;
202
203         if (attrs->perms & PVFS_G_SGID)
204                 perm_mode |= S_ISGID;
205         if (attrs->perms & PVFS_U_SUID)
206                 perm_mode |= S_ISUID;
207
208         inode->i_mode = perm_mode;
209
210         if (is_root_handle(inode)) {
211                 /* special case: mark the root inode as sticky */
212                 inode->i_mode |= S_ISVTX;
213                 gossip_debug(GOSSIP_UTILS_DEBUG,
214                              "Marking inode %pU as sticky\n",
215                              get_khandle_from_ino(inode));
216         }
217
218         switch (attrs->objtype) {
219         case PVFS_TYPE_METAFILE:
220                 inode->i_mode |= S_IFREG;
221                 ret = 0;
222                 break;
223         case PVFS_TYPE_DIRECTORY:
224                 inode->i_mode |= S_IFDIR;
225                 /* NOTE: we have no good way to keep nlink consistent
226                  * for directories across clients; keep constant at 1.
227                  * Why 1?  If we go with 2, then find(1) gets confused
228                  * and won't work properly withouth the -noleaf option
229                  */
230                 set_nlink(inode, 1);
231                 ret = 0;
232                 break;
233         case PVFS_TYPE_SYMLINK:
234                 inode->i_mode |= S_IFLNK;
235
236                 /* copy link target to inode private data */
237                 if (pvfs2_inode && symname) {
238                         strncpy(pvfs2_inode->link_target,
239                                 symname,
240                                 PVFS_NAME_MAX);
241                         gossip_debug(GOSSIP_UTILS_DEBUG,
242                                      "Copied attr link target %s\n",
243                                      pvfs2_inode->link_target);
244                 }
245                 gossip_debug(GOSSIP_UTILS_DEBUG,
246                              "symlink mode %o\n",
247                              inode->i_mode);
248                 ret = 0;
249                 break;
250         default:
251                 gossip_err("pvfs2: copy_attributes_to_inode: got invalid attribute type %x\n",
252                         attrs->objtype);
253         }
254
255         gossip_debug(GOSSIP_UTILS_DEBUG,
256                      "pvfs2: copy_attributes_to_inode: setting i_mode to %o, i_size to %lu\n",
257                      inode->i_mode,
258                      (unsigned long)i_size_read(inode));
259
260         return ret;
261 }
262
263 /*
264  * NOTE: in kernel land, we never use the sys_attr->link_target for
265  * anything, so don't bother copying it into the sys_attr object here.
266  */
267 static inline int copy_attributes_from_inode(struct inode *inode,
268                                              struct PVFS_sys_attr_s *attrs,
269                                              struct iattr *iattr)
270 {
271         umode_t tmp_mode;
272
273         if (!iattr || !inode || !attrs) {
274                 gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
275                            "in copy_attributes_from_inode!\n",
276                            iattr,
277                            inode,
278                            attrs);
279                 return -EINVAL;
280         }
281         /*
282          * We need to be careful to only copy the attributes out of the
283          * iattr object that we know are valid.
284          */
285         attrs->mask = 0;
286         if (iattr->ia_valid & ATTR_UID) {
287                 attrs->owner = from_kuid(current_user_ns(), iattr->ia_uid);
288                 attrs->mask |= PVFS_ATTR_SYS_UID;
289                 gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
290         }
291         if (iattr->ia_valid & ATTR_GID) {
292                 attrs->group = from_kgid(current_user_ns(), iattr->ia_gid);
293                 attrs->mask |= PVFS_ATTR_SYS_GID;
294                 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
295         }
296
297         if (iattr->ia_valid & ATTR_ATIME) {
298                 attrs->mask |= PVFS_ATTR_SYS_ATIME;
299                 if (iattr->ia_valid & ATTR_ATIME_SET) {
300                         attrs->atime =
301                             pvfs2_convert_time_field((void *)&iattr->ia_atime);
302                         attrs->mask |= PVFS_ATTR_SYS_ATIME_SET;
303                 }
304         }
305         if (iattr->ia_valid & ATTR_MTIME) {
306                 attrs->mask |= PVFS_ATTR_SYS_MTIME;
307                 if (iattr->ia_valid & ATTR_MTIME_SET) {
308                         attrs->mtime =
309                             pvfs2_convert_time_field((void *)&iattr->ia_mtime);
310                         attrs->mask |= PVFS_ATTR_SYS_MTIME_SET;
311                 }
312         }
313         if (iattr->ia_valid & ATTR_CTIME)
314                 attrs->mask |= PVFS_ATTR_SYS_CTIME;
315
316         /*
317          * PVFS2 cannot set size with a setattr operation.  Probably not likely
318          * to be requested through the VFS, but just in case, don't worry about
319          * ATTR_SIZE
320          */
321
322         if (iattr->ia_valid & ATTR_MODE) {
323                 tmp_mode = iattr->ia_mode;
324                 if (tmp_mode & (S_ISVTX)) {
325                         if (is_root_handle(inode)) {
326                                 /*
327                                  * allow sticky bit to be set on root (since
328                                  * it shows up that way by default anyhow),
329                                  * but don't show it to the server
330                                  */
331                                 tmp_mode -= S_ISVTX;
332                         } else {
333                                 gossip_debug(GOSSIP_UTILS_DEBUG,
334                                              "User attempted to set sticky bit on non-root directory; returning EINVAL.\n");
335                                 return -EINVAL;
336                         }
337                 }
338
339                 if (tmp_mode & (S_ISUID)) {
340                         gossip_debug(GOSSIP_UTILS_DEBUG,
341                                      "Attempting to set setuid bit (not supported); returning EINVAL.\n");
342                         return -EINVAL;
343                 }
344
345                 attrs->perms = PVFS_util_translate_mode(tmp_mode);
346                 attrs->mask |= PVFS_ATTR_SYS_PERM;
347         }
348
349         return 0;
350 }
351
352 /*
353  * issues a pvfs2 getattr request and fills in the appropriate inode
354  * attributes if successful.  returns 0 on success; -errno otherwise
355  */
356 int pvfs2_inode_getattr(struct inode *inode, __u32 getattr_mask)
357 {
358         struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
359         struct pvfs2_kernel_op_s *new_op;
360         int ret = -EINVAL;
361
362         gossip_debug(GOSSIP_UTILS_DEBUG,
363                      "%s: called on inode %pU\n",
364                      __func__,
365                      get_khandle_from_ino(inode));
366
367         new_op = op_alloc(PVFS2_VFS_OP_GETATTR);
368         if (!new_op)
369                 return -ENOMEM;
370         new_op->upcall.req.getattr.refn = pvfs2_inode->refn;
371         new_op->upcall.req.getattr.mask = getattr_mask;
372
373         ret = service_operation(new_op, __func__,
374                                 get_interruptible_flag(inode));
375         if (ret != 0)
376                 goto out;
377
378         if (copy_attributes_to_inode(inode,
379                         &new_op->downcall.resp.getattr.attributes,
380                         new_op->downcall.resp.getattr.link_target)) {
381                 gossip_err("%s: failed to copy attributes\n", __func__);
382                 ret = -ENOENT;
383                 goto out;
384         }
385
386         /*
387          * Store blksize in pvfs2 specific part of inode structure; we are
388          * only going to use this to report to stat to make sure it doesn't
389          * perturb any inode related code paths.
390          */
391         if (new_op->downcall.resp.getattr.attributes.objtype ==
392                         PVFS_TYPE_METAFILE) {
393                 pvfs2_inode->blksize =
394                         new_op->downcall.resp.getattr.attributes.blksize;
395         } else {
396                 /* mimic behavior of generic_fillattr() for other types. */
397                 pvfs2_inode->blksize = (1 << inode->i_blkbits);
398
399         }
400
401 out:
402         gossip_debug(GOSSIP_UTILS_DEBUG,
403                      "Getattr on handle %pU, "
404                      "fsid %d\n  (inode ct = %d) returned %d\n",
405                      &pvfs2_inode->refn.khandle,
406                      pvfs2_inode->refn.fs_id,
407                      (int)atomic_read(&inode->i_count),
408                      ret);
409
410         op_release(new_op);
411         return ret;
412 }
413
414 /*
415  * issues a pvfs2 setattr request to make sure the new attribute values
416  * take effect if successful.  returns 0 on success; -errno otherwise
417  */
418 int pvfs2_inode_setattr(struct inode *inode, struct iattr *iattr)
419 {
420         struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
421         struct pvfs2_kernel_op_s *new_op;
422         int ret;
423
424         new_op = op_alloc(PVFS2_VFS_OP_SETATTR);
425         if (!new_op)
426                 return -ENOMEM;
427
428         new_op->upcall.req.setattr.refn = pvfs2_inode->refn;
429         ret = copy_attributes_from_inode(inode,
430                        &new_op->upcall.req.setattr.attributes,
431                        iattr);
432         if (ret < 0) {
433                 op_release(new_op);
434                 return ret;
435         }
436
437         ret = service_operation(new_op, __func__,
438                                 get_interruptible_flag(inode));
439
440         gossip_debug(GOSSIP_UTILS_DEBUG,
441                      "pvfs2_inode_setattr: returning %d\n",
442                      ret);
443
444         /* when request is serviced properly, free req op struct */
445         op_release(new_op);
446
447         /*
448          * successful setattr should clear the atime, mtime and
449          * ctime flags.
450          */
451         if (ret == 0) {
452                 ClearAtimeFlag(pvfs2_inode);
453                 ClearMtimeFlag(pvfs2_inode);
454                 ClearCtimeFlag(pvfs2_inode);
455                 ClearModeFlag(pvfs2_inode);
456         }
457
458         return ret;
459 }
460
461 int pvfs2_flush_inode(struct inode *inode)
462 {
463         /*
464          * If it is a dirty inode, this function gets called.
465          * Gather all the information that needs to be setattr'ed
466          * Right now, this will only be used for mode, atime, mtime
467          * and/or ctime.
468          */
469         struct iattr wbattr;
470         int ret;
471         int mtime_flag;
472         int ctime_flag;
473         int atime_flag;
474         int mode_flag;
475         struct pvfs2_inode_s *pvfs2_inode = PVFS2_I(inode);
476
477         memset(&wbattr, 0, sizeof(wbattr));
478
479         /*
480          * check inode flags up front, and clear them if they are set.  This
481          * will prevent multiple processes from all trying to flush the same
482          * inode if they call close() simultaneously
483          */
484         mtime_flag = MtimeFlag(pvfs2_inode);
485         ClearMtimeFlag(pvfs2_inode);
486         ctime_flag = CtimeFlag(pvfs2_inode);
487         ClearCtimeFlag(pvfs2_inode);
488         atime_flag = AtimeFlag(pvfs2_inode);
489         ClearAtimeFlag(pvfs2_inode);
490         mode_flag = ModeFlag(pvfs2_inode);
491         ClearModeFlag(pvfs2_inode);
492
493         /*  -- Lazy atime,mtime and ctime update --
494          * Note: all times are dictated by server in the new scheme
495          * and not by the clients
496          *
497          * Also mode updates are being handled now..
498          */
499
500         if (mtime_flag)
501                 wbattr.ia_valid |= ATTR_MTIME;
502         if (ctime_flag)
503                 wbattr.ia_valid |= ATTR_CTIME;
504         if (atime_flag)
505                 wbattr.ia_valid |= ATTR_ATIME;
506
507         if (mode_flag) {
508                 wbattr.ia_mode = inode->i_mode;
509                 wbattr.ia_valid |= ATTR_MODE;
510         }
511
512         gossip_debug(GOSSIP_UTILS_DEBUG,
513                      "*********** pvfs2_flush_inode: %pU "
514                      "(ia_valid %d)\n",
515                      get_khandle_from_ino(inode),
516                      wbattr.ia_valid);
517         if (wbattr.ia_valid == 0) {
518                 gossip_debug(GOSSIP_UTILS_DEBUG,
519                              "pvfs2_flush_inode skipping setattr()\n");
520                 return 0;
521         }
522
523         gossip_debug(GOSSIP_UTILS_DEBUG,
524                      "pvfs2_flush_inode (%pU) writing mode %o\n",
525                      get_khandle_from_ino(inode),
526                      inode->i_mode);
527
528         ret = pvfs2_inode_setattr(inode, &wbattr);
529
530         return ret;
531 }
532
533 int pvfs2_unmount_sb(struct super_block *sb)
534 {
535         int ret = -EINVAL;
536         struct pvfs2_kernel_op_s *new_op = NULL;
537
538         gossip_debug(GOSSIP_UTILS_DEBUG,
539                      "pvfs2_unmount_sb called on sb %p\n",
540                      sb);
541
542         new_op = op_alloc(PVFS2_VFS_OP_FS_UMOUNT);
543         if (!new_op)
544                 return -ENOMEM;
545         new_op->upcall.req.fs_umount.id = PVFS2_SB(sb)->id;
546         new_op->upcall.req.fs_umount.fs_id = PVFS2_SB(sb)->fs_id;
547         strncpy(new_op->upcall.req.fs_umount.pvfs2_config_server,
548                 PVFS2_SB(sb)->devname,
549                 PVFS_MAX_SERVER_ADDR_LEN);
550
551         gossip_debug(GOSSIP_UTILS_DEBUG,
552                      "Attempting PVFS2 Unmount via host %s\n",
553                      new_op->upcall.req.fs_umount.pvfs2_config_server);
554
555         ret = service_operation(new_op, "pvfs2_fs_umount", 0);
556
557         gossip_debug(GOSSIP_UTILS_DEBUG,
558                      "pvfs2_unmount: got return value of %d\n", ret);
559         if (ret)
560                 sb = ERR_PTR(ret);
561         else
562                 PVFS2_SB(sb)->mount_pending = 1;
563
564         op_release(new_op);
565         return ret;
566 }
567
568 /*
569  * NOTE: on successful cancellation, be sure to return -EINTR, as
570  * that's the return value the caller expects
571  */
572 int pvfs2_cancel_op_in_progress(__u64 tag)
573 {
574         int ret = -EINVAL;
575         struct pvfs2_kernel_op_s *new_op = NULL;
576
577         gossip_debug(GOSSIP_UTILS_DEBUG,
578                      "pvfs2_cancel_op_in_progress called on tag %llu\n",
579                      llu(tag));
580
581         new_op = op_alloc(PVFS2_VFS_OP_CANCEL);
582         if (!new_op)
583                 return -ENOMEM;
584         new_op->upcall.req.cancel.op_tag = tag;
585
586         gossip_debug(GOSSIP_UTILS_DEBUG,
587                      "Attempting PVFS2 operation cancellation of tag %llu\n",
588                      llu(new_op->upcall.req.cancel.op_tag));
589
590         ret = service_operation(new_op, "pvfs2_cancel", PVFS2_OP_CANCELLATION);
591
592         gossip_debug(GOSSIP_UTILS_DEBUG,
593                      "pvfs2_cancel_op_in_progress: got return value of %d\n",
594                      ret);
595
596         op_release(new_op);
597         return ret;
598 }
599
600 void pvfs2_op_initialize(struct pvfs2_kernel_op_s *op)
601 {
602         if (op) {
603                 spin_lock(&op->lock);
604                 op->io_completed = 0;
605
606                 op->upcall.type = PVFS2_VFS_OP_INVALID;
607                 op->downcall.type = PVFS2_VFS_OP_INVALID;
608                 op->downcall.status = -1;
609
610                 op->op_state = OP_VFS_STATE_UNKNOWN;
611                 op->tag = 0;
612                 spin_unlock(&op->lock);
613         }
614 }
615
616 void pvfs2_make_bad_inode(struct inode *inode)
617 {
618         if (is_root_handle(inode)) {
619                 /*
620                  * if this occurs, the pvfs2-client-core was killed but we
621                  * can't afford to lose the inode operations and such
622                  * associated with the root handle in any case.
623                  */
624                 gossip_debug(GOSSIP_UTILS_DEBUG,
625                              "*** NOT making bad root inode %pU\n",
626                              get_khandle_from_ino(inode));
627         } else {
628                 gossip_debug(GOSSIP_UTILS_DEBUG,
629                              "*** making bad inode %pU\n",
630                              get_khandle_from_ino(inode));
631                 make_bad_inode(inode);
632         }
633 }
634
635 /* Block all blockable signals... */
636 void block_signals(sigset_t *orig_sigset)
637 {
638         sigset_t mask;
639
640         /*
641          * Initialize all entries in the signal set to the
642          * inverse of the given mask.
643          */
644         siginitsetinv(&mask, sigmask(SIGKILL));
645
646         /* Block 'em Danno... */
647         sigprocmask(SIG_BLOCK, &mask, orig_sigset);
648 }
649
650 /* set the signal mask to the given template... */
651 void set_signals(sigset_t *sigset)
652 {
653         sigprocmask(SIG_SETMASK, sigset, NULL);
654 }
655
656 __u64 pvfs2_convert_time_field(void *time_ptr)
657 {
658         __u64 pvfs2_time;
659         struct timespec *tspec = (struct timespec *)time_ptr;
660
661         pvfs2_time = (__u64) ((time_t) tspec->tv_sec);
662         return pvfs2_time;
663 }
664
665 /*
666  * The following is a very dirty hack that is now a permanent part of the
667  * PVFS2 protocol. See protocol.h for more error definitions.
668  */
669
670 /* The order matches include/pvfs2-types.h in the OrangeFS source. */
671 static int PINT_errno_mapping[] = {
672         0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM,
673         EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE,
674         EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG,
675         ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH,
676         EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM,
677         EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE,
678         ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE,
679         EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS,
680         ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY,
681         EACCES, ECONNRESET, ERANGE
682 };
683
684 int pvfs2_normalize_to_errno(__s32 error_code)
685 {
686         __u32 i;
687
688         /* Success */
689         if (error_code == 0) {
690                 return 0;
691         /*
692          * This shouldn't ever happen. If it does it should be fixed on the
693          * server.
694          */
695         } else if (error_code > 0) {
696                 gossip_err("pvfs2: error status receieved.\n");
697                 gossip_err("pvfs2: assuming error code is inverted.\n");
698                 error_code = -error_code;
699         }
700
701         /*
702          * XXX: This is very bad since error codes from PVFS2 may not be
703          * suitable for return into userspace.
704          */
705
706         /*
707          * Convert PVFS2 error values into errno values suitable for return
708          * from the kernel.
709          */
710         if ((-error_code) & PVFS_NON_ERRNO_ERROR_BIT) {
711                 if (((-error_code) &
712                     (PVFS_ERROR_NUMBER_BITS|PVFS_NON_ERRNO_ERROR_BIT|
713                     PVFS_ERROR_BIT)) == PVFS_ECANCEL) {
714                         /*
715                          * cancellation error codes generally correspond to
716                          * a timeout from the client's perspective
717                          */
718                         error_code = -ETIMEDOUT;
719                 } else {
720                         /* assume a default error code */
721                         gossip_err("pvfs2: warning: got error code without errno equivalent: %d.\n", error_code);
722                         error_code = -EINVAL;
723                 }
724
725         /* Convert PVFS2 encoded errno values into regular errno values. */
726         } else if ((-error_code) & PVFS_ERROR_BIT) {
727                 i = (-error_code) & ~(PVFS_ERROR_BIT|PVFS_ERROR_CLASS_BITS);
728                 if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping))
729                         error_code = -PINT_errno_mapping[i];
730                 else
731                         error_code = -EINVAL;
732
733         /*
734          * Only PVFS2 protocol error codes should ever come here. Otherwise
735          * there is a bug somewhere.
736          */
737         } else {
738                 gossip_err("pvfs2: pvfs2_normalize_to_errno: got error code which is not from PVFS2.\n");
739         }
740         return error_code;
741 }
742
743 #define NUM_MODES 11
744 __s32 PVFS_util_translate_mode(int mode)
745 {
746         int ret = 0;
747         int i = 0;
748         static int modes[NUM_MODES] = {
749                 S_IXOTH, S_IWOTH, S_IROTH,
750                 S_IXGRP, S_IWGRP, S_IRGRP,
751                 S_IXUSR, S_IWUSR, S_IRUSR,
752                 S_ISGID, S_ISUID
753         };
754         static int pvfs2_modes[NUM_MODES] = {
755                 PVFS_O_EXECUTE, PVFS_O_WRITE, PVFS_O_READ,
756                 PVFS_G_EXECUTE, PVFS_G_WRITE, PVFS_G_READ,
757                 PVFS_U_EXECUTE, PVFS_U_WRITE, PVFS_U_READ,
758                 PVFS_G_SGID, PVFS_U_SUID
759         };
760
761         for (i = 0; i < NUM_MODES; i++)
762                 if (mode & modes[i])
763                         ret |= pvfs2_modes[i];
764
765         return ret;
766 }
767 #undef NUM_MODES
768
769 /*
770  * After obtaining a string representation of the client's debug
771  * keywords and their associated masks, this function is called to build an
772  * array of these values.
773  */
774 int orangefs_prepare_cdm_array(char *debug_array_string)
775 {
776         int i;
777         int rc = -EINVAL;
778         char *cds_head = NULL;
779         char *cds_delimiter = NULL;
780         int keyword_len = 0;
781
782         gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
783
784         /*
785          * figure out how many elements the cdm_array needs.
786          */
787         for (i = 0; i < strlen(debug_array_string); i++)
788                 if (debug_array_string[i] == '\n')
789                         cdm_element_count++;
790
791         if (!cdm_element_count) {
792                 pr_info("No elements in client debug array string!\n");
793                 goto out;
794         }
795
796         cdm_array =
797                 kzalloc(cdm_element_count * sizeof(struct client_debug_mask),
798                         GFP_KERNEL);
799         if (!cdm_array) {
800                 pr_info("malloc failed for cdm_array!\n");
801                 rc = -ENOMEM;
802                 goto out;
803         }
804
805         cds_head = debug_array_string;
806
807         for (i = 0; i < cdm_element_count; i++) {
808                 cds_delimiter = strchr(cds_head, '\n');
809                 *cds_delimiter = '\0';
810
811                 keyword_len = strcspn(cds_head, " ");
812
813                 cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL);
814                 if (!cdm_array[i].keyword) {
815                         rc = -ENOMEM;
816                         goto out;
817                 }
818
819                 sscanf(cds_head,
820                        "%s %llx %llx",
821                        cdm_array[i].keyword,
822                        (unsigned long long *)&(cdm_array[i].mask1),
823                        (unsigned long long *)&(cdm_array[i].mask2));
824
825                 if (!strcmp(cdm_array[i].keyword, PVFS2_VERBOSE))
826                         client_verbose_index = i;
827
828                 if (!strcmp(cdm_array[i].keyword, PVFS2_ALL))
829                         client_all_index = i;
830
831                 cds_head = cds_delimiter + 1;
832         }
833
834         rc = cdm_element_count;
835
836         gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc);
837
838 out:
839
840         return rc;
841
842 }
843
844 /*
845  * /sys/kernel/debug/orangefs/debug-help can be catted to
846  * see all the available kernel and client debug keywords.
847  *
848  * When the kernel boots, we have no idea what keywords the
849  * client supports, nor their associated masks.
850  *
851  * We pass through this function once at boot and stamp a
852  * boilerplate "we don't know" message for the client in the
853  * debug-help file. We pass through here again when the client
854  * starts and then we can fill out the debug-help file fully.
855  *
856  * The client might be restarted any number of times between
857  * reboots, we only build the debug-help file the first time.
858  */
859 int orangefs_prepare_debugfs_help_string(int at_boot)
860 {
861         int rc = -EINVAL;
862         int i;
863         int byte_count = 0;
864         char *client_title = "Client Debug Keywords:\n";
865         char *kernel_title = "Kernel Debug Keywords:\n";
866
867         gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
868
869         if (at_boot) {
870                 byte_count += strlen(HELP_STRING_UNINITIALIZED);
871                 client_title = HELP_STRING_UNINITIALIZED;
872         } else {
873                 /*
874                  * fill the client keyword/mask array and remember
875                  * how many elements there were.
876                  */
877                 cdm_element_count =
878                         orangefs_prepare_cdm_array(client_debug_array_string);
879                 if (cdm_element_count <= 0)
880                         goto out;
881
882                 /* Count the bytes destined for debug_help_string. */
883                 byte_count += strlen(client_title);
884
885                 for (i = 0; i < cdm_element_count; i++) {
886                         byte_count += strlen(cdm_array[i].keyword + 2);
887                         if (byte_count >= DEBUG_HELP_STRING_SIZE) {
888                                 pr_info("%s: overflow 1!\n", __func__);
889                                 goto out;
890                         }
891                 }
892
893                 gossip_debug(GOSSIP_UTILS_DEBUG,
894                              "%s: cdm_element_count:%d:\n",
895                              __func__,
896                              cdm_element_count);
897         }
898
899         byte_count += strlen(kernel_title);
900         for (i = 0; i < num_kmod_keyword_mask_map; i++) {
901                 byte_count +=
902                         strlen(s_kmod_keyword_mask_map[i].keyword + 2);
903                 if (byte_count >= DEBUG_HELP_STRING_SIZE) {
904                         pr_info("%s: overflow 2!\n", __func__);
905                         goto out;
906                 }
907         }
908
909         /* build debug_help_string. */
910         debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL);
911         if (!debug_help_string) {
912                 rc = -ENOMEM;
913                 goto out;
914         }
915
916         strcat(debug_help_string, client_title);
917
918         if (!at_boot) {
919                 for (i = 0; i < cdm_element_count; i++) {
920                         strcat(debug_help_string, "\t");
921                         strcat(debug_help_string, cdm_array[i].keyword);
922                         strcat(debug_help_string, "\n");
923                 }
924         }
925
926         strcat(debug_help_string, "\n");
927         strcat(debug_help_string, kernel_title);
928
929         for (i = 0; i < num_kmod_keyword_mask_map; i++) {
930                 strcat(debug_help_string, "\t");
931                 strcat(debug_help_string, s_kmod_keyword_mask_map[i].keyword);
932                 strcat(debug_help_string, "\n");
933         }
934
935         rc = 0;
936
937 out:
938
939         return rc;
940
941 }
942
943 /*
944  * kernel = type 0
945  * client = type 1
946  */
947 void debug_mask_to_string(void *mask, int type)
948 {
949         int i;
950         int len = 0;
951         char *debug_string;
952         int element_count = 0;
953
954         gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
955
956         if (type) {
957                 debug_string = client_debug_string;
958                 element_count = cdm_element_count;
959         } else {
960                 debug_string = kernel_debug_string;
961                 element_count = num_kmod_keyword_mask_map;
962         }
963
964         memset(debug_string, 0, PVFS2_MAX_DEBUG_STRING_LEN);
965
966         /*
967          * Some keywords, like "all" or "verbose", are amalgams of
968          * numerous other keywords. Make a special check for those
969          * before grinding through the whole mask only to find out
970          * later...
971          */
972         if (check_amalgam_keyword(mask, type))
973                 goto out;
974
975         /* Build the debug string. */
976         for (i = 0; i < element_count; i++)
977                 if (type)
978                         do_c_string(mask, i);
979                 else
980                         do_k_string(mask, i);
981
982         len = strlen(debug_string);
983
984         if ((len) && (type))
985                 client_debug_string[len - 1] = '\0';
986         else if (len)
987                 kernel_debug_string[len - 1] = '\0';
988         else if (type)
989                 strcpy(client_debug_string, "none");
990         else
991                 strcpy(kernel_debug_string, "none");
992
993 out:
994 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string);
995
996         return;
997
998 }
999
1000 void do_k_string(void *k_mask, int index)
1001 {
1002         __u64 *mask = (__u64 *) k_mask;
1003
1004         if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword))
1005                 goto out;
1006
1007         if (*mask & s_kmod_keyword_mask_map[index].mask_val) {
1008                 if ((strlen(kernel_debug_string) +
1009                      strlen(s_kmod_keyword_mask_map[index].keyword))
1010                         < PVFS2_MAX_DEBUG_STRING_LEN - 1) {
1011                                 strcat(kernel_debug_string,
1012                                        s_kmod_keyword_mask_map[index].keyword);
1013                                 strcat(kernel_debug_string, ",");
1014                         } else {
1015                                 gossip_err("%s: overflow!\n", __func__);
1016                                 strcpy(kernel_debug_string, PVFS2_ALL);
1017                                 goto out;
1018                         }
1019         }
1020
1021 out:
1022
1023         return;
1024 }
1025
1026 void do_c_string(void *c_mask, int index)
1027 {
1028         struct client_debug_mask *mask = (struct client_debug_mask *) c_mask;
1029
1030         if (keyword_is_amalgam(cdm_array[index].keyword))
1031                 goto out;
1032
1033         if ((mask->mask1 & cdm_array[index].mask1) ||
1034             (mask->mask2 & cdm_array[index].mask2)) {
1035                 if ((strlen(client_debug_string) +
1036                      strlen(cdm_array[index].keyword) + 1)
1037                         < PVFS2_MAX_DEBUG_STRING_LEN - 2) {
1038                                 strcat(client_debug_string,
1039                                        cdm_array[index].keyword);
1040                                 strcat(client_debug_string, ",");
1041                         } else {
1042                                 gossip_err("%s: overflow!\n", __func__);
1043                                 strcpy(client_debug_string, PVFS2_ALL);
1044                                 goto out;
1045                         }
1046         }
1047 out:
1048         return;
1049 }
1050
1051 int keyword_is_amalgam(char *keyword)
1052 {
1053         int rc = 0;
1054
1055         if ((!strcmp(keyword, PVFS2_ALL)) || (!strcmp(keyword, PVFS2_VERBOSE)))
1056                 rc = 1;
1057
1058         return rc;
1059 }
1060
1061 /*
1062  * kernel = type 0
1063  * client = type 1
1064  *
1065  * return 1 if we found an amalgam.
1066  */
1067 int check_amalgam_keyword(void *mask, int type)
1068 {
1069         __u64 *k_mask;
1070         struct client_debug_mask *c_mask;
1071         int k_all_index = num_kmod_keyword_mask_map - 1;
1072         int rc = 0;
1073
1074         if (type) {
1075                 c_mask = (struct client_debug_mask *) mask;
1076
1077                 if ((c_mask->mask1 == cdm_array[client_all_index].mask1) &&
1078                     (c_mask->mask2 == cdm_array[client_all_index].mask2)) {
1079                         strcpy(client_debug_string, PVFS2_ALL);
1080                         rc = 1;
1081                         goto out;
1082                 }
1083
1084                 if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) &&
1085                     (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) {
1086                         strcpy(client_debug_string, PVFS2_VERBOSE);
1087                         rc = 1;
1088                         goto out;
1089                 }
1090
1091         } else {
1092                 k_mask = (__u64 *) mask;
1093
1094                 if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) {
1095                         strcpy(kernel_debug_string, PVFS2_ALL);
1096                         rc = 1;
1097                         goto out;
1098                 }
1099         }
1100
1101 out:
1102
1103         return rc;
1104 }
1105
1106 /*
1107  * kernel = type 0
1108  * client = type 1
1109  */
1110 void debug_string_to_mask(char *debug_string, void *mask, int type)
1111 {
1112         char *unchecked_keyword;
1113         int i;
1114         char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL);
1115         char *original_pointer;
1116         int element_count = 0;
1117         struct client_debug_mask *c_mask;
1118         __u64 *k_mask;
1119
1120         gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
1121
1122         if (type) {
1123                 c_mask = (struct client_debug_mask *)mask;
1124                 element_count = cdm_element_count;
1125         } else {
1126                 k_mask = (__u64 *)mask;
1127                 *k_mask = 0;
1128                 element_count = num_kmod_keyword_mask_map;
1129         }
1130
1131         original_pointer = strsep_fodder;
1132         while ((unchecked_keyword = strsep(&strsep_fodder, ",")))
1133                 if (strlen(unchecked_keyword)) {
1134                         for (i = 0; i < element_count; i++)
1135                                 if (type)
1136                                         do_c_mask(i,
1137                                                   unchecked_keyword,
1138                                                   &c_mask);
1139                                 else
1140                                         do_k_mask(i,
1141                                                   unchecked_keyword,
1142                                                   &k_mask);
1143                 }
1144
1145         kfree(original_pointer);
1146 }
1147
1148 void do_c_mask(int i,
1149                char *unchecked_keyword,
1150                struct client_debug_mask **sane_mask)
1151 {
1152
1153         if (!strcmp(cdm_array[i].keyword, unchecked_keyword)) {
1154                 (**sane_mask).mask1 = (**sane_mask).mask1 | cdm_array[i].mask1;
1155                 (**sane_mask).mask2 = (**sane_mask).mask2 | cdm_array[i].mask2;
1156         }
1157 }
1158
1159 void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask)
1160 {
1161
1162         if (!strcmp(s_kmod_keyword_mask_map[i].keyword, unchecked_keyword))
1163                 **sane_mask = (**sane_mask) |
1164                                 s_kmod_keyword_mask_map[i].mask_val;
1165 }