Thread (29 messages) 29 messages, 3 authors, 2012-10-05

Re: [PATCH 7/9] fsfreeze: freeze_super and thaw_bdev don't play well together

From: Jan Kara <jack@suse.cz>
Date: 2012-09-26 09:09:59

On Wed 26-09-12 17:22:53, Fernando Luis Vazquez Cao wrote:
On 2012/09/26 01:39, Jan Kara wrote:
quoted
quoted
quoted
quoted
@@ -1365,29 +1363,27 @@ static void sb_wait_write(struct super_b
  * freezing. Then we transition to SB_FREEZE_COMPLETE state. This state is
  * mostly auxiliary for filesystems to verify they do not modify frozen fs.
  *
- * sb->s_writers.frozen is protected by sb->s_umount.
+ * sb->s_writers.frozen and sb->s_freeze_count are protected by sb->s_umount.
  */
 int freeze_super(struct super_block *sb)
 {
-	int ret;
+	int ret = 0;
 	atomic_inc(&sb->s_active);
 	down_write(&sb->s_umount);
-	if (sb->s_writers.frozen != SB_UNFROZEN) {
-		deactivate_locked_super(sb);
-		return -EBUSY;
-	}
 	if (!(sb->s_flags & MS_BORN)) {
-		up_write(&sb->s_umount);
-		return 0;	/* sic - it's "nothing to do" */
+		atomic_dec(&sb->s_active);
+		goto out_active;	/* sic - it's "nothing to do" */
  Why not 'goto out_deactivate' here instead of manually decrementing
s_active?
I was afraid that calling deactivate_locked_super()
when the MS_BORN flag is set could release the
last active reference to the superblock and
end up freeing it.
  Well, the caller has to have the sb pinned somehow so that it can safely
pass it into freeze_super(). So deactivate_locked_super() cannot really
end up freeing the superblock...
I should have explained my fears better. If no one else
is holding an active reference we will end up executing:

fs->kill_sb(s);
...
put_filesystem(fs);
put_super(s);

in deactivate_locked_super(). If s_count is greater than 0
the superblock will not be freed, as you say, however we
still do "fs->kill_sb(s)" and "put_filesystem(fs)" and I am not
sure whether this is safe when MS_BORN flag is not set in
the superblock. I will check how MS_BORN is being used
once more and try to figure it out (if you are familiar with
MS_BORN I would appreciate it your advise).
  I see. Well, from a brief check I don't think we should ever get to a
superblock without MS_BORN set. All functions iterating over superblocks
return only superblocks with MS_BORN set. In particular freeze_bdev() even
has an active reference itself and ioctl_fsfreeze() has a file open on the
sb which guarantees an active reference as well...

So maybe just removing that check altogether should be OK.

								Honza
-- 
Jan Kara [off-list ref]
SUSE Labs, CR
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help