Skip to contentSkip to conversation

fs: block pipe_write() on a frozen filesystem

PATCH In review Eric Sandeen 4 participants 5 messages Sep 27, 2012 – Apr 2, 2013 VFS

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 fs: block pipe_write() on a frozen filesystem

I noticed that this can sneak past a frozen filesystem:

# mkfifo /mnt/test/fifo
# echo foo > /mnt/test/fifo &
# fsfreeze -f /mnt/test
# cat /mnt/test/fifo

and we get a warning that jbd2 has entered a transaction while frozen:

WARNING: at fs/ext4/super.c:240 ext4_journal_start_sb+0xce/0xe0 [ext4]() (Not tainted)

which is: WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE);

and we get there via the file_update_time() path in pipe_write().

---

Is this too big a hammer? file_update_time() is conditional...

fs/pipe.c +2 -0
index 8d85d70..d19a709 100644
@@ -501,6 +501,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
 
 	do_wakeup = 0;
 	ret = 0;
+	sb_start_write(inode->i_sb);
 	mutex_lock(&inode->i_mutex);
 	pipe = inode->i_pipe;
 
@@ -659,6 +660,7 @@ out:
 		if (err)
 			ret = err;
 	}
+	sb_end_write(inode->i_sb);
 	return ret;
 }
 
reviewer Reviewed-by on v1 1/1
#1 lore raw
Quoted 11 lines · Eric Sandeen

I noticed that this can sneak past a frozen filesystem:

# mkfifo /mnt/test/fifo
# echo foo > /mnt/test/fifo &
# fsfreeze -f /mnt/test
# cat /mnt/test/fifo

and we get a warning that jbd2 has entered a transaction while frozen:

WARNING: at fs/ext4/super.c:240 ext4_journal_start_sb+0xce/0xe0 [ext4]() (Not tainted)
Quoted 8 lines

which is: WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE);

and we get there via the file_update_time() path in pipe_write().

---

Is this too big a hammer? file_update_time() is conditional...

I think your patch is fine. Just skipping update of mtime could cause
userspace issues (although they seem rather unlikely to me). So you can add

Honza

Quoted 22 lines
fs/pipe.c +2 -0
index 8d85d70..d19a709 100644
@@ -501,6 +501,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
 
 	do_wakeup = 0;
 	ret = 0;
+	sb_start_write(inode->i_sb);
 	mutex_lock(&inode->i_mutex);
 	pipe = inode->i_pipe;
 
@@ -659,6 +660,7 @@ out:
 		if (err)
 			ret = err;
 	}
+	sb_end_write(inode->i_sb);
 	return ret;
 }
 
#2 lore raw

Re: [PATCH] fs: block pipe_write() on a frozen filesystem PING..

In reply to Eric Sandeen
Quoted 1 line · Eric Sandeen

I noticed that this can sneak past a frozen filesystem:

Ping.. any body want to take care about that patch?

Quoted 44 lines
# mkfifo /mnt/test/fifo
# echo foo > /mnt/test/fifo &
# fsfreeze -f /mnt/test
# cat /mnt/test/fifo

and we get a warning that jbd2 has entered a transaction while frozen:

WARNING: at fs/ext4/super.c:240 ext4_journal_start_sb+0xce/0xe0 [ext4]() (Not tainted)

which is: WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE);

and we get there via the file_update_time() path in pipe_write().

---

Is this too big a hammer? file_update_time() is conditional...

fs/pipe.c +2 -1
index 8d85d70..d19a709 100644
@@ -501,6 +501,7 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov,
 
 	do_wakeup = 0;
 	ret = 0;
+	sb_start_write(inode->i_sb);
 	mutex_lock(&inode->i_mutex);
 	pipe = inode->i_pipe;
 
@@ -659,6 +660,7 @@ out:
 		if (err)
 			ret = err;
 	}
+	sb_end_write(inode->i_sb);
 	return ret;
 }
 
 
--

To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

maintainer
#3 lore raw

Re: [PATCH] fs: block pipe_write() on a frozen filesystem PING..

Quoted 3 lines · Dmitry Monakhov
Quoted 1 line · Eric Sandeen

I noticed that this can sneak past a frozen filesystem:

Ping.. any body want to take care about that patch?

NAK. Note that writing to FIFO that sits on filesystem that is outright read-only is allowed just fine; blocking it for frozen ones is bogus.

IOW, it should be treated the same way we treat touch_atime(). Moreover, it should only be done around file_update_time(). With trylock.

#4 lore raw

Re: [PATCH] fs: block pipe_write() on a frozen filesystem PING..

Quoted 10 lines · Al Viro
Quoted 3 lines · Dmitry Monakhov
Quoted 1 line · Eric Sandeen

I noticed that this can sneak past a frozen filesystem:

Ping.. any body want to take care about that patch?

NAK. Note that writing to FIFO that sits on filesystem that is outright read-only is allowed just fine; blocking it for frozen ones is bogus.

IOW, it should be treated the same way we treat touch_atime(). Moreover, it should only be done around file_update_time(). With trylock.

Ok fair enough.
Please take a look at updated version

Quoted 1 line

From c01acb73b8dc9e7a891b8f087ad3eb53bb06d270 Mon Sep 17 00:00:00 2001

From: Dmitry Monakhov <[email protected]>
Date: Wed, 3 Apr 2013 00:19:15 +0400
Subject: [PATCH] [PATCH] fs: skip mtime update for fifo on a frozen filesystem

Eric noticed that this can sneak past a frozen filesystem:

# mkfifo /mnt/test/fifo
# echo foo > /mnt/test/fifo &
# fsfreeze -f /mnt/test
# cat /mnt/test/fifo
and we get a warning that jbd2 has entered a transaction while frozen:
WARNING: at fs/ext4/super.c:240 ext4_journal_start_sb+0xce/0xe0 [ext4]() (Not tainted)
which is: WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE);
and we get there via the file_update_time() path in pipe_write().
If filesystem is frozen we can block pipe_write() but this is not optimal
because fifo is special_file so let's skip mtime update as we do
with touch_atime()
---
 fs/pipe.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
fs/pipe.c +2 -1
index 2234f3f..62f63d5 100644
@@ -654,10 +654,11 @@ out:
 		wake_up_interruptible_sync_poll(&pipe->wait, POLLIN | POLLRDNORM);
 		kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
 	}
-	if (ret > 0) {
+	if (ret > 0 && sb_start_write_trylock(inode->i_sb)) {
 		int err = file_update_time(filp);
 		if (err)
 			ret = err;
+		sb_end_write(inode->i_sb);
 	}
 	return ret;
 }
Signature · 1 line
1.7.1