devorangefs-req.c 24 KB

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