Whamcloud - gitweb
land 0.5.20.3 b_devel onto HEAD (b_devel will remain)
[fs/lustre-release.git] / lustre / kernel_patches / patches / vfs_intent_hp.patch
index 63f09b3..fa0998a 100644 (file)
@@ -1,15 +1,16 @@
- fs/dcache.c            |    3 
- fs/namei.c             |  306 ++++++++++++++++++++++++++++++++++++++++---------
+ fs/dcache.c            |    8 
+ fs/namei.c             |  335 +++++++++++++++++----
  fs/nfsd/vfs.c          |    2 
- fs/open.c              |   63 +++++++---
- fs/stat.c              |   29 +++-
- include/linux/dcache.h |   31 ++++
- include/linux/fs.h     |   22 +++
+ fs/open.c              |  142 +++++++-
+ fs/stat.c              |   24 +
+ include/linux/dcache.h |   26 +
+ include/linux/fs.h     |   2+
  kernel/ksyms.c         |    1 
- 8 files changed, 384 insertions(+), 73 deletions(-)
-
---- linux-2.4.19-hp2_pnnl2/fs/dcache.c~vfs_intent_hp   Sun Jan 19 19:04:47 2003
-+++ linux-2.4.19-hp2_pnnl2-root/fs/dcache.c    Sun Jan 19 19:04:47 2003
+ fs/exec.c                   |   18 -
+ 9 files changed, 487 insertions(+), 96 deletions(-)
+--- linux-2.4.19-hp2_pnnl4/fs/dcache.c~vfs_intent_hp   Sun Jan 19 19:04:47 2003
++++ linux-2.4.19-hp2_pnnl4-root/fs/dcache.c    Sun Jan 19 19:04:47 2003
 @@ -186,6 +188,13 @@ int d_invalidate(struct dentry * dentry)
                spin_unlock(&dcache_lock);
                return 0;
        INIT_LIST_HEAD(&dentry->d_hash);
        INIT_LIST_HEAD(&dentry->d_lru);
        INIT_LIST_HEAD(&dentry->d_subdirs);
---- linux-2.4.19-hp2_pnnl2/fs/namei.c~vfs_intent_hp    Sun Jan 19 19:04:47 2003
-+++ linux-2.4.19-hp2_pnnl2-root/fs/namei.c     Sun Jan 19 19:35:55 2003
+@@ -859,13 +867,19 @@ void d_delete(struct dentry * dentry)
+  * Adds a dentry to the hash according to its name.
+  */
+  
+-void d_rehash(struct dentry * entry)
++void __d_rehash(struct dentry * entry, int lock)
+ {
+       struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash);
+       if (!list_empty(&entry->d_hash)) BUG();
+-      spin_lock(&dcache_lock);
++      if (lock) spin_lock(&dcache_lock);
+       list_add(&entry->d_hash, list);
+-      spin_unlock(&dcache_lock);
++      if (lock) spin_unlock(&dcache_lock);
++}
++EXPORT_SYMBOL(__d_rehash);
++
++void d_rehash(struct dentry * entry)
++{
++      __d_rehash(entry, 1);
+ }
+ #define do_switch(x,y) do { \
+--- linux-2.4.19-hp2_pnnl4/fs/namei.c~vfs_intent_hp    Sun Jan 19 19:04:47 2003
++++ linux-2.4.19-hp2_pnnl4-root/fs/namei.c     Sun Jan 19 19:35:55 2003
 @@ -94,6 +97,13 @@
   * XEmacs seems to be relying on it...
   */
        path_release(nd);
        return -ELOOP;
  }
+@@ -381,15 +416,26 @@ int follow_up(struct vfsmount **mnt, str
+       return __follow_up(mnt, dentry);
+ }
+-static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry)
++static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry,
++                              struct lookup_intent *it)
+ {
+       struct vfsmount *mounted;
+       spin_lock(&dcache_lock);
+       mounted = lookup_mnt(*mnt, *dentry);
+       if (mounted) {
++              int opc = 0, mode = 0;
+               *mnt = mntget(mounted);
+               spin_unlock(&dcache_lock);
++              if (it) {
++                      opc = it->it_op;
++                      mode = it->it_mode;
++              }
++              intent_release(*dentry, it);
++              if (it) {
++                      it->it_op = opc;
++                      it->it_mode = mode;
++              }
+               dput(*dentry);
+               mntput(mounted->mnt_parent);
+               *dentry = dget(mounted->mnt_root);
+@@ -401,7 +447,7 @@ static inline int __follow_down(struct v
+ int follow_down(struct vfsmount **mnt, struct dentry **dentry)
+ {
+-      return __follow_down(mnt,dentry);
++      return __follow_down(mnt,dentry,NULL);
+ }
+  
+ static inline void follow_dotdot(struct nameidata *nd)
+@@ -437,7 +483,7 @@ static inline void follow_dotdot(struct 
+               mntput(nd->mnt);
+               nd->mnt = parent;
+       }
+-      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry))
++      while (d_mountpoint(nd->dentry) && __follow_down(&nd->mnt, &nd->dentry, NULL))
+               ;
+ }
 @@ -447,7 +482,8 @@ static inline void follow_dotdot(struct 
   *
   * We expect 'base' to be positive and a directory.
  {
        struct dentry *dentry;
        struct inode *inode;
-@@ -520,9 +556,9 @@ int link_path_walk(const char * name, st
+@@ -520,15 +556,15 @@ int link_path_walk(const char * name, st
                                break;
                }
                /* This does the actual lookups.. */
                        err = PTR_ERR(dentry);
                        if (IS_ERR(dentry))
                                break;
+               }
+               /* Check mountpoints.. */
+-              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
++              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, NULL))
+                       ;
+               err = -ENOENT;
 @@ -539,8 +575,8 @@ int link_path_walk(const char * name, st
                if (!inode->i_op)
                        goto out_dput;
                        break;
                continue;
                /* here ends the main loop */
-@@ -583,9 +619,9 @@ last_component:
+@@ -583,19 +619,20 @@ last_component:
                        if (err < 0)
                                break;
                }
                        err = PTR_ERR(dentry);
                        if (IS_ERR(dentry))
                                break;
-@@ -594,8 +630,9 @@ last_component:
+               }
+-              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
++              while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry, it))
                        ;
                inode = dentry->d_inode;
                if ((lookup_flags & LOOKUP_FOLLOW)
        /* Negative dentry, just create the file */
        if (!dentry->d_inode) {
                if (!IS_POSIXACL(dir->d_inode))
-@@ -1071,7 +1156,8 @@ do_last:
+@@ -1066,12 +1151,13 @@ do_last:
+               error = -ELOOP;
+               if (flag & O_NOFOLLOW)
+                       goto exit_dput;
+-              while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
++              while (__follow_down(&nd->mnt,&dentry,it) && d_mountpoint(dentry));
+       }
        error = -ENOENT;
        if (!dentry->d_inode)
                goto exit_dput;
                goto do_link;
  
        dput(nd->dentry);
+@@ -1145,7 +1231,7 @@ do_last:
+               if (!error) {
+                       DQUOT_INIT(inode);
+                       
+-                      error = do_truncate(dentry, 0);
++                      error = do_truncate(dentry, 0, 1);
+               }
+               put_write_access(inode);
+               if (error)
 @@ -1157,8 +1243,10 @@ ok:
        return 0;
  
 +                                 nd.last.name,
 +                                 nd.last.len,
 +                                 mode, dev);
-+              /* the file system want to use normal vfs path now */
++              /* the file system wants to use normal vfs path now */
 +              if (error != -EOPNOTSUPP)
 +                      goto out2;
 +      }
 +                                         nd.last.name,
 +                                         nd.last.len,
 +                                         mode);
-+                      /* the file system want to use normal vfs path now */
++                      /* the file system wants to use normal vfs path now */
 +                      if (error != -EOPNOTSUPP)
 +                              goto out2;
 +              }
                path_release(&nd);
  out:
                putname(tmp);
-@@ -1450,8 +1578,17 @@ asmlinkage long sys_rmdir(const char * p
+@@ -1450,8 +1578,33 @@ asmlinkage long sys_rmdir(const char * p
                        error = -EBUSY;
                        goto exit1;
        }
 +      if (nd.dentry->d_inode->i_op->rmdir2) {
 +              struct inode_operations *op = nd.dentry->d_inode->i_op;
++              struct dentry *last;
++
++              down(&nd.dentry->d_inode->i_sem);
++              last = lookup_hash_it(&nd.last, nd.dentry, NULL);
++              up(&nd.dentry->d_inode->i_sem);
++              if (IS_ERR(last)) {
++                      error = PTR_ERR(last);
++                      goto exit1;
++              }
++              if (d_mountpoint(last)) {
++                      dput(last);
++                      error = -EBUSY;
++                      goto exit1;
++              }
++              dput(last);
++
 +              error = op->rmdir2(nd.dentry->d_inode,
 +                                 nd.last.name,
 +                                 nd.last.len);
-+              /* the file system want to use normal vfs path now */
++              /* the file system wants to use normal vfs path now */
 +              if (error != -EOPNOTSUPP)
 +                      goto exit1;
 +      }
 +              error = op->unlink2(nd.dentry->d_inode,
 +                                  nd.last.name,
 +                                  nd.last.len);
-+              /* the file system want to use normal vfs path now */
++              /* the file system wants to use normal vfs path now */
 +              if (error != -EOPNOTSUPP)
 +                      goto exit1;
 +      }
                if (error)
                        goto out;
 -              dentry = lookup_create(&nd, 0);
-+              if (nd.dentry->d_inode->i_op->symlink2) {
++              if (nd.dentry->d_inode->i_op->symlink2) {
 +                      struct inode_operations *op = nd.dentry->d_inode->i_op;
 +                      error = op->symlink2(nd.dentry->d_inode,
 +                                           nd.last.name,
 +                                           nd.last.len,
 +                                           from);
-+                      /* the file system want to use normal vfs path now */
++                      /* the file system wants to use normal vfs path now */
 +                      if (error != -EOPNOTSUPP)
 +                              goto out2;
 +              }
 +                                        nd.dentry->d_inode,
 +                                        nd.last.name,
 +                                        nd.last.len);
-+                      /* the file system want to use normal vfs path now */
++                      /* the file system wants to use normal vfs path now */
 +                      if (error != -EOPNOTSUPP)
 +                              goto out_release;
 +              }
        if (!error) {
                if (old_dir == new_dir)
                        inode_dir_notify(old_dir, DN_RENAME);
-@@ -1886,9 +2068,23 @@ static inline int do_rename(const char *
-       if (newnd.last_type != LAST_NORM)
-               goto exit2;
+@@ -1888,7 +2070,7 @@ static inline int do_rename(const char *
  
-+      if (old_dir->d_inode->i_op->rename2) {
-+              lock_kernel();
-+              error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
-+                                                      new_dir->d_inode,
-+                                                      oldnd.last.name,
-+                                                      oldnd.last.len,
-+                                                      newnd.last.name,
-+                                                      newnd.last.len);
-+              unlock_kernel();
-+              /* the file system want to use normal vfs path now */
-+              if (error != -EOPNOTSUPP)
-+                      goto exit2;
-+      }
-+
        double_lock(new_dir, old_dir);
  
 -      old_dentry = lookup_hash(&oldnd.last, old_dir);
        error = PTR_ERR(old_dentry);
        if (IS_ERR(old_dentry))
                goto exit3;
-@@ -1904,14 +2100,14 @@ static inline int do_rename(const char *
+@@ -1904,16 +2086,37 @@ static inline int do_rename(const char *
                if (newnd.last.name[newnd.last.len])
                        goto exit4;
        }
        if (IS_ERR(new_dentry))
                goto exit4;
  
++      if (old_dir->d_inode->i_op->rename2) {
++              lock_kernel();
++              /* don't rename mount point. mds will take care of
++               * the rest sanity checking */
++              if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) {
++                      error = -EBUSY;
++                      goto exit5;
++              }
++
++              error = old_dir->d_inode->i_op->rename2(old_dir->d_inode,
++                                                      new_dir->d_inode,
++                                                      oldnd.last.name,
++                                                      oldnd.last.len,
++                                                      newnd.last.name,
++                                                      newnd.last.len);
++              unlock_kernel();
++              /* the file system wants to use normal vfs path now */
++              if (error != -EOPNOTSUPP)
++                      goto exit5;
++      }
++
        lock_kernel();
        error = vfs_rename(old_dir->d_inode, old_dentry,
 -                                 new_dir->d_inode, new_dentry);
 +                                 new_dir->d_inode, new_dentry, NULL);
        unlock_kernel();
+-
++exit5:
        dput(new_dentry);
+ exit4:
+       dput(old_dentry);
 @@ -1964,7 +2163,8 @@ out:
  }
  
        if (page) {
                kunmap(page);
                page_cache_release(page);
---- linux-2.4.19-hp2_pnnl2/fs/nfsd/vfs.c~vfs_intent_hp Sun Jan 19 19:04:47 2003
-+++ linux-2.4.19-hp2_pnnl2-root/fs/nfsd/vfs.c  Sun Jan 19 19:37:57 2003
+--- linux-2.4.19-hp2_pnnl4/fs/nfsd/vfs.c~vfs_intent_hp Sun Jan 19 19:04:47 2003
++++ linux-2.4.19-hp2_pnnl4-root/fs/nfsd/vfs.c  Sun Jan 19 19:37:57 2003
 @@ -1295,7 +1295,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
                        err = nfserr_perm;
        } else
        if (!err && EX_ISSYNC(tfhp->fh_export)) {
                nfsd_sync_dir(tdentry);
                nfsd_sync_dir(fdentry);
---- linux-2.4.19-hp2_pnnl2/fs/open.c~vfs_intent_hp     Sun Jan 19 19:04:47 2003
-+++ linux-2.4.19-hp2_pnnl2-root/fs/open.c      Sun Jan 19 19:41:00 2003
-@@ -19,6 +19,9 @@
+--- linux-2.4.19-hp2_pnnl4/fs/open.c~vfs_intent_hp     Sun Jan 19 19:04:47 2003
++++ linux-2.4.19-hp2_pnnl4-root/fs/open.c      Sun Jan 19 19:41:00 2003
+@@ -19,6 +19,8 @@
  #include <asm/uaccess.h>
  
  #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
 +extern int path_walk_it(const char *name, struct nameidata *nd,
 +                      struct lookup_intent *it);
-+extern void intent_release(struct dentry *de, struct lookup_intent *it);
  
  int vfs_statfs(struct super_block *sb, struct statfs *buf)
  {
+@@ -95,9 +97,10 @@ void fd_install(unsigned int fd, struct 
+       write_unlock(&files->file_lock);
+ }
+-int do_truncate(struct dentry *dentry, loff_t length)
++int do_truncate(struct dentry *dentry, loff_t length, int called_from_open)
+ {
+       struct inode *inode = dentry->d_inode;
++      struct inode_operations *op = dentry->d_inode->i_op;
+       int error;
+       struct iattr newattrs;
+@@ -108,7 +111,14 @@ int do_truncate(struct dentry *dentry, l
+       down(&inode->i_sem);
+       newattrs.ia_size = length;
+       newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+-      error = notify_change(dentry, &newattrs);
++      if (called_from_open)
++              newattrs.ia_valid |= ATTR_FROM_OPEN;
++      if (op->setattr_raw) {
++              newattrs.ia_valid |= ATTR_RAW;
++              newattrs.ia_ctime = CURRENT_TIME;
++              error = op->setattr_raw(inode, &newattrs);
++      } else 
++              error = notify_change(dentry, &newattrs);
+       up(&inode->i_sem);
+       return error;
+ }
 @@ -118,12 +121,13 @@ static inline long do_sys_truncate(const
        struct nameidata nd;
        struct inode * inode;
        int error;
-+      struct lookup_intent it = { .it_op = IT_TRUNC };
++      struct lookup_intent it = { .it_op = IT_GETATTR };
  
        error = -EINVAL;
        if (length < 0) /* sorry, but loff_t says... */
        if (error)
                goto out;
        inode = nd.dentry->d_inode;
-@@ -168,6 +172,7 @@ static inline long do_sys_truncate(const
+@@ -163,11 +167,13 @@ static inline long do_sys_truncate(const
+       error = locks_verify_truncate(inode, NULL, length);
+       if (!error) {
+               DQUOT_INIT(inode);
+-              error = do_truncate(nd.dentry, length);
++              intent_release(nd.dentry, &it);
++              error = do_truncate(nd.dentry, length, 0);
+       }
        put_write_access(inode);
  
  dput_and_out:
        path_release(&nd);
  out:
        return error;
-@@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam
-       struct nameidata nd;
+@@ -215,7 +228,7 @@ static inline long do_sys_ftruncate(unsi
+       error = locks_verify_truncate(inode, file, length);
+       if (!error)
+-              error = do_truncate(dentry, length);
++              error = do_truncate(dentry, length, 0);
+ out_putf:
+       fput(file);
+ out:
+@@ -260,11 +273,13 @@ asmlinkage long sys_utime(char * filenam
        struct inode * inode;
        struct iattr newattrs;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
  
 -      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
++      error = user_path_walk_it(filename, &nd, NULL);
        if (error)
                goto out;
        inode = nd.dentry->d_inode;
-@@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam
++      /* this is safe without a Lustre lock because it only depends
++         on the super block */
+       error = -EROFS;
+       if (IS_RDONLY(inode))
+               goto dput_and_out;
+@@ -279,11 +294,29 @@ asmlinkage long sys_utime(char * filenam
+                       goto dput_and_out;
+               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+-      } else {
++      }
++
++      if (inode->i_op->setattr_raw) {
++              struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++              newattrs.ia_valid |= ATTR_RAW;
++              error = op->setattr_raw(inode, &newattrs);
++              /* the file system wants to use normal vfs path now */
++              if (error != -EOPNOTSUPP)
++                      goto dput_and_out;
++      }
++
++      error = -EROFS;
++      if (IS_RDONLY(inode))
++              goto dput_and_out;
++
++      error = -EPERM;
++      if (!times) {
+               if (current->fsuid != inode->i_uid &&
+                   (error = permission(inode,MAY_WRITE)) != 0)
+                       goto dput_and_out;
        }
++
        error = notify_change(nd.dentry, &newattrs);
  dput_and_out:
-+      intent_release(nd.dentry, &it);
        path_release(&nd);
- out:
-       return error;
-@@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena
-       struct nameidata nd;
+@@ -304,12 +337,14 @@ asmlinkage long sys_utimes(char * filena
        struct inode * inode;
        struct iattr newattrs;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
  
 -      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
++      error = user_path_walk_it(filename, &nd, NULL);
  
        if (error)
                goto out;
-@@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena
-       }
-       error = notify_change(nd.dentry, &newattrs);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
+       inode = nd.dentry->d_inode;
++      /* this is safe without a Lustre lock because it only depends
++         on the super block */
+       error = -EROFS;
+       if (IS_RDONLY(inode))
+               goto dput_and_out;
+@@ -324,7 +359,20 @@ asmlinkage long sys_utimes(char * filena
+               newattrs.ia_atime = times[0].tv_sec;
+               newattrs.ia_mtime = times[1].tv_sec;
+               newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET;
+-      } else {
++      }
++
++      if (inode->i_op->setattr_raw) {
++              struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++              newattrs.ia_valid |= ATTR_RAW;
++              error = op->setattr_raw(inode, &newattrs);
++              /* the file system wants to use normal vfs path now */
++              if (error != -EOPNOTSUPP)
++                      goto dput_and_out;
++      }
++
++      error = -EPERM;
++      if (!utimes) {
+               if (current->fsuid != inode->i_uid &&
+                   (error = permission(inode,MAY_WRITE)) != 0)
+                       goto dput_and_out;
 @@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * 
        int old_fsuid, old_fsgid;
        kernel_cap_t old_cap;
        path_release(&nd);
  out:
        return error;
-@@ -515,8 +530,9 @@ asmlinkage long sys_chmod(const char * f
-       struct inode * inode;
-       int error;
-       struct iattr newattrs;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
+@@ -508,6 +564,18 @@ asmlinkage long sys_chmod(const char * f
+       if (IS_RDONLY(inode))
+               goto dput_and_out;
  
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (error)
++      if (inode->i_op->setattr_raw) {
++              struct inode_operations *op = nd.dentry->d_inode->i_op;
++
++              newattrs.ia_mode = mode;
++              newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
++              newattrs.ia_valid |= ATTR_RAW;
++              error = op->setattr_raw(inode, &newattrs);
++              /* the file system wants to use normal vfs path now */
++              if (error != -EOPNOTSUPP)
++                      goto dput_and_out;
++      }
++
+       error = -EPERM;
+       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+               goto dput_and_out;
+@@ -538,6 +606,20 @@ static int chown_common(struct dentry * 
+       error = -EROFS;
+       if (IS_RDONLY(inode))
+               goto out;
++
++      if (inode->i_op->setattr_raw) {
++              struct inode_operations *op = dentry->d_inode->i_op;
++
++              newattrs.ia_uid = user;
++              newattrs.ia_gid = group;
++              newattrs.ia_valid = ATTR_UID | ATTR_GID;
++              newattrs.ia_valid |= ATTR_RAW;
++              error = op->setattr_raw(inode, &newattrs);
++              /* the file system wants to use normal vfs path now */
++              if (error != -EOPNOTSUPP)
++                      return error;
++      }
++
+       error = -EPERM;
+       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                goto out;
-       inode = nd.dentry->d_inode;
-@@ -536,6 +552,7 @@ asmlinkage long sys_chmod(const char * f
-       error = notify_change(nd.dentry, &newattrs);
- dput_and_out:
-+      intent_release(nd.dentry, &it);
-       path_release(&nd);
- out:
-       return error;
-@@ -605,10 +622,12 @@ asmlinkage long sys_chown(const char * f
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
--      error = user_path_walk(filename, &nd);
-+      error = user_path_walk_it(filename, &nd, &it);
-       if (!error) {
-               error = chown_common(nd.dentry, user, group);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
-@@ -618,10 +637,12 @@ asmlinkage long sys_lchown(const char * 
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_SETATTR };
--      error = user_path_walk_link(filename, &nd);
-+      error = user_path_walk_link_it(filename, &nd, &it);
-       if (!error) {
-               error = chown_common(nd.dentry, user, group);
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
 @@ -655,10 +676,16 @@ asmlinkage long sys_fchown(unsigned int 
   * for the internal routines (ie open_namei()/follow_link() etc). 00 is
   * used by symlinks.
  /*
   * Find an empty file descriptor entry, and mark it busy.
   */
---- linux-2.4.19-hp2_pnnl2/fs/stat.c~vfs_intent_hp     Sun Jan 19 19:04:47 2003
-+++ linux-2.4.19-hp2_pnnl2-root/fs/stat.c      Sun Jan 19 19:44:51 2003
-@@ -13,6 +13,7 @@
- #include <asm/uaccess.h>
-+extern void intent_release(struct dentry *de, struct lookup_intent *it);
- /*
-  * Revalidate the inode. This is required for proper NFS attribute caching.
-  */
+--- linux-2.4.19-hp2_pnnl4/fs/stat.c~vfs_intent_hp     Sun Jan 19 19:04:47 2003
++++ linux-2.4.19-hp2_pnnl4-root/fs/stat.c      Sun Jan 19 19:44:51 2003
 @@ -135,13 +136,15 @@ static int cp_new_stat(struct inode * in
  asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
  {
                path_release(&nd);
        }
        return error;
-@@ -247,11 +256,12 @@ asmlinkage long sys_readlink(const char 
- {
-       struct nameidata nd;
-       int error;
-+      struct lookup_intent it = { .it_op = IT_READLINK };
-       if (bufsiz <= 0)
-               return -EINVAL;
--      error = user_path_walk_link(path, &nd);
-+      error = user_path_walk_link_it(path, &nd, &it);
-       if (!error) {
-               struct inode * inode = nd.dentry->d_inode;
-@@ -261,6 +271,7 @@ asmlinkage long sys_readlink(const char 
-                       UPDATE_ATIME(inode);
-                       error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
-               }
-+              intent_release(nd.dentry, &it);
-               path_release(&nd);
-       }
-       return error;
 @@ -333,12 +344,14 @@ asmlinkage long sys_stat64(char * filena
  {
        struct nameidata nd;
                path_release(&nd);
        }
        return error;
---- linux-2.4.19-hp2_pnnl2/include/linux/dcache.h~vfs_intent_hp        Sun Jan 19 19:04:47 2003
-+++ linux-2.4.19-hp2_pnnl2-root/include/linux/dcache.h Sun Jan 19 19:04:48 2003
-@@ -6,6 +6,27 @@
+--- linux-2.4.19-hp2_pnnl4/fs/exec.c~vfs_intent_hp     Sun Feb  9 01:14:52 2003
++++ linux-2.4.19-hp2_pnnl4-root/fs/exec.c      Sun Feb  9 01:29:49 2003
+@@ -103,13 +104,18 @@ static inline void put_binfmt(struct lin
+  *
+  * Also note that we take the address to load from from the file itself.
+  */
++extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
++                          int flags, struct lookup_intent *it);
++int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd,
++                 struct lookup_intent *it);
+ asmlinkage long sys_uselib(const char * library)
+ {
+       struct file * file;
+       struct nameidata nd;
+       int error;
++      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
+-      error = user_path_walk(library, &nd);
++      error = user_path_walk_it(library, &nd, &it);
+       if (error)
+               goto out;
+@@ -121,7 +127,8 @@ asmlinkage long sys_uselib(const char * 
+       if (error)
+               goto exit;
+-      file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++      file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
++      intent_release(nd.dentry, &it);
+       error = PTR_ERR(file);
+       if (IS_ERR(file))
+               goto out;
+@@ -350,9 +350,10 @@ struct file *open_exec(const char *name)
+       struct inode *inode;
+       struct file *file;
+       int err = 0;
++      struct lookup_intent it = { .it_op = IT_OPEN, .it_flags = O_RDONLY };
+       if (path_init(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
+-              err = path_walk(name, &nd);
++              err = path_walk_it(name, &nd, &it);
+       file = ERR_PTR(err);
+       if (!err) {
+               inode = nd.dentry->d_inode;
+@@ -363,7 +369,8 @@ struct file *open_exec(const char *name)
+                               err = -EACCES;
+                       file = ERR_PTR(err);
+                       if (!err) {
+-                              file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
++                              file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it);
++                              intent_release(nd.dentry, &it);
+                               if (!IS_ERR(file)) {
+                                       err = deny_write_access(file);
+                                       if (err) {
+@@ -976,7 +986,7 @@ int do_coredump(long signr, struct pt_re
+               goto close_fail;
+       if (!file->f_op->write)
+               goto close_fail;
+-      if (do_truncate(file->f_dentry, 0) != 0)
++      if (do_truncate(file->f_dentry, 0, 0) != 0)
+               goto close_fail;
+       retval = binfmt->core_dump(signr, regs, file);
+--- linux-2.4.19-hp2_pnnl4/include/linux/dcache.h~vfs_intent_hp        Sun Jan 19 19:04:47 2003
++++ linux-2.4.19-hp2_pnnl4-root/include/linux/dcache.h Sun Jan 19 19:04:48 2003
+@@ -6,6 +6,25 @@
  #include <asm/atomic.h>
  #include <linux/mount.h>
  
 +#define IT_CREAT    (1<<1)
 +#define IT_READDIR  (1<<2)
 +#define IT_GETATTR  (1<<3)
-+#define IT_SETATTR  (1<<4)
-+#define IT_TRUNC    (1<<5)
-+#define IT_READLINK (1<<6)
-+#define IT_LOOKUP   (1<<7)
++#define IT_LOOKUP   (1<<4)
++#define IT_UNLINK   (1<<5)
 +
 +struct lookup_intent {
 +      int it_op;
        unsigned long d_vfs_flags;
        void * d_fsdata;                /* fs-specific data */
        unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
-@@ -90,6 +119,8 @@ struct dentry_operations {
+@@ -90,8 +119,15 @@ struct dentry_operations {
        int (*d_delete)(struct dentry *);
        void (*d_release)(struct dentry *);
        void (*d_iput)(struct dentry *, struct inode *);
 +      void (*d_intent_release)(struct dentry *, struct lookup_intent *);
  };
  
++/* defined in fs/namei.c */
++extern void intent_release(struct dentry *de, struct lookup_intent *it);
++/* defined in fs/dcache.c */
++extern void __d_rehash(struct dentry * entry, int lock);
++
  /* the dentry parameter passed to d_hash and d_compare is the parent
-@@ -124,6 +148,7 @@ d_iput:            no              no              yes
+  * directory of the entries to be compared. It is used in case these
+  * functions need any directory specific information for determining
+@@ -124,6 +149,7 @@ d_iput:            no              no              yes
                                         * s_nfsd_free_path semaphore will be down
                                         */
  #define DCACHE_REFERENCED     0x0008  /* Recently used, don't discard. */
  
  extern spinlock_t dcache_lock;
  
---- linux-2.4.19-hp2_pnnl2/include/linux/fs.h~vfs_intent_hp    Sun Jan 19 19:04:47 2003
-+++ linux-2.4.19-hp2_pnnl2-root/include/linux/fs.h     Sun Jan 19 19:04:48 2003
+--- linux-2.4.19-hp2_pnnl4/include/linux/fs.h~vfs_intent_hp    Sun Jan 19 19:04:47 2003
++++ linux-2.4.19-hp2_pnnl4-root/include/linux/fs.h     Sun Jan 19 19:04:48 2003
+@@ -338,6 +338,8 @@ extern void set_bh_page(struct buffer_he
+ #define ATTR_MTIME_SET        256
+ #define ATTR_FORCE    512     /* Not a change, but a change it */
+ #define ATTR_ATTR_FLAG        1024
++#define ATTR_RAW      2048    /* file system, not vfs will massage attrs */
++#define ATTR_FROM_OPEN        4096    /* called from open path, ie O_TRUNC */
+ /*
+  * This is the Inode Attributes structure, used for notify_change().  It
 @@ -575,6 +575,7 @@ struct file {
  
        /* needed for tty driver, and maybe others */
  
  /*
   * File types
-@@ -876,16 +879,28 @@ struct file_operations {
+@@ -876,20 +879,33 @@ struct file_operations {
  struct inode_operations {
        int (*create) (struct inode *,struct dentry *,int);
        struct dentry * (*lookup) (struct inode *,struct dentry *);
        void (*truncate) (struct inode *);
        int (*permission) (struct inode *, int);
        int (*revalidate) (struct dentry *);
+       int (*setattr) (struct dentry *, struct iattr *);
++      int (*setattr_raw) (struct inode *, struct iattr *);
+       int (*getattr) (struct dentry *, struct iattr *);
+       int (*setxattr) (struct dentry *, const char *, void *, size_t, int);
+       ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
+@@ -1112,7 +1130,7 @@ static inline int get_lease(struct inode
+ asmlinkage long sys_open(const char *, int, int);
+ asmlinkage long sys_close(unsigned int);      /* yes, it's really unsigned */
+-extern int do_truncate(struct dentry *, loff_t start);
++extern int do_truncate(struct dentry *, loff_t start, int called_from_open);
+ extern struct file *filp_open(const char *, int, int);
+ extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
 @@ -1354,6 +1369,7 @@ typedef int (*read_actor_t)(read_descrip
  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
  
  extern int page_readlink(struct dentry *, char *, int);
  extern int page_follow_link(struct dentry *, struct nameidata *);
  extern struct inode_operations page_symlink_inode_operations;
---- linux-2.4.19-hp2_pnnl2/kernel/ksyms.c~vfs_intent_hp        Sun Jan 19 19:04:47 2003
-+++ linux-2.4.19-hp2_pnnl2-root/kernel/ksyms.c Sun Jan 19 19:04:48 2003
+--- linux-2.4.19-hp2_pnnl4/kernel/ksyms.c~vfs_intent_hp        Sun Jan 19 19:04:47 2003
++++ linux-2.4.19-hp2_pnnl4-root/kernel/ksyms.c Sun Jan 19 19:04:48 2003
 @@ -293,6 +293,7 @@ EXPORT_SYMBOL(read_cache_page);
  EXPORT_SYMBOL(set_page_dirty);
  EXPORT_SYMBOL(vfs_readlink);
  EXPORT_SYMBOL(page_readlink);
  EXPORT_SYMBOL(page_follow_link);
  EXPORT_SYMBOL(page_symlink_inode_operations);
-
-_