devorangefs-req.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * (C) 2001 Clemson University and The University of Chicago
  4. *
  5. * Changes by Acxiom Corporation to add protocol version to kernel
  6. * communication, Copyright Acxiom Corporation, 2005.
  7. *
  8. * See COPYING in top-level directory.
  9. */
  10. #include "protocol.h"
  11. #include "orangefs-kernel.h"
  12. #include "orangefs-dev-proto.h"
  13. #include "orangefs-bufmap.h"
  14. #include "orangefs-debugfs.h"
  15. #include <linux/debugfs.h>
  16. #include <linux/slab.h>
  17. /* this file implements the /dev/pvfs2-req device node */
  18. uint32_t orangefs_userspace_version;
  19. static int open_access_count;
  20. static DEFINE_MUTEX(devreq_mutex);
  21. #define DUMP_DEVICE_ERROR() \
  22. do { \
  23. gossip_err("*****************************************************\n");\
  24. gossip_err("ORANGEFS Device Error: You cannot open the device file "); \
  25. gossip_err("\n/dev/%s more than once. Please make sure that\nthere " \
  26. "are no ", ORANGEFS_REQDEVICE_NAME); \
  27. gossip_err("instances of a program using this device\ncurrently " \
  28. "running. (You must verify this!)\n"); \
  29. gossip_err("For example, you can use the lsof program as follows:\n");\
  30. gossip_err("'lsof | grep %s' (run this as root)\n", \
  31. ORANGEFS_REQDEVICE_NAME); \
  32. gossip_err(" open_access_count = %d\n", open_access_count); \
  33. gossip_err("*****************************************************\n");\
  34. } while (0)
  35. static int hash_func(__u64 tag, int table_size)
  36. {
  37. return do_div(tag, (unsigned int)table_size);
  38. }
  39. static void orangefs_devreq_add_op(struct orangefs_kernel_op_s *op)
  40. {
  41. int index = hash_func(op->tag, hash_table_size);
  42. list_add_tail(&op->list, &orangefs_htable_ops_in_progress[index]);
  43. }
  44. /*
  45. * find the op with this tag and remove it from the in progress
  46. * hash table.
  47. */
  48. static struct orangefs_kernel_op_s *orangefs_devreq_remove_op(__u64 tag)
  49. {
  50. struct orangefs_kernel_op_s *op, *next;
  51. int index;
  52. index = hash_func(tag, hash_table_size);
  53. spin_lock(&orangefs_htable_ops_in_progress_lock);
  54. list_for_each_entry_safe(op,
  55. next,
  56. &orangefs_htable_ops_in_progress[index],
  57. list) {
  58. if (op->tag == tag && !op_state_purged(op) &&
  59. !op_state_given_up(op)) {
  60. list_del_init(&op->list);
  61. spin_unlock(&orangefs_htable_ops_in_progress_lock);
  62. return op;
  63. }
  64. }
  65. spin_unlock(&orangefs_htable_ops_in_progress_lock);
  66. return NULL;
  67. }
  68. /* Returns whether any FS are still pending remounted */
  69. static int mark_all_pending_mounts(void)
  70. {
  71. int unmounted = 1;
  72. struct orangefs_sb_info_s *orangefs_sb = NULL;
  73. spin_lock(&orangefs_superblocks_lock);
  74. list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
  75. /* All of these file system require a remount */
  76. orangefs_sb->mount_pending = 1;
  77. unmounted = 0;
  78. }
  79. spin_unlock(&orangefs_superblocks_lock);
  80. return unmounted;
  81. }
  82. /*
  83. * Determine if a given file system needs to be remounted or not
  84. * Returns -1 on error
  85. * 0 if already mounted
  86. * 1 if needs remount
  87. */
  88. static int fs_mount_pending(__s32 fsid)
  89. {
  90. int mount_pending = -1;
  91. struct orangefs_sb_info_s *orangefs_sb = NULL;
  92. spin_lock(&orangefs_superblocks_lock);
  93. list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
  94. if (orangefs_sb->fs_id == fsid) {
  95. mount_pending = orangefs_sb->mount_pending;
  96. break;
  97. }
  98. }
  99. spin_unlock(&orangefs_superblocks_lock);
  100. return mount_pending;
  101. }
  102. static int orangefs_devreq_open(struct inode *inode, struct file *file)
  103. {
  104. int ret = -EINVAL;
  105. /* in order to ensure that the filesystem driver sees correct UIDs */
  106. if (file->f_cred->user_ns != &init_user_ns) {
  107. gossip_err("%s: device cannot be opened outside init_user_ns\n",
  108. __func__);
  109. goto out;
  110. }
  111. if (!(file->f_flags & O_NONBLOCK)) {
  112. gossip_err("%s: device cannot be opened in blocking mode\n",
  113. __func__);
  114. goto out;
  115. }
  116. ret = -EACCES;
  117. gossip_debug(GOSSIP_DEV_DEBUG, "client-core: opening device\n");
  118. mutex_lock(&devreq_mutex);
  119. if (open_access_count == 0) {
  120. open_access_count = 1;
  121. ret = 0;
  122. } else {
  123. DUMP_DEVICE_ERROR();
  124. }
  125. mutex_unlock(&devreq_mutex);
  126. out:
  127. gossip_debug(GOSSIP_DEV_DEBUG,
  128. "pvfs2-client-core: open device complete (ret = %d)\n",
  129. ret);
  130. return ret;
  131. }
  132. /* Function for read() callers into the device */
  133. static ssize_t orangefs_devreq_read(struct file *file,
  134. char __user *buf,
  135. size_t count, loff_t *offset)
  136. {
  137. struct orangefs_kernel_op_s *op, *temp;
  138. __s32 proto_ver = ORANGEFS_KERNEL_PROTO_VERSION;
  139. static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
  140. struct orangefs_kernel_op_s *cur_op;
  141. unsigned long ret;
  142. /* We do not support blocking IO. */
  143. if (!(file->f_flags & O_NONBLOCK)) {
  144. gossip_err("%s: blocking read from client-core.\n",
  145. __func__);
  146. return -EINVAL;
  147. }
  148. /*
  149. * The client will do an ioctl to find MAX_DEV_REQ_UPSIZE, then
  150. * always read with that size buffer.
  151. */
  152. if (count != MAX_DEV_REQ_UPSIZE) {
  153. gossip_err("orangefs: client-core tried to read wrong size\n");
  154. return -EINVAL;
  155. }
  156. /* Check for an empty list before locking. */
  157. if (list_empty(&orangefs_request_list))
  158. return -EAGAIN;
  159. restart:
  160. cur_op = NULL;
  161. /* Get next op (if any) from top of list. */
  162. spin_lock(&orangefs_request_list_lock);
  163. list_for_each_entry_safe(op, temp, &orangefs_request_list, list) {
  164. __s32 fsid;
  165. /* This lock is held past the end of the loop when we break. */
  166. spin_lock(&op->lock);
  167. if (unlikely(op_state_purged(op) || op_state_given_up(op))) {
  168. spin_unlock(&op->lock);
  169. continue;
  170. }
  171. fsid = fsid_of_op(op);
  172. if (fsid != ORANGEFS_FS_ID_NULL) {
  173. int ret;
  174. /* Skip ops whose filesystem needs to be mounted. */
  175. ret = fs_mount_pending(fsid);
  176. if (ret == 1) {
  177. gossip_debug(GOSSIP_DEV_DEBUG,
  178. "%s: mount pending, skipping op tag "
  179. "%llu %s\n",
  180. __func__,
  181. llu(op->tag),
  182. get_opname_string(op));
  183. spin_unlock(&op->lock);
  184. continue;
  185. /*
  186. * Skip ops whose filesystem we don't know about unless
  187. * it is being mounted or unmounted. It is possible for
  188. * a filesystem we don't know about to be unmounted if
  189. * it fails to mount in the kernel after userspace has
  190. * been sent the mount request.
  191. */
  192. /* XXX: is there a better way to detect this? */
  193. } else if (ret == -1 &&
  194. !(op->upcall.type ==
  195. ORANGEFS_VFS_OP_FS_MOUNT ||
  196. op->upcall.type ==
  197. ORANGEFS_VFS_OP_GETATTR ||
  198. op->upcall.type ==
  199. ORANGEFS_VFS_OP_FS_UMOUNT)) {
  200. gossip_debug(GOSSIP_DEV_DEBUG,
  201. "orangefs: skipping op tag %llu %s\n",
  202. llu(op->tag), get_opname_string(op));
  203. gossip_err(
  204. "orangefs: ERROR: fs_mount_pending %d\n",
  205. fsid);
  206. spin_unlock(&op->lock);
  207. continue;
  208. }
  209. }
  210. /*
  211. * Either this op does not pertain to a filesystem, is mounting
  212. * a filesystem, or pertains to a mounted filesystem. Let it
  213. * through.
  214. */
  215. cur_op = op;
  216. break;
  217. }
  218. /*
  219. * At this point we either have a valid op and can continue or have not
  220. * found an op and must ask the client to try again later.
  221. */
  222. if (!cur_op) {
  223. spin_unlock(&orangefs_request_list_lock);
  224. return -EAGAIN;
  225. }
  226. gossip_debug(GOSSIP_DEV_DEBUG, "%s: reading op tag %llu %s\n",
  227. __func__,
  228. llu(cur_op->tag),
  229. get_opname_string(cur_op));
  230. /*
  231. * Such an op should never be on the list in the first place. If so, we
  232. * will abort.
  233. */
  234. if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) {
  235. gossip_err("orangefs: ERROR: Current op already queued.\n");
  236. list_del_init(&cur_op->list);
  237. spin_unlock(&cur_op->lock);
  238. spin_unlock(&orangefs_request_list_lock);
  239. return -EAGAIN;
  240. }
  241. list_del_init(&cur_op->list);
  242. spin_unlock(&orangefs_request_list_lock);
  243. spin_unlock(&cur_op->lock);
  244. /* Push the upcall out. */
  245. ret = copy_to_user(buf, &proto_ver, sizeof(__s32));
  246. if (ret != 0)
  247. goto error;
  248. ret = copy_to_user(buf+sizeof(__s32), &magic, sizeof(__s32));
  249. if (ret != 0)
  250. goto error;
  251. ret = copy_to_user(buf+2 * sizeof(__s32), &cur_op->tag, sizeof(__u64));
  252. if (ret != 0)
  253. goto error;
  254. ret = copy_to_user(buf+2*sizeof(__s32)+sizeof(__u64), &cur_op->upcall,
  255. sizeof(struct orangefs_upcall_s));
  256. if (ret != 0)
  257. goto error;
  258. spin_lock(&orangefs_htable_ops_in_progress_lock);
  259. spin_lock(&cur_op->lock);
  260. if (unlikely(op_state_given_up(cur_op))) {
  261. spin_unlock(&cur_op->lock);
  262. spin_unlock(&orangefs_htable_ops_in_progress_lock);
  263. complete(&cur_op->waitq);
  264. goto restart;
  265. }
  266. /*
  267. * Set the operation to be in progress and move it between lists since
  268. * it has been sent to the client.
  269. */
  270. set_op_state_inprogress(cur_op);
  271. gossip_debug(GOSSIP_DEV_DEBUG,
  272. "%s: 1 op:%s: op_state:%d: process:%s:\n",
  273. __func__,
  274. get_opname_string(cur_op),
  275. cur_op->op_state,
  276. current->comm);
  277. orangefs_devreq_add_op(cur_op);
  278. spin_unlock(&cur_op->lock);
  279. spin_unlock(&orangefs_htable_ops_in_progress_lock);
  280. /* The client only asks to read one size buffer. */
  281. return MAX_DEV_REQ_UPSIZE;
  282. error:
  283. /*
  284. * We were unable to copy the op data to the client. Put the op back in
  285. * list. If client has crashed, the op will be purged later when the
  286. * device is released.
  287. */
  288. gossip_err("orangefs: Failed to copy data to user space\n");
  289. spin_lock(&orangefs_request_list_lock);
  290. spin_lock(&cur_op->lock);
  291. if (likely(!op_state_given_up(cur_op))) {
  292. set_op_state_waiting(cur_op);
  293. gossip_debug(GOSSIP_DEV_DEBUG,
  294. "%s: 2 op:%s: op_state:%d: process:%s:\n",
  295. __func__,
  296. get_opname_string(cur_op),
  297. cur_op->op_state,
  298. current->comm);
  299. list_add(&cur_op->list, &orangefs_request_list);
  300. spin_unlock(&cur_op->lock);
  301. } else {
  302. spin_unlock(&cur_op->lock);
  303. complete(&cur_op->waitq);
  304. }
  305. spin_unlock(&orangefs_request_list_lock);
  306. return -EFAULT;
  307. }
  308. /*
  309. * Function for writev() callers into the device.
  310. *
  311. * Userspace should have written:
  312. * - __u32 version
  313. * - __u32 magic
  314. * - __u64 tag
  315. * - struct orangefs_downcall_s
  316. * - trailer buffer (in the case of READDIR operations)
  317. */
  318. static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
  319. struct iov_iter *iter)
  320. {
  321. ssize_t ret;
  322. struct orangefs_kernel_op_s *op = NULL;
  323. struct {
  324. __u32 version;
  325. __u32 magic;
  326. __u64 tag;
  327. } head;
  328. int total = ret = iov_iter_count(iter);
  329. int downcall_size = sizeof(struct orangefs_downcall_s);
  330. int head_size = sizeof(head);
  331. gossip_debug(GOSSIP_DEV_DEBUG, "%s: total:%d: ret:%zd:\n",
  332. __func__,
  333. total,
  334. ret);
  335. if (total < MAX_DEV_REQ_DOWNSIZE) {
  336. gossip_err("%s: total:%d: must be at least:%u:\n",
  337. __func__,
  338. total,
  339. (unsigned int) MAX_DEV_REQ_DOWNSIZE);
  340. return -EFAULT;
  341. }
  342. if (!copy_from_iter_full(&head, head_size, iter)) {
  343. gossip_err("%s: failed to copy head.\n", __func__);
  344. return -EFAULT;
  345. }
  346. if (head.version < ORANGEFS_MINIMUM_USERSPACE_VERSION) {
  347. gossip_err("%s: userspace claims version"
  348. "%d, minimum version required: %d.\n",
  349. __func__,
  350. head.version,
  351. ORANGEFS_MINIMUM_USERSPACE_VERSION);
  352. return -EPROTO;
  353. }
  354. if (head.magic != ORANGEFS_DEVREQ_MAGIC) {
  355. gossip_err("Error: Device magic number does not match.\n");
  356. return -EPROTO;
  357. }
  358. if (!orangefs_userspace_version) {
  359. orangefs_userspace_version = head.version;
  360. } else if (orangefs_userspace_version != head.version) {
  361. gossip_err("Error: userspace version changes\n");
  362. return -EPROTO;
  363. }
  364. /* remove the op from the in progress hash table */
  365. op = orangefs_devreq_remove_op(head.tag);
  366. if (!op) {
  367. gossip_debug(GOSSIP_DEV_DEBUG,
  368. "%s: No one's waiting for tag %llu\n",
  369. __func__, llu(head.tag));
  370. return ret;
  371. }
  372. if (!copy_from_iter_full(&op->downcall, downcall_size, iter)) {
  373. gossip_err("%s: failed to copy downcall.\n", __func__);
  374. goto Efault;
  375. }
  376. if (op->downcall.status)
  377. goto wakeup;
  378. /*
  379. * We've successfully peeled off the head and the downcall.
  380. * Something has gone awry if total doesn't equal the
  381. * sum of head_size, downcall_size and trailer_size.
  382. */
  383. if ((head_size + downcall_size + op->downcall.trailer_size) != total) {
  384. gossip_err("%s: funky write, head_size:%d"
  385. ": downcall_size:%d: trailer_size:%lld"
  386. ": total size:%d:\n",
  387. __func__,
  388. head_size,
  389. downcall_size,
  390. op->downcall.trailer_size,
  391. total);
  392. goto Efault;
  393. }
  394. /* Only READDIR operations should have trailers. */
  395. if ((op->downcall.type != ORANGEFS_VFS_OP_READDIR) &&
  396. (op->downcall.trailer_size != 0)) {
  397. gossip_err("%s: %x operation with trailer.",
  398. __func__,
  399. op->downcall.type);
  400. goto Efault;
  401. }
  402. /* READDIR operations should always have trailers. */
  403. if ((op->downcall.type == ORANGEFS_VFS_OP_READDIR) &&
  404. (op->downcall.trailer_size == 0)) {
  405. gossip_err("%s: %x operation with no trailer.",
  406. __func__,
  407. op->downcall.type);
  408. goto Efault;
  409. }
  410. if (op->downcall.type != ORANGEFS_VFS_OP_READDIR)
  411. goto wakeup;
  412. op->downcall.trailer_buf = vmalloc(op->downcall.trailer_size);
  413. if (!op->downcall.trailer_buf)
  414. goto Enomem;
  415. memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size);
  416. if (!copy_from_iter_full(op->downcall.trailer_buf,
  417. op->downcall.trailer_size, iter)) {
  418. gossip_err("%s: failed to copy trailer.\n", __func__);
  419. vfree(op->downcall.trailer_buf);
  420. goto Efault;
  421. }
  422. wakeup:
  423. /*
  424. * Return to vfs waitqueue, and back to service_operation
  425. * through wait_for_matching_downcall.
  426. */
  427. spin_lock(&op->lock);
  428. if (unlikely(op_is_cancel(op))) {
  429. spin_unlock(&op->lock);
  430. put_cancel(op);
  431. } else if (unlikely(op_state_given_up(op))) {
  432. spin_unlock(&op->lock);
  433. complete(&op->waitq);
  434. } else {
  435. set_op_state_serviced(op);
  436. gossip_debug(GOSSIP_DEV_DEBUG,
  437. "%s: op:%s: op_state:%d: process:%s:\n",
  438. __func__,
  439. get_opname_string(op),
  440. op->op_state,
  441. current->comm);
  442. spin_unlock(&op->lock);
  443. }
  444. return ret;
  445. Efault:
  446. op->downcall.status = -(ORANGEFS_ERROR_BIT | 9);
  447. ret = -EFAULT;
  448. goto wakeup;
  449. Enomem:
  450. op->downcall.status = -(ORANGEFS_ERROR_BIT | 8);
  451. ret = -ENOMEM;
  452. goto wakeup;
  453. }
  454. /*
  455. * NOTE: gets called when the last reference to this device is dropped.
  456. * Using the open_access_count variable, we enforce a reference count
  457. * on this file so that it can be opened by only one process at a time.
  458. * the devreq_mutex is used to make sure all i/o has completed
  459. * before we call orangefs_bufmap_finalize, and similar such tricky
  460. * situations
  461. */
  462. static int orangefs_devreq_release(struct inode *inode, struct file *file)
  463. {
  464. int unmounted = 0;
  465. gossip_debug(GOSSIP_DEV_DEBUG,
  466. "%s:pvfs2-client-core: exiting, closing device\n",
  467. __func__);
  468. mutex_lock(&devreq_mutex);
  469. orangefs_bufmap_finalize();
  470. open_access_count = -1;
  471. unmounted = mark_all_pending_mounts();
  472. gossip_debug(GOSSIP_DEV_DEBUG, "ORANGEFS Device Close: Filesystem(s) %s\n",
  473. (unmounted ? "UNMOUNTED" : "MOUNTED"));
  474. purge_waiting_ops();
  475. purge_inprogress_ops();
  476. orangefs_bufmap_run_down();
  477. gossip_debug(GOSSIP_DEV_DEBUG,
  478. "pvfs2-client-core: device close complete\n");
  479. open_access_count = 0;
  480. orangefs_userspace_version = 0;
  481. mutex_unlock(&devreq_mutex);
  482. return 0;
  483. }
  484. int is_daemon_in_service(void)
  485. {
  486. int in_service;
  487. /*
  488. * What this function does is checks if client-core is alive
  489. * based on the access count we maintain on the device.
  490. */
  491. mutex_lock(&devreq_mutex);
  492. in_service = open_access_count == 1 ? 0 : -EIO;
  493. mutex_unlock(&devreq_mutex);
  494. return in_service;
  495. }
  496. bool __is_daemon_in_service(void)
  497. {
  498. return open_access_count == 1;
  499. }
  500. static inline long check_ioctl_command(unsigned int command)
  501. {
  502. /* Check for valid ioctl codes */
  503. if (_IOC_TYPE(command) != ORANGEFS_DEV_MAGIC) {
  504. gossip_err("device ioctl magic numbers don't match! Did you rebuild pvfs2-client-core/libpvfs2? [cmd %x, magic %x != %x]\n",
  505. command,
  506. _IOC_TYPE(command),
  507. ORANGEFS_DEV_MAGIC);
  508. return -EINVAL;
  509. }
  510. /* and valid ioctl commands */
  511. if (_IOC_NR(command) >= ORANGEFS_DEV_MAXNR || _IOC_NR(command) <= 0) {
  512. gossip_err("Invalid ioctl command number [%d >= %d]\n",
  513. _IOC_NR(command), ORANGEFS_DEV_MAXNR);
  514. return -ENOIOCTLCMD;
  515. }
  516. return 0;
  517. }
  518. static long dispatch_ioctl_command(unsigned int command, unsigned long arg)
  519. {
  520. static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
  521. static __s32 max_up_size = MAX_DEV_REQ_UPSIZE;
  522. static __s32 max_down_size = MAX_DEV_REQ_DOWNSIZE;
  523. struct ORANGEFS_dev_map_desc user_desc;
  524. int ret = 0;
  525. int upstream_kmod = 1;
  526. struct orangefs_sb_info_s *orangefs_sb;
  527. /* mtmoore: add locking here */
  528. switch (command) {
  529. case ORANGEFS_DEV_GET_MAGIC:
  530. return ((put_user(magic, (__s32 __user *) arg) == -EFAULT) ?
  531. -EIO :
  532. 0);
  533. case ORANGEFS_DEV_GET_MAX_UPSIZE:
  534. return ((put_user(max_up_size,
  535. (__s32 __user *) arg) == -EFAULT) ?
  536. -EIO :
  537. 0);
  538. case ORANGEFS_DEV_GET_MAX_DOWNSIZE:
  539. return ((put_user(max_down_size,
  540. (__s32 __user *) arg) == -EFAULT) ?
  541. -EIO :
  542. 0);
  543. case ORANGEFS_DEV_MAP:
  544. ret = copy_from_user(&user_desc,
  545. (struct ORANGEFS_dev_map_desc __user *)
  546. arg,
  547. sizeof(struct ORANGEFS_dev_map_desc));
  548. /* WTF -EIO and not -EFAULT? */
  549. return ret ? -EIO : orangefs_bufmap_initialize(&user_desc);
  550. case ORANGEFS_DEV_REMOUNT_ALL:
  551. gossip_debug(GOSSIP_DEV_DEBUG,
  552. "%s: got ORANGEFS_DEV_REMOUNT_ALL\n",
  553. __func__);
  554. /*
  555. * remount all mounted orangefs volumes to regain the lost
  556. * dynamic mount tables (if any) -- NOTE: this is done
  557. * without keeping the superblock list locked due to the
  558. * upcall/downcall waiting. also, the request mutex is
  559. * used to ensure that no operations will be serviced until
  560. * all of the remounts are serviced (to avoid ops between
  561. * mounts to fail)
  562. */
  563. ret = mutex_lock_interruptible(&orangefs_request_mutex);
  564. if (ret < 0)
  565. return ret;
  566. gossip_debug(GOSSIP_DEV_DEBUG,
  567. "%s: priority remount in progress\n",
  568. __func__);
  569. spin_lock(&orangefs_superblocks_lock);
  570. list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
  571. /*
  572. * We have to drop the spinlock, so entries can be
  573. * removed. They can't be freed, though, so we just
  574. * keep the forward pointers and zero the back ones -
  575. * that way we can get to the rest of the list.
  576. */
  577. if (!orangefs_sb->list.prev)
  578. continue;
  579. gossip_debug(GOSSIP_DEV_DEBUG,
  580. "%s: Remounting SB %p\n",
  581. __func__,
  582. orangefs_sb);
  583. spin_unlock(&orangefs_superblocks_lock);
  584. ret = orangefs_remount(orangefs_sb);
  585. spin_lock(&orangefs_superblocks_lock);
  586. if (ret) {
  587. gossip_debug(GOSSIP_DEV_DEBUG,
  588. "SB %p remount failed\n",
  589. orangefs_sb);
  590. break;
  591. }
  592. }
  593. spin_unlock(&orangefs_superblocks_lock);
  594. gossip_debug(GOSSIP_DEV_DEBUG,
  595. "%s: priority remount complete\n",
  596. __func__);
  597. mutex_unlock(&orangefs_request_mutex);
  598. return ret;
  599. case ORANGEFS_DEV_UPSTREAM:
  600. ret = copy_to_user((void __user *)arg,
  601. &upstream_kmod,
  602. sizeof(upstream_kmod));
  603. if (ret != 0)
  604. return -EIO;
  605. else
  606. return ret;
  607. case ORANGEFS_DEV_CLIENT_MASK:
  608. return orangefs_debugfs_new_client_mask((void __user *)arg);
  609. case ORANGEFS_DEV_CLIENT_STRING:
  610. return orangefs_debugfs_new_client_string((void __user *)arg);
  611. case ORANGEFS_DEV_DEBUG:
  612. return orangefs_debugfs_new_debug((void __user *)arg);
  613. default:
  614. return -ENOIOCTLCMD;
  615. }
  616. return -ENOIOCTLCMD;
  617. }
  618. static long orangefs_devreq_ioctl(struct file *file,
  619. unsigned int command, unsigned long arg)
  620. {
  621. long ret;
  622. /* Check for properly constructed commands */
  623. ret = check_ioctl_command(command);
  624. if (ret < 0)
  625. return (int)ret;
  626. return (int)dispatch_ioctl_command(command, arg);
  627. }
  628. #ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */
  629. /* Compat structure for the ORANGEFS_DEV_MAP ioctl */
  630. struct ORANGEFS_dev_map_desc32 {
  631. compat_uptr_t ptr;
  632. __s32 total_size;
  633. __s32 size;
  634. __s32 count;
  635. };
  636. static unsigned long translate_dev_map26(unsigned long args, long *error)
  637. {
  638. struct ORANGEFS_dev_map_desc32 __user *p32 = (void __user *)args;
  639. /*
  640. * Depending on the architecture, allocate some space on the
  641. * user-call-stack based on our expected layout.
  642. */
  643. struct ORANGEFS_dev_map_desc __user *p =
  644. compat_alloc_user_space(sizeof(*p));
  645. compat_uptr_t addr;
  646. *error = 0;
  647. /* get the ptr from the 32 bit user-space */
  648. if (get_user(addr, &p32->ptr))
  649. goto err;
  650. /* try to put that into a 64-bit layout */
  651. if (put_user(compat_ptr(addr), &p->ptr))
  652. goto err;
  653. /* copy the remaining fields */
  654. if (copy_in_user(&p->total_size, &p32->total_size, sizeof(__s32)))
  655. goto err;
  656. if (copy_in_user(&p->size, &p32->size, sizeof(__s32)))
  657. goto err;
  658. if (copy_in_user(&p->count, &p32->count, sizeof(__s32)))
  659. goto err;
  660. return (unsigned long)p;
  661. err:
  662. *error = -EFAULT;
  663. return 0;
  664. }
  665. /*
  666. * 32 bit user-space apps' ioctl handlers when kernel modules
  667. * is compiled as a 64 bit one
  668. */
  669. static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd,
  670. unsigned long args)
  671. {
  672. long ret;
  673. unsigned long arg = args;
  674. /* Check for properly constructed commands */
  675. ret = check_ioctl_command(cmd);
  676. if (ret < 0)
  677. return ret;
  678. if (cmd == ORANGEFS_DEV_MAP) {
  679. /*
  680. * convert the arguments to what we expect internally
  681. * in kernel space
  682. */
  683. arg = translate_dev_map26(args, &ret);
  684. if (ret < 0) {
  685. gossip_err("Could not translate dev map\n");
  686. return ret;
  687. }
  688. }
  689. /* no other ioctl requires translation */
  690. return dispatch_ioctl_command(cmd, arg);
  691. }
  692. #endif /* CONFIG_COMPAT is in .config */
  693. /* the assigned character device major number */
  694. static int orangefs_dev_major;
  695. /*
  696. * Initialize orangefs device specific state:
  697. * Must be called at module load time only
  698. */
  699. int orangefs_dev_init(void)
  700. {
  701. /* register orangefs-req device */
  702. orangefs_dev_major = register_chrdev(0,
  703. ORANGEFS_REQDEVICE_NAME,
  704. &orangefs_devreq_file_operations);
  705. if (orangefs_dev_major < 0) {
  706. gossip_debug(GOSSIP_DEV_DEBUG,
  707. "Failed to register /dev/%s (error %d)\n",
  708. ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
  709. return orangefs_dev_major;
  710. }
  711. gossip_debug(GOSSIP_DEV_DEBUG,
  712. "*** /dev/%s character device registered ***\n",
  713. ORANGEFS_REQDEVICE_NAME);
  714. gossip_debug(GOSSIP_DEV_DEBUG, "'mknod /dev/%s c %d 0'.\n",
  715. ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
  716. return 0;
  717. }
  718. void orangefs_dev_cleanup(void)
  719. {
  720. unregister_chrdev(orangefs_dev_major, ORANGEFS_REQDEVICE_NAME);
  721. gossip_debug(GOSSIP_DEV_DEBUG,
  722. "*** /dev/%s character device unregistered ***\n",
  723. ORANGEFS_REQDEVICE_NAME);
  724. }
  725. static __poll_t orangefs_devreq_poll(struct file *file,
  726. struct poll_table_struct *poll_table)
  727. {
  728. __poll_t poll_revent_mask = 0;
  729. poll_wait(file, &orangefs_request_list_waitq, poll_table);
  730. if (!list_empty(&orangefs_request_list))
  731. poll_revent_mask |= EPOLLIN;
  732. return poll_revent_mask;
  733. }
  734. const struct file_operations orangefs_devreq_file_operations = {
  735. .owner = THIS_MODULE,
  736. .read = orangefs_devreq_read,
  737. .write_iter = orangefs_devreq_write_iter,
  738. .open = orangefs_devreq_open,
  739. .release = orangefs_devreq_release,
  740. .unlocked_ioctl = orangefs_devreq_ioctl,
  741. #ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */
  742. .compat_ioctl = orangefs_devreq_compat_ioctl,
  743. #endif
  744. .poll = orangefs_devreq_poll
  745. };