aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2006-04-19 09:56:40 -0400
committerJens Axboe <axboe@suse.de>2006-04-19 09:56:40 -0400
commit2a27250e6cf47ca1ea3bea0a55e4b7889c097627 (patch)
tree3dbd4747df21e72420ab6fb91fc174173903c803
parentc4f895cbe1e95aab633207fb19c650b7c984c01a (diff)
[PATCH] tee: link_pipe() must be careful when dropping one of the pipe locks
We need to ensure that we only drop a lock that is ordered last, to avoid ABBA deadlocks with competing processes. Signed-off-by: Jens Axboe <axboe@suse.de>
-rw-r--r--fs/splice.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/splice.c b/fs/splice.c
index 78cd264340f2..4f5e6b09fb26 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1012,7 +1012,9 @@ static int link_pipe(struct pipe_inode_info *ipipe,
1012 size_t len, unsigned int flags) 1012 size_t len, unsigned int flags)
1013{ 1013{
1014 struct pipe_buffer *ibuf, *obuf; 1014 struct pipe_buffer *ibuf, *obuf;
1015 int ret = 0, do_wakeup = 0, i; 1015 int ret, do_wakeup, i, ipipe_first;
1016
1017 ret = do_wakeup = ipipe_first = 0;
1016 1018
1017 /* 1019 /*
1018 * Potential ABBA deadlock, work around it by ordering lock 1020 * Potential ABBA deadlock, work around it by ordering lock
@@ -1020,6 +1022,7 @@ static int link_pipe(struct pipe_inode_info *ipipe,
1020 * could deadlock (one doing tee from A -> B, the other from B -> A). 1022 * could deadlock (one doing tee from A -> B, the other from B -> A).
1021 */ 1023 */
1022 if (ipipe->inode < opipe->inode) { 1024 if (ipipe->inode < opipe->inode) {
1025 ipipe_first = 1;
1023 mutex_lock(&ipipe->inode->i_mutex); 1026 mutex_lock(&ipipe->inode->i_mutex);
1024 mutex_lock(&opipe->inode->i_mutex); 1027 mutex_lock(&opipe->inode->i_mutex);
1025 } else { 1028 } else {
@@ -1068,9 +1071,11 @@ static int link_pipe(struct pipe_inode_info *ipipe,
1068 1071
1069 /* 1072 /*
1070 * We have input available, but no output room. 1073 * We have input available, but no output room.
1071 * If we already copied data, return that. 1074 * If we already copied data, return that. If we
1075 * need to drop the opipe lock, it must be ordered
1076 * last to avoid deadlocks.
1072 */ 1077 */
1073 if (flags & SPLICE_F_NONBLOCK) { 1078 if ((flags & SPLICE_F_NONBLOCK) || !ipipe_first) {
1074 if (!ret) 1079 if (!ret)
1075 ret = -EAGAIN; 1080 ret = -EAGAIN;
1076 break; 1081 break;
@@ -1104,7 +1109,12 @@ static int link_pipe(struct pipe_inode_info *ipipe,
1104 if (ret) 1109 if (ret)
1105 break; 1110 break;
1106 } 1111 }
1107 if (flags & SPLICE_F_NONBLOCK) { 1112 /*
1113 * pipe_wait() drops the ipipe mutex. To avoid deadlocks
1114 * with another process, we can only safely do that if
1115 * the ipipe lock is ordered last.
1116 */
1117 if ((flags & SPLICE_F_NONBLOCK) || ipipe_first) {
1108 if (!ret) 1118 if (!ret)
1109 ret = -EAGAIN; 1119 ret = -EAGAIN;
1110 break; 1120 break;