Subject: Re: [vserver] linux 3.10.36 and patch-3.10.33-vs2.3.6.8.diff
From: Herbert Poetzl <herbert@13thfloor.at>
Date: Fri, 4 Apr 2014 21:28:05 +0200

On Thu, Apr 03, 2014 at 09:58:01PM -0500, Corey Wright wrote:
> applying patch-3.10.33-vs2.3.6.8.diff to linux-3.10.36 fails.

> the change of atomically setting ext4 inode flags in fs/ext4/inode.c [1]
> causes two linux-vserver patch rejects.

> Hunk #1 FAILED at 38.
> Hunk #2 FAILED at 4045.

> [1]
> http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=0a0ae7b3fb0fb301da83f7c7da38807c76b2b869

> the first failure is only because of including a new header (and
> invalidating the context).

> to address the second failure, i modified the linux-vserver
> code (which includes both i_flags and i_vflags) to update inode
> flags atomically (ie call set_mask_bits), just like 3.10.36
> introduced. the patch also references ext4_get_inode_flags(),
> but that's only because the linux-vserver changes within that
> function are in the same context as the ext4_set_inode_flags
> conflicts, not because that function changed in 3.10.36.

> the attached patch fixes the two failures (and Makefile's
> EXTRAVERSION, too).

Thanks, will incorporate soon.

best,
Herbert

> instructions:
> 1. acquire linux-3.10.36
> 2. apply patch-3.10.33-vs2.3.6.8.diff
> 3. apply the attached patch-3.10.33-36-vs2.3.6.8.diff

> i've successfully built the resulting kernel, but i'm currently
> unable to test it (against testme.sh and testfs.sh in
> virtualbox) until this weekend. if somebody tests the resulting
> kernel before then, then please reply with your results.

> corey
> --
> undefined@pobox.com

> diff -urNpd a/linux-3.10.36-vs2.3.6.8/Makefile b/linux-3.10.36-vs2.3.6.8/Makefile
> --- a/linux-3.10.36-vs2.3.6.8/Makefile	2014-04-03 18:34:32.000000000 -0500
> +++ b/linux-3.10.36-vs2.3.6.8/Makefile	2014-04-03 18:45:29.000000000 -0500
> @@ -1,7 +1,7 @@
>  VERSION = 3
>  PATCHLEVEL = 10
>  SUBLEVEL = 36
> -EXTRAVERSION =
> +EXTRAVERSION = -vs2.3.6.8
>  NAME = TOSSUG Baby Fish

>  # *DOCUMENTATION*
> diff -urNpd a/linux-3.10.36-vs2.3.6.8/fs/ext4/inode.c b/linux-3.10.36-vs2.3.6.8/fs/ext4/inode.c
> --- a/linux-3.10.36-vs2.3.6.8/fs/ext4/inode.c	2014-04-03 20:09:31.000000000 -0500
> +++ b/linux-3.10.36-vs2.3.6.8/fs/ext4/inode.c	2014-04-03 20:11:15.000000000 -0500
> @@ -39,6 +39,7 @@
>  #include <linux/ratelimit.h>
>  #include <linux/aio.h>
>  #include <linux/bitops.h>
> +#include <linux/vs_tag.h>

>  #include "ext4_jbd2.h"
>  #include "xattr.h"
> @@ -4046,43 +4047,65 @@ void ext4_set_inode_flags(struct inode *
>  {
>  	unsigned int flags = EXT4_I(inode)->i_flags;
>  	unsigned int new_fl = 0;
> +	unsigned int new_vf = 0;
> +
> +	if (flags & EXT4_IMMUTABLE_FL)
> +		new_fl |= S_IMMUTABLE;
> +	if (flags & EXT4_IXUNLINK_FL)
> +		new_fl |= S_IXUNLINK;

>  	if (flags & EXT4_SYNC_FL)
>  		new_fl |= S_SYNC;
>  	if (flags & EXT4_APPEND_FL)
>  		new_fl |= S_APPEND;
> -	if (flags & EXT4_IMMUTABLE_FL)
> -		new_fl |= S_IMMUTABLE;
>  	if (flags & EXT4_NOATIME_FL)
>  		new_fl |= S_NOATIME;
>  	if (flags & EXT4_DIRSYNC_FL)
>  		new_fl |= S_DIRSYNC;
>  	set_mask_bits(&inode->i_flags,
> -		      S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC, new_fl);
> +		      S_IMMUTABLE|S_IXUNLINK|S_SYNC|S_APPEND|S_NOATIME|S_DIRSYNC,
> +		      new_fl);
> +
> +	if (flags & EXT4_BARRIER_FL)
> +		new_vf |= V_BARRIER;
> +	if (flags & EXT4_COW_FL)
> +		new_vf |= V_COW;
> +	set_mask_bits(&inode->i_vflags, V_BARRIER|V_COW, new_vf);
>  }

>  /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
>  void ext4_get_inode_flags(struct ext4_inode_info *ei)
>  {
> -	unsigned int vfs_fl;
> +	unsigned int vfs_fl, vfs_vf;
>  	unsigned long old_fl, new_fl;

>  	do {
>  		vfs_fl = ei->vfs_inode.i_flags;
> +		vfs_vf = ei->vfs_inode.i_vflags;
>  		old_fl = ei->i_flags;
>  		new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL|
>  				EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|
> -				EXT4_DIRSYNC_FL);
> +				EXT4_DIRSYNC_FL|EXT4_BARRIER_FL|
> +				EXT4_COW_FL);
> +
> +		if (vfs_fl & S_IMMUTABLE)
> +			new_fl |= EXT4_IMMUTABLE_FL;
> +		if (vfs_fl & S_IXUNLINK)
> +			new_fl |= EXT4_IXUNLINK_FL;
> +
>  		if (vfs_fl & S_SYNC)
>  			new_fl |= EXT4_SYNC_FL;
>  		if (vfs_fl & S_APPEND)
>  			new_fl |= EXT4_APPEND_FL;
> -		if (vfs_fl & S_IMMUTABLE)
> -			new_fl |= EXT4_IMMUTABLE_FL;
>  		if (vfs_fl & S_NOATIME)
>  			new_fl |= EXT4_NOATIME_FL;
>  		if (vfs_fl & S_DIRSYNC)
>  			new_fl |= EXT4_DIRSYNC_FL;
> +
> +		if (vfs_vf & V_BARRIER)
> +			new_fl |= EXT4_BARRIER_FL;
> +		if (vfs_vf & V_COW)
> +			new_fl |= EXT4_COW_FL;
>  	} while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl);
>  }