Author: zbyniu                       Date: Thu May 29 14:20:20 2008 GMT
Module: SOURCES                       Tag: LINUX_2_6
---- Log message:
- repatched 
https://forgesvn1.novell.com/svn/apparmor/trunk/kernel-patches/2.6.25 rev 1266

---- Files affected:
SOURCES:
   kernel-apparmor.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/kernel-apparmor.patch
diff -u /dev/null SOURCES/kernel-apparmor.patch:1.1.2.1
--- /dev/null   Thu May 29 16:20:20 2008
+++ SOURCES/kernel-apparmor.patch       Thu May 29 16:20:14 2008
@@ -0,0 +1,8983 @@
+diff -uprN e/fs/afs/dir.c f/fs/afs/dir.c
+--- e/fs/afs/dir.c     2008-04-17 02:49:44.000000000 +0000
++++ f/fs/afs/dir.c     2008-05-28 20:29:29.410207000 +0000
+@@ -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 e/fs/afs/file.c f/fs/afs/file.c
+--- e/fs/afs/file.c    2008-04-17 02:49:44.000000000 +0000
++++ f/fs/afs/file.c    2008-05-28 20:29:29.410207000 +0000
+@@ -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 e/fs/afs/inode.c f/fs/afs/inode.c
+--- e/fs/afs/inode.c   2008-04-17 02:49:44.000000000 +0000
++++ f/fs/afs/inode.c   2008-05-28 20:29:29.410207000 +0000
+@@ -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 e/fs/afs/internal.h f/fs/afs/internal.h
+--- e/fs/afs/internal.h        2008-04-17 02:49:44.000000000 +0000
++++ f/fs/afs/internal.h        2008-05-28 20:29:29.410207000 +0000
+@@ -550,6 +550,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 e/fs/attr.c f/fs/attr.c
+--- e/fs/attr.c        2008-04-17 02:49:44.000000000 +0000
++++ f/fs/attr.c        2008-05-28 20:29:29.410207000 +0000
+@@ -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;
+@@ -158,13 +159,17 @@ 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
++                              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))
+@@ -182,5 +187,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 e/fs/dcache.c f/fs/dcache.c
+--- e/fs/dcache.c      2008-04-17 02:49:44.000000000 +0000
++++ f/fs/dcache.c      2008-05-28 20:29:29.410207000 +0000
+@@ -1747,86 +1747,118 @@ shouldnt_be_hashed:
+ }
+ 
+ /**
+- * d_path - return the path of a dentry
++ * __d_path - return the path of a dentry
+  * @dentry: dentry to report
+  * @vfsmnt: vfsmnt to which the dentry belongs
+  * @root: root dentry
+  * @rootmnt: vfsmnt to which the root dentry belongs
+  * @buffer: buffer to return value in
+  * @buflen: buffer length
++ * @fail_deleted: what to return for deleted files
++ * @disconnect: don't return a path starting with / when disconnected
+  *
+- * Convert a dentry into an ASCII path name. If the entry has been deleted
++ * Convert a dentry into an ASCII path name. If the entry has been deleted,
++ * then if @fail_deleted is true, ERR_PTR(-ENOENT) is returned. Otherwise,
+  * the string " (deleted)" is appended. Note that this is ambiguous.
+  *
+  * Returns the buffer or an error code if the path was too long.
++ * If @dentry is not connected to @root, the path returned will be relative
++ * (i.e., it will not start with a slash).
+  *
+- * "buflen" should be positive. Caller holds the dcache_lock.
++ * Returns the buffer or an error code.
+  */
+-static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
+-                     struct path *root, char *buffer, int buflen)
++char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
++             struct path *root, char *buffer, int buflen,
++             int fail_deleted, int disconnect)
+ {
+-      char * end = buffer+buflen;
+-      char * retval;
+-      int namelen;
++      int namelen, vfsmount_locked = 0;
++      const unsigned char *name;
++
++      if (buflen < 2)
++              return ERR_PTR(-ENAMETOOLONG);
++      buffer += --buflen;
++      *buffer = '\0';
+ 
+-      *--end = '\0';
+-      buflen--;
++      spin_lock(&dcache_lock);
+       if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
+-              buflen -= 10;
+-              end -= 10;
+-              if (buflen < 0)
++              if (fail_deleted) {
++                      buffer = ERR_PTR(-ENOENT);
++                      goto out;
++              }
++              if (buflen < 10)
+                       goto Elong;
+-              memcpy(end, " (deleted)", 10);
++              buflen -= 10;
++              buffer -= 10;
++              memcpy(buffer, " (deleted)", 10);
+       }
+ 
+-      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? */
+-                      spin_lock(&vfsmount_lock);
+-                      if (vfsmnt->mnt_parent == vfsmnt) {
+-                              spin_unlock(&vfsmount_lock);
+-                              goto global_root;
++                      if (!vfsmount_locked) {
++                              spin_lock(&vfsmount_lock);
++                              vfsmount_locked = 1;
+                       }
++                      if (vfsmnt->mnt_parent == vfsmnt)
++                              goto global_root;
+                       dentry = vfsmnt->mnt_mountpoint;
+                       vfsmnt = vfsmnt->mnt_parent;
+-                      spin_unlock(&vfsmount_lock);
+                       continue;
+               }
+               parent = dentry->d_parent;
+               prefetch(parent);
+               namelen = dentry->d_name.len;
+-              buflen -= namelen + 1;
+-              if (buflen < 0)
++              if (buflen < namelen + 1)
+                       goto Elong;
+-              end -= namelen;
+-              memcpy(end, dentry->d_name.name, namelen);
+-              *--end = '/';
+-              retval = end;
++              buflen -= namelen + 1;
++              buffer -= namelen;
++              memcpy(buffer, dentry->d_name.name, namelen);
++              *--buffer = '/';
+               dentry = parent;
+       }
++      /* Get '/' right. */
++      if (*buffer != '/')
++              *--buffer = '/';
+ 
+-      return retval;
++out:
++      if (vfsmount_locked)
++              spin_unlock(&vfsmount_lock);
++      spin_unlock(&dcache_lock);
++      return buffer;
+ 
+ global_root:
++      /*
++       * 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;
+-      buflen -= namelen;
+-      if (buflen < 0)
++      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++;
++              buflen++;
++      }
++      if (disconnect && *name == '/') {
++          /* Make sure we won't return a pathname starting with '/' */
++              name++;
++              namelen--;
++      }
++      if (buflen < namelen)
+               goto Elong;
+-      retval -= namelen-1;    /* hit the slash */
+-      memcpy(retval, dentry->d_name.name, namelen);
+-      return retval;
++      buffer -= namelen;
++      memcpy(buffer, dentry->d_name.name, namelen);
++      goto out;
++
+ Elong:
+-      return ERR_PTR(-ENAMETOOLONG);
++      buffer = ERR_PTR(-ENAMETOOLONG);
++      goto out;
+ }
+ 
+ /**
+@@ -1861,9 +1893,7 @@ char *d_path(struct path *path, char *bu
+       root = current->fs->root;
+       path_get(&current->fs->root);
+       read_unlock(&current->fs->lock);
+-      spin_lock(&dcache_lock);
+-      res = __d_path(path->dentry, path->mnt, &root, buf, buflen);
+-      spin_unlock(&dcache_lock);
++      res = __d_path(path->dentry, path->mnt, &root, buf, buflen, 0, 0);
+       path_put(&root);
+       return res;
+ }
+@@ -1909,9 +1939,9 @@ char *dynamic_dname(struct dentry *dentr
+  */
+ asmlinkage long sys_getcwd(char __user *buf, unsigned long size)
+ {
+-      int error;
++      int error, len;
+       struct path pwd, root;
+-      char *page = (char *) __get_free_page(GFP_USER);
++      char *page = (char *) __get_free_page(GFP_USER), *cwd;
+ 
+       if (!page)
+               return -ENOMEM;
+@@ -1923,29 +1953,18 @@ asmlinkage long sys_getcwd(char __user *
+       path_get(&current->fs->root);
+       read_unlock(&current->fs->lock);
+ 
+-      error = -ENOENT;
+-      /* Has the current directory has been unlinked? */
+-      spin_lock(&dcache_lock);
+-      if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) {
+-              unsigned long len;
+-              char * cwd;
+-
+-              cwd = __d_path(pwd.dentry, pwd.mnt, &root, page, PAGE_SIZE);
+-              spin_unlock(&dcache_lock);
+-
+-              error = PTR_ERR(cwd);
+-              if (IS_ERR(cwd))
+-                      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);
++      cwd = __d_path(pwd.dentry, pwd.mnt, &root, page, PAGE_SIZE, 1, 0);
++      error = PTR_ERR(cwd);
++      if (IS_ERR(cwd))
++              goto out;
++
++      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 e/fs/ecryptfs/inode.c f/fs/ecryptfs/inode.c
+--- e/fs/ecryptfs/inode.c      2008-04-17 02:49:44.000000000 +0000
++++ f/fs/ecryptfs/inode.c      2008-05-28 20:29:28.910241000 +0000
+@@ -388,19 +388,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);
+@@ -425,10 +430,11 @@ 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);
+ 
+       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;
+@@ -448,6 +454,7 @@ static int ecryptfs_symlink(struct inode
+ {
+       int rc;
+       struct dentry *lower_dentry;
++      struct vfsmount *lower_mnt;
+       struct dentry *lower_dir_dentry;
+       umode_t mode;
+       char *encoded_symname;
+@@ -456,6 +463,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);
+       mode = S_IALLUGO;
+       encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname,
+@@ -465,7 +473,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, mode);
+       kfree(encoded_symname);
+       if (rc || !lower_dentry->d_inode)
+@@ -487,11 +495,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);
+@@ -510,14 +521,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);
+@@ -535,11 +548,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);
+@@ -560,19 +576,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);
+@@ -848,6 +869,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;
+@@ -858,6 +880,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);
+@@ -908,7 +931,7 @@ static int ecryptfs_setattr(struct dentr
+       if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
+               ia->ia_valid &= ~ATTR_MODE;
+ 
+-      rc = notify_change(lower_dentry, ia);
++      rc = notify_change(lower_dentry, lower_mnt, ia);
+ out:
+       fsstack_copy_attr_all(inode, lower_inode, NULL);
+       return rc;
+diff -uprN e/fs/exec.c f/fs/exec.c
+--- e/fs/exec.c        2008-04-17 02:49:44.000000000 +0000
++++ f/fs/exec.c        2008-05-28 20:29:28.910241000 +0000
+@@ -1777,7 +1777,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 e/fs/fat/file.c f/fs/fat/file.c
+--- e/fs/fat/file.c    2008-04-17 02:49:44.000000000 +0000
++++ f/fs/fat/file.c    2008-05-28 20:29:28.910241000 +0000
+@@ -92,7 +92,7 @@ int fat_generic_ioctl(struct inode *inod
+               }
+ 
+               /* This MUST be done before doing anything irreversible... */
+-              err = notify_change(filp->f_path.dentry, &ia);
++              err = notify_change(filp->f_path.dentry, filp->f_path.mnt, &ia);
+               if (err)
+                       goto up;
+ 
+diff -uprN e/fs/fuse/dir.c f/fs/fuse/dir.c
+--- e/fs/fuse/dir.c    2008-04-17 02:49:44.000000000 +0000
++++ f/fs/fuse/dir.c    2008-05-28 20:29:29.410207000 +0000
+@@ -1064,21 +1064,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;
+ 
+@@ -1097,7 +1098,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;
+@@ -1114,8 +1115,8 @@ static void iattr_to_fattr(struct iattr 
+  * vmtruncate() doesn't allow for this case, so do the rlimit checking
+  * and the actual truncation by hand.
<<Diff was trimmed, longer than 597 lines>>
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to