0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "protocol.h"
0012 #include "orangefs-kernel.h"
0013 #include "orangefs-dev-proto.h"
0014 #include "orangefs-bufmap.h"
0015 #include "orangefs-debugfs.h"
0016
0017 #include <linux/debugfs.h>
0018 #include <linux/slab.h>
0019
0020
0021
0022 uint32_t orangefs_userspace_version;
0023
0024 static int open_access_count;
0025
0026 static DEFINE_MUTEX(devreq_mutex);
0027
0028 #define DUMP_DEVICE_ERROR() \
0029 do { \
0030 gossip_err("*****************************************************\n");\
0031 gossip_err("ORANGEFS Device Error: You cannot open the device file "); \
0032 gossip_err("\n/dev/%s more than once. Please make sure that\nthere " \
0033 "are no ", ORANGEFS_REQDEVICE_NAME); \
0034 gossip_err("instances of a program using this device\ncurrently " \
0035 "running. (You must verify this!)\n"); \
0036 gossip_err("For example, you can use the lsof program as follows:\n");\
0037 gossip_err("'lsof | grep %s' (run this as root)\n", \
0038 ORANGEFS_REQDEVICE_NAME); \
0039 gossip_err(" open_access_count = %d\n", open_access_count); \
0040 gossip_err("*****************************************************\n");\
0041 } while (0)
0042
0043 static int hash_func(__u64 tag, int table_size)
0044 {
0045 return do_div(tag, (unsigned int)table_size);
0046 }
0047
0048 static void orangefs_devreq_add_op(struct orangefs_kernel_op_s *op)
0049 {
0050 int index = hash_func(op->tag, hash_table_size);
0051
0052 list_add_tail(&op->list, &orangefs_htable_ops_in_progress[index]);
0053 }
0054
0055
0056
0057
0058
0059 static struct orangefs_kernel_op_s *orangefs_devreq_remove_op(__u64 tag)
0060 {
0061 struct orangefs_kernel_op_s *op, *next;
0062 int index;
0063
0064 index = hash_func(tag, hash_table_size);
0065
0066 spin_lock(&orangefs_htable_ops_in_progress_lock);
0067 list_for_each_entry_safe(op,
0068 next,
0069 &orangefs_htable_ops_in_progress[index],
0070 list) {
0071 if (op->tag == tag && !op_state_purged(op) &&
0072 !op_state_given_up(op)) {
0073 list_del_init(&op->list);
0074 spin_unlock(&orangefs_htable_ops_in_progress_lock);
0075 return op;
0076 }
0077 }
0078
0079 spin_unlock(&orangefs_htable_ops_in_progress_lock);
0080 return NULL;
0081 }
0082
0083
0084 static int mark_all_pending_mounts(void)
0085 {
0086 int unmounted = 1;
0087 struct orangefs_sb_info_s *orangefs_sb = NULL;
0088
0089 spin_lock(&orangefs_superblocks_lock);
0090 list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
0091
0092 orangefs_sb->mount_pending = 1;
0093 unmounted = 0;
0094 }
0095 spin_unlock(&orangefs_superblocks_lock);
0096 return unmounted;
0097 }
0098
0099
0100
0101
0102
0103
0104
0105 static int fs_mount_pending(__s32 fsid)
0106 {
0107 int mount_pending = -1;
0108 struct orangefs_sb_info_s *orangefs_sb = NULL;
0109
0110 spin_lock(&orangefs_superblocks_lock);
0111 list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
0112 if (orangefs_sb->fs_id == fsid) {
0113 mount_pending = orangefs_sb->mount_pending;
0114 break;
0115 }
0116 }
0117 spin_unlock(&orangefs_superblocks_lock);
0118 return mount_pending;
0119 }
0120
0121 static int orangefs_devreq_open(struct inode *inode, struct file *file)
0122 {
0123 int ret = -EINVAL;
0124
0125
0126 if (file->f_cred->user_ns != &init_user_ns) {
0127 gossip_err("%s: device cannot be opened outside init_user_ns\n",
0128 __func__);
0129 goto out;
0130 }
0131
0132 if (!(file->f_flags & O_NONBLOCK)) {
0133 gossip_err("%s: device cannot be opened in blocking mode\n",
0134 __func__);
0135 goto out;
0136 }
0137 ret = -EACCES;
0138 gossip_debug(GOSSIP_DEV_DEBUG, "client-core: opening device\n");
0139 mutex_lock(&devreq_mutex);
0140
0141 if (open_access_count == 0) {
0142 open_access_count = 1;
0143 ret = 0;
0144 } else {
0145 DUMP_DEVICE_ERROR();
0146 }
0147 mutex_unlock(&devreq_mutex);
0148
0149 out:
0150
0151 gossip_debug(GOSSIP_DEV_DEBUG,
0152 "pvfs2-client-core: open device complete (ret = %d)\n",
0153 ret);
0154 return ret;
0155 }
0156
0157
0158 static ssize_t orangefs_devreq_read(struct file *file,
0159 char __user *buf,
0160 size_t count, loff_t *offset)
0161 {
0162 struct orangefs_kernel_op_s *op, *temp;
0163 __s32 proto_ver = ORANGEFS_KERNEL_PROTO_VERSION;
0164 static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
0165 struct orangefs_kernel_op_s *cur_op;
0166 unsigned long ret;
0167
0168
0169 if (!(file->f_flags & O_NONBLOCK)) {
0170 gossip_err("%s: blocking read from client-core.\n",
0171 __func__);
0172 return -EINVAL;
0173 }
0174
0175
0176
0177
0178
0179 if (count != MAX_DEV_REQ_UPSIZE) {
0180 gossip_err("orangefs: client-core tried to read wrong size\n");
0181 return -EINVAL;
0182 }
0183
0184
0185 if (list_empty(&orangefs_request_list))
0186 return -EAGAIN;
0187
0188 restart:
0189 cur_op = NULL;
0190
0191 spin_lock(&orangefs_request_list_lock);
0192 list_for_each_entry_safe(op, temp, &orangefs_request_list, list) {
0193 __s32 fsid;
0194
0195 spin_lock(&op->lock);
0196 if (unlikely(op_state_purged(op) || op_state_given_up(op))) {
0197 spin_unlock(&op->lock);
0198 continue;
0199 }
0200
0201 fsid = fsid_of_op(op);
0202 if (fsid != ORANGEFS_FS_ID_NULL) {
0203 int ret;
0204
0205 ret = fs_mount_pending(fsid);
0206 if (ret == 1) {
0207 gossip_debug(GOSSIP_DEV_DEBUG,
0208 "%s: mount pending, skipping op tag "
0209 "%llu %s\n",
0210 __func__,
0211 llu(op->tag),
0212 get_opname_string(op));
0213 spin_unlock(&op->lock);
0214 continue;
0215
0216
0217
0218
0219
0220
0221
0222
0223 } else if (ret == -1 &&
0224 !(op->upcall.type ==
0225 ORANGEFS_VFS_OP_FS_MOUNT ||
0226 op->upcall.type ==
0227 ORANGEFS_VFS_OP_GETATTR ||
0228 op->upcall.type ==
0229 ORANGEFS_VFS_OP_FS_UMOUNT)) {
0230 gossip_debug(GOSSIP_DEV_DEBUG,
0231 "orangefs: skipping op tag %llu %s\n",
0232 llu(op->tag), get_opname_string(op));
0233 gossip_err(
0234 "orangefs: ERROR: fs_mount_pending %d\n",
0235 fsid);
0236 spin_unlock(&op->lock);
0237 continue;
0238 }
0239 }
0240
0241
0242
0243
0244
0245 cur_op = op;
0246 break;
0247 }
0248
0249
0250
0251
0252
0253 if (!cur_op) {
0254 spin_unlock(&orangefs_request_list_lock);
0255 return -EAGAIN;
0256 }
0257
0258 gossip_debug(GOSSIP_DEV_DEBUG, "%s: reading op tag %llu %s\n",
0259 __func__,
0260 llu(cur_op->tag),
0261 get_opname_string(cur_op));
0262
0263
0264
0265
0266
0267 if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) {
0268 gossip_err("orangefs: ERROR: Current op already queued.\n");
0269 list_del_init(&cur_op->list);
0270 spin_unlock(&cur_op->lock);
0271 spin_unlock(&orangefs_request_list_lock);
0272 return -EAGAIN;
0273 }
0274
0275 list_del_init(&cur_op->list);
0276 spin_unlock(&orangefs_request_list_lock);
0277
0278 spin_unlock(&cur_op->lock);
0279
0280
0281 ret = copy_to_user(buf, &proto_ver, sizeof(__s32));
0282 if (ret != 0)
0283 goto error;
0284 ret = copy_to_user(buf + sizeof(__s32), &magic, sizeof(__s32));
0285 if (ret != 0)
0286 goto error;
0287 ret = copy_to_user(buf + 2 * sizeof(__s32),
0288 &cur_op->tag,
0289 sizeof(__u64));
0290 if (ret != 0)
0291 goto error;
0292 ret = copy_to_user(buf + 2 * sizeof(__s32) + sizeof(__u64),
0293 &cur_op->upcall,
0294 sizeof(struct orangefs_upcall_s));
0295 if (ret != 0)
0296 goto error;
0297
0298 spin_lock(&orangefs_htable_ops_in_progress_lock);
0299 spin_lock(&cur_op->lock);
0300 if (unlikely(op_state_given_up(cur_op))) {
0301 spin_unlock(&cur_op->lock);
0302 spin_unlock(&orangefs_htable_ops_in_progress_lock);
0303 complete(&cur_op->waitq);
0304 goto restart;
0305 }
0306
0307
0308
0309
0310
0311 set_op_state_inprogress(cur_op);
0312 gossip_debug(GOSSIP_DEV_DEBUG,
0313 "%s: 1 op:%s: op_state:%d: process:%s:\n",
0314 __func__,
0315 get_opname_string(cur_op),
0316 cur_op->op_state,
0317 current->comm);
0318 orangefs_devreq_add_op(cur_op);
0319 spin_unlock(&cur_op->lock);
0320 spin_unlock(&orangefs_htable_ops_in_progress_lock);
0321
0322
0323 return MAX_DEV_REQ_UPSIZE;
0324 error:
0325
0326
0327
0328
0329
0330 gossip_err("orangefs: Failed to copy data to user space\n");
0331 spin_lock(&orangefs_request_list_lock);
0332 spin_lock(&cur_op->lock);
0333 if (likely(!op_state_given_up(cur_op))) {
0334 set_op_state_waiting(cur_op);
0335 gossip_debug(GOSSIP_DEV_DEBUG,
0336 "%s: 2 op:%s: op_state:%d: process:%s:\n",
0337 __func__,
0338 get_opname_string(cur_op),
0339 cur_op->op_state,
0340 current->comm);
0341 list_add(&cur_op->list, &orangefs_request_list);
0342 spin_unlock(&cur_op->lock);
0343 } else {
0344 spin_unlock(&cur_op->lock);
0345 complete(&cur_op->waitq);
0346 }
0347 spin_unlock(&orangefs_request_list_lock);
0348 return -EFAULT;
0349 }
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361 static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
0362 struct iov_iter *iter)
0363 {
0364 ssize_t ret;
0365 struct orangefs_kernel_op_s *op = NULL;
0366 struct {
0367 __u32 version;
0368 __u32 magic;
0369 __u64 tag;
0370 } head;
0371 int total = ret = iov_iter_count(iter);
0372 int downcall_size = sizeof(struct orangefs_downcall_s);
0373 int head_size = sizeof(head);
0374
0375 gossip_debug(GOSSIP_DEV_DEBUG, "%s: total:%d: ret:%zd:\n",
0376 __func__,
0377 total,
0378 ret);
0379
0380 if (total < MAX_DEV_REQ_DOWNSIZE) {
0381 gossip_err("%s: total:%d: must be at least:%u:\n",
0382 __func__,
0383 total,
0384 (unsigned int) MAX_DEV_REQ_DOWNSIZE);
0385 return -EFAULT;
0386 }
0387
0388 if (!copy_from_iter_full(&head, head_size, iter)) {
0389 gossip_err("%s: failed to copy head.\n", __func__);
0390 return -EFAULT;
0391 }
0392
0393 if (head.version < ORANGEFS_MINIMUM_USERSPACE_VERSION) {
0394 gossip_err("%s: userspace claims version"
0395 "%d, minimum version required: %d.\n",
0396 __func__,
0397 head.version,
0398 ORANGEFS_MINIMUM_USERSPACE_VERSION);
0399 return -EPROTO;
0400 }
0401
0402 if (head.magic != ORANGEFS_DEVREQ_MAGIC) {
0403 gossip_err("Error: Device magic number does not match.\n");
0404 return -EPROTO;
0405 }
0406
0407 if (!orangefs_userspace_version) {
0408 orangefs_userspace_version = head.version;
0409 } else if (orangefs_userspace_version != head.version) {
0410 gossip_err("Error: userspace version changes\n");
0411 return -EPROTO;
0412 }
0413
0414
0415 op = orangefs_devreq_remove_op(head.tag);
0416 if (!op) {
0417 gossip_debug(GOSSIP_DEV_DEBUG,
0418 "%s: No one's waiting for tag %llu\n",
0419 __func__, llu(head.tag));
0420 return ret;
0421 }
0422
0423 if (!copy_from_iter_full(&op->downcall, downcall_size, iter)) {
0424 gossip_err("%s: failed to copy downcall.\n", __func__);
0425 goto Efault;
0426 }
0427
0428 if (op->downcall.status)
0429 goto wakeup;
0430
0431
0432
0433
0434
0435
0436 if ((head_size + downcall_size + op->downcall.trailer_size) != total) {
0437 gossip_err("%s: funky write, head_size:%d"
0438 ": downcall_size:%d: trailer_size:%lld"
0439 ": total size:%d:\n",
0440 __func__,
0441 head_size,
0442 downcall_size,
0443 op->downcall.trailer_size,
0444 total);
0445 goto Efault;
0446 }
0447
0448
0449 if ((op->downcall.type != ORANGEFS_VFS_OP_READDIR) &&
0450 (op->downcall.trailer_size != 0)) {
0451 gossip_err("%s: %x operation with trailer.",
0452 __func__,
0453 op->downcall.type);
0454 goto Efault;
0455 }
0456
0457
0458 if ((op->downcall.type == ORANGEFS_VFS_OP_READDIR) &&
0459 (op->downcall.trailer_size == 0)) {
0460 gossip_err("%s: %x operation with no trailer.",
0461 __func__,
0462 op->downcall.type);
0463 goto Efault;
0464 }
0465
0466 if (op->downcall.type != ORANGEFS_VFS_OP_READDIR)
0467 goto wakeup;
0468
0469 op->downcall.trailer_buf = vzalloc(op->downcall.trailer_size);
0470 if (!op->downcall.trailer_buf)
0471 goto Enomem;
0472
0473 if (!copy_from_iter_full(op->downcall.trailer_buf,
0474 op->downcall.trailer_size, iter)) {
0475 gossip_err("%s: failed to copy trailer.\n", __func__);
0476 vfree(op->downcall.trailer_buf);
0477 goto Efault;
0478 }
0479
0480 wakeup:
0481
0482
0483
0484
0485 spin_lock(&op->lock);
0486 if (unlikely(op_is_cancel(op))) {
0487 spin_unlock(&op->lock);
0488 put_cancel(op);
0489 } else if (unlikely(op_state_given_up(op))) {
0490 spin_unlock(&op->lock);
0491 complete(&op->waitq);
0492 } else {
0493 set_op_state_serviced(op);
0494 gossip_debug(GOSSIP_DEV_DEBUG,
0495 "%s: op:%s: op_state:%d: process:%s:\n",
0496 __func__,
0497 get_opname_string(op),
0498 op->op_state,
0499 current->comm);
0500 spin_unlock(&op->lock);
0501 }
0502 return ret;
0503
0504 Efault:
0505 op->downcall.status = -(ORANGEFS_ERROR_BIT | 9);
0506 ret = -EFAULT;
0507 goto wakeup;
0508
0509 Enomem:
0510 op->downcall.status = -(ORANGEFS_ERROR_BIT | 8);
0511 ret = -ENOMEM;
0512 goto wakeup;
0513 }
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523 static int orangefs_devreq_release(struct inode *inode, struct file *file)
0524 {
0525 int unmounted = 0;
0526
0527 gossip_debug(GOSSIP_DEV_DEBUG,
0528 "%s:pvfs2-client-core: exiting, closing device\n",
0529 __func__);
0530
0531 mutex_lock(&devreq_mutex);
0532 orangefs_bufmap_finalize();
0533
0534 open_access_count = -1;
0535
0536 unmounted = mark_all_pending_mounts();
0537 gossip_debug(GOSSIP_DEV_DEBUG, "ORANGEFS Device Close: Filesystem(s) %s\n",
0538 (unmounted ? "UNMOUNTED" : "MOUNTED"));
0539
0540 purge_waiting_ops();
0541 purge_inprogress_ops();
0542
0543 orangefs_bufmap_run_down();
0544
0545 gossip_debug(GOSSIP_DEV_DEBUG,
0546 "pvfs2-client-core: device close complete\n");
0547 open_access_count = 0;
0548 orangefs_userspace_version = 0;
0549 mutex_unlock(&devreq_mutex);
0550 return 0;
0551 }
0552
0553 int is_daemon_in_service(void)
0554 {
0555 int in_service;
0556
0557
0558
0559
0560
0561 mutex_lock(&devreq_mutex);
0562 in_service = open_access_count == 1 ? 0 : -EIO;
0563 mutex_unlock(&devreq_mutex);
0564 return in_service;
0565 }
0566
0567 bool __is_daemon_in_service(void)
0568 {
0569 return open_access_count == 1;
0570 }
0571
0572 static inline long check_ioctl_command(unsigned int command)
0573 {
0574
0575 if (_IOC_TYPE(command) != ORANGEFS_DEV_MAGIC) {
0576 gossip_err("device ioctl magic numbers don't match! Did you rebuild pvfs2-client-core/libpvfs2? [cmd %x, magic %x != %x]\n",
0577 command,
0578 _IOC_TYPE(command),
0579 ORANGEFS_DEV_MAGIC);
0580 return -EINVAL;
0581 }
0582
0583 if (_IOC_NR(command) >= ORANGEFS_DEV_MAXNR || _IOC_NR(command) <= 0) {
0584 gossip_err("Invalid ioctl command number [%d >= %d]\n",
0585 _IOC_NR(command), ORANGEFS_DEV_MAXNR);
0586 return -ENOIOCTLCMD;
0587 }
0588 return 0;
0589 }
0590
0591 static long dispatch_ioctl_command(unsigned int command, unsigned long arg)
0592 {
0593 static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
0594 static __s32 max_up_size = MAX_DEV_REQ_UPSIZE;
0595 static __s32 max_down_size = MAX_DEV_REQ_DOWNSIZE;
0596 struct ORANGEFS_dev_map_desc user_desc;
0597 int ret = 0;
0598 int upstream_kmod = 1;
0599 struct orangefs_sb_info_s *orangefs_sb;
0600
0601
0602
0603 switch (command) {
0604 case ORANGEFS_DEV_GET_MAGIC:
0605 return ((put_user(magic, (__s32 __user *) arg) == -EFAULT) ?
0606 -EIO :
0607 0);
0608 case ORANGEFS_DEV_GET_MAX_UPSIZE:
0609 return ((put_user(max_up_size,
0610 (__s32 __user *) arg) == -EFAULT) ?
0611 -EIO :
0612 0);
0613 case ORANGEFS_DEV_GET_MAX_DOWNSIZE:
0614 return ((put_user(max_down_size,
0615 (__s32 __user *) arg) == -EFAULT) ?
0616 -EIO :
0617 0);
0618 case ORANGEFS_DEV_MAP:
0619 ret = copy_from_user(&user_desc,
0620 (struct ORANGEFS_dev_map_desc __user *)
0621 arg,
0622 sizeof(struct ORANGEFS_dev_map_desc));
0623
0624 return ret ? -EIO : orangefs_bufmap_initialize(&user_desc);
0625 case ORANGEFS_DEV_REMOUNT_ALL:
0626 gossip_debug(GOSSIP_DEV_DEBUG,
0627 "%s: got ORANGEFS_DEV_REMOUNT_ALL\n",
0628 __func__);
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639 ret = mutex_lock_interruptible(&orangefs_request_mutex);
0640 if (ret < 0)
0641 return ret;
0642 gossip_debug(GOSSIP_DEV_DEBUG,
0643 "%s: priority remount in progress\n",
0644 __func__);
0645 spin_lock(&orangefs_superblocks_lock);
0646 list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
0647
0648
0649
0650
0651
0652
0653 if (!orangefs_sb->list.prev)
0654 continue;
0655 gossip_debug(GOSSIP_DEV_DEBUG,
0656 "%s: Remounting SB %p\n",
0657 __func__,
0658 orangefs_sb);
0659
0660 spin_unlock(&orangefs_superblocks_lock);
0661 ret = orangefs_remount(orangefs_sb);
0662 spin_lock(&orangefs_superblocks_lock);
0663 if (ret) {
0664 gossip_debug(GOSSIP_DEV_DEBUG,
0665 "SB %p remount failed\n",
0666 orangefs_sb);
0667 break;
0668 }
0669 }
0670 spin_unlock(&orangefs_superblocks_lock);
0671 gossip_debug(GOSSIP_DEV_DEBUG,
0672 "%s: priority remount complete\n",
0673 __func__);
0674 mutex_unlock(&orangefs_request_mutex);
0675 return ret;
0676
0677 case ORANGEFS_DEV_UPSTREAM:
0678 ret = copy_to_user((void __user *)arg,
0679 &upstream_kmod,
0680 sizeof(upstream_kmod));
0681
0682 if (ret != 0)
0683 return -EIO;
0684 else
0685 return ret;
0686
0687 case ORANGEFS_DEV_CLIENT_MASK:
0688 return orangefs_debugfs_new_client_mask((void __user *)arg);
0689 case ORANGEFS_DEV_CLIENT_STRING:
0690 return orangefs_debugfs_new_client_string((void __user *)arg);
0691 case ORANGEFS_DEV_DEBUG:
0692 return orangefs_debugfs_new_debug((void __user *)arg);
0693 default:
0694 return -ENOIOCTLCMD;
0695 }
0696 return -ENOIOCTLCMD;
0697 }
0698
0699 static long orangefs_devreq_ioctl(struct file *file,
0700 unsigned int command, unsigned long arg)
0701 {
0702 long ret;
0703
0704
0705 ret = check_ioctl_command(command);
0706 if (ret < 0)
0707 return (int)ret;
0708
0709 return (int)dispatch_ioctl_command(command, arg);
0710 }
0711
0712 #ifdef CONFIG_COMPAT
0713
0714
0715 struct ORANGEFS_dev_map_desc32 {
0716 compat_uptr_t ptr;
0717 __s32 total_size;
0718 __s32 size;
0719 __s32 count;
0720 };
0721
0722
0723
0724
0725
0726 static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd,
0727 unsigned long args)
0728 {
0729 long ret;
0730
0731
0732 ret = check_ioctl_command(cmd);
0733 if (ret < 0)
0734 return ret;
0735 if (cmd == ORANGEFS_DEV_MAP) {
0736 struct ORANGEFS_dev_map_desc desc;
0737 struct ORANGEFS_dev_map_desc32 d32;
0738
0739 if (copy_from_user(&d32, (void __user *)args, sizeof(d32)))
0740 return -EFAULT;
0741
0742 desc.ptr = compat_ptr(d32.ptr);
0743 desc.total_size = d32.total_size;
0744 desc.size = d32.size;
0745 desc.count = d32.count;
0746 return orangefs_bufmap_initialize(&desc);
0747 }
0748
0749 return dispatch_ioctl_command(cmd, args);
0750 }
0751
0752 #endif
0753
0754 static __poll_t orangefs_devreq_poll(struct file *file,
0755 struct poll_table_struct *poll_table)
0756 {
0757 __poll_t poll_revent_mask = 0;
0758
0759 poll_wait(file, &orangefs_request_list_waitq, poll_table);
0760
0761 if (!list_empty(&orangefs_request_list))
0762 poll_revent_mask |= EPOLLIN;
0763 return poll_revent_mask;
0764 }
0765
0766
0767 static int orangefs_dev_major;
0768
0769 static const struct file_operations orangefs_devreq_file_operations = {
0770 .owner = THIS_MODULE,
0771 .read = orangefs_devreq_read,
0772 .write_iter = orangefs_devreq_write_iter,
0773 .open = orangefs_devreq_open,
0774 .release = orangefs_devreq_release,
0775 .unlocked_ioctl = orangefs_devreq_ioctl,
0776
0777 #ifdef CONFIG_COMPAT
0778 .compat_ioctl = orangefs_devreq_compat_ioctl,
0779 #endif
0780 .poll = orangefs_devreq_poll
0781 };
0782
0783
0784
0785
0786
0787 int orangefs_dev_init(void)
0788 {
0789
0790 orangefs_dev_major = register_chrdev(0,
0791 ORANGEFS_REQDEVICE_NAME,
0792 &orangefs_devreq_file_operations);
0793 if (orangefs_dev_major < 0) {
0794 gossip_debug(GOSSIP_DEV_DEBUG,
0795 "Failed to register /dev/%s (error %d)\n",
0796 ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
0797 return orangefs_dev_major;
0798 }
0799
0800 gossip_debug(GOSSIP_DEV_DEBUG,
0801 "*** /dev/%s character device registered ***\n",
0802 ORANGEFS_REQDEVICE_NAME);
0803 gossip_debug(GOSSIP_DEV_DEBUG, "'mknod /dev/%s c %d 0'.\n",
0804 ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
0805 return 0;
0806 }
0807
0808 void orangefs_dev_cleanup(void)
0809 {
0810 unregister_chrdev(orangefs_dev_major, ORANGEFS_REQDEVICE_NAME);
0811 gossip_debug(GOSSIP_DEV_DEBUG,
0812 "*** /dev/%s character device unregistered ***\n",
0813 ORANGEFS_REQDEVICE_NAME);
0814 }