aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2009-04-14 13:48:41 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-04-15 06:10:12 -0400
commit61e0d47c33cc371f725bcda4a47ae0efe652dba8 (patch)
treee00f99b506f1c1a16e3ba987e3390deda6bd2e03 /fs
parentf8cc774ce4844811a55e2352f1443055e3994e28 (diff)
splice: add helpers for locking pipe inode
There are lots of sequences like this, especially in splice code: if (pipe->inode) mutex_lock(&pipe->inode->i_mutex); /* do something */ if (pipe->inode) mutex_unlock(&pipe->inode->i_mutex); so introduce helpers which do the conditional locking and unlocking. Also replace the inode_double_lock() call with a pipe_double_lock() helper to avoid spreading the use of this functionality beyond the pipe code. This patch is just a cleanup, and should cause no behavioral changes. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/inode.c36
-rw-r--r--fs/pipe.c42
-rw-r--r--fs/splice.c50
3 files changed, 59 insertions, 69 deletions
diff --git a/fs/inode.c b/fs/inode.c
index d06d6d268de9..6ad14a1cd8c9 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1470,42 +1470,6 @@ static void __wait_on_freeing_inode(struct inode *inode)
1470 spin_lock(&inode_lock); 1470 spin_lock(&inode_lock);
1471} 1471}
1472 1472
1473/*
1474 * We rarely want to lock two inodes that do not have a parent/child
1475 * relationship (such as directory, child inode) simultaneously. The
1476 * vast majority of file systems should be able to get along fine
1477 * without this. Do not use these functions except as a last resort.
1478 */
1479void inode_double_lock(struct inode *inode1, struct inode *inode2)
1480{
1481 if (inode1 == NULL || inode2 == NULL || inode1 == inode2) {
1482 if (inode1)
1483 mutex_lock(&inode1->i_mutex);
1484 else if (inode2)
1485 mutex_lock(&inode2->i_mutex);
1486 return;
1487 }
1488
1489 if (inode1 < inode2) {
1490 mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT);
1491 mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD);
1492 } else {
1493 mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
1494 mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
1495 }
1496}
1497EXPORT_SYMBOL(inode_double_lock);
1498
1499void inode_double_unlock(struct inode *inode1, struct inode *inode2)
1500{
1501 if (inode1)
1502 mutex_unlock(&inode1->i_mutex);
1503
1504 if (inode2 && inode2 != inode1)
1505 mutex_unlock(&inode2->i_mutex);
1506}
1507EXPORT_SYMBOL(inode_double_unlock);
1508
1509static __initdata unsigned long ihash_entries; 1473static __initdata unsigned long ihash_entries;
1510static int __init set_ihash_entries(char *str) 1474static int __init set_ihash_entries(char *str)
1511{ 1475{
diff --git a/fs/pipe.c b/fs/pipe.c
index 4af7aa521813..13414ec45b8d 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -37,6 +37,42 @@
37 * -- Manfred Spraul <manfred@colorfullife.com> 2002-05-09 37 * -- Manfred Spraul <manfred@colorfullife.com> 2002-05-09
38 */ 38 */
39 39
40static void pipe_lock_nested(struct pipe_inode_info *pipe, int subclass)
41{
42 if (pipe->inode)
43 mutex_lock_nested(&pipe->inode->i_mutex, subclass);
44}
45
46void pipe_lock(struct pipe_inode_info *pipe)
47{
48 /*
49 * pipe_lock() nests non-pipe inode locks (for writing to a file)
50 */
51 pipe_lock_nested(pipe, I_MUTEX_PARENT);
52}
53EXPORT_SYMBOL(pipe_lock);
54
55void pipe_unlock(struct pipe_inode_info *pipe)
56{
57 if (pipe->inode)
58 mutex_unlock(&pipe->inode->i_mutex);
59}
60EXPORT_SYMBOL(pipe_unlock);
61
62void pipe_double_lock(struct pipe_inode_info *pipe1,
63 struct pipe_inode_info *pipe2)
64{
65 BUG_ON(pipe1 == pipe2);
66
67 if (pipe1 < pipe2) {
68 pipe_lock_nested(pipe1, I_MUTEX_PARENT);
69 pipe_lock_nested(pipe2, I_MUTEX_CHILD);
70 } else {
71 pipe_lock_nested(pipe2, I_MUTEX_CHILD);
72 pipe_lock_nested(pipe1, I_MUTEX_PARENT);
73 }
74}
75
40/* Drop the inode semaphore and wait for a pipe event, atomically */ 76/* Drop the inode semaphore and wait for a pipe event, atomically */
41void pipe_wait(struct pipe_inode_info *pipe) 77void pipe_wait(struct pipe_inode_info *pipe)
42{ 78{
@@ -47,12 +83,10 @@ void pipe_wait(struct pipe_inode_info *pipe)
47 * is considered a noninteractive wait: 83 * is considered a noninteractive wait:
48 */ 84 */
49 prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE); 85 prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
50 if (pipe->inode) 86 pipe_unlock(pipe);
51 mutex_unlock(&pipe->inode->i_mutex);
52 schedule(); 87 schedule();
53 finish_wait(&pipe->wait, &wait); 88 finish_wait(&pipe->wait, &wait);
54 if (pipe->inode) 89 pipe_lock(pipe);
55 mutex_lock(&pipe->inode->i_mutex);
56} 90}
57 91
58static int 92static int
diff --git a/fs/splice.c b/fs/splice.c
index 128ee36a719b..5384a90665d0 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -182,8 +182,7 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
182 do_wakeup = 0; 182 do_wakeup = 0;
183 page_nr = 0; 183 page_nr = 0;
184 184
185 if (pipe->inode) 185 pipe_lock(pipe);
186 mutex_lock(&pipe->inode->i_mutex);
187 186
188 for (;;) { 187 for (;;) {
189 if (!pipe->readers) { 188 if (!pipe->readers) {
@@ -245,15 +244,13 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
245 pipe->waiting_writers--; 244 pipe->waiting_writers--;
246 } 245 }
247 246
248 if (pipe->inode) { 247 pipe_unlock(pipe);
249 mutex_unlock(&pipe->inode->i_mutex);
250 248
251 if (do_wakeup) { 249 if (do_wakeup) {
252 smp_mb(); 250 smp_mb();
253 if (waitqueue_active(&pipe->wait)) 251 if (waitqueue_active(&pipe->wait))
254 wake_up_interruptible(&pipe->wait); 252 wake_up_interruptible(&pipe->wait);
255 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); 253 kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
256 }
257 } 254 }
258 255
259 while (page_nr < spd_pages) 256 while (page_nr < spd_pages)
@@ -801,11 +798,9 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
801 .u.file = out, 798 .u.file = out,
802 }; 799 };
803 800
804 if (pipe->inode) 801 pipe_lock(pipe);
805 mutex_lock(&pipe->inode->i_mutex);
806 ret = __splice_from_pipe(pipe, &sd, actor); 802 ret = __splice_from_pipe(pipe, &sd, actor);
807 if (pipe->inode) 803 pipe_unlock(pipe);
808 mutex_unlock(&pipe->inode->i_mutex);
809 804
810 return ret; 805 return ret;
811} 806}
@@ -837,8 +832,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
837 }; 832 };
838 ssize_t ret; 833 ssize_t ret;
839 834
840 if (pipe->inode) 835 pipe_lock(pipe);
841 mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT);
842 836
843 splice_from_pipe_begin(&sd); 837 splice_from_pipe_begin(&sd);
844 do { 838 do {
@@ -854,8 +848,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
854 } while (ret > 0); 848 } while (ret > 0);
855 splice_from_pipe_end(pipe, &sd); 849 splice_from_pipe_end(pipe, &sd);
856 850
857 if (pipe->inode) 851 pipe_unlock(pipe);
858 mutex_unlock(&pipe->inode->i_mutex);
859 852
860 if (sd.num_spliced) 853 if (sd.num_spliced)
861 ret = sd.num_spliced; 854 ret = sd.num_spliced;
@@ -1348,8 +1341,7 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *iov,
1348 if (!pipe) 1341 if (!pipe)
1349 return -EBADF; 1342 return -EBADF;
1350 1343
1351 if (pipe->inode) 1344 pipe_lock(pipe);
1352 mutex_lock(&pipe->inode->i_mutex);
1353 1345
1354 error = ret = 0; 1346 error = ret = 0;
1355 while (nr_segs) { 1347 while (nr_segs) {
@@ -1404,8 +1396,7 @@ static long vmsplice_to_user(struct file *file, const struct iovec __user *iov,
1404 iov++; 1396 iov++;
1405 } 1397 }
1406 1398
1407 if (pipe->inode) 1399 pipe_unlock(pipe);
1408 mutex_unlock(&pipe->inode->i_mutex);
1409 1400
1410 if (!ret) 1401 if (!ret)
1411 ret = error; 1402 ret = error;
@@ -1533,7 +1524,7 @@ static int link_ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
1533 return 0; 1524 return 0;
1534 1525
1535 ret = 0; 1526 ret = 0;
1536 mutex_lock(&pipe->inode->i_mutex); 1527 pipe_lock(pipe);
1537 1528
1538 while (!pipe->nrbufs) { 1529 while (!pipe->nrbufs) {
1539 if (signal_pending(current)) { 1530 if (signal_pending(current)) {
@@ -1551,7 +1542,7 @@ static int link_ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
1551 pipe_wait(pipe); 1542 pipe_wait(pipe);
1552 } 1543 }
1553 1544
1554 mutex_unlock(&pipe->inode->i_mutex); 1545 pipe_unlock(pipe);
1555 return ret; 1546 return ret;
1556} 1547}
1557 1548
@@ -1571,7 +1562,7 @@ static int link_opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
1571 return 0; 1562 return 0;
1572 1563
1573 ret = 0; 1564 ret = 0;
1574 mutex_lock(&pipe->inode->i_mutex); 1565 pipe_lock(pipe);
1575 1566
1576 while (pipe->nrbufs >= PIPE_BUFFERS) { 1567 while (pipe->nrbufs >= PIPE_BUFFERS) {
1577 if (!pipe->readers) { 1568 if (!pipe->readers) {
@@ -1592,7 +1583,7 @@ static int link_opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
1592 pipe->waiting_writers--; 1583 pipe->waiting_writers--;
1593 } 1584 }
1594 1585
1595 mutex_unlock(&pipe->inode->i_mutex); 1586 pipe_unlock(pipe);
1596 return ret; 1587 return ret;
1597} 1588}
1598 1589
@@ -1608,10 +1599,10 @@ static int link_pipe(struct pipe_inode_info *ipipe,
1608 1599
1609 /* 1600 /*
1610 * Potential ABBA deadlock, work around it by ordering lock 1601 * Potential ABBA deadlock, work around it by ordering lock
1611 * grabbing by inode address. Otherwise two different processes 1602 * grabbing by pipe info address. Otherwise two different processes
1612 * could deadlock (one doing tee from A -> B, the other from B -> A). 1603 * could deadlock (one doing tee from A -> B, the other from B -> A).
1613 */ 1604 */
1614 inode_double_lock(ipipe->inode, opipe->inode); 1605 pipe_double_lock(ipipe, opipe);
1615 1606
1616 do { 1607 do {
1617 if (!opipe->readers) { 1608 if (!opipe->readers) {
@@ -1662,7 +1653,8 @@ static int link_pipe(struct pipe_inode_info *ipipe,
1662 if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK)) 1653 if (!ret && ipipe->waiting_writers && (flags & SPLICE_F_NONBLOCK))
1663 ret = -EAGAIN; 1654 ret = -EAGAIN;
1664 1655
1665 inode_double_unlock(ipipe->inode, opipe->inode); 1656 pipe_unlock(ipipe);
1657 pipe_unlock(opipe);
1666 1658
1667 /* 1659 /*
1668 * If we put data in the output pipe, wakeup any potential readers. 1660 * If we put data in the output pipe, wakeup any potential readers.