From: Jeff Mahoney <jeffm@suse.com>
Subject: Add fsetattr

 An AppArmor patch removed ia_file and ATTR_FILE from struct iattr and
 replaced it with the fsetattr file_operation.

 This patch fixes aufs to use it.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
 fs/aufs25/dir.c   |    1 +
 fs/aufs25/f_op.c  |    1 +
 fs/aufs25/i_op.c  |   26 ++++++++++++++------------
 fs/aufs25/inode.h |    1 +
 fs/aufs25/misc.c  |    5 ++---
 fs/aufs25/vfsub.c |   13 ++++++++++---
 fs/aufs25/vfsub.h |    2 ++
 7 files changed, 31 insertions(+), 18 deletions(-)

--- a/fs/aufs25/dir.c
+++ b/fs/aufs25/dir.c
@@ -570,4 +570,5 @@ struct file_operations aufs_dir_fop = {
 	.release	= aufs_release_dir,
 	.flush		= aufs_flush,
 	.fsync		= aufs_fsync_dir,
+	.fsetattr	= aufs_fsetattr,
 };
--- a/fs/aufs25/f_op.c
+++ b/fs/aufs25/f_op.c
@@ -658,4 +658,5 @@ struct file_operations aufs_file_fop = {
 	.splice_write	= aufs_splice_write,
 	.splice_read	= aufs_splice_read,
 #endif
+	.fsetattr	= aufs_fsetattr,
 };
--- a/fs/aufs25/i_op.c
+++ b/fs/aufs25/i_op.c
@@ -608,7 +608,8 @@ static long aufs_fallocate(struct inode
 }
 #endif
 
-static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
+static int aufs_do_setattr(struct dentry *dentry, struct iattr *ia,
+			   struct file *file)
 {
 	int err;
 	struct inode *inode;
@@ -616,7 +617,6 @@ static int aufs_setattr(struct dentry *d
 	struct vfsub_args vargs;
 	struct super_block *sb;
 	__u32 events;
-	struct file *file;
 	loff_t sz;
 	struct au_icpup_args rargs;
 
@@ -627,13 +627,8 @@ static int aufs_setattr(struct dentry *d
 	sb = dentry->d_sb;
 	si_read_lock(sb, AuLock_FLUSH);
 
-	file = NULL;
-	if (ia->ia_valid & ATTR_FILE) {
-		/* currently ftruncate(2) only */
-		file = ia->ia_file;
+	if (file)
 		fi_write_lock(file);
-		ia->ia_file = au_h_fptr(file, au_fbstart(file));
-	}
 
 	sz = -1;
 	if ((ia->ia_valid & ATTR_SIZE)
@@ -679,16 +674,23 @@ static int aufs_setattr(struct dentry *d
 	}
 	di_write_unlock(dentry);
  out:
-	if (file) {
-		ia->ia_file = file;
-		//ia->ia_valid |= ATTR_FILE;
+	if (file)
 		fi_write_unlock(file);
-	}
 	si_read_unlock(sb);
 	AuTraceErr(err);
 	return err;
 }
 
+static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
+{
+	return aufs_do_setattr(dentry, ia, NULL);
+}
+
+int aufs_fsetattr(struct file *file, struct iattr *ia)
+{
+	return aufs_do_setattr(file->f_dentry, ia, file);
+}
+
 /* ---------------------------------------------------------------------- */
 
 static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
--- a/fs/aufs25/inode.h
+++ b/fs/aufs25/inode.h
@@ -65,6 +65,7 @@ int au_test_h_perm_sio(struct inode *h_i
 
 /* i_op.c */
 extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop;
+int aufs_fsetattr(struct file *file, struct iattr *ia);
 
 /* au_wr_dir flags */
 #define AuWrDir_ADD_ENTRY	1
--- a/fs/aufs25/misc.c
+++ b/fs/aufs25/misc.c
@@ -286,10 +286,9 @@ int au_copy_file(struct file *dst, struc
 		} while (err == -EAGAIN || err == -EINTR);
 		if (err == 1) {
 			ia->ia_size = dst->f_pos;
-			ia->ia_valid = ATTR_SIZE | ATTR_FILE;
-			ia->ia_file = dst;
+			ia->ia_valid = ATTR_SIZE;
 			mutex_lock_nested(&h_i->i_mutex, AuLsc_I_CHILD2);
-			err = vfsub_notify_change(h_d, ia, &vargs);
+			err = vfsub_fnotify_change(h_d, ia, &vargs, dst);
 			mutex_unlock(&h_i->i_mutex);
 		}
 	}
--- a/fs/aufs25/vfsub.c
+++ b/fs/aufs25/vfsub.c
@@ -463,6 +463,7 @@ struct notify_change_args {
 	struct dentry *h_dentry;
 	struct iattr *ia;
 	struct vfsub_args *vargs;
+	struct file *file;
 };
 
 static void call_notify_change(void *args)
@@ -479,7 +480,7 @@ static void call_notify_change(void *arg
 	if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
 		vfsub_ignore(a->vargs);
 		lockdep_off();
-		*a->errp = notify_change(a->h_dentry, NULL, a->ia);
+		*a->errp = fnotify_change(a->h_dentry, NULL, a->ia, a->file);
 		lockdep_on();
 		if (!*a->errp)
 			au_update_fuse_h_inode(NULL, a->h_dentry); /*ignore*/
@@ -510,8 +511,8 @@ static void vfsub_notify_change_dlgt(str
 }
 #endif
 
-int vfsub_notify_change(struct dentry *dentry, struct iattr *ia,
-			struct vfsub_args *vargs)
+int vfsub_fnotify_change(struct dentry *dentry, struct iattr *ia,
+			struct vfsub_args *vargs, struct file *file)
 {
 	int err;
 	struct notify_change_args args = {
@@ -527,6 +528,12 @@ int vfsub_notify_change(struct dentry *d
 	return err;
 }
 
+int vfsub_notify_change(struct dentry *dentry, struct iattr *ia,
+			struct vfsub_args *vargs)
+{
+	return vfsub_fnotify_change(dentry, ia, vargs, NULL);
+}
+
 /* ---------------------------------------------------------------------- */
 
 struct unlink_args {
--- a/fs/aufs25/vfsub.h
+++ b/fs/aufs25/vfsub.h
@@ -483,6 +483,8 @@ int vfsub_sio_rmdir(struct inode *dir, s
 
 /* ---------------------------------------------------------------------- */
 
+int vfsub_fnotify_change(struct dentry *dentry, struct iattr *ia,
+			struct vfsub_args *vargs, struct file *file);
 int vfsub_notify_change(struct dentry *dentry, struct iattr *ia,
 			struct vfsub_args *vargs);
 int vfsub_unlink(struct inode *dir, struct dentry *dentry,
