devorangefs-req.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  1. /*
  2. * (C) 2001 Clemson University and The University of Chicago
  3. *
  4. * Changes by Acxiom Corporation to add protocol version to kernel
  5. * communication, Copyright Acxiom Corporation, 2005.
  6. *
  7. * See COPYING in top-level directory.
  8. */
  9. #include "protocol.h"
  10. #include "orangefs-kernel.h"
  11. #include "orangefs-dev-proto.h"
  12. #include "orangefs-bufmap.h"
  13. #include <linux/debugfs.h>
  14. #include <linux/slab.h>
  15. /* this file implements the /dev/pvfs2-req device node */
  16. static int open_access_count;
  17. #define DUMP_DEVICE_ERROR() \
  18. do { \
  19. gossip_err("*****************************************************\n");\
  20. gossip_err("ORANGEFS Device Error: You cannot open the device file "); \
  21. gossip_err("\n/dev/%s more than once. Please make sure that\nthere " \
  22. "are no ", ORANGEFS_REQDEVICE_NAME); \
  23. gossip_err("instances of a program using this device\ncurrently " \
  24. "running. (You must verify this!)\n"); \
  25. gossip_err("For example, you can use the lsof program as follows:\n");\
  26. gossip_err("'lsof | grep %s' (run this as root)\n", \
  27. ORANGEFS_REQDEVICE_NAME); \
  28. gossip_err(" open_access_count = %d\n", open_access_count); \
  29. gossip_err("*****************************************************\n");\
  30. } while (0)
  31. static int hash_func(__u64 tag, int table_size)
  32. {
  33. return do_div(tag, (unsigned int)table_size);
  34. }
  35. static void orangefs_devreq_add_op(struct orangefs_kernel_op_s *op)
  36. {
  37. int index = hash_func(op->tag, hash_table_size);
  38. spin_lock(&htable_ops_in_progress_lock);
  39. list_add_tail(&op->list, &htable_ops_in_progress[index]);
  40. spin_unlock(&htable_ops_in_progress_lock);
  41. }
  42. static struct orangefs_kernel_op_s *orangefs_devreq_remove_op(__u64 tag)
  43. {
  44. struct orangefs_kernel_op_s *op, *next;
  45. int index;
  46. index = hash_func(tag, hash_table_size);
  47. spin_lock(&htable_ops_in_progress_lock);
  48. list_for_each_entry_safe(op,
  49. next,
  50. &htable_ops_in_progress[index],
  51. list) {
  52. if (op->tag == tag) {
  53. list_del(&op->list);
  54. spin_unlock(&htable_ops_in_progress_lock);
  55. return op;
  56. }
  57. }
  58. spin_unlock(&htable_ops_in_progress_lock);
  59. return NULL;
  60. }
  61. static int orangefs_devreq_open(struct inode *inode, struct file *file)
  62. {
  63. int ret = -EINVAL;
  64. if (!(file->f_flags & O_NONBLOCK)) {
  65. gossip_err("%s: device cannot be opened in blocking mode\n",
  66. __func__);
  67. goto out;
  68. }
  69. ret = -EACCES;
  70. gossip_debug(GOSSIP_DEV_DEBUG, "client-core: opening device\n");
  71. mutex_lock(&devreq_mutex);
  72. if (open_access_count == 0) {
  73. open_access_count++;
  74. ret = 0;
  75. } else {
  76. DUMP_DEVICE_ERROR();
  77. }
  78. mutex_unlock(&devreq_mutex);
  79. out:
  80. gossip_debug(GOSSIP_DEV_DEBUG,
  81. "pvfs2-client-core: open device complete (ret = %d)\n",
  82. ret);
  83. return ret;
  84. }
  85. /* Function for read() callers into the device */
  86. static ssize_t orangefs_devreq_read(struct file *file,
  87. char __user *buf,
  88. size_t count, loff_t *offset)
  89. {
  90. struct orangefs_kernel_op_s *op, *temp;
  91. __s32 proto_ver = ORANGEFS_KERNEL_PROTO_VERSION;
  92. static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
  93. struct orangefs_kernel_op_s *cur_op = NULL;
  94. unsigned long ret;
  95. /* We do not support blocking IO. */
  96. if (!(file->f_flags & O_NONBLOCK)) {
  97. gossip_err("%s: blocking read from client-core.\n",
  98. __func__);
  99. return -EINVAL;
  100. }
  101. /*
  102. * The client will do an ioctl to find MAX_DEV_REQ_UPSIZE, then
  103. * always read with that size buffer.
  104. */
  105. if (count != MAX_DEV_REQ_UPSIZE) {
  106. gossip_err("orangefs: client-core tried to read wrong size\n");
  107. return -EINVAL;
  108. }
  109. /* Get next op (if any) from top of list. */
  110. spin_lock(&orangefs_request_list_lock);
  111. list_for_each_entry_safe(op, temp, &orangefs_request_list, list) {
  112. __s32 fsid;
  113. /* This lock is held past the end of the loop when we break. */
  114. spin_lock(&op->lock);
  115. fsid = fsid_of_op(op);
  116. if (fsid != ORANGEFS_FS_ID_NULL) {
  117. int ret;
  118. /* Skip ops whose filesystem needs to be mounted. */
  119. ret = fs_mount_pending(fsid);
  120. if (ret == 1) {
  121. gossip_debug(GOSSIP_DEV_DEBUG,
  122. "orangefs: skipping op tag %llu %s\n",
  123. llu(op->tag), get_opname_string(op));
  124. spin_unlock(&op->lock);
  125. continue;
  126. /*
  127. * Skip ops whose filesystem we don't know about unless
  128. * it is being mounted.
  129. */
  130. /* XXX: is there a better way to detect this? */
  131. } else if (ret == -1 &&
  132. !(op->upcall.type ==
  133. ORANGEFS_VFS_OP_FS_MOUNT ||
  134. op->upcall.type ==
  135. ORANGEFS_VFS_OP_GETATTR)) {
  136. gossip_debug(GOSSIP_DEV_DEBUG,
  137. "orangefs: skipping op tag %llu %s\n",
  138. llu(op->tag), get_opname_string(op));
  139. gossip_err(
  140. "orangefs: ERROR: fs_mount_pending %d\n",
  141. fsid);
  142. spin_unlock(&op->lock);
  143. continue;
  144. }
  145. }
  146. /*
  147. * Either this op does not pertain to a filesystem, is mounting
  148. * a filesystem, or pertains to a mounted filesystem. Let it
  149. * through.
  150. */
  151. cur_op = op;
  152. break;
  153. }
  154. /*
  155. * At this point we either have a valid op and can continue or have not
  156. * found an op and must ask the client to try again later.
  157. */
  158. if (!cur_op) {
  159. spin_unlock(&orangefs_request_list_lock);
  160. return -EAGAIN;
  161. }
  162. gossip_debug(GOSSIP_DEV_DEBUG, "orangefs: reading op tag %llu %s\n",
  163. llu(cur_op->tag), get_opname_string(cur_op));
  164. /*
  165. * Such an op should never be on the list in the first place. If so, we
  166. * will abort.
  167. */
  168. if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) {
  169. gossip_err("orangefs: ERROR: Current op already queued.\n");
  170. list_del(&cur_op->list);
  171. spin_unlock(&cur_op->lock);
  172. spin_unlock(&orangefs_request_list_lock);
  173. return -EAGAIN;
  174. }
  175. /*
  176. * Set the operation to be in progress and move it between lists since
  177. * it has been sent to the client.
  178. */
  179. set_op_state_inprogress(cur_op);
  180. list_del(&cur_op->list);
  181. spin_unlock(&orangefs_request_list_lock);
  182. orangefs_devreq_add_op(cur_op);
  183. spin_unlock(&cur_op->lock);
  184. /* Push the upcall out. */
  185. ret = copy_to_user(buf, &proto_ver, sizeof(__s32));
  186. if (ret != 0)
  187. goto error;
  188. ret = copy_to_user(buf+sizeof(__s32), &magic, sizeof(__s32));
  189. if (ret != 0)
  190. goto error;
  191. ret = copy_to_user(buf+2 * sizeof(__s32), &cur_op->tag, sizeof(__u64));
  192. if (ret != 0)
  193. goto error;
  194. ret = copy_to_user(buf+2*sizeof(__s32)+sizeof(__u64), &cur_op->upcall,
  195. sizeof(struct orangefs_upcall_s));
  196. if (ret != 0)
  197. goto error;
  198. /* The client only asks to read one size buffer. */
  199. return MAX_DEV_REQ_UPSIZE;
  200. error:
  201. /*
  202. * We were unable to copy the op data to the client. Put the op back in
  203. * list. If client has crashed, the op will be purged later when the
  204. * device is released.
  205. */
  206. gossip_err("orangefs: Failed to copy data to user space\n");
  207. spin_lock(&orangefs_request_list_lock);
  208. spin_lock(&cur_op->lock);
  209. set_op_state_waiting(cur_op);
  210. orangefs_devreq_remove_op(cur_op->tag);
  211. list_add(&cur_op->list, &orangefs_request_list);
  212. spin_unlock(&cur_op->lock);
  213. spin_unlock(&orangefs_request_list_lock);
  214. return -EFAULT;
  215. }
  216. /*
  217. * Function for writev() callers into the device.
  218. *
  219. * Userspace should have written:
  220. * - __u32 version
  221. * - __u32 magic
  222. * - __u64 tag
  223. * - struct orangefs_downcall_s
  224. * - trailer buffer (in the case of READDIR operations)
  225. */
  226. static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
  227. struct iov_iter *iter)
  228. {
  229. ssize_t ret;
  230. struct orangefs_kernel_op_s *op = NULL;
  231. struct {
  232. __u32 version;
  233. __u32 magic;
  234. __u64 tag;
  235. } head;
  236. int total = ret = iov_iter_count(iter);
  237. int n;
  238. int downcall_size = sizeof(struct orangefs_downcall_s);
  239. int head_size = sizeof(head);
  240. gossip_debug(GOSSIP_DEV_DEBUG, "%s: total:%d: ret:%zd:\n",
  241. __func__,
  242. total,
  243. ret);
  244. if (total < MAX_DEV_REQ_DOWNSIZE) {
  245. gossip_err("%s: total:%d: must be at least:%u:\n",
  246. __func__,
  247. total,
  248. (unsigned int) MAX_DEV_REQ_DOWNSIZE);
  249. ret = -EFAULT;
  250. goto out;
  251. }
  252. n = copy_from_iter(&head, head_size, iter);
  253. if (n < head_size) {
  254. gossip_err("%s: failed to copy head.\n", __func__);
  255. ret = -EFAULT;
  256. goto out;
  257. }
  258. if (head.version < ORANGEFS_MINIMUM_USERSPACE_VERSION) {
  259. gossip_err("%s: userspace claims version"
  260. "%d, minimum version required: %d.\n",
  261. __func__,
  262. head.version,
  263. ORANGEFS_MINIMUM_USERSPACE_VERSION);
  264. ret = -EPROTO;
  265. goto out;
  266. }
  267. if (head.magic != ORANGEFS_DEVREQ_MAGIC) {
  268. gossip_err("Error: Device magic number does not match.\n");
  269. ret = -EPROTO;
  270. goto out;
  271. }
  272. op = orangefs_devreq_remove_op(head.tag);
  273. if (!op) {
  274. gossip_err("WARNING: No one's waiting for tag %llu\n",
  275. llu(head.tag));
  276. goto out;
  277. }
  278. get_op(op); /* increase ref count. */
  279. n = copy_from_iter(&op->downcall, downcall_size, iter);
  280. if (n != downcall_size) {
  281. gossip_err("%s: failed to copy downcall.\n", __func__);
  282. put_op(op);
  283. ret = -EFAULT;
  284. goto out;
  285. }
  286. if (op->downcall.status)
  287. goto wakeup;
  288. /*
  289. * We've successfully peeled off the head and the downcall.
  290. * Something has gone awry if total doesn't equal the
  291. * sum of head_size, downcall_size and trailer_size.
  292. */
  293. if ((head_size + downcall_size + op->downcall.trailer_size) != total) {
  294. gossip_err("%s: funky write, head_size:%d"
  295. ": downcall_size:%d: trailer_size:%lld"
  296. ": total size:%d:\n",
  297. __func__,
  298. head_size,
  299. downcall_size,
  300. op->downcall.trailer_size,
  301. total);
  302. put_op(op);
  303. ret = -EFAULT;
  304. goto out;
  305. }
  306. /* Only READDIR operations should have trailers. */
  307. if ((op->downcall.type != ORANGEFS_VFS_OP_READDIR) &&
  308. (op->downcall.trailer_size != 0)) {
  309. gossip_err("%s: %x operation with trailer.",
  310. __func__,
  311. op->downcall.type);
  312. put_op(op);
  313. ret = -EFAULT;
  314. goto out;
  315. }
  316. /* READDIR operations should always have trailers. */
  317. if ((op->downcall.type == ORANGEFS_VFS_OP_READDIR) &&
  318. (op->downcall.trailer_size == 0)) {
  319. gossip_err("%s: %x operation with no trailer.",
  320. __func__,
  321. op->downcall.type);
  322. put_op(op);
  323. ret = -EFAULT;
  324. goto out;
  325. }
  326. if (op->downcall.type != ORANGEFS_VFS_OP_READDIR)
  327. goto wakeup;
  328. op->downcall.trailer_buf =
  329. vmalloc(op->downcall.trailer_size);
  330. if (op->downcall.trailer_buf == NULL) {
  331. gossip_err("%s: failed trailer vmalloc.\n",
  332. __func__);
  333. put_op(op);
  334. ret = -ENOMEM;
  335. goto out;
  336. }
  337. memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size);
  338. n = copy_from_iter(op->downcall.trailer_buf,
  339. op->downcall.trailer_size,
  340. iter);
  341. if (n != op->downcall.trailer_size) {
  342. gossip_err("%s: failed to copy trailer.\n", __func__);
  343. vfree(op->downcall.trailer_buf);
  344. put_op(op);
  345. ret = -EFAULT;
  346. goto out;
  347. }
  348. wakeup:
  349. /*
  350. * If this operation is an I/O operation we need to wait
  351. * for all data to be copied before we can return to avoid
  352. * buffer corruption and races that can pull the buffers
  353. * out from under us.
  354. *
  355. * Essentially we're synchronizing with other parts of the
  356. * vfs implicitly by not allowing the user space
  357. * application reading/writing this device to return until
  358. * the buffers are done being used.
  359. */
  360. if (op->downcall.type == ORANGEFS_VFS_OP_FILE_IO) {
  361. int timed_out = 0;
  362. DEFINE_WAIT(wait_entry);
  363. /*
  364. * tell the vfs op waiting on a waitqueue
  365. * that this op is done
  366. */
  367. spin_lock(&op->lock);
  368. set_op_state_serviced(op);
  369. spin_unlock(&op->lock);
  370. wake_up_interruptible(&op->waitq);
  371. while (1) {
  372. spin_lock(&op->lock);
  373. prepare_to_wait_exclusive(
  374. &op->io_completion_waitq,
  375. &wait_entry,
  376. TASK_INTERRUPTIBLE);
  377. if (op->io_completed) {
  378. spin_unlock(&op->lock);
  379. break;
  380. }
  381. spin_unlock(&op->lock);
  382. if (!signal_pending(current)) {
  383. int timeout =
  384. MSECS_TO_JIFFIES(1000 *
  385. op_timeout_secs);
  386. if (!schedule_timeout(timeout)) {
  387. gossip_debug(GOSSIP_DEV_DEBUG,
  388. "%s: timed out.\n",
  389. __func__);
  390. timed_out = 1;
  391. break;
  392. }
  393. continue;
  394. }
  395. gossip_debug(GOSSIP_DEV_DEBUG,
  396. "%s: signal on I/O wait, aborting\n",
  397. __func__);
  398. break;
  399. }
  400. spin_lock(&op->lock);
  401. finish_wait(&op->io_completion_waitq, &wait_entry);
  402. spin_unlock(&op->lock);
  403. /* NOTE: for I/O operations we handle releasing the op
  404. * object except in the case of timeout. the reason we
  405. * can't free the op in timeout cases is that the op
  406. * service logic in the vfs retries operations using
  407. * the same op ptr, thus it can't be freed.
  408. */
  409. if (!timed_out)
  410. op_release(op);
  411. } else {
  412. /*
  413. * tell the vfs op waiting on a waitqueue that
  414. * this op is done
  415. */
  416. spin_lock(&op->lock);
  417. set_op_state_serviced(op);
  418. spin_unlock(&op->lock);
  419. /*
  420. * for every other operation (i.e. non-I/O), we need to
  421. * wake up the callers for downcall completion
  422. * notification
  423. */
  424. wake_up_interruptible(&op->waitq);
  425. }
  426. out:
  427. return ret;
  428. }
  429. /* Returns whether any FS are still pending remounted */
  430. static int mark_all_pending_mounts(void)
  431. {
  432. int unmounted = 1;
  433. struct orangefs_sb_info_s *orangefs_sb = NULL;
  434. spin_lock(&orangefs_superblocks_lock);
  435. list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
  436. /* All of these file system require a remount */
  437. orangefs_sb->mount_pending = 1;
  438. unmounted = 0;
  439. }
  440. spin_unlock(&orangefs_superblocks_lock);
  441. return unmounted;
  442. }
  443. /*
  444. * Determine if a given file system needs to be remounted or not
  445. * Returns -1 on error
  446. * 0 if already mounted
  447. * 1 if needs remount
  448. */
  449. int fs_mount_pending(__s32 fsid)
  450. {
  451. int mount_pending = -1;
  452. struct orangefs_sb_info_s *orangefs_sb = NULL;
  453. spin_lock(&orangefs_superblocks_lock);
  454. list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
  455. if (orangefs_sb->fs_id == fsid) {
  456. mount_pending = orangefs_sb->mount_pending;
  457. break;
  458. }
  459. }
  460. spin_unlock(&orangefs_superblocks_lock);
  461. return mount_pending;
  462. }
  463. /*
  464. * NOTE: gets called when the last reference to this device is dropped.
  465. * Using the open_access_count variable, we enforce a reference count
  466. * on this file so that it can be opened by only one process at a time.
  467. * the devreq_mutex is used to make sure all i/o has completed
  468. * before we call orangefs_bufmap_finalize, and similar such tricky
  469. * situations
  470. */
  471. static int orangefs_devreq_release(struct inode *inode, struct file *file)
  472. {
  473. int unmounted = 0;
  474. gossip_debug(GOSSIP_DEV_DEBUG,
  475. "%s:pvfs2-client-core: exiting, closing device\n",
  476. __func__);
  477. mutex_lock(&devreq_mutex);
  478. if (orangefs_get_bufmap_init())
  479. orangefs_bufmap_finalize();
  480. open_access_count--;
  481. unmounted = mark_all_pending_mounts();
  482. gossip_debug(GOSSIP_DEV_DEBUG, "ORANGEFS Device Close: Filesystem(s) %s\n",
  483. (unmounted ? "UNMOUNTED" : "MOUNTED"));
  484. mutex_unlock(&devreq_mutex);
  485. /*
  486. * Walk through the list of ops in the request list, mark them
  487. * as purged and wake them up.
  488. */
  489. purge_waiting_ops();
  490. /*
  491. * Walk through the hash table of in progress operations; mark
  492. * them as purged and wake them up
  493. */
  494. purge_inprogress_ops();
  495. gossip_debug(GOSSIP_DEV_DEBUG,
  496. "pvfs2-client-core: device close complete\n");
  497. return 0;
  498. }
  499. int is_daemon_in_service(void)
  500. {
  501. int in_service;
  502. /*
  503. * What this function does is checks if client-core is alive
  504. * based on the access count we maintain on the device.
  505. */
  506. mutex_lock(&devreq_mutex);
  507. in_service = open_access_count == 1 ? 0 : -EIO;
  508. mutex_unlock(&devreq_mutex);
  509. return in_service;
  510. }
  511. static inline long check_ioctl_command(unsigned int command)
  512. {
  513. /* Check for valid ioctl codes */
  514. if (_IOC_TYPE(command) != ORANGEFS_DEV_MAGIC) {
  515. gossip_err("device ioctl magic numbers don't match! Did you rebuild pvfs2-client-core/libpvfs2? [cmd %x, magic %x != %x]\n",
  516. command,
  517. _IOC_TYPE(command),
  518. ORANGEFS_DEV_MAGIC);
  519. return -EINVAL;
  520. }
  521. /* and valid ioctl commands */
  522. if (_IOC_NR(command) >= ORANGEFS_DEV_MAXNR || _IOC_NR(command) <= 0) {
  523. gossip_err("Invalid ioctl command number [%d >= %d]\n",
  524. _IOC_NR(command), ORANGEFS_DEV_MAXNR);
  525. return -ENOIOCTLCMD;
  526. }
  527. return 0;
  528. }
  529. static long dispatch_ioctl_command(unsigned int command, unsigned long arg)
  530. {
  531. static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
  532. static __s32 max_up_size = MAX_DEV_REQ_UPSIZE;
  533. static __s32 max_down_size = MAX_DEV_REQ_DOWNSIZE;
  534. struct ORANGEFS_dev_map_desc user_desc;
  535. int ret = 0;
  536. struct dev_mask_info_s mask_info = { 0 };
  537. struct dev_mask2_info_s mask2_info = { 0, 0 };
  538. int upstream_kmod = 1;
  539. struct list_head *tmp = NULL;
  540. struct orangefs_sb_info_s *orangefs_sb = NULL;
  541. /* mtmoore: add locking here */
  542. switch (command) {
  543. case ORANGEFS_DEV_GET_MAGIC:
  544. return ((put_user(magic, (__s32 __user *) arg) == -EFAULT) ?
  545. -EIO :
  546. 0);
  547. case ORANGEFS_DEV_GET_MAX_UPSIZE:
  548. return ((put_user(max_up_size,
  549. (__s32 __user *) arg) == -EFAULT) ?
  550. -EIO :
  551. 0);
  552. case ORANGEFS_DEV_GET_MAX_DOWNSIZE:
  553. return ((put_user(max_down_size,
  554. (__s32 __user *) arg) == -EFAULT) ?
  555. -EIO :
  556. 0);
  557. case ORANGEFS_DEV_MAP:
  558. ret = copy_from_user(&user_desc,
  559. (struct ORANGEFS_dev_map_desc __user *)
  560. arg,
  561. sizeof(struct ORANGEFS_dev_map_desc));
  562. if (orangefs_get_bufmap_init()) {
  563. return -EINVAL;
  564. } else {
  565. return ret ?
  566. -EIO :
  567. orangefs_bufmap_initialize(&user_desc);
  568. }
  569. case ORANGEFS_DEV_REMOUNT_ALL:
  570. gossip_debug(GOSSIP_DEV_DEBUG,
  571. "%s: got ORANGEFS_DEV_REMOUNT_ALL\n",
  572. __func__);
  573. /*
  574. * remount all mounted orangefs volumes to regain the lost
  575. * dynamic mount tables (if any) -- NOTE: this is done
  576. * without keeping the superblock list locked due to the
  577. * upcall/downcall waiting. also, the request semaphore is
  578. * used to ensure that no operations will be serviced until
  579. * all of the remounts are serviced (to avoid ops between
  580. * mounts to fail)
  581. */
  582. ret = mutex_lock_interruptible(&request_mutex);
  583. if (ret < 0)
  584. return ret;
  585. gossip_debug(GOSSIP_DEV_DEBUG,
  586. "%s: priority remount in progress\n",
  587. __func__);
  588. list_for_each(tmp, &orangefs_superblocks) {
  589. orangefs_sb =
  590. list_entry(tmp,
  591. struct orangefs_sb_info_s,
  592. list);
  593. if (orangefs_sb && (orangefs_sb->sb)) {
  594. gossip_debug(GOSSIP_DEV_DEBUG,
  595. "%s: Remounting SB %p\n",
  596. __func__,
  597. orangefs_sb);
  598. ret = orangefs_remount(orangefs_sb->sb);
  599. if (ret) {
  600. gossip_debug(GOSSIP_DEV_DEBUG,
  601. "SB %p remount failed\n",
  602. orangefs_sb);
  603. break;
  604. }
  605. }
  606. }
  607. gossip_debug(GOSSIP_DEV_DEBUG,
  608. "%s: priority remount complete\n",
  609. __func__);
  610. mutex_unlock(&request_mutex);
  611. return ret;
  612. case ORANGEFS_DEV_UPSTREAM:
  613. ret = copy_to_user((void __user *)arg,
  614. &upstream_kmod,
  615. sizeof(upstream_kmod));
  616. if (ret != 0)
  617. return -EIO;
  618. else
  619. return ret;
  620. case ORANGEFS_DEV_CLIENT_MASK:
  621. ret = copy_from_user(&mask2_info,
  622. (void __user *)arg,
  623. sizeof(struct dev_mask2_info_s));
  624. if (ret != 0)
  625. return -EIO;
  626. client_debug_mask.mask1 = mask2_info.mask1_value;
  627. client_debug_mask.mask2 = mask2_info.mask2_value;
  628. pr_info("%s: client debug mask has been been received "
  629. ":%llx: :%llx:\n",
  630. __func__,
  631. (unsigned long long)client_debug_mask.mask1,
  632. (unsigned long long)client_debug_mask.mask2);
  633. return ret;
  634. case ORANGEFS_DEV_CLIENT_STRING:
  635. ret = copy_from_user(&client_debug_array_string,
  636. (void __user *)arg,
  637. ORANGEFS_MAX_DEBUG_STRING_LEN);
  638. if (ret != 0) {
  639. pr_info("%s: CLIENT_STRING: copy_from_user failed\n",
  640. __func__);
  641. return -EIO;
  642. }
  643. pr_info("%s: client debug array string has been received.\n",
  644. __func__);
  645. if (!help_string_initialized) {
  646. /* Free the "we don't know yet" default string... */
  647. kfree(debug_help_string);
  648. /* build a proper debug help string */
  649. if (orangefs_prepare_debugfs_help_string(0)) {
  650. gossip_err("%s: no debug help string \n",
  651. __func__);
  652. return -EIO;
  653. }
  654. /* Replace the boilerplate boot-time debug-help file. */
  655. debugfs_remove(help_file_dentry);
  656. help_file_dentry =
  657. debugfs_create_file(
  658. ORANGEFS_KMOD_DEBUG_HELP_FILE,
  659. 0444,
  660. debug_dir,
  661. debug_help_string,
  662. &debug_help_fops);
  663. if (!help_file_dentry) {
  664. gossip_err("%s: debugfs_create_file failed for"
  665. " :%s:!\n",
  666. __func__,
  667. ORANGEFS_KMOD_DEBUG_HELP_FILE);
  668. return -EIO;
  669. }
  670. }
  671. debug_mask_to_string(&client_debug_mask, 1);
  672. debugfs_remove(client_debug_dentry);
  673. orangefs_client_debug_init();
  674. help_string_initialized++;
  675. return ret;
  676. case ORANGEFS_DEV_DEBUG:
  677. ret = copy_from_user(&mask_info,
  678. (void __user *)arg,
  679. sizeof(mask_info));
  680. if (ret != 0)
  681. return -EIO;
  682. if (mask_info.mask_type == KERNEL_MASK) {
  683. if ((mask_info.mask_value == 0)
  684. && (kernel_mask_set_mod_init)) {
  685. /*
  686. * the kernel debug mask was set when the
  687. * kernel module was loaded; don't override
  688. * it if the client-core was started without
  689. * a value for ORANGEFS_KMODMASK.
  690. */
  691. return 0;
  692. }
  693. debug_mask_to_string(&mask_info.mask_value,
  694. mask_info.mask_type);
  695. gossip_debug_mask = mask_info.mask_value;
  696. pr_info("%s: kernel debug mask has been modified to "
  697. ":%s: :%llx:\n",
  698. __func__,
  699. kernel_debug_string,
  700. (unsigned long long)gossip_debug_mask);
  701. } else if (mask_info.mask_type == CLIENT_MASK) {
  702. debug_mask_to_string(&mask_info.mask_value,
  703. mask_info.mask_type);
  704. pr_info("%s: client debug mask has been modified to"
  705. ":%s: :%llx:\n",
  706. __func__,
  707. client_debug_string,
  708. llu(mask_info.mask_value));
  709. } else {
  710. gossip_lerr("Invalid mask type....\n");
  711. return -EINVAL;
  712. }
  713. return ret;
  714. default:
  715. return -ENOIOCTLCMD;
  716. }
  717. return -ENOIOCTLCMD;
  718. }
  719. static long orangefs_devreq_ioctl(struct file *file,
  720. unsigned int command, unsigned long arg)
  721. {
  722. long ret;
  723. /* Check for properly constructed commands */
  724. ret = check_ioctl_command(command);
  725. if (ret < 0)
  726. return (int)ret;
  727. return (int)dispatch_ioctl_command(command, arg);
  728. }
  729. #ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */
  730. /* Compat structure for the ORANGEFS_DEV_MAP ioctl */
  731. struct ORANGEFS_dev_map_desc32 {
  732. compat_uptr_t ptr;
  733. __s32 total_size;
  734. __s32 size;
  735. __s32 count;
  736. };
  737. static unsigned long translate_dev_map26(unsigned long args, long *error)
  738. {
  739. struct ORANGEFS_dev_map_desc32 __user *p32 = (void __user *)args;
  740. /*
  741. * Depending on the architecture, allocate some space on the
  742. * user-call-stack based on our expected layout.
  743. */
  744. struct ORANGEFS_dev_map_desc __user *p =
  745. compat_alloc_user_space(sizeof(*p));
  746. compat_uptr_t addr;
  747. *error = 0;
  748. /* get the ptr from the 32 bit user-space */
  749. if (get_user(addr, &p32->ptr))
  750. goto err;
  751. /* try to put that into a 64-bit layout */
  752. if (put_user(compat_ptr(addr), &p->ptr))
  753. goto err;
  754. /* copy the remaining fields */
  755. if (copy_in_user(&p->total_size, &p32->total_size, sizeof(__s32)))
  756. goto err;
  757. if (copy_in_user(&p->size, &p32->size, sizeof(__s32)))
  758. goto err;
  759. if (copy_in_user(&p->count, &p32->count, sizeof(__s32)))
  760. goto err;
  761. return (unsigned long)p;
  762. err:
  763. *error = -EFAULT;
  764. return 0;
  765. }
  766. /*
  767. * 32 bit user-space apps' ioctl handlers when kernel modules
  768. * is compiled as a 64 bit one
  769. */
  770. static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd,
  771. unsigned long args)
  772. {
  773. long ret;
  774. unsigned long arg = args;
  775. /* Check for properly constructed commands */
  776. ret = check_ioctl_command(cmd);
  777. if (ret < 0)
  778. return ret;
  779. if (cmd == ORANGEFS_DEV_MAP) {
  780. /*
  781. * convert the arguments to what we expect internally
  782. * in kernel space
  783. */
  784. arg = translate_dev_map26(args, &ret);
  785. if (ret < 0) {
  786. gossip_err("Could not translate dev map\n");
  787. return ret;
  788. }
  789. }
  790. /* no other ioctl requires translation */
  791. return dispatch_ioctl_command(cmd, arg);
  792. }
  793. #endif /* CONFIG_COMPAT is in .config */
  794. /*
  795. * The following two ioctl32 functions had been refactored into the above
  796. * CONFIG_COMPAT ifdef, but that was an over simplification that was
  797. * not noticed until we tried to compile on power pc...
  798. */
  799. #if (defined(CONFIG_COMPAT) && !defined(HAVE_REGISTER_IOCTL32_CONVERSION)) || !defined(CONFIG_COMPAT)
  800. static int orangefs_ioctl32_init(void)
  801. {
  802. return 0;
  803. }
  804. static void orangefs_ioctl32_cleanup(void)
  805. {
  806. return;
  807. }
  808. #endif
  809. /* the assigned character device major number */
  810. static int orangefs_dev_major;
  811. /*
  812. * Initialize orangefs device specific state:
  813. * Must be called at module load time only
  814. */
  815. int orangefs_dev_init(void)
  816. {
  817. int ret;
  818. /* register the ioctl32 sub-system */
  819. ret = orangefs_ioctl32_init();
  820. if (ret < 0)
  821. return ret;
  822. /* register orangefs-req device */
  823. orangefs_dev_major = register_chrdev(0,
  824. ORANGEFS_REQDEVICE_NAME,
  825. &orangefs_devreq_file_operations);
  826. if (orangefs_dev_major < 0) {
  827. gossip_debug(GOSSIP_DEV_DEBUG,
  828. "Failed to register /dev/%s (error %d)\n",
  829. ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
  830. orangefs_ioctl32_cleanup();
  831. return orangefs_dev_major;
  832. }
  833. gossip_debug(GOSSIP_DEV_DEBUG,
  834. "*** /dev/%s character device registered ***\n",
  835. ORANGEFS_REQDEVICE_NAME);
  836. gossip_debug(GOSSIP_DEV_DEBUG, "'mknod /dev/%s c %d 0'.\n",
  837. ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
  838. return 0;
  839. }
  840. void orangefs_dev_cleanup(void)
  841. {
  842. unregister_chrdev(orangefs_dev_major, ORANGEFS_REQDEVICE_NAME);
  843. gossip_debug(GOSSIP_DEV_DEBUG,
  844. "*** /dev/%s character device unregistered ***\n",
  845. ORANGEFS_REQDEVICE_NAME);
  846. /* unregister the ioctl32 sub-system */
  847. orangefs_ioctl32_cleanup();
  848. }
  849. static unsigned int orangefs_devreq_poll(struct file *file,
  850. struct poll_table_struct *poll_table)
  851. {
  852. int poll_revent_mask = 0;
  853. if (open_access_count == 1) {
  854. poll_wait(file, &orangefs_request_list_waitq, poll_table);
  855. spin_lock(&orangefs_request_list_lock);
  856. if (!list_empty(&orangefs_request_list))
  857. poll_revent_mask |= POLL_IN;
  858. spin_unlock(&orangefs_request_list_lock);
  859. }
  860. return poll_revent_mask;
  861. }
  862. const struct file_operations orangefs_devreq_file_operations = {
  863. .owner = THIS_MODULE,
  864. .read = orangefs_devreq_read,
  865. .write_iter = orangefs_devreq_write_iter,
  866. .open = orangefs_devreq_open,
  867. .release = orangefs_devreq_release,
  868. .unlocked_ioctl = orangefs_devreq_ioctl,
  869. #ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */
  870. .compat_ioctl = orangefs_devreq_compat_ioctl,
  871. #endif
  872. .poll = orangefs_devreq_poll
  873. };