genlock.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. /* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/fb.h>
  13. #include <linux/slab.h>
  14. #include <linux/module.h>
  15. #include <linux/list.h>
  16. #include <linux/file.h>
  17. #include <linux/sched.h>
  18. #include <linux/fs.h>
  19. #include <linux/wait.h>
  20. #include <linux/uaccess.h>
  21. #include <linux/anon_inodes.h>
  22. #include <linux/miscdevice.h>
  23. #include <linux/genlock.h>
  24. /* Lock states - can either be unlocked, held as an exclusive write lock or a
  25. * shared read lock
  26. */
  27. #define _UNLOCKED 0
  28. #define _RDLOCK GENLOCK_RDLOCK
  29. #define _WRLOCK GENLOCK_WRLOCK
  30. #define GENLOCK_LOG_ERR(fmt, args...) \
  31. pr_err("genlock: %s: " fmt, __func__, ##args)
  32. /* The genlock magic stored in the kernel private data is used to protect
  33. * against the possibility of user space passing a valid fd to a
  34. * non-genlock file for genlock_attach_lock()
  35. */
  36. #define GENLOCK_MAGIC_OK 0xD2EAD10C
  37. #define GENLOCK_MAGIC_BAD 0xD2EADBAD
  38. struct genlock {
  39. unsigned int magic; /* Magic for attach verification */
  40. struct list_head active; /* List of handles holding lock */
  41. spinlock_t lock; /* Spinlock to protect the lock internals */
  42. wait_queue_head_t queue; /* Holding pen for processes pending lock */
  43. struct file *file; /* File structure for exported lock */
  44. int state; /* Current state of the lock */
  45. struct kref refcount;
  46. };
  47. struct genlock_handle {
  48. struct genlock *lock; /* Lock currently attached to the handle */
  49. struct list_head entry; /* List node for attaching to a lock */
  50. struct file *file; /* File structure associated with handle */
  51. int active; /* Number of times the active lock has been
  52. taken */
  53. };
  54. /*
  55. * Create a spinlock to protect against a race condition when a lock gets
  56. * released while another process tries to attach it
  57. */
  58. static DEFINE_SPINLOCK(genlock_ref_lock);
  59. static void genlock_destroy(struct kref *kref)
  60. {
  61. struct genlock *lock = container_of(kref, struct genlock,
  62. refcount);
  63. /*
  64. * Clear the private data for the file descriptor in case the fd is
  65. * still active after the lock gets released
  66. */
  67. if (lock->file)
  68. lock->file->private_data = NULL;
  69. lock->magic = GENLOCK_MAGIC_BAD;
  70. kfree(lock);
  71. }
  72. /*
  73. * Release the genlock object. Called when all the references to
  74. * the genlock file descriptor are released
  75. */
  76. static int genlock_release(struct inode *inodep, struct file *file)
  77. {
  78. struct genlock *lock = file->private_data;
  79. /*
  80. * Clear the refrence back to this file structure to avoid
  81. * somehow reusing the lock after the file has been destroyed
  82. */
  83. if (lock)
  84. lock->file = NULL;
  85. return 0;
  86. }
  87. static const struct file_operations genlock_fops = {
  88. .release = genlock_release,
  89. };
  90. /**
  91. * genlock_create_lock - Create a new lock
  92. * @handle - genlock handle to attach the lock to
  93. *
  94. * Returns: a pointer to the genlock
  95. */
  96. struct genlock *genlock_create_lock(struct genlock_handle *handle)
  97. {
  98. struct genlock *lock;
  99. void *ret;
  100. if (IS_ERR_OR_NULL(handle)) {
  101. GENLOCK_LOG_ERR("Invalid handle\n");
  102. return ERR_PTR(-EINVAL);
  103. }
  104. if (handle->lock != NULL) {
  105. GENLOCK_LOG_ERR("Handle already has a lock attached\n");
  106. return ERR_PTR(-EINVAL);
  107. }
  108. lock = kzalloc(sizeof(*lock), GFP_KERNEL);
  109. if (lock == NULL) {
  110. GENLOCK_LOG_ERR("Unable to allocate memory for a lock\n");
  111. return ERR_PTR(-ENOMEM);
  112. }
  113. INIT_LIST_HEAD(&lock->active);
  114. init_waitqueue_head(&lock->queue);
  115. spin_lock_init(&lock->lock);
  116. lock->magic = GENLOCK_MAGIC_OK;
  117. lock->state = _UNLOCKED;
  118. /*
  119. * Create an anonyonmous inode for the object that can exported to
  120. * other processes
  121. */
  122. ret = anon_inode_getfile("genlock", &genlock_fops, lock, O_RDWR);
  123. if (IS_ERR_OR_NULL(ret)) {
  124. GENLOCK_LOG_ERR("Unable to create lock inode\n");
  125. kfree(lock);
  126. return ret;
  127. }
  128. lock->file = ret;
  129. /* Attach the new lock to the handle */
  130. handle->lock = lock;
  131. kref_init(&lock->refcount);
  132. return lock;
  133. }
  134. EXPORT_SYMBOL(genlock_create_lock);
  135. /*
  136. * Get a file descriptor reference to a lock suitable for sharing with
  137. * other processes
  138. */
  139. static int genlock_get_fd(struct genlock *lock)
  140. {
  141. int ret;
  142. if (!lock->file) {
  143. GENLOCK_LOG_ERR("No file attached to the lock\n");
  144. return -EINVAL;
  145. }
  146. ret = get_unused_fd_flags(0);
  147. if (ret < 0)
  148. return ret;
  149. fd_install(ret, lock->file);
  150. return ret;
  151. }
  152. /**
  153. * genlock_attach_lock - Attach an existing lock to a handle
  154. * @handle - Pointer to a genlock handle to attach the lock to
  155. * @fd - file descriptor for the exported lock
  156. *
  157. * Returns: A pointer to the attached lock structure
  158. */
  159. struct genlock *genlock_attach_lock(struct genlock_handle *handle, int fd)
  160. {
  161. struct file *file;
  162. struct genlock *lock;
  163. if (IS_ERR_OR_NULL(handle)) {
  164. GENLOCK_LOG_ERR("Invalid handle\n");
  165. return ERR_PTR(-EINVAL);
  166. }
  167. if (handle->lock != NULL) {
  168. GENLOCK_LOG_ERR("Handle already has a lock attached\n");
  169. return ERR_PTR(-EINVAL);
  170. }
  171. file = fget(fd);
  172. if (file == NULL) {
  173. GENLOCK_LOG_ERR("Bad file descriptor\n");
  174. return ERR_PTR(-EBADF);
  175. }
  176. /*
  177. * take a spinlock to avoid a race condition if the lock is
  178. * released and then attached
  179. */
  180. spin_lock(&genlock_ref_lock);
  181. lock = file->private_data;
  182. fput(file);
  183. if (lock == NULL) {
  184. GENLOCK_LOG_ERR("File descriptor is invalid\n");
  185. goto fail_invalid;
  186. }
  187. if (lock->magic != GENLOCK_MAGIC_OK) {
  188. GENLOCK_LOG_ERR("Magic is invalid - 0x%X\n", lock->magic);
  189. goto fail_invalid;
  190. }
  191. handle->lock = lock;
  192. kref_get(&lock->refcount);
  193. spin_unlock(&genlock_ref_lock);
  194. return lock;
  195. fail_invalid:
  196. spin_unlock(&genlock_ref_lock);
  197. return ERR_PTR(-EINVAL);
  198. }
  199. EXPORT_SYMBOL(genlock_attach_lock);
  200. /* Helper function that returns 1 if the specified handle holds the lock */
  201. static int handle_has_lock(struct genlock *lock, struct genlock_handle *handle)
  202. {
  203. struct genlock_handle *h;
  204. list_for_each_entry(h, &lock->active, entry) {
  205. if (h == handle)
  206. return 1;
  207. }
  208. return 0;
  209. }
  210. /* If the lock just became available, signal the next entity waiting for it */
  211. static void _genlock_signal(struct genlock *lock)
  212. {
  213. if (list_empty(&lock->active)) {
  214. /* If the list is empty, then the lock is free */
  215. lock->state = _UNLOCKED;
  216. /* Wake up the first process sitting in the queue */
  217. wake_up(&lock->queue);
  218. }
  219. }
  220. /* Attempt to release the handle's ownership of the lock */
  221. static int _genlock_unlock(struct genlock *lock, struct genlock_handle *handle)
  222. {
  223. int ret = -EINVAL;
  224. unsigned long irqflags;
  225. spin_lock_irqsave(&lock->lock, irqflags);
  226. if (lock->state == _UNLOCKED) {
  227. GENLOCK_LOG_ERR("Trying to unlock an unlocked handle\n");
  228. goto done;
  229. }
  230. /* Make sure this handle is an owner of the lock */
  231. if (!handle_has_lock(lock, handle)) {
  232. GENLOCK_LOG_ERR("handle does not have lock attached to it\n");
  233. goto done;
  234. }
  235. /* If the handle holds no more references to the lock then
  236. release it (maybe) */
  237. if (--handle->active == 0) {
  238. list_del(&handle->entry);
  239. _genlock_signal(lock);
  240. }
  241. ret = 0;
  242. done:
  243. spin_unlock_irqrestore(&lock->lock, irqflags);
  244. return ret;
  245. }
  246. /* Attempt to acquire the lock for the handle */
  247. static int _genlock_lock(struct genlock *lock, struct genlock_handle *handle,
  248. int op, int flags, uint32_t timeout)
  249. {
  250. unsigned long irqflags;
  251. int ret = 0;
  252. unsigned long ticks = msecs_to_jiffies(timeout);
  253. spin_lock_irqsave(&lock->lock, irqflags);
  254. /* Sanity check - no blocking locks in a debug context. Even if it
  255. * succeed to not block, the mere idea is too dangerous to continue
  256. */
  257. if (in_interrupt() && !(flags & GENLOCK_NOBLOCK))
  258. BUG();
  259. /* Fast path - the lock is unlocked, so go do the needful */
  260. if (lock->state == _UNLOCKED)
  261. goto dolock;
  262. if (handle_has_lock(lock, handle)) {
  263. /*
  264. * If the handle already holds the lock and the lock type is
  265. * a read lock then just increment the active pointer. This
  266. * allows the handle to do recursive read locks. Recursive
  267. * write locks are not allowed in order to support
  268. * synchronization within a process using a single gralloc
  269. * handle.
  270. */
  271. if (lock->state == _RDLOCK && op == _RDLOCK) {
  272. handle->active++;
  273. goto done;
  274. }
  275. /*
  276. * If the handle holds a write lock then the owner can switch
  277. * to a read lock if they want. Do the transition atomically
  278. * then wake up any pending waiters in case they want a read
  279. * lock too. In order to support synchronization within a
  280. * process the caller must explicity request to convert the
  281. * lock type with the GENLOCK_WRITE_TO_READ flag.
  282. */
  283. if (flags & GENLOCK_WRITE_TO_READ) {
  284. if (lock->state == _WRLOCK && op == _RDLOCK) {
  285. lock->state = _RDLOCK;
  286. wake_up(&lock->queue);
  287. goto done;
  288. } else {
  289. GENLOCK_LOG_ERR("Invalid state to convert"
  290. "write to read\n");
  291. ret = -EINVAL;
  292. goto done;
  293. }
  294. }
  295. } else {
  296. /*
  297. * Check to ensure the caller has not attempted to convert a
  298. * write to a read without holding the lock.
  299. */
  300. if (flags & GENLOCK_WRITE_TO_READ) {
  301. GENLOCK_LOG_ERR("Handle must have lock to convert"
  302. "write to read\n");
  303. ret = -EINVAL;
  304. goto done;
  305. }
  306. /*
  307. * If we request a read and the lock is held by a read, then go
  308. * ahead and share the lock
  309. */
  310. if (op == GENLOCK_RDLOCK && lock->state == _RDLOCK)
  311. goto dolock;
  312. }
  313. /* Treat timeout 0 just like a NOBLOCK flag and return if the
  314. lock cannot be aquired without blocking */
  315. if (flags & GENLOCK_NOBLOCK || timeout == 0) {
  316. ret = -EAGAIN;
  317. goto done;
  318. }
  319. /*
  320. * Wait while the lock remains in an incompatible state
  321. * state op wait
  322. * -------------------
  323. * unlocked n/a no
  324. * read read no
  325. * read write yes
  326. * write n/a yes
  327. */
  328. while ((lock->state == _RDLOCK && op == _WRLOCK) ||
  329. lock->state == _WRLOCK) {
  330. signed long elapsed;
  331. spin_unlock_irqrestore(&lock->lock, irqflags);
  332. elapsed = wait_event_interruptible_timeout(lock->queue,
  333. lock->state == _UNLOCKED ||
  334. (lock->state == _RDLOCK && op == _RDLOCK),
  335. ticks);
  336. spin_lock_irqsave(&lock->lock, irqflags);
  337. if (elapsed <= 0) {
  338. ret = (elapsed < 0) ? elapsed : -ETIMEDOUT;
  339. goto done;
  340. }
  341. ticks = (unsigned long) elapsed;
  342. }
  343. dolock:
  344. /* We can now get the lock, add ourselves to the list of owners */
  345. list_add_tail(&handle->entry, &lock->active);
  346. lock->state = op;
  347. handle->active++;
  348. done:
  349. spin_unlock_irqrestore(&lock->lock, irqflags);
  350. return ret;
  351. }
  352. /**
  353. * genlock_lock - Acquire or release a lock (depreciated)
  354. * @handle - pointer to the genlock handle that is requesting the lock
  355. * @op - the operation to perform (RDLOCK, WRLOCK, UNLOCK)
  356. * @flags - flags to control the operation
  357. * @timeout - optional timeout to wait for the lock to come free
  358. *
  359. * Returns: 0 on success or error code on failure
  360. */
  361. int genlock_lock(struct genlock_handle *handle, int op, int flags,
  362. uint32_t timeout)
  363. {
  364. struct genlock *lock;
  365. unsigned long irqflags;
  366. int ret = 0;
  367. if (IS_ERR_OR_NULL(handle)) {
  368. GENLOCK_LOG_ERR("Invalid handle\n");
  369. return -EINVAL;
  370. }
  371. lock = handle->lock;
  372. if (lock == NULL) {
  373. GENLOCK_LOG_ERR("Handle does not have a lock attached\n");
  374. return -EINVAL;
  375. }
  376. switch (op) {
  377. case GENLOCK_UNLOCK:
  378. ret = _genlock_unlock(lock, handle);
  379. break;
  380. case GENLOCK_RDLOCK:
  381. spin_lock_irqsave(&lock->lock, irqflags);
  382. if (handle_has_lock(lock, handle)) {
  383. /* request the WRITE_TO_READ flag for compatibility */
  384. flags |= GENLOCK_WRITE_TO_READ;
  385. }
  386. spin_unlock_irqrestore(&lock->lock, irqflags);
  387. /* fall through to take lock */
  388. case GENLOCK_WRLOCK:
  389. ret = _genlock_lock(lock, handle, op, flags, timeout);
  390. break;
  391. default:
  392. GENLOCK_LOG_ERR("Invalid lock operation\n");
  393. ret = -EINVAL;
  394. break;
  395. }
  396. return ret;
  397. }
  398. EXPORT_SYMBOL(genlock_lock);
  399. /**
  400. * genlock_dreadlock - Acquire or release a lock
  401. * @handle - pointer to the genlock handle that is requesting the lock
  402. * @op - the operation to perform (RDLOCK, WRLOCK, UNLOCK)
  403. * @flags - flags to control the operation
  404. * @timeout - optional timeout to wait for the lock to come free
  405. *
  406. * Returns: 0 on success or error code on failure
  407. */
  408. int genlock_dreadlock(struct genlock_handle *handle, int op, int flags,
  409. uint32_t timeout)
  410. {
  411. struct genlock *lock;
  412. int ret = 0;
  413. if (IS_ERR_OR_NULL(handle)) {
  414. GENLOCK_LOG_ERR("Invalid handle\n");
  415. return -EINVAL;
  416. }
  417. lock = handle->lock;
  418. if (lock == NULL) {
  419. GENLOCK_LOG_ERR("Handle does not have a lock attached\n");
  420. return -EINVAL;
  421. }
  422. switch (op) {
  423. case GENLOCK_UNLOCK:
  424. ret = _genlock_unlock(lock, handle);
  425. break;
  426. case GENLOCK_RDLOCK:
  427. case GENLOCK_WRLOCK:
  428. ret = _genlock_lock(lock, handle, op, flags, timeout);
  429. break;
  430. default:
  431. GENLOCK_LOG_ERR("Invalid lock operation\n");
  432. ret = -EINVAL;
  433. break;
  434. }
  435. return ret;
  436. }
  437. EXPORT_SYMBOL(genlock_dreadlock);
  438. /**
  439. * genlock_wait - Wait for the lock to be released
  440. * @handle - pointer to the genlock handle that is waiting for the lock
  441. * @timeout - optional timeout to wait for the lock to get released
  442. */
  443. int genlock_wait(struct genlock_handle *handle, uint32_t timeout)
  444. {
  445. struct genlock *lock;
  446. unsigned long irqflags;
  447. int ret = 0;
  448. unsigned long ticks = msecs_to_jiffies(timeout);
  449. if (IS_ERR_OR_NULL(handle)) {
  450. GENLOCK_LOG_ERR("Invalid handle\n");
  451. return -EINVAL;
  452. }
  453. lock = handle->lock;
  454. if (lock == NULL) {
  455. GENLOCK_LOG_ERR("Handle does not have a lock attached\n");
  456. return -EINVAL;
  457. }
  458. spin_lock_irqsave(&lock->lock, irqflags);
  459. /*
  460. * if timeout is 0 and the lock is already unlocked, then success
  461. * otherwise return -EAGAIN
  462. */
  463. if (timeout == 0) {
  464. ret = (lock->state == _UNLOCKED) ? 0 : -EAGAIN;
  465. goto done;
  466. }
  467. while (lock->state != _UNLOCKED) {
  468. signed long elapsed;
  469. spin_unlock_irqrestore(&lock->lock, irqflags);
  470. elapsed = wait_event_interruptible_timeout(lock->queue,
  471. lock->state == _UNLOCKED, ticks);
  472. spin_lock_irqsave(&lock->lock, irqflags);
  473. if (elapsed <= 0) {
  474. ret = (elapsed < 0) ? elapsed : -ETIMEDOUT;
  475. break;
  476. }
  477. ticks = (unsigned long) elapsed;
  478. }
  479. done:
  480. spin_unlock_irqrestore(&lock->lock, irqflags);
  481. return ret;
  482. }
  483. static void genlock_release_lock(struct genlock_handle *handle)
  484. {
  485. unsigned long flags;
  486. if (handle == NULL || handle->lock == NULL)
  487. return;
  488. spin_lock_irqsave(&handle->lock->lock, flags);
  489. /* If the handle is holding the lock, then force it closed */
  490. if (handle_has_lock(handle->lock, handle)) {
  491. list_del(&handle->entry);
  492. _genlock_signal(handle->lock);
  493. }
  494. spin_unlock_irqrestore(&handle->lock->lock, flags);
  495. spin_lock(&genlock_ref_lock);
  496. kref_put(&handle->lock->refcount, genlock_destroy);
  497. spin_unlock(&genlock_ref_lock);
  498. handle->lock = NULL;
  499. handle->active = 0;
  500. }
  501. /*
  502. * Release function called when all references to a handle are released
  503. */
  504. static int genlock_handle_release(struct inode *inodep, struct file *file)
  505. {
  506. struct genlock_handle *handle = file->private_data;
  507. genlock_release_lock(handle);
  508. kfree(handle);
  509. return 0;
  510. }
  511. static const struct file_operations genlock_handle_fops = {
  512. .release = genlock_handle_release
  513. };
  514. /*
  515. * Allocate a new genlock handle
  516. */
  517. static struct genlock_handle *_genlock_get_handle(void)
  518. {
  519. struct genlock_handle *handle = kzalloc(sizeof(*handle), GFP_KERNEL);
  520. if (handle == NULL) {
  521. GENLOCK_LOG_ERR("Unable to allocate memory for the handle\n");
  522. return ERR_PTR(-ENOMEM);
  523. }
  524. return handle;
  525. }
  526. /**
  527. * genlock_get_handle - Create a new genlock handle
  528. *
  529. * Returns: A pointer to a new genlock handle
  530. */
  531. struct genlock_handle *genlock_get_handle(void)
  532. {
  533. void *ret;
  534. struct genlock_handle *handle = _genlock_get_handle();
  535. if (IS_ERR(handle))
  536. return handle;
  537. ret = anon_inode_getfile("genlock-handle",
  538. &genlock_handle_fops, handle, O_RDWR);
  539. if (IS_ERR_OR_NULL(ret)) {
  540. GENLOCK_LOG_ERR("Unable to create handle inode\n");
  541. kfree(handle);
  542. return ret;
  543. }
  544. handle->file = ret;
  545. return handle;
  546. }
  547. EXPORT_SYMBOL(genlock_get_handle);
  548. /**
  549. * genlock_put_handle - release a reference to a genlock handle
  550. * @handle - A pointer to the handle to release
  551. */
  552. void genlock_put_handle(struct genlock_handle *handle)
  553. {
  554. if (handle)
  555. fput(handle->file);
  556. }
  557. EXPORT_SYMBOL(genlock_put_handle);
  558. /**
  559. * genlock_get_handle_fd - Get a handle reference from a file descriptor
  560. * @fd - The file descriptor for a genlock handle
  561. */
  562. struct genlock_handle *genlock_get_handle_fd(int fd)
  563. {
  564. struct file *file = fget(fd);
  565. if (file == NULL)
  566. return ERR_PTR(-EINVAL);
  567. return file->private_data;
  568. }
  569. EXPORT_SYMBOL(genlock_get_handle_fd);
  570. /*
  571. * Get a file descriptor reference to a lock suitable for sharing with
  572. * other processes
  573. */
  574. int genlock_get_fd_handle(struct genlock_handle *handle)
  575. {
  576. int ret;
  577. struct genlock *lock;
  578. if (IS_ERR_OR_NULL(handle))
  579. return -EINVAL;
  580. lock = handle->lock;
  581. if (IS_ERR(lock))
  582. return PTR_ERR(lock);
  583. if (!lock->file) {
  584. GENLOCK_LOG_ERR("No file attached to the lock\n");
  585. return -EINVAL;
  586. }
  587. ret = get_unused_fd_flags(0);
  588. if (ret < 0)
  589. return ret;
  590. fd_install(ret, lock->file);
  591. /*
  592. * Taking a reference for lock file.
  593. * This is required as now we have two file descriptor
  594. * pointing to same file. If one FD is closed, lock file
  595. * will be closed. Taking this reference will make sure
  596. * that file doesn't get close. This refrence will go
  597. * when client will call close on this FD.
  598. */
  599. fget(ret);
  600. return ret;
  601. }
  602. EXPORT_SYMBOL(genlock_get_fd_handle);
  603. #ifdef CONFIG_GENLOCK_MISCDEVICE
  604. static long genlock_dev_ioctl(struct file *filep, unsigned int cmd,
  605. unsigned long arg)
  606. {
  607. struct genlock_lock param;
  608. struct genlock_handle *handle = filep->private_data;
  609. struct genlock *lock;
  610. int ret;
  611. if (IS_ERR_OR_NULL(handle))
  612. return -EINVAL;
  613. switch (cmd) {
  614. case GENLOCK_IOC_NEW: {
  615. lock = genlock_create_lock(handle);
  616. if (IS_ERR(lock))
  617. return PTR_ERR(lock);
  618. return 0;
  619. }
  620. case GENLOCK_IOC_EXPORT: {
  621. if (handle->lock == NULL) {
  622. GENLOCK_LOG_ERR("Handle does not have a lock"
  623. "attached\n");
  624. return -EINVAL;
  625. }
  626. ret = genlock_get_fd(handle->lock);
  627. if (ret < 0)
  628. return ret;
  629. memset(&param, 0, sizeof(param));
  630. param.fd = ret;
  631. if (copy_to_user((void __user *) arg, &param,
  632. sizeof(param)))
  633. return -EFAULT;
  634. return 0;
  635. }
  636. case GENLOCK_IOC_ATTACH: {
  637. if (copy_from_user(&param, (void __user *) arg,
  638. sizeof(param)))
  639. return -EFAULT;
  640. lock = genlock_attach_lock(handle, param.fd);
  641. if (IS_ERR(lock))
  642. return PTR_ERR(lock);
  643. return 0;
  644. }
  645. case GENLOCK_IOC_LOCK: {
  646. if (copy_from_user(&param, (void __user *) arg,
  647. sizeof(param)))
  648. return -EFAULT;
  649. return genlock_lock(handle, param.op, param.flags,
  650. param.timeout);
  651. }
  652. case GENLOCK_IOC_DREADLOCK: {
  653. if (copy_from_user(&param, (void __user *) arg,
  654. sizeof(param)))
  655. return -EFAULT;
  656. return genlock_dreadlock(handle, param.op, param.flags,
  657. param.timeout);
  658. }
  659. case GENLOCK_IOC_WAIT: {
  660. if (copy_from_user(&param, (void __user *) arg,
  661. sizeof(param)))
  662. return -EFAULT;
  663. return genlock_wait(handle, param.timeout);
  664. }
  665. case GENLOCK_IOC_RELEASE: {
  666. /*
  667. * Return error - this ioctl has been deprecated.
  668. * Locks should only be released when the handle is
  669. * destroyed
  670. */
  671. GENLOCK_LOG_ERR("Deprecated RELEASE ioctl called\n");
  672. return -EINVAL;
  673. }
  674. default:
  675. GENLOCK_LOG_ERR("Invalid ioctl\n");
  676. return -EINVAL;
  677. }
  678. }
  679. static int genlock_dev_release(struct inode *inodep, struct file *file)
  680. {
  681. struct genlock_handle *handle = file->private_data;
  682. genlock_release_lock(handle);
  683. kfree(handle);
  684. return 0;
  685. }
  686. static int genlock_dev_open(struct inode *inodep, struct file *file)
  687. {
  688. struct genlock_handle *handle = _genlock_get_handle();
  689. if (IS_ERR(handle))
  690. return PTR_ERR(handle);
  691. handle->file = file;
  692. file->private_data = handle;
  693. return 0;
  694. }
  695. static const struct file_operations genlock_dev_fops = {
  696. .open = genlock_dev_open,
  697. .release = genlock_dev_release,
  698. .unlocked_ioctl = genlock_dev_ioctl,
  699. };
  700. static struct miscdevice genlock_dev;
  701. static int genlock_dev_init(void)
  702. {
  703. genlock_dev.minor = MISC_DYNAMIC_MINOR;
  704. genlock_dev.name = "genlock";
  705. genlock_dev.fops = &genlock_dev_fops;
  706. genlock_dev.parent = NULL;
  707. return misc_register(&genlock_dev);
  708. }
  709. static void genlock_dev_close(void)
  710. {
  711. misc_deregister(&genlock_dev);
  712. }
  713. module_init(genlock_dev_init);
  714. module_exit(genlock_dev_close);
  715. #endif