SOURCES: kernel-apparmor-after-grsec_full.patch (NEW) - patches from https:...

zbyniu zbyniu at pld-linux.org
Wed Oct 29 23:27:58 CET 2008


Author: zbyniu                       Date: Wed Oct 29 22:27:58 2008 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- patches from https://forgesvn1.novell.com/svn/apparmor/trunk/kernel-patches/2.6.27
- rev 1303 repackaged to one file

---- Files affected:
SOURCES:
   kernel-apparmor-after-grsec_full.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/kernel-apparmor-after-grsec_full.patch
diff -u /dev/null SOURCES/kernel-apparmor-after-grsec_full.patch:1.1
--- /dev/null	Wed Oct 29 23:27:59 2008
+++ SOURCES/kernel-apparmor-after-grsec_full.patch	Wed Oct 29 23:27:53 2008
@@ -0,0 +1,9230 @@
+diff -uprN linux-2.6.27./fs/afs/dir.c linux-2.6.27/fs/afs/dir.c
+--- linux-2.6.27./fs/afs/dir.c	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/afs/dir.c	2008-10-29 14:28:53.282780285 +0100
+@@ -45,6 +45,7 @@ const struct file_operations afs_dir_fil
+ 	.release	= afs_release,
+ 	.readdir	= afs_readdir,
+ 	.lock		= afs_lock,
++	.fsetattr	= afs_fsetattr,
+ };
+ 
+ const struct inode_operations afs_dir_inode_operations = {
+diff -uprN linux-2.6.27./fs/afs/file.c linux-2.6.27/fs/afs/file.c
+--- linux-2.6.27./fs/afs/file.c	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/afs/file.c	2008-10-29 14:28:53.282780285 +0100
+@@ -36,6 +36,7 @@ const struct file_operations afs_file_op
+ 	.fsync		= afs_fsync,
+ 	.lock		= afs_lock,
+ 	.flock		= afs_flock,
++	.fsetattr	= afs_fsetattr,
+ };
+ 
+ const struct inode_operations afs_file_inode_operations = {
+diff -uprN linux-2.6.27./fs/afs/inode.c linux-2.6.27/fs/afs/inode.c
+--- linux-2.6.27./fs/afs/inode.c	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/afs/inode.c	2008-10-29 14:28:53.282780285 +0100
+@@ -358,7 +358,8 @@ void afs_clear_inode(struct inode *inode
+ /*
+  * set the attributes of an inode
+  */
+-int afs_setattr(struct dentry *dentry, struct iattr *attr)
++static int afs_do_setattr(struct dentry *dentry, struct iattr *attr,
++		   struct file *file)
+ {
+ 	struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode);
+ 	struct key *key;
+@@ -380,8 +381,8 @@ int afs_setattr(struct dentry *dentry, s
+ 		afs_writeback_all(vnode);
+ 	}
+ 
+-	if (attr->ia_valid & ATTR_FILE) {
+-		key = attr->ia_file->private_data;
++	if (file) {
++		key = file->private_data;
+ 	} else {
+ 		key = afs_request_key(vnode->volume->cell);
+ 		if (IS_ERR(key)) {
+@@ -391,10 +392,20 @@ int afs_setattr(struct dentry *dentry, s
+ 	}
+ 
+ 	ret = afs_vnode_setattr(vnode, key, attr);
+-	if (!(attr->ia_valid & ATTR_FILE))
++	if (!file)
+ 		key_put(key);
+ 
+ error:
+ 	_leave(" = %d", ret);
+ 	return ret;
+ }
++
++int afs_setattr(struct dentry *dentry, struct iattr *attr)
++{
++	return afs_do_setattr(dentry, attr, NULL);
++}
++
++int afs_fsetattr(struct file *file, struct iattr *attr)
++{
++	return afs_do_setattr(file->f_path.dentry, attr, file);
++}
+diff -uprN linux-2.6.27./fs/afs/internal.h linux-2.6.27/fs/afs/internal.h
+--- linux-2.6.27./fs/afs/internal.h	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/afs/internal.h	2008-10-29 14:28:53.282780285 +0100
+@@ -548,6 +548,7 @@ extern void afs_zap_data(struct afs_vnod
+ extern int afs_validate(struct afs_vnode *, struct key *);
+ extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+ extern int afs_setattr(struct dentry *, struct iattr *);
++extern int afs_fsetattr(struct file *, struct iattr *);
+ extern void afs_clear_inode(struct inode *);
+ 
+ /*
+diff -uprN linux-2.6.27./fs/attr.c linux-2.6.27/fs/attr.c
+--- linux-2.6.27./fs/attr.c	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/attr.c	2008-10-29 14:28:53.289441230 +0100
+@@ -100,7 +100,8 @@ int inode_setattr(struct inode * inode, 
+ }
+ EXPORT_SYMBOL(inode_setattr);
+ 
+-int notify_change(struct dentry * dentry, struct iattr * attr)
++int fnotify_change(struct dentry *dentry, struct vfsmount *mnt,
++		   struct iattr *attr, struct file *file)
+ {
+ 	struct inode *inode = dentry->d_inode;
+ 	mode_t mode = inode->i_mode;
+@@ -163,13 +164,28 @@ int notify_change(struct dentry * dentry
+ 		down_write(&dentry->d_inode->i_alloc_sem);
+ 
+ 	if (inode->i_op && inode->i_op->setattr) {
+-		error = security_inode_setattr(dentry, attr);
+-		if (!error)
+-			error = inode->i_op->setattr(dentry, attr);
++		error = security_inode_setattr(dentry, mnt, attr);
++		if (!error) {
++			if (file && file->f_op && file->f_op->fsetattr)
++				error = file->f_op->fsetattr(file, attr);
++			else {
++				/* External file system still expect to be
++				 * passed a file pointer via ia_file and
++				 * have it announced via ATTR_FILE. This
++				 * just makes it so they don't need to
++				 * change their API just for us. External
++				 * callers will have set these themselves. */
++				if (file) {
++					attr->ia_valid |= ATTR_FILE;
++					attr->ia_file = file;
++				}
++				error = inode->i_op->setattr(dentry, attr);
++			}
++		}
+ 	} else {
+ 		error = inode_change_ok(inode, attr);
+ 		if (!error)
+-			error = security_inode_setattr(dentry, attr);
++			error = security_inode_setattr(dentry, mnt, attr);
+ 		if (!error) {
+ 			if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+ 			    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
+@@ -187,5 +203,12 @@ int notify_change(struct dentry * dentry
+ 
+ 	return error;
+ }
++EXPORT_SYMBOL_GPL(fnotify_change);
++
++int notify_change(struct dentry *dentry, struct vfsmount *mnt,
++		  struct iattr *attr)
++{
++	return fnotify_change(dentry, mnt, attr, NULL);
++}
+ 
+ EXPORT_SYMBOL(notify_change);
+diff -uprN linux-2.6.27./fs/dcache.c linux-2.6.27/fs/dcache.c
+--- linux-2.6.27./fs/dcache.c	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/dcache.c	2008-10-29 14:28:53.279441727 +0100
+@@ -1897,44 +1897,46 @@ static int prepend_name(char **buffer, i
+  * @root: root vfsmnt/dentry (may be modified by this function)
+  * @buffer: buffer to return value in
+  * @buflen: buffer length
++ * @flags: flags controling behavior of d_path
+  *
+- * Convert a dentry into an ASCII path name. If the entry has been deleted
+- * the string " (deleted)" is appended. Note that this is ambiguous.
+- *
+- * Returns the buffer or an error code if the path was too long.
+- *
+- * "buflen" should be positive. Caller holds the dcache_lock.
++ * Convert a dentry into an ASCII path name. If the entry has been deleted,
++ * then if @flags has D_PATH_FAIL_DELETED set, ERR_PTR(-ENOENT) is returned.
++ * Otherwise, the string " (deleted)" is appended. Note that this is ambiguous.
+  *
+  * If path is not reachable from the supplied root, then the value of
+- * root is changed (without modifying refcounts).
++ * root is changed (without modifying refcounts).  The path returned in this
++ * case will be relative (i.e., it will not start with a slash).
++ *
++ * Returns the buffer or an error code if the path was too long.
+  */
+ char *__d_path(const struct path *path, struct path *root,
+-	       char *buffer, int buflen)
++	       char *buffer, int buflen, int flags)
+ {
+ 	struct dentry *dentry = path->dentry;
+ 	struct vfsmount *vfsmnt = path->mnt;
+-	char *end = buffer + buflen;
+-	char *retval;
++	const unsigned char *name;
++	int namelen;
++
++	buffer += buflen;
++	prepend(&buffer, &buflen, "\0", 1);
+ 
+ 	spin_lock(&vfsmount_lock);
+-	prepend(&end, &buflen, "\0", 1);
+-	if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
+-		(prepend(&end, &buflen, " (deleted)", 10) != 0))
++	spin_lock(&dcache_lock);
++	if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
++		if (flags & D_PATH_FAIL_DELETED) {
++			buffer = ERR_PTR(-ENOENT);
++			goto out;
++		}
++		if (prepend(&buffer, &buflen, " (deleted)", 10) != 0)
+ 			goto Elong;
+-
++	}
+ 	if (buflen < 1)
+ 		goto Elong;
+-	/* Get '/' right */
+-	retval = end-1;
+-	*retval = '/';
+ 
+-	for (;;) {
++	while (dentry != root->dentry || vfsmnt != root->mnt) {
+ 		struct dentry * parent;
+ 
+-		if (dentry == root->dentry && vfsmnt == root->mnt)
+-			break;
+ 		if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
+-			/* Global root? */
+ 			if (vfsmnt->mnt_parent == vfsmnt) {
+ 				goto global_root;
+ 			}
+@@ -1944,27 +1946,51 @@ char *__d_path(const struct path *path, 
+ 		}
+ 		parent = dentry->d_parent;
+ 		prefetch(parent);
+-		if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
+-		    (prepend(&end, &buflen, "/", 1) != 0))
++		if ((prepend_name(&buffer, &buflen, &dentry->d_name) != 0) ||
++		    (prepend(&buffer, &buflen, "/", 1) != 0))
+ 			goto Elong;
+-		retval = end;
+ 		dentry = parent;
+ 	}
++	/* Get '/' right. */
++	if (*buffer != '/' && prepend(&buffer, &buflen, "/", 1))
++		goto Elong;
+ 
+ out:
++	spin_unlock(&dcache_lock);
+ 	spin_unlock(&vfsmount_lock);
+-	return retval;
++	return buffer;
+ 
+ global_root:
+-	retval += 1;	/* hit the slash */
+-	if (prepend_name(&retval, &buflen, &dentry->d_name) != 0)
++	/*
++	 * We went past the (vfsmount, dentry) we were looking for and have
++	 * either hit a root dentry, a lazily unmounted dentry, an
++	 * unconnected dentry, or the file is on a pseudo filesystem.
++	 */
++        namelen = dentry->d_name.len;
++	name = dentry->d_name.name;
++
++	/*
++	 * If this is a root dentry, then overwrite the slash.  This
++	 * will also DTRT with pseudo filesystems which have root
++	 * dentries named "foo:".
++	 */
++	if (IS_ROOT(dentry) && *buffer == '/') {
++		buffer++;
++		buflen++;
++	}
++	if ((flags & D_PATH_DISCONNECT) && *name == '/') {
++		/* Make sure we won't return a pathname starting with '/' */
++		name++;
++		namelen--;
++	}
++	if (prepend(&buffer, &buflen, name, namelen))
+ 		goto Elong;
+ 	root->mnt = vfsmnt;
+ 	root->dentry = dentry;
+ 	goto out;
+ 
+ Elong:
+-	retval = ERR_PTR(-ENAMETOOLONG);
++	buffer = ERR_PTR(-ENAMETOOLONG);
+ 	goto out;
+ }
+ 
+@@ -2001,10 +2027,8 @@ char *d_path(const struct path *path, ch
+ 	root = current->fs->root;
+ 	path_get(&root);
+ 	read_unlock(&current->fs->lock);
+-	spin_lock(&dcache_lock);
+ 	tmp = root;
+-	res = __d_path(path, &tmp, buf, buflen);
+-	spin_unlock(&dcache_lock);
++	res = __d_path(path, &tmp, buf, buflen, 0);
+ 	path_put(&root);
+ 	return res;
+ }
+@@ -2087,9 +2111,9 @@ Elong:
+  */
+ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
+ {
+-	int error;
+-	struct path pwd, root;
+-	char *page = (char *) __get_free_page(GFP_USER);
++	int error, len;
++	struct path pwd, root, tmp;
++	char *page = (char *) __get_free_page(GFP_USER), *cwd;
+ 
+ 	if (!page)
+ 		return -ENOMEM;
+@@ -2101,30 +2125,20 @@ asmlinkage long sys_getcwd(char __user *
+ 	path_get(&root);
+ 	read_unlock(&current->fs->lock);
+ 
+-	error = -ENOENT;
+-	/* Has the current directory has been unlinked? */
+-	spin_lock(&dcache_lock);
+-	if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) {
+-		unsigned long len;
+-		struct path tmp = root;
+-		char * cwd;
+-
+-		cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE);
+-		spin_unlock(&dcache_lock);
+-
++	tmp = root;
++	cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE, D_PATH_FAIL_DELETED);
++	if (IS_ERR(cwd)) {
+ 		error = PTR_ERR(cwd);
+-		if (IS_ERR(cwd))
+-			goto out;
++ 		goto out;
++	}
+ 
+-		error = -ERANGE;
+-		len = PAGE_SIZE + page - cwd;
+-		if (len <= size) {
+-			error = len;
+-			if (copy_to_user(buf, cwd, len))
+-				error = -EFAULT;
+-		}
+-	} else
+-		spin_unlock(&dcache_lock);
++	error = -ERANGE;
++	len = PAGE_SIZE + page - cwd;
++	if (len <= size) {
++		error = len;
++		if (copy_to_user(buf, cwd, len))
++			error = -EFAULT;
++	}
+ 
+ out:
+ 	path_put(&pwd);
+diff -uprN linux-2.6.27./fs/ecryptfs/inode.c linux-2.6.27/fs/ecryptfs/inode.c
+--- linux-2.6.27./fs/ecryptfs/inode.c	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/ecryptfs/inode.c	2008-10-29 14:28:53.242566343 +0100
+@@ -403,19 +403,24 @@ static int ecryptfs_link(struct dentry *
+ 			 struct dentry *new_dentry)
+ {
+ 	struct dentry *lower_old_dentry;
++	struct vfsmount *lower_old_mnt;
+ 	struct dentry *lower_new_dentry;
++	struct vfsmount *lower_new_mnt;
+ 	struct dentry *lower_dir_dentry;
+ 	u64 file_size_save;
+ 	int rc;
+ 
+ 	file_size_save = i_size_read(old_dentry->d_inode);
+ 	lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
++	lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry);
+ 	lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
++	lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
+ 	dget(lower_old_dentry);
+ 	dget(lower_new_dentry);
+ 	lower_dir_dentry = lock_parent(lower_new_dentry);
+-	rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
+-		      lower_new_dentry);
++	rc = vfs_link(lower_old_dentry, lower_old_mnt,
++		      lower_dir_dentry->d_inode, lower_new_dentry,
++		      lower_new_mnt);
+ 	if (rc || !lower_new_dentry->d_inode)
+ 		goto out_lock;
+ 	rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
+@@ -440,11 +445,12 @@ static int ecryptfs_unlink(struct inode 
+ {
+ 	int rc = 0;
+ 	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
++	struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+ 	struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
+ 	struct dentry *lower_dir_dentry;
+ 
+ 	lower_dir_dentry = lock_parent(lower_dentry);
+-	rc = vfs_unlink(lower_dir_inode, lower_dentry);
++	rc = vfs_unlink(lower_dir_inode, lower_dentry, lower_mnt);
+ 	if (rc) {
+ 		printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
+ 		goto out_unlock;
+@@ -464,6 +470,7 @@ static int ecryptfs_symlink(struct inode
+ {
+ 	int rc;
+ 	struct dentry *lower_dentry;
++	struct vfsmount *lower_mnt;
+ 	struct dentry *lower_dir_dentry;
+ 	char *encoded_symname;
+ 	int encoded_symlen;
+@@ -471,6 +478,7 @@ static int ecryptfs_symlink(struct inode
+ 
+ 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
+ 	dget(lower_dentry);
++	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+ 	lower_dir_dentry = lock_parent(lower_dentry);
+ 	encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname,
+ 						  strlen(symname),
+@@ -479,7 +487,7 @@ static int ecryptfs_symlink(struct inode
+ 		rc = encoded_symlen;
+ 		goto out_lock;
+ 	}
+-	rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
++	rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, lower_mnt,
+ 			 encoded_symname);
+ 	kfree(encoded_symname);
+ 	if (rc || !lower_dentry->d_inode)
+@@ -501,11 +509,14 @@ static int ecryptfs_mkdir(struct inode *
+ {
+ 	int rc;
+ 	struct dentry *lower_dentry;
++	struct vfsmount *lower_mnt;
+ 	struct dentry *lower_dir_dentry;
+ 
+ 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
++	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+ 	lower_dir_dentry = lock_parent(lower_dentry);
+-	rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
++	rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt,
++		       mode);
+ 	if (rc || !lower_dentry->d_inode)
+ 		goto out;
+ 	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
+@@ -524,14 +535,16 @@ out:
+ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
+ {
+ 	struct dentry *lower_dentry;
++	struct vfsmount *lower_mnt;
+ 	struct dentry *lower_dir_dentry;
+ 	int rc;
+ 
+ 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
++	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+ 	dget(dentry);
+ 	lower_dir_dentry = lock_parent(lower_dentry);
+ 	dget(lower_dentry);
+-	rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
++	rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt);
+ 	dput(lower_dentry);
+ 	if (!rc)
+ 		d_delete(lower_dentry);
+@@ -549,11 +562,14 @@ ecryptfs_mknod(struct inode *dir, struct
+ {
+ 	int rc;
+ 	struct dentry *lower_dentry;
++	struct vfsmount *lower_mnt;
+ 	struct dentry *lower_dir_dentry;
+ 
+ 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
++	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+ 	lower_dir_dentry = lock_parent(lower_dentry);
+-	rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
++	rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, mode,
++		       dev);
+ 	if (rc || !lower_dentry->d_inode)
+ 		goto out;
+ 	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
+@@ -574,19 +590,24 @@ ecryptfs_rename(struct inode *old_dir, s
+ {
+ 	int rc;
+ 	struct dentry *lower_old_dentry;
++	struct vfsmount *lower_old_mnt;
+ 	struct dentry *lower_new_dentry;
++	struct vfsmount *lower_new_mnt;
+ 	struct dentry *lower_old_dir_dentry;
+ 	struct dentry *lower_new_dir_dentry;
+ 
+ 	lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
++	lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry);
+ 	lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
++	lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
+ 	dget(lower_old_dentry);
+ 	dget(lower_new_dentry);
+ 	lower_old_dir_dentry = dget_parent(lower_old_dentry);
+ 	lower_new_dir_dentry = dget_parent(lower_new_dentry);
+ 	lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+ 	rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
+-			lower_new_dir_dentry->d_inode, lower_new_dentry);
++			lower_old_mnt, lower_new_dir_dentry->d_inode,
++			lower_new_dentry, lower_new_mnt);
+ 	if (rc)
+ 		goto out_lock;
+ 	fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL);
+@@ -849,6 +870,7 @@ static int ecryptfs_setattr(struct dentr
+ {
+ 	int rc = 0;
+ 	struct dentry *lower_dentry;
++	struct vfsmount *lower_mnt;
+ 	struct inode *inode;
+ 	struct inode *lower_inode;
+ 	struct ecryptfs_crypt_stat *crypt_stat;
+@@ -859,6 +881,7 @@ static int ecryptfs_setattr(struct dentr
+ 	inode = dentry->d_inode;
+ 	lower_inode = ecryptfs_inode_to_lower(inode);
+ 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
++	lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
+ 	mutex_lock(&crypt_stat->cs_mutex);
+ 	if (S_ISDIR(dentry->d_inode->i_mode))
+ 		crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
+@@ -910,7 +933,7 @@ static int ecryptfs_setattr(struct dentr
+ 		ia->ia_valid &= ~ATTR_MODE;
+ 
+ 	mutex_lock(&lower_dentry->d_inode->i_mutex);
+-	rc = notify_change(lower_dentry, ia);
++	rc = notify_change(lower_dentry, lower_mnt, ia);
+ 	mutex_unlock(&lower_dentry->d_inode->i_mutex);
+ out:
+ 	fsstack_copy_attr_all(inode, lower_inode, NULL);
+diff -uprN linux-2.6.27./fs/exec.c linux-2.6.27/fs/exec.c
+--- linux-2.6.27./fs/exec.c	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/exec.c	2008-10-29 14:28:53.172364339 +0100
+@@ -1827,7 +1827,8 @@ int do_coredump(long signr, int exit_cod
+ 		goto close_fail;
+ 	if (!file->f_op->write)
+ 		goto close_fail;
+-	if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0)
++	if (!ispipe &&
++	    do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0)
+ 		goto close_fail;
+ 
+ 	retval = binfmt->core_dump(signr, regs, file, core_limit);
+diff -uprN linux-2.6.27./fs/fat/file.c linux-2.6.27/fs/fat/file.c
+--- linux-2.6.27./fs/fat/file.c	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/fat/file.c	2008-10-29 14:28:53.175696536 +0100
+@@ -98,7 +98,7 @@ int fat_generic_ioctl(struct inode *inod
+ 		 * out the RO attribute for checking by the security
+ 		 * module, just because it maps to a file mode.
+ 		 */
+-		err = security_inode_setattr(filp->f_path.dentry, &ia);
++		err = security_inode_setattr(filp->f_path.dentry, filp->f_path.mnt, &ia);
+ 		if (err)
+ 			goto up;
+ 
+diff -uprN linux-2.6.27./fs/fuse/dir.c linux-2.6.27/fs/fuse/dir.c
+--- linux-2.6.27./fs/fuse/dir.c	2008-10-10 00:13:53.000000000 +0200
++++ linux-2.6.27/fs/fuse/dir.c	2008-10-29 14:28:53.282780285 +0100
+@@ -1105,21 +1105,22 @@ static int fuse_dir_fsync(struct file *f
+ 	return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
+ }
+ 
+-static bool update_mtime(unsigned ivalid)
++static bool update_mtime(unsigned ivalid, bool have_file)
+ {
+ 	/* Always update if mtime is explicitly set  */
+ 	if (ivalid & ATTR_MTIME_SET)
+ 		return true;
+ 
+ 	/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
+-	if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
++	if ((ivalid & ATTR_SIZE) && ((ivalid & ATTR_OPEN) || have_file))
+ 		return false;
+ 
+ 	/* In all other cases update */
+ 	return true;
+ }
+ 
+-static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
++static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
++			   bool have_file)
+ {
+ 	unsigned ivalid = iattr->ia_valid;
+ 
+@@ -1138,7 +1139,7 @@ static void iattr_to_fattr(struct iattr 
+ 		if (!(ivalid & ATTR_ATIME_SET))
+ 			arg->valid |= FATTR_ATIME_NOW;
+ 	}
+-	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
++	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, have_file)) {
+ 		arg->valid |= FATTR_MTIME;
+ 		arg->mtime = iattr->ia_mtime.tv_sec;
+ 		arg->mtimensec = iattr->ia_mtime.tv_nsec;
+@@ -1199,8 +1200,8 @@ void fuse_release_nowrite(struct inode *
+  * vmtruncate() doesn't allow for this case, so do the rlimit checking
+  * and the actual truncation by hand.
+  */
+-static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
+-			   struct file *file)
++int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
++		    struct file *file)
+ {
+ 	struct inode *inode = entry->d_inode;
+ 	struct fuse_conn *fc = get_fuse_conn(inode);
+@@ -1244,7 +1245,7 @@ static int fuse_do_setattr(struct dentry
+ 
+ 	memset(&inarg, 0, sizeof(inarg));
+ 	memset(&outarg, 0, sizeof(outarg));
+-	iattr_to_fattr(attr, &inarg);
++	iattr_to_fattr(attr, &inarg, file != NULL);
+ 	if (file) {
+ 		struct fuse_file *ff = file->private_data;
+ 		inarg.valid |= FATTR_FH;
+@@ -1314,10 +1315,7 @@ error:
+ 
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list