Whamcloud - gitweb
file llobdstat.pl was initially added on branch b_devel.
[fs/lustre-release.git] / lustre / kernel_patches / patches / vanilla-2.4.19.patch
1
2
3
4  arch/i386/mm/init.c            |    6 
5  arch/ia64/mm/init.c            |    6 
6  drivers/block/blkpg.c          |   35 ++++
7  drivers/block/loop.c           |    5 
8  drivers/ide/ide-disk.c         |    6 
9  fs/dcache.c                    |    1 
10  fs/ext3/Makefile               |    2 
11  fs/ext3/super.c                |    2 
12  fs/namei.c                     |  296 ++++++++++++++++++++++++++++++++++-------
13  fs/nfsd/vfs.c                  |    2 
14  fs/open.c                      |   63 ++++++--
15  fs/stat.c                      |   30 +++-
16  include/linux/blkdev.h         |    4 
17  include/linux/dcache.h         |   31 ++++
18  include/linux/fs.h             |   23 +++
19  include/linux/lustre_version.h |    1 
20  include/linux/slab.h           |    1 
21  kernel/ksyms.c                 |    7 
22  mm/slab.c                      |   53 +++++++
23  19 files changed, 501 insertions(+), 73 deletions(-)
24
25 --- /dev/null   Fri Aug 30 17:31:37 2002
26 +++ linux-2.4.19-root/include/linux/lustre_version.h    Sun Jan 19 19:54:00 2003
27 @@ -0,0 +1 @@
28 +#define LUSTRE_KERNEL_VERSION 7
29 --- linux-2.4.19/arch/ia64/mm/init.c~vanilla-2.4.19     Sun Jan 19 19:46:42 2003
30 +++ linux-2.4.19-root/arch/ia64/mm/init.c       Sun Jan 19 19:46:42 2003
31 @@ -37,6 +37,12 @@ unsigned long MAX_DMA_ADDRESS = PAGE_OFF
32  
33  static unsigned long totalram_pages;
34  
35 +struct page *check_get_page(unsigned long kaddr)
36 +{
37 +#warning FIXME: Lustre team, is this solid?
38 +       return virt_to_page(kaddr);
39 +}
40 +
41  int
42  do_check_pgt_cache (int low, int high)
43  {
44 --- linux-2.4.19/arch/i386/mm/init.c~vanilla-2.4.19     Sun Jan 19 19:46:42 2003
45 +++ linux-2.4.19-root/arch/i386/mm/init.c       Sun Jan 19 19:46:42 2003
46 @@ -43,6 +43,12 @@ unsigned long highstart_pfn, highend_pfn
47  static unsigned long totalram_pages;
48  static unsigned long totalhigh_pages;
49  
50 +struct page *check_get_page(unsigned long kaddr)
51 +{
52 +#warning FIXME: Lustre team, is this solid?
53 +       return virt_to_page(kaddr);
54 +}
55 +
56  int do_check_pgt_cache(int low, int high)
57  {
58         int freed = 0;
59 --- linux-2.4.19/drivers/block/blkpg.c~vanilla-2.4.19   Sun Jan 19 19:46:42 2003
60 +++ linux-2.4.19-root/drivers/block/blkpg.c     Sun Jan 19 19:46:42 2003
61 @@ -296,3 +296,38 @@ int blk_ioctl(kdev_t dev, unsigned int c
62  }
63  
64  EXPORT_SYMBOL(blk_ioctl);
65 +
66 +#define NUM_DEV_NO_WRITE 16
67 +static int dev_no_write[NUM_DEV_NO_WRITE];
68 +
69 +/*
70 + * Debug code for turning block devices "read-only" (will discard writes
71 + * silently).  This is for filesystem crash/recovery testing.
72 + */
73 +void dev_set_rdonly(kdev_t dev, int no_write)
74 +{
75 +       if (dev) {
76 +               printk(KERN_WARNING "Turning device %s read-only\n",
77 +                      bdevname(dev));
78 +               dev_no_write[no_write] = 0xdead0000 + dev;
79 +       }
80 +}
81 +
82 +int dev_check_rdonly(kdev_t dev) {
83 +       int i;
84 +
85 +       for (i = 0; i < NUM_DEV_NO_WRITE; i++) {
86 +               if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 &&
87 +                   dev == (dev_no_write[i] & 0xffff))
88 +                       return 1;
89 +       }
90 +       return 0;
91 +}
92 +
93 +void dev_clear_rdonly(int no_write) {
94 +       dev_no_write[no_write] = 0;
95 +}
96 +
97 +EXPORT_SYMBOL(dev_set_rdonly);
98 +EXPORT_SYMBOL(dev_check_rdonly);
99 +EXPORT_SYMBOL(dev_clear_rdonly);
100 --- linux-2.4.19/drivers/block/loop.c~vanilla-2.4.19    Sun Jan 19 19:46:42 2003
101 +++ linux-2.4.19-root/drivers/block/loop.c      Sun Jan 19 19:46:42 2003
102 @@ -474,6 +474,11 @@ static int loop_make_request(request_que
103         spin_unlock_irq(&lo->lo_lock);
104  
105         if (rw == WRITE) {
106 +#ifdef CONFIG_DEV_RDONLY
107 +               if (dev_check_rdonly(rbh->b_rdev))
108 +                       goto err;
109 +#endif
110 +
111                 if (lo->lo_flags & LO_FLAGS_READ_ONLY)
112                         goto err;
113         } else if (rw == READA) {
114 --- linux-2.4.19/drivers/ide/ide-disk.c~vanilla-2.4.19  Sun Jan 19 19:46:42 2003
115 +++ linux-2.4.19-root/drivers/ide/ide-disk.c    Sun Jan 19 19:46:42 2003
116 @@ -551,6 +551,12 @@ static ide_startstop_t lba_48_rw_disk (i
117   */
118  static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
119  {
120 +#ifdef CONFIG_DEV_RDONLY
121 +       if (rq->cmd == WRITE && dev_check_rdonly(rq->rq_dev)) {
122 +               ide_end_request(1, HWGROUP(drive));
123 +               return ide_stopped;
124 +       }
125 +#endif
126         if (IDE_CONTROL_REG)
127                 OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
128  
129 --- linux-2.4.19/fs/ext3/Makefile~vanilla-2.4.19        Sun Jan 19 19:46:42 2003
130 +++ linux-2.4.19-root/fs/ext3/Makefile  Sun Jan 19 19:46:42 2003
131 @@ -9,6 +9,8 @@
132  
133  O_TARGET := ext3.o
134  
135 +export-objs := super.o
136 +
137  obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \
138                 ioctl.o namei.o super.o symlink.o
139  obj-m    := $(O_TARGET)
140 --- linux-2.4.19/fs/ext3/super.c~vanilla-2.4.19 Sun Jan 19 19:46:42 2003
141 +++ linux-2.4.19-root/fs/ext3/super.c   Sun Jan 19 19:46:42 2003
142 @@ -1744,7 +1744,7 @@ static void __exit exit_ext3_fs(void)
143         unregister_filesystem(&ext3_fs_type);
144  }
145  
146 -EXPORT_NO_SYMBOLS;
147 +EXPORT_SYMBOL(ext3_bread);
148  
149  MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
150  MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions");
151 --- linux-2.4.19/include/linux/blkdev.h~vanilla-2.4.19  Sun Jan 19 19:46:42 2003
152 +++ linux-2.4.19-root/include/linux/blkdev.h    Sun Jan 19 21:05:55 2003
153 @@ -240,4 +240,8 @@ static inline unsigned int block_size(kd
154         return retval;
155  }
156  
157 +#define CONFIG_DEV_RDONLY
158 +void dev_set_rdonly(kdev_t, int);
159 +int dev_check_rdonly(kdev_t);
160 +void dev_clear_rdonly(int);
161  #endif
162 --- linux-2.4.19/include/linux/slab.h~vanilla-2.4.19    Sun Jan 19 19:46:42 2003
163 +++ linux-2.4.19-root/include/linux/slab.h      Sun Jan 19 21:05:52 2003
164 @@ -57,6 +57,7 @@ extern int kmem_cache_destroy(kmem_cache
165  extern int kmem_cache_shrink(kmem_cache_t *);
166  extern void *kmem_cache_alloc(kmem_cache_t *, int);
167  extern void kmem_cache_free(kmem_cache_t *, void *);
168 +extern int kmem_cache_validate(kmem_cache_t *cachep, void *objp);
169  
170  extern void *kmalloc(size_t, int);
171  extern void kfree(const void *);
172 --- linux-2.4.19/kernel/ksyms.c~vanilla-2.4.19  Sun Jan 19 19:46:42 2003
173 +++ linux-2.4.19-root/kernel/ksyms.c    Sun Jan 19 19:46:42 2003
174 @@ -264,6 +264,7 @@ EXPORT_SYMBOL(read_cache_page);
175  EXPORT_SYMBOL(set_page_dirty);
176  EXPORT_SYMBOL(vfs_readlink);
177  EXPORT_SYMBOL(vfs_follow_link);
178 +EXPORT_SYMBOL(vfs_follow_link_it);
179  EXPORT_SYMBOL(page_readlink);
180  EXPORT_SYMBOL(page_follow_link);
181  EXPORT_SYMBOL(page_symlink_inode_operations);
182 @@ -280,6 +281,12 @@ EXPORT_SYMBOL(dcache_dir_fsync);
183  EXPORT_SYMBOL(dcache_readdir);
184  EXPORT_SYMBOL(dcache_dir_ops);
185  
186 +/* lustre */
187 +EXPORT_SYMBOL(panic_notifier_list);
188 +EXPORT_SYMBOL(pagecache_lock_cacheline);
189 +EXPORT_SYMBOL(do_kern_mount);
190 +EXPORT_SYMBOL(kmem_cache_validate);
191 +
192  /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */
193  EXPORT_SYMBOL(default_llseek);
194  EXPORT_SYMBOL(dentry_open);
195 --- linux-2.4.19/include/linux/dcache.h~vanilla-2.4.19  Sun Jan 19 19:46:42 2003
196 +++ linux-2.4.19-root/include/linux/dcache.h    Sun Jan 19 19:46:42 2003
197 @@ -6,6 +6,34 @@
198  #include <asm/atomic.h>
199  #include <linux/mount.h>
200  
201 +#define IT_OPEN  (1)
202 +#define IT_CREAT  (1<<1)
203 +#define IT_MKDIR  (1<<2)
204 +#define IT_LINK  (1<<3)
205 +#define IT_LINK2  (1<<4)
206 +#define IT_SYMLINK  (1<<5)
207 +#define IT_UNLINK  (1<<6)
208 +#define IT_RMDIR  (1<<7)
209 +#define IT_RENAME  (1<<8)
210 +#define IT_RENAME2  (1<<9)
211 +#define IT_READDIR  (1<<10)
212 +#define IT_GETATTR  (1<<11)
213 +#define IT_SETATTR  (1<<12)
214 +#define IT_READLINK  (1<<13)
215 +#define IT_MKNOD  (1<<14)
216 +#define IT_LOOKUP  (1<<15)
217 +
218 +struct lookup_intent {
219 +       int it_op;
220 +       int it_mode;
221 +       int it_disposition;
222 +       int it_status;
223 +       struct iattr *it_iattr;
224 +       __u64 it_lock_handle[2];
225 +       int it_lock_mode;
226 +       void *it_data;
227 +};
228 +
229  /*
230   * linux/include/linux/dcache.h
231   *
232 @@ -78,6 +106,7 @@ struct dentry {
233         unsigned long d_time;           /* used by d_revalidate */
234         struct dentry_operations  *d_op;
235         struct super_block * d_sb;      /* The root of the dentry tree */
236 +       struct lookup_intent *d_it;
237         unsigned long d_vfs_flags;
238         void * d_fsdata;                /* fs-specific data */
239         unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
240 @@ -90,6 +119,8 @@ struct dentry_operations {
241         int (*d_delete)(struct dentry *);
242         void (*d_release)(struct dentry *);
243         void (*d_iput)(struct dentry *, struct inode *);
244 +       int (*d_revalidate2)(struct dentry *, int, struct lookup_intent *);
245 +       void (*d_intent_release)(struct dentry *, struct lookup_intent *);
246  };
247  
248  /* the dentry parameter passed to d_hash and d_compare is the parent
249 --- linux-2.4.19/include/linux/fs.h~vanilla-2.4.19      Sun Jan 19 19:46:42 2003
250 +++ linux-2.4.19-root/include/linux/fs.h        Sun Jan 19 21:05:40 2003
251 @@ -541,6 +541,7 @@ struct file {
252  
253         /* needed for tty driver, and maybe others */
254         void                    *private_data;
255 +       struct lookup_intent    *f_intent;
256  
257         /* preallocated helper kiobuf to speedup O_DIRECT */
258         struct kiobuf           *f_iobuf;
259 @@ -792,7 +793,9 @@ extern int vfs_symlink(struct inode *, s
260  extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
261  extern int vfs_rmdir(struct inode *, struct dentry *);
262  extern int vfs_unlink(struct inode *, struct dentry *);
263 -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
264 +int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
265 +               struct inode *new_dir, struct dentry *new_dentry,
266 +               struct lookup_intent *it);
267  
268  /*
269   * File types
270 @@ -853,16 +856,28 @@ struct file_operations {
271  struct inode_operations {
272         int (*create) (struct inode *,struct dentry *,int);
273         struct dentry * (*lookup) (struct inode *,struct dentry *);
274 +       struct dentry * (*lookup2) (struct inode *,struct dentry *, struct lookup_intent *);
275         int (*link) (struct dentry *,struct inode *,struct dentry *);
276 +       int (*link2) (struct inode *,struct inode *, const char *, int);
277         int (*unlink) (struct inode *,struct dentry *);
278 +       int (*unlink2) (struct inode *, char *, int);
279         int (*symlink) (struct inode *,struct dentry *,const char *);
280 +       int (*symlink2) (struct inode *,const char *, int, const char *);
281         int (*mkdir) (struct inode *,struct dentry *,int);
282 +       int (*mkdir2) (struct inode *,char *, int,int);
283         int (*rmdir) (struct inode *,struct dentry *);
284 +       int (*rmdir2) (struct inode *, char *, int);
285         int (*mknod) (struct inode *,struct dentry *,int,int);
286 +       int (*mknod2) (struct inode *,char *, int,int,int);
287         int (*rename) (struct inode *, struct dentry *,
288                         struct inode *, struct dentry *);
289 +       int (*rename2) (struct inode *, struct inode *, 
290 +                       char *oldname, int oldlen, 
291 +                       char *newname, int newlen);
292         int (*readlink) (struct dentry *, char *,int);
293         int (*follow_link) (struct dentry *, struct nameidata *);
294 +       int (*follow_link2) (struct dentry *, struct nameidata *,
295 +                              struct lookup_intent *it);
296         void (*truncate) (struct inode *);
297         int (*permission) (struct inode *, int);
298         int (*revalidate) (struct dentry *);
299 @@ -999,6 +1014,7 @@ extern int unregister_filesystem(struct 
300  extern struct vfsmount *kern_mount(struct file_system_type *);
301  extern int may_umount(struct vfsmount *);
302  extern long do_mount(char *, char *, char *, unsigned long, void *);
303 +struct vfsmount *do_kern_mount(const char *fstype, int flags, char *name, void *data);
304  extern void umount_tree(struct vfsmount *);
305  
306  #define kern_umount mntput
307 @@ -1329,6 +1345,7 @@ typedef int (*read_actor_t)(read_descrip
308  extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
309  
310  extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
311 +extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it));
312  extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
313  extern int FASTCALL(path_walk(const char *, struct nameidata *));
314  extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
315 @@ -1339,6 +1356,8 @@ extern struct dentry * lookup_one_len(co
316  extern struct dentry * lookup_hash(struct qstr *, struct dentry *);
317  #define user_path_walk(name,nd)         __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd)
318  #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd)
319 +#define user_path_walk_it(name,nd,it)  __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it)
320 +#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it)
321  
322  extern void iput(struct inode *);
323  extern void force_delete(struct inode *);
324 @@ -1448,6 +1467,8 @@ extern struct file_operations generic_ro
325  
326  extern int vfs_readlink(struct dentry *, char *, int, const char *);
327  extern int vfs_follow_link(struct nameidata *, const char *);
328 +extern int vfs_follow_link_it(struct nameidata *, const char *,
329 +                             struct lookup_intent *it);
330  extern int page_readlink(struct dentry *, char *, int);
331  extern int page_follow_link(struct dentry *, struct nameidata *);
332  extern struct inode_operations page_symlink_inode_operations;
333 --- linux-2.4.19/fs/dcache.c~vanilla-2.4.19     Sun Jan 19 19:46:42 2003
334 +++ linux-2.4.19-root/fs/dcache.c       Sun Jan 19 19:46:42 2003
335 @@ -616,6 +616,7 @@ struct dentry * d_alloc(struct dentry * 
336         dentry->d_op = NULL;
337         dentry->d_fsdata = NULL;
338         dentry->d_mounted = 0;
339 +       dentry->d_it = NULL;
340         INIT_LIST_HEAD(&dentry->d_hash);
341         INIT_LIST_HEAD(&dentry->d_lru);
342         INIT_LIST_HEAD(&dentry->d_subdirs);
343 --- linux-2.4.19/fs/nfsd/vfs.c~vanilla-2.4.19   Sun Jan 19 19:46:42 2003
344 +++ linux-2.4.19-root/fs/nfsd/vfs.c     Sun Jan 19 19:46:42 2003
345 @@ -1295,7 +1295,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
346                         err = nfserr_perm;
347         } else
348  #endif
349 -       err = vfs_rename(fdir, odentry, tdir, ndentry);
350 +       err = vfs_rename(fdir, odentry, tdir, ndentry, NULL);
351         if (!err && EX_ISSYNC(tfhp->fh_export)) {
352                 nfsd_sync_dir(tdentry);
353                 nfsd_sync_dir(fdentry);
354 --- linux-2.4.19/fs/namei.c~vanilla-2.4.19      Sun Jan 19 19:46:42 2003
355 +++ linux-2.4.19-root/fs/namei.c        Sun Jan 19 19:46:42 2003
356 @@ -94,6 +94,12 @@
357   * XEmacs seems to be relying on it...
358   */
359  
360 +void intent_release(struct dentry *de, struct lookup_intent *it)
361 +{
362 +       if (it && de->d_op && de->d_op->d_intent_release)
363 +               de->d_op->d_intent_release(de, it);
364 +}
365 +
366  /* In order to reduce some races, while at the same time doing additional
367   * checking and hopefully speeding things up, we copy filenames to the
368   * kernel data space before using them..
369 @@ -260,10 +266,19 @@ void path_release(struct nameidata *nd)
370   * Internal lookup() using the new generic dcache.
371   * SMP-safe
372   */
373 -static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
374 +static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name,
375 +                                   int flags, struct lookup_intent *it)
376  {
377         struct dentry * dentry = d_lookup(parent, name);
378  
379 +       if (dentry && dentry->d_op && dentry->d_op->d_revalidate2) {
380 +               if (!dentry->d_op->d_revalidate2(dentry, flags, it) &&
381 +                   !d_invalidate(dentry)) {
382 +                       dput(dentry);
383 +                       dentry = NULL;
384 +               }
385 +               return dentry;
386 +       } else
387         if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
388                 if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
389                         dput(dentry);
390 @@ -281,7 +296,8 @@ static struct dentry * cached_lookup(str
391   * make sure that nobody added the entry to the dcache in the meantime..
392   * SMP-safe
393   */
394 -static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
395 +static struct dentry *real_lookup(struct dentry *parent, struct qstr *name,
396 +                                 int flags, struct lookup_intent *it)
397  {
398         struct dentry * result;
399         struct inode *dir = parent->d_inode;
400 @@ -300,6 +316,9 @@ static struct dentry * real_lookup(struc
401                 result = ERR_PTR(-ENOMEM);
402                 if (dentry) {
403                         lock_kernel();
404 +                       if (dir->i_op->lookup2)
405 +                               result = dir->i_op->lookup2(dir, dentry, it);
406 +                       else
407                         result = dir->i_op->lookup(dir, dentry);
408                         unlock_kernel();
409                         if (result)
410 @@ -321,6 +340,12 @@ static struct dentry * real_lookup(struc
411                         dput(result);
412                         result = ERR_PTR(-ENOENT);
413                 }
414 +       } else if (result->d_op && result->d_op->d_revalidate2) {
415 +               if (!result->d_op->d_revalidate2(result, flags, it) &&
416 +                   !d_invalidate(result)) {
417 +                       dput(result);
418 +                       result = ERR_PTR(-ENOENT);
419 +               }
420         }
421         return result;
422  }
423 @@ -332,7 +357,8 @@ static struct dentry * real_lookup(struc
424   * Without that kind of total limit, nasty chains of consecutive
425   * symlinks can cause almost arbitrarily long lookups. 
426   */
427 -static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
428 +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd,
429 +                                struct lookup_intent *it)
430  {
431         int err;
432         if (current->link_count >= 5)
433 @@ -346,10 +372,14 @@ static inline int do_follow_link(struct 
434         current->link_count++;
435         current->total_link_count++;
436         UPDATE_ATIME(dentry->d_inode);
437 -       err = dentry->d_inode->i_op->follow_link(dentry, nd);
438 +       if (dentry->d_inode->i_op->follow_link2)
439 +               err = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
440 +       else
441 +               err = dentry->d_inode->i_op->follow_link(dentry, nd);
442         current->link_count--;
443         return err;
444  loop:
445 +       intent_release(dentry, it);
446         path_release(nd);
447         return -ELOOP;
448  }
449 @@ -447,7 +477,8 @@ static inline void follow_dotdot(struct 
450   *
451   * We expect 'base' to be positive and a directory.
452   */
453 -int link_path_walk(const char * name, struct nameidata *nd)
454 +int link_path_walk_it(const char *name, struct nameidata *nd,
455 +                     struct lookup_intent *it)
456  {
457         struct dentry *dentry;
458         struct inode *inode;
459 @@ -520,9 +551,9 @@ int link_path_walk(const char * name, st
460                                 break;
461                 }
462                 /* This does the actual lookups.. */
463 -               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
464 +               dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
465                 if (!dentry) {
466 -                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
467 +                       dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, NULL);
468                         err = PTR_ERR(dentry);
469                         if (IS_ERR(dentry))
470                                 break;
471 @@ -539,8 +570,8 @@ int link_path_walk(const char * name, st
472                 if (!inode->i_op)
473                         goto out_dput;
474  
475 -               if (inode->i_op->follow_link) {
476 -                       err = do_follow_link(dentry, nd);
477 +               if (inode->i_op->follow_link || inode->i_op->follow_link2) {
478 +                       err = do_follow_link(dentry, nd, NULL);
479                         dput(dentry);
480                         if (err)
481                                 goto return_err;
482 @@ -556,7 +587,7 @@ int link_path_walk(const char * name, st
483                         nd->dentry = dentry;
484                 }
485                 err = -ENOTDIR; 
486 -               if (!inode->i_op->lookup)
487 +               if (!inode->i_op->lookup && !inode->i_op->lookup2)
488                         break;
489                 continue;
490                 /* here ends the main loop */
491 @@ -583,9 +614,9 @@ last_component:
492                         if (err < 0)
493                                 break;
494                 }
495 -               dentry = cached_lookup(nd->dentry, &this, 0);
496 +               dentry = cached_lookup(nd->dentry, &this, 0, it);
497                 if (!dentry) {
498 -                       dentry = real_lookup(nd->dentry, &this, 0);
499 +                       dentry = real_lookup(nd->dentry, &this, 0, it);
500                         err = PTR_ERR(dentry);
501                         if (IS_ERR(dentry))
502                                 break;
503 @@ -593,9 +624,9 @@ last_component:
504                 while (d_mountpoint(dentry) && __follow_down(&nd->mnt, &dentry))
505                         ;
506                 inode = dentry->d_inode;
507 -               if ((lookup_flags & LOOKUP_FOLLOW)
508 -                   && inode && inode->i_op && inode->i_op->follow_link) {
509 -                       err = do_follow_link(dentry, nd);
510 +               if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op &&
511 +                   (inode->i_op->follow_link || inode->i_op->follow_link2)) {
512 +                       err = do_follow_link(dentry, nd, it);
513                         dput(dentry);
514                         if (err)
515                                 goto return_err;
516 @@ -609,7 +640,8 @@ last_component:
517                         goto no_inode;
518                 if (lookup_flags & LOOKUP_DIRECTORY) {
519                         err = -ENOTDIR; 
520 -                       if (!inode->i_op || !inode->i_op->lookup)
521 +                       if (!inode->i_op ||
522 +                           (!inode->i_op->lookup && !inode->i_op->lookup2))
523                                 break;
524                 }
525                 goto return_base;
526 @@ -646,15 +678,28 @@ out_dput:
527                 dput(dentry);
528                 break;
529         }
530 +       if (err)
531 +               intent_release(nd->dentry, it);
532         path_release(nd);
533  return_err:
534         return err;
535  }
536  
537 +int link_path_walk(const char * name, struct nameidata *nd)
538 +{
539 +       return link_path_walk_it(name, nd, NULL);
540 +}
541 +
542 +int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it)
543 +{
544 +       current->total_link_count = 0;
545 +       return link_path_walk_it(name, nd, it);
546 +}
547 +
548  int path_walk(const char * name, struct nameidata *nd)
549  {
550         current->total_link_count = 0;
551 -       return link_path_walk(name, nd);
552 +       return link_path_walk_it(name, nd, NULL);
553  }
554  
555  /* SMP-safe */
556 @@ -757,7 +802,8 @@ int path_init(const char *name, unsigned
557   * needs parent already locked. Doesn't follow mounts.
558   * SMP-safe.
559   */
560 -struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
561 +struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base,
562 +                              struct lookup_intent *it)
563  {
564         struct dentry * dentry;
565         struct inode *inode;
566 @@ -780,13 +826,16 @@ struct dentry * lookup_hash(struct qstr 
567                         goto out;
568         }
569  
570 -       dentry = cached_lookup(base, name, 0);
571 +       dentry = cached_lookup(base, name, 0, it);
572         if (!dentry) {
573                 struct dentry *new = d_alloc(base, name);
574                 dentry = ERR_PTR(-ENOMEM);
575                 if (!new)
576                         goto out;
577                 lock_kernel();
578 +               if (inode->i_op->lookup2)
579 +                       dentry = inode->i_op->lookup2(inode, new, it);
580 +               else
581                 dentry = inode->i_op->lookup(inode, new);
582                 unlock_kernel();
583                 if (!dentry)
584 @@ -798,6 +847,12 @@ out:
585         return dentry;
586  }
587  
588 +struct dentry * lookup_hash(struct qstr *name, struct dentry * base)
589 +{
590 +       return lookup_hash_it(name, base, NULL);
591 +}
592 +
593 +
594  /* SMP-safe */
595  struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
596  {
597 @@ -819,7 +874,7 @@ struct dentry * lookup_one_len(const cha
598         }
599         this.hash = end_name_hash(hash);
600  
601 -       return lookup_hash(&this, base);
602 +       return lookup_hash_it(&this, base, NULL);
603  access:
604         return ERR_PTR(-EACCES);
605  }
606 @@ -851,6 +906,23 @@ int __user_walk(const char *name, unsign
607         return err;
608  }
609  
610 +int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd,
611 +                  struct lookup_intent *it)
612 +{
613 +       char *tmp;
614 +       int err;
615 +
616 +       tmp = getname(name);
617 +       err = PTR_ERR(tmp);
618 +       if (!IS_ERR(tmp)) {
619 +               err = 0;
620 +               if (path_init(tmp, flags, nd))
621 +                       err = path_walk_it(tmp, nd, it);
622 +               putname(tmp);
623 +       }
624 +       return err;
625 +}
626 +
627  /*
628   * It's inline, so penalty for filesystems that don't use sticky bit is
629   * minimal.
630 @@ -987,7 +1059,8 @@ exit_lock:
631   * for symlinks (where the permissions are checked later).
632   * SMP-safe
633   */
634 -int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
635 +int open_namei_it(const char *pathname, int flag, int mode,
636 +                 struct nameidata *nd, struct lookup_intent *it)
637  {
638         int acc_mode, error = 0;
639         struct inode *inode;
640 @@ -1002,7 +1075,7 @@ int open_namei(const char * pathname, in
641          */
642         if (!(flag & O_CREAT)) {
643                 if (path_init(pathname, lookup_flags(flag), nd))
644 -                       error = path_walk(pathname, nd);
645 +                       error = path_walk_it(pathname, nd, it);
646                 if (error)
647                         return error;
648                 dentry = nd->dentry;
649 @@ -1012,6 +1085,10 @@ int open_namei(const char * pathname, in
650         /*
651          * Create - we need to know the parent.
652          */
653 +       if (it) {
654 +               it->it_mode = mode;
655 +               it->it_op |= IT_CREAT;
656 +       }
657         if (path_init(pathname, LOOKUP_PARENT, nd))
658                 error = path_walk(pathname, nd);
659         if (error)
660 @@ -1028,7 +1105,7 @@ int open_namei(const char * pathname, in
661  
662         dir = nd->dentry;
663         down(&dir->d_inode->i_sem);
664 -       dentry = lookup_hash(&nd->last, nd->dentry);
665 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
666  
667  do_last:
668         error = PTR_ERR(dentry);
669 @@ -1037,6 +1114,7 @@ do_last:
670                 goto exit;
671         }
672  
673 +       it->it_mode = mode;
674         /* Negative dentry, just create the file */
675         if (!dentry->d_inode) {
676                 error = vfs_create(dir->d_inode, dentry,
677 @@ -1070,7 +1148,8 @@ do_last:
678         error = -ENOENT;
679         if (!dentry->d_inode)
680                 goto exit_dput;
681 -       if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link)
682 +       if (dentry->d_inode->i_op && (dentry->d_inode->i_op->follow_link ||
683 +                                     dentry->d_inode->i_op->follow_link2))
684                 goto do_link;
685  
686         dput(nd->dentry);
687 @@ -1156,8 +1235,10 @@ ok:
688         return 0;
689  
690  exit_dput:
691 +       intent_release(dentry, it);
692         dput(dentry);
693  exit:
694 +       intent_release(nd->dentry, it);
695         path_release(nd);
696         return error;
697  
698 @@ -1176,7 +1257,12 @@ do_link:
699          * are done. Procfs-like symlinks just set LAST_BIND.
700          */
701         UPDATE_ATIME(dentry->d_inode);
702 -       error = dentry->d_inode->i_op->follow_link(dentry, nd);
703 +       if (dentry->d_inode->i_op->follow_link2)
704 +               error = dentry->d_inode->i_op->follow_link2(dentry, nd, it);
705 +       else
706 +               error = dentry->d_inode->i_op->follow_link(dentry, nd);
707 +       if (error)
708 +               intent_release(dentry, it);
709         dput(dentry);
710         if (error)
711                 return error;
712 @@ -1198,13 +1284,20 @@ do_link:
713         }
714         dir = nd->dentry;
715         down(&dir->d_inode->i_sem);
716 -       dentry = lookup_hash(&nd->last, nd->dentry);
717 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
718         putname(nd->last.name);
719         goto do_last;
720  }
721  
722 +int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd)
723 +{
724 +       return open_namei_it(pathname, flag, mode, nd, NULL);
725 +}
726 +
727 +
728  /* SMP-safe */
729 -static struct dentry *lookup_create(struct nameidata *nd, int is_dir)
730 +static struct dentry *lookup_create(struct nameidata *nd, int is_dir,
731 +                                   struct lookup_intent *it)
732  {
733         struct dentry *dentry;
734  
735 @@ -1212,7 +1305,7 @@ static struct dentry *lookup_create(stru
736         dentry = ERR_PTR(-EEXIST);
737         if (nd->last_type != LAST_NORM)
738                 goto fail;
739 -       dentry = lookup_hash(&nd->last, nd->dentry);
740 +       dentry = lookup_hash_it(&nd->last, nd->dentry, it);
741         if (IS_ERR(dentry))
742                 goto fail;
743         if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
744 @@ -1258,6 +1351,7 @@ asmlinkage long sys_mknod(const char * f
745         char * tmp;
746         struct dentry * dentry;
747         struct nameidata nd;
748 +       struct lookup_intent it = { .it_op = IT_MKNOD, .it_mode = mode };
749  
750         if (S_ISDIR(mode))
751                 return -EPERM;
752 @@ -1269,7 +1363,19 @@ asmlinkage long sys_mknod(const char * f
753                 error = path_walk(tmp, &nd);
754         if (error)
755                 goto out;
756 -       dentry = lookup_create(&nd, 0);
757 +
758 +       if (nd.dentry->d_inode->i_op->mknod2) {
759 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
760 +               error = op->mknod2(nd.dentry->d_inode, 
761 +                                  nd.last.name, 
762 +                                  nd.last.len,
763 +                                  mode, dev);
764 +               /* the file system want to use normal vfs path now */
765 +               if (error != -EOPNOTSUPP)
766 +                       goto out2;
767 +       }
768 +       
769 +       dentry = lookup_create(&nd, 0, &it);
770         error = PTR_ERR(dentry);
771  
772         mode &= ~current->fs->umask;
773 @@ -1287,9 +1393,11 @@ asmlinkage long sys_mknod(const char * f
774                 default:
775                         error = -EINVAL;
776                 }
777 +               intent_release(dentry, &it);
778                 dput(dentry);
779         }
780         up(&nd.dentry->d_inode->i_sem);
781 + out2:
782         path_release(&nd);
783  out:
784         putname(tmp);
785 @@ -1327,6 +1435,7 @@ asmlinkage long sys_mkdir(const char * p
786  {
787         int error = 0;
788         char * tmp;
789 +       struct lookup_intent it = { .it_op = IT_MKDIR, .it_mode = mode };
790  
791         tmp = getname(pathname);
792         error = PTR_ERR(tmp);
793 @@ -1338,14 +1447,26 @@ asmlinkage long sys_mkdir(const char * p
794                         error = path_walk(tmp, &nd);
795                 if (error)
796                         goto out;
797 -               dentry = lookup_create(&nd, 1);
798 +               if (nd.dentry->d_inode->i_op->mkdir2) {
799 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
800 +                       error = op->mkdir2(nd.dentry->d_inode, 
801 +                                          nd.last.name, 
802 +                                          nd.last.len,
803 +                                          mode);
804 +                       /* the file system want to use normal vfs path now */
805 +                       if (error != -EOPNOTSUPP)
806 +                               goto out2;
807 +               }
808 +               dentry = lookup_create(&nd, 1, &it);
809                 error = PTR_ERR(dentry);
810                 if (!IS_ERR(dentry)) {
811                         error = vfs_mkdir(nd.dentry->d_inode, dentry,
812                                           mode & ~current->fs->umask);
813 +                       intent_release(dentry, &it);
814                         dput(dentry);
815                 }
816                 up(&nd.dentry->d_inode->i_sem);
817 +out2:
818                 path_release(&nd);
819  out:
820                 putname(tmp);
821 @@ -1426,6 +1547,7 @@ asmlinkage long sys_rmdir(const char * p
822         char * name;
823         struct dentry *dentry;
824         struct nameidata nd;
825 +       struct lookup_intent it = { .it_op = IT_RMDIR };
826  
827         name = getname(pathname);
828         if(IS_ERR(name))
829 @@ -1447,11 +1569,21 @@ asmlinkage long sys_rmdir(const char * p
830                         error = -EBUSY;
831                         goto exit1;
832         }
833 +       if (nd.dentry->d_inode->i_op->rmdir2) {
834 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
835 +               error = op->rmdir2(nd.dentry->d_inode, 
836 +                                  nd.last.name, 
837 +                                  nd.last.len);
838 +               /* the file system want to use normal vfs path now */
839 +               if (error != -EOPNOTSUPP)
840 +                       goto exit1;
841 +       }
842         down(&nd.dentry->d_inode->i_sem);
843 -       dentry = lookup_hash(&nd.last, nd.dentry);
844 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
845         error = PTR_ERR(dentry);
846         if (!IS_ERR(dentry)) {
847                 error = vfs_rmdir(nd.dentry->d_inode, dentry);
848 +               intent_release(dentry, &it);
849                 dput(dentry);
850         }
851         up(&nd.dentry->d_inode->i_sem);
852 @@ -1495,6 +1627,7 @@ asmlinkage long sys_unlink(const char * 
853         char * name;
854         struct dentry *dentry;
855         struct nameidata nd;
856 +       struct lookup_intent it = { .it_op = IT_UNLINK };
857  
858         name = getname(pathname);
859         if(IS_ERR(name))
860 @@ -1507,8 +1640,17 @@ asmlinkage long sys_unlink(const char * 
861         error = -EISDIR;
862         if (nd.last_type != LAST_NORM)
863                 goto exit1;
864 +       if (nd.dentry->d_inode->i_op->unlink2) {
865 +               struct inode_operations *op = nd.dentry->d_inode->i_op;
866 +               error = op->unlink2(nd.dentry->d_inode, 
867 +                                   nd.last.name, 
868 +                                   nd.last.len);
869 +               /* the file system want to use normal vfs path now */
870 +               if (error != -EOPNOTSUPP)
871 +                       goto exit1;
872 +       }
873         down(&nd.dentry->d_inode->i_sem);
874 -       dentry = lookup_hash(&nd.last, nd.dentry);
875 +       dentry = lookup_hash_it(&nd.last, nd.dentry, &it);
876         error = PTR_ERR(dentry);
877         if (!IS_ERR(dentry)) {
878                 /* Why not before? Because we want correct error value */
879 @@ -1516,6 +1658,7 @@ asmlinkage long sys_unlink(const char * 
880                         goto slashes;
881                 error = vfs_unlink(nd.dentry->d_inode, dentry);
882         exit2:
883 +               intent_release(dentry, &it);
884                 dput(dentry);
885         }
886         up(&nd.dentry->d_inode->i_sem);
887 @@ -1562,6 +1705,7 @@ asmlinkage long sys_symlink(const char *
888         int error = 0;
889         char * from;
890         char * to;
891 +       struct lookup_intent it = { .it_op = IT_SYMLINK };
892  
893         from = getname(oldname);
894         if(IS_ERR(from))
895 @@ -1576,15 +1720,28 @@ asmlinkage long sys_symlink(const char *
896                         error = path_walk(to, &nd);
897                 if (error)
898                         goto out;
899 -               dentry = lookup_create(&nd, 0);
900 +               if (nd.dentry->d_inode->i_op->symlink2) {
901 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
902 +                       error = op->symlink2(nd.dentry->d_inode, 
903 +                                            nd.last.name, 
904 +                                            nd.last.len,
905 +                                            from);
906 +                       /* the file system want to use normal vfs path now */
907 +                       if (error != -EOPNOTSUPP)
908 +                               goto out2;
909 +               }
910 +               it.it_data = from;
911 +               dentry = lookup_create(&nd, 0, &it);
912                 error = PTR_ERR(dentry);
913                 if (!IS_ERR(dentry)) {
914                         error = vfs_symlink(nd.dentry->d_inode, dentry, from);
915 +                       intent_release(dentry, &it);
916                         dput(dentry);
917                 }
918                 up(&nd.dentry->d_inode->i_sem);
919 +       out2:
920                 path_release(&nd);
921 -out:
922 +       out:
923                 putname(to);
924         }
925         putname(from);
926 @@ -1645,6 +1802,7 @@ asmlinkage long sys_link(const char * ol
927         int error;
928         char * from;
929         char * to;
930 +       struct lookup_intent it = { .it_op = IT_LINK };
931  
932         from = getname(oldname);
933         if(IS_ERR(from))
934 @@ -1657,7 +1815,7 @@ asmlinkage long sys_link(const char * ol
935  
936                 error = 0;
937                 if (path_init(from, LOOKUP_POSITIVE, &old_nd))
938 -                       error = path_walk(from, &old_nd);
939 +                       error = path_walk_it(from, &old_nd, &it);
940                 if (error)
941                         goto exit;
942                 if (path_init(to, LOOKUP_PARENT, &nd))
943 @@ -1667,10 +1825,22 @@ asmlinkage long sys_link(const char * ol
944                 error = -EXDEV;
945                 if (old_nd.mnt != nd.mnt)
946                         goto out_release;
947 -               new_dentry = lookup_create(&nd, 0);
948 +               if (nd.dentry->d_inode->i_op->link2) {
949 +                       struct inode_operations *op = nd.dentry->d_inode->i_op;
950 +                       error = op->link2(old_nd.dentry->d_inode, 
951 +                                         nd.dentry->d_inode, 
952 +                                         nd.last.name, 
953 +                                         nd.last.len);
954 +                       /* the file system want to use normal vfs path now */
955 +                       if (error != -EOPNOTSUPP)
956 +                               goto out_release;
957 +               }
958 +               it.it_op = IT_LINK2;
959 +               new_dentry = lookup_create(&nd, 0, &it);
960                 error = PTR_ERR(new_dentry);
961                 if (!IS_ERR(new_dentry)) {
962                         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
963 +                       intent_release(new_dentry, &it);
964                         dput(new_dentry);
965                 }
966                 up(&nd.dentry->d_inode->i_sem);
967 @@ -1713,7 +1883,8 @@ exit:
968   *        locking].
969   */
970  int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
971 -              struct inode *new_dir, struct dentry *new_dentry)
972 +                  struct inode *new_dir, struct dentry *new_dentry,
973 +                  struct lookup_intent *it)
974  {
975         int error;
976         struct inode *target;
977 @@ -1771,6 +1942,7 @@ int vfs_rename_dir(struct inode *old_dir
978                 error = -EBUSY;
979         else 
980                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
981 +       intent_release(new_dentry, it);
982         if (target) {
983                 if (!error)
984                         target->i_flags |= S_DEAD;
985 @@ -1792,7 +1964,8 @@ out_unlock:
986  }
987  
988  int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
989 -              struct inode *new_dir, struct dentry *new_dentry)
990 +                    struct inode *new_dir, struct dentry *new_dentry,
991 +                    struct lookup_intent *it)
992  {
993         int error;
994  
995 @@ -1823,6 +1996,7 @@ int vfs_rename_other(struct inode *old_d
996                 error = -EBUSY;
997         else
998                 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry);
999 +       intent_release(new_dentry, it);
1000         double_up(&old_dir->i_zombie, &new_dir->i_zombie);
1001         if (error)
1002                 return error;
1003 @@ -1834,13 +2008,14 @@ int vfs_rename_other(struct inode *old_d
1004  }
1005  
1006  int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1007 -              struct inode *new_dir, struct dentry *new_dentry)
1008 +              struct inode *new_dir, struct dentry *new_dentry,
1009 +              struct lookup_intent *it)
1010  {
1011         int error;
1012         if (S_ISDIR(old_dentry->d_inode->i_mode))
1013 -               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
1014 +               error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry,it);
1015         else
1016 -               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
1017 +               error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry,it);
1018         if (!error) {
1019                 if (old_dir == new_dir)
1020                         inode_dir_notify(old_dir, DN_RENAME);
1021 @@ -1857,6 +2032,7 @@ static inline int do_rename(const char *
1022         int error = 0;
1023         struct dentry * old_dir, * new_dir;
1024         struct dentry * old_dentry, *new_dentry;
1025 +       struct lookup_intent it = { .it_op = IT_RENAME };
1026         struct nameidata oldnd, newnd;
1027  
1028         if (path_init(oldname, LOOKUP_PARENT, &oldnd))
1029 @@ -1883,9 +2059,23 @@ static inline int do_rename(const char *
1030         if (newnd.last_type != LAST_NORM)
1031                 goto exit2;
1032  
1033 +       if (old_dir->d_inode->i_op->rename2) {
1034 +               lock_kernel();
1035 +               error = old_dir->d_inode->i_op->rename2(old_dir->d_inode, 
1036 +                                               new_dir->d_inode,
1037 +                                               oldnd.last.name, 
1038 +                                               oldnd.last.len,
1039 +                                               newnd.last.name,
1040 +                                               newnd.last.len);
1041 +               unlock_kernel();
1042 +               /* the file system want to use normal vfs path now */
1043 +               if (error != -EOPNOTSUPP)
1044 +                       goto exit2;
1045 +       }
1046 +
1047         double_lock(new_dir, old_dir);
1048  
1049 -       old_dentry = lookup_hash(&oldnd.last, old_dir);
1050 +       old_dentry = lookup_hash_it(&oldnd.last, old_dir, &it);
1051         error = PTR_ERR(old_dentry);
1052         if (IS_ERR(old_dentry))
1053                 goto exit3;
1054 @@ -1901,18 +2091,21 @@ static inline int do_rename(const char *
1055                 if (newnd.last.name[newnd.last.len])
1056                         goto exit4;
1057         }
1058 -       new_dentry = lookup_hash(&newnd.last, new_dir);
1059 +       it.it_op = IT_RENAME2;
1060 +       new_dentry = lookup_hash_it(&newnd.last, new_dir, &it);
1061         error = PTR_ERR(new_dentry);
1062         if (IS_ERR(new_dentry))
1063                 goto exit4;
1064  
1065         lock_kernel();
1066         error = vfs_rename(old_dir->d_inode, old_dentry,
1067 -                                  new_dir->d_inode, new_dentry);
1068 +                                  new_dir->d_inode, new_dentry, &it);
1069         unlock_kernel();
1070  
1071 +       intent_release(new_dentry, &it);
1072         dput(new_dentry);
1073  exit4:
1074 +       intent_release(old_dentry, &it);
1075         dput(old_dentry);
1076  exit3:
1077         double_up(&new_dir->d_inode->i_sem, &old_dir->d_inode->i_sem);
1078 @@ -1961,7 +2154,8 @@ out:
1079  }
1080  
1081  static inline int
1082 -__vfs_follow_link(struct nameidata *nd, const char *link)
1083 +__vfs_follow_link(struct nameidata *nd, const char *link,
1084 +                 struct lookup_intent *it)
1085  {
1086         int res = 0;
1087         char *name;
1088 @@ -1974,7 +2168,7 @@ __vfs_follow_link(struct nameidata *nd, 
1089                         /* weird __emul_prefix() stuff did it */
1090                         goto out;
1091         }
1092 -       res = link_path_walk(link, nd);
1093 +       res = link_path_walk_it(link, nd, it);
1094  out:
1095         if (current->link_count || res || nd->last_type!=LAST_NORM)
1096                 return res;
1097 @@ -1996,7 +2190,13 @@ fail:
1098  
1099  int vfs_follow_link(struct nameidata *nd, const char *link)
1100  {
1101 -       return __vfs_follow_link(nd, link);
1102 +       return __vfs_follow_link(nd, link, NULL);
1103 +}
1104 +
1105 +int vfs_follow_link_it(struct nameidata *nd, const char *link,
1106 +                      struct lookup_intent *it)
1107 +{
1108 +       return __vfs_follow_link(nd, link, it);
1109  }
1110  
1111  /* get the link contents into pagecache */
1112 @@ -2038,7 +2238,7 @@ int page_follow_link(struct dentry *dent
1113  {
1114         struct page *page = NULL;
1115         char *s = page_getlink(dentry, &page);
1116 -       int res = __vfs_follow_link(nd, s);
1117 +       int res = __vfs_follow_link(nd, s, NULL);
1118         if (page) {
1119                 kunmap(page);
1120                 page_cache_release(page);
1121 --- linux-2.4.19/fs/open.c~vanilla-2.4.19       Sun Jan 19 19:46:42 2003
1122 +++ linux-2.4.19-root/fs/open.c Sun Jan 19 19:46:42 2003
1123 @@ -19,6 +19,9 @@
1124  #include <asm/uaccess.h>
1125  
1126  #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
1127 +extern int path_walk_it(const char *name, struct nameidata *nd,
1128 +                       struct lookup_intent *it);
1129 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1130  
1131  int vfs_statfs(struct super_block *sb, struct statfs *buf)
1132  {
1133 @@ -118,12 +121,13 @@ static inline long do_sys_truncate(const
1134         struct nameidata nd;
1135         struct inode * inode;
1136         int error;
1137 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1138  
1139         error = -EINVAL;
1140         if (length < 0) /* sorry, but loff_t says... */
1141                 goto out;
1142  
1143 -       error = user_path_walk(path, &nd);
1144 +       error = user_path_walk_it(path, &nd, &it);
1145         if (error)
1146                 goto out;
1147         inode = nd.dentry->d_inode;
1148 @@ -168,6 +172,7 @@ static inline long do_sys_truncate(const
1149         put_write_access(inode);
1150  
1151  dput_and_out:
1152 +       intent_release(nd.dentry, &it);
1153         path_release(&nd);
1154  out:
1155         return error;
1156 @@ -259,8 +264,9 @@ asmlinkage long sys_utime(char * filenam
1157         struct nameidata nd;
1158         struct inode * inode;
1159         struct iattr newattrs;
1160 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1161  
1162 -       error = user_path_walk(filename, &nd);
1163 +       error = user_path_walk_it(filename, &nd, &it);
1164         if (error)
1165                 goto out;
1166         inode = nd.dentry->d_inode;
1167 @@ -286,6 +292,7 @@ asmlinkage long sys_utime(char * filenam
1168         }
1169         error = notify_change(nd.dentry, &newattrs);
1170  dput_and_out:
1171 +       intent_release(nd.dentry, &it);
1172         path_release(&nd);
1173  out:
1174         return error;
1175 @@ -303,8 +310,9 @@ asmlinkage long sys_utimes(char * filena
1176         struct nameidata nd;
1177         struct inode * inode;
1178         struct iattr newattrs;
1179 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1180  
1181 -       error = user_path_walk(filename, &nd);
1182 +       error = user_path_walk_it(filename, &nd, &it);
1183  
1184         if (error)
1185                 goto out;
1186 @@ -331,6 +339,7 @@ asmlinkage long sys_utimes(char * filena
1187         }
1188         error = notify_change(nd.dentry, &newattrs);
1189  dput_and_out:
1190 +       intent_release(nd.dentry, &it);
1191         path_release(&nd);
1192  out:
1193         return error;
1194 @@ -347,6 +356,7 @@ asmlinkage long sys_access(const char * 
1195         int old_fsuid, old_fsgid;
1196         kernel_cap_t old_cap;
1197         int res;
1198 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1199  
1200         if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
1201                 return -EINVAL;
1202 @@ -364,13 +374,14 @@ asmlinkage long sys_access(const char * 
1203         else
1204                 current->cap_effective = current->cap_permitted;
1205  
1206 -       res = user_path_walk(filename, &nd);
1207 +       res = user_path_walk_it(filename, &nd, &it);
1208         if (!res) {
1209                 res = permission(nd.dentry->d_inode, mode);
1210                 /* SuS v2 requires we report a read only fs too */
1211                 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
1212                    && !special_file(nd.dentry->d_inode->i_mode))
1213                         res = -EROFS;
1214 +               intent_release(nd.dentry, &it);
1215                 path_release(&nd);
1216         }
1217  
1218 @@ -386,6 +397,7 @@ asmlinkage long sys_chdir(const char * f
1219         int error;
1220         struct nameidata nd;
1221         char *name;
1222 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1223  
1224         name = getname(filename);
1225         error = PTR_ERR(name);
1226 @@ -394,7 +406,7 @@ asmlinkage long sys_chdir(const char * f
1227  
1228         error = 0;
1229         if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
1230 -               error = path_walk(name, &nd);
1231 +               error = path_walk_it(name, &nd, &it);
1232         putname(name);
1233         if (error)
1234                 goto out;
1235 @@ -406,6 +418,7 @@ asmlinkage long sys_chdir(const char * f
1236         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
1237  
1238  dput_and_out:
1239 +       intent_release(nd.dentry, &it);
1240         path_release(&nd);
1241  out:
1242         return error;
1243 @@ -446,6 +459,7 @@ asmlinkage long sys_chroot(const char * 
1244         int error;
1245         struct nameidata nd;
1246         char *name;
1247 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1248  
1249         name = getname(filename);
1250         error = PTR_ERR(name);
1251 @@ -454,7 +468,7 @@ asmlinkage long sys_chroot(const char * 
1252  
1253         path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
1254                       LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
1255 -       error = path_walk(name, &nd);   
1256 +       error = path_walk_it(name, &nd, &it);
1257         putname(name);
1258         if (error)
1259                 goto out;
1260 @@ -471,6 +485,7 @@ asmlinkage long sys_chroot(const char * 
1261         set_fs_altroot();
1262         error = 0;
1263  dput_and_out:
1264 +       intent_release(nd.dentry, &it);
1265         path_release(&nd);
1266  out:
1267         return error;
1268 @@ -515,8 +530,9 @@ asmlinkage long sys_chmod(const char * f
1269         struct inode * inode;
1270         int error;
1271         struct iattr newattrs;
1272 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1273  
1274 -       error = user_path_walk(filename, &nd);
1275 +       error = user_path_walk_it(filename, &nd, &it);
1276         if (error)
1277                 goto out;
1278         inode = nd.dentry->d_inode;
1279 @@ -536,6 +552,7 @@ asmlinkage long sys_chmod(const char * f
1280         error = notify_change(nd.dentry, &newattrs);
1281  
1282  dput_and_out:
1283 +       intent_release(nd.dentry, &it);
1284         path_release(&nd);
1285  out:
1286         return error;
1287 @@ -605,10 +622,12 @@ asmlinkage long sys_chown(const char * f
1288  {
1289         struct nameidata nd;
1290         int error;
1291 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1292  
1293 -       error = user_path_walk(filename, &nd);
1294 +       error = user_path_walk_it(filename, &nd, &it);
1295         if (!error) {
1296                 error = chown_common(nd.dentry, user, group);
1297 +               intent_release(nd.dentry, &it);
1298                 path_release(&nd);
1299         }
1300         return error;
1301 @@ -618,10 +637,12 @@ asmlinkage long sys_lchown(const char * 
1302  {
1303         struct nameidata nd;
1304         int error;
1305 +       struct lookup_intent it = { .it_op = IT_SETATTR };
1306  
1307 -       error = user_path_walk_link(filename, &nd);
1308 +       error = user_path_walk_link_it(filename, &nd, &it);
1309         if (!error) {
1310                 error = chown_common(nd.dentry, user, group);
1311 +               intent_release(nd.dentry, &it);
1312                 path_release(&nd);
1313         }
1314         return error;
1315 @@ -655,10 +676,16 @@ asmlinkage long sys_fchown(unsigned int 
1316   * for the internal routines (ie open_namei()/follow_link() etc). 00 is
1317   * used by symlinks.
1318   */
1319 +extern int open_namei_it(const char *filename, int namei_flags, int mode,
1320 +                        struct nameidata *nd, struct lookup_intent *it);
1321 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1322 +                           int flags, struct lookup_intent *it);
1323 +
1324  struct file *filp_open(const char * filename, int flags, int mode)
1325  {
1326         int namei_flags, error;
1327         struct nameidata nd;
1328 +       struct lookup_intent it = { .it_op = IT_OPEN };
1329  
1330         namei_flags = flags;
1331         if ((namei_flags+1) & O_ACCMODE)
1332 @@ -666,14 +693,15 @@ struct file *filp_open(const char * file
1333         if (namei_flags & O_TRUNC)
1334                 namei_flags |= 2;
1335  
1336 -       error = open_namei(filename, namei_flags, mode, &nd);
1337 -       if (!error)
1338 -               return dentry_open(nd.dentry, nd.mnt, flags);
1339 +       error = open_namei_it(filename, namei_flags, mode, &nd, &it);
1340 +       if (error)
1341 +               return ERR_PTR(error);
1342  
1343 -       return ERR_PTR(error);
1344 +       return dentry_open_it(nd.dentry, nd.mnt, flags, &it);
1345  }
1346  
1347 -struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1348 +struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt,
1349 +                           int flags, struct lookup_intent *it)
1350  {
1351         struct file * f;
1352         struct inode *inode;
1353 @@ -716,6 +744,7 @@ struct file *dentry_open(struct dentry *
1354         }
1355         f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
1356  
1357 +       intent_release(dentry, it);
1358         return f;
1359  
1360  cleanup_all:
1361 @@ -730,11 +759,17 @@ cleanup_all:
1362  cleanup_file:
1363         put_filp(f);
1364  cleanup_dentry:
1365 +       intent_release(dentry, it);
1366         dput(dentry);
1367         mntput(mnt);
1368         return ERR_PTR(error);
1369  }
1370  
1371 +struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
1372 +{
1373 +       return dentry_open_it(dentry, mnt, flags, NULL);
1374 +}
1375 +
1376  /*
1377   * Find an empty file descriptor entry, and mark it busy.
1378   */
1379 --- linux-2.4.19/fs/stat.c~vanilla-2.4.19       Sun Jan 19 19:46:42 2003
1380 +++ linux-2.4.19-root/fs/stat.c Sun Jan 19 19:46:42 2003
1381 @@ -13,6 +13,7 @@
1382  
1383  #include <asm/uaccess.h>
1384  
1385 +extern void intent_release(struct dentry *de, struct lookup_intent *it);
1386  /*
1387   * Revalidate the inode. This is required for proper NFS attribute caching.
1388   */
1389 @@ -135,13 +136,15 @@ static int cp_new_stat(struct inode * in
1390  asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
1391  {
1392         struct nameidata nd;
1393 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1394         int error;
1395  
1396 -       error = user_path_walk(filename, &nd);
1397 +       error = user_path_walk_it(filename, &nd, &it);
1398         if (!error) {
1399                 error = do_revalidate(nd.dentry);
1400                 if (!error)
1401                         error = cp_old_stat(nd.dentry->d_inode, statbuf);
1402 +               intent_release(nd.dentry, &it);
1403                 path_release(&nd);
1404         }
1405         return error;
1406 @@ -151,13 +154,15 @@ asmlinkage long sys_stat(char * filename
1407  asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
1408  {
1409         struct nameidata nd;
1410 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1411         int error;
1412  
1413 -       error = user_path_walk(filename, &nd);
1414 +       error = user_path_walk_it(filename, &nd, &it);
1415         if (!error) {
1416                 error = do_revalidate(nd.dentry);
1417                 if (!error)
1418                         error = cp_new_stat(nd.dentry->d_inode, statbuf);
1419 +               intent_release(nd.dentry, &it);
1420                 path_release(&nd);
1421         }
1422         return error;
1423 @@ -172,13 +177,15 @@ asmlinkage long sys_newstat(char * filen
1424  asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
1425  {
1426         struct nameidata nd;
1427 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1428         int error;
1429  
1430 -       error = user_path_walk_link(filename, &nd);
1431 +       error = user_path_walk_link_it(filename, &nd, &it);
1432         if (!error) {
1433                 error = do_revalidate(nd.dentry);
1434                 if (!error)
1435                         error = cp_old_stat(nd.dentry->d_inode, statbuf);
1436 +               intent_release(nd.dentry, &it);
1437                 path_release(&nd);
1438         }
1439         return error;
1440 @@ -189,13 +196,15 @@ asmlinkage long sys_lstat(char * filenam
1441  asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
1442  {
1443         struct nameidata nd;
1444 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1445         int error;
1446  
1447 -       error = user_path_walk_link(filename, &nd);
1448 +       error = user_path_walk_link_it(filename, &nd, &it);
1449         if (!error) {
1450                 error = do_revalidate(nd.dentry);
1451                 if (!error)
1452                         error = cp_new_stat(nd.dentry->d_inode, statbuf);
1453 +               intent_release(nd.dentry, &it);
1454                 path_release(&nd);
1455         }
1456         return error;
1457 @@ -247,20 +256,21 @@ asmlinkage long sys_readlink(const char 
1458  {
1459         struct nameidata nd;
1460         int error;
1461 +       struct lookup_intent it = { .it_op = IT_READLINK };
1462  
1463         if (bufsiz <= 0)
1464                 return -EINVAL;
1465  
1466 -       error = user_path_walk_link(path, &nd);
1467 +       error = user_path_walk_link_it(path, &nd, &it);
1468         if (!error) {
1469                 struct inode * inode = nd.dentry->d_inode;
1470 -
1471                 error = -EINVAL;
1472                 if (inode->i_op && inode->i_op->readlink &&
1473                     !(error = do_revalidate(nd.dentry))) {
1474                         UPDATE_ATIME(inode);
1475                         error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
1476                 }
1477 +               intent_release(nd.dentry, &it);
1478                 path_release(&nd);
1479         }
1480         return error;
1481 @@ -333,12 +343,14 @@ asmlinkage long sys_stat64(char * filena
1482  {
1483         struct nameidata nd;
1484         int error;
1485 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1486  
1487 -       error = user_path_walk(filename, &nd);
1488 +       error = user_path_walk_it(filename, &nd, &it);
1489         if (!error) {
1490                 error = do_revalidate(nd.dentry);
1491                 if (!error)
1492                         error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1493 +               intent_release(nd.dentry, &it);
1494                 path_release(&nd);
1495         }
1496         return error;
1497 @@ -348,12 +360,14 @@ asmlinkage long sys_lstat64(char * filen
1498  {
1499         struct nameidata nd;
1500         int error;
1501 +       struct lookup_intent it = { .it_op = IT_GETATTR };
1502  
1503 -       error = user_path_walk_link(filename, &nd);
1504 +       error = user_path_walk_link_it(filename, &nd, &it);
1505         if (!error) {
1506                 error = do_revalidate(nd.dentry);
1507                 if (!error)
1508                         error = cp_new_stat64(nd.dentry->d_inode, statbuf);
1509 +               intent_release(nd.dentry, &it);
1510                 path_release(&nd);
1511         }
1512         return error;
1513 --- linux-2.4.19/mm/slab.c~vanilla-2.4.19       Sun Jan 19 19:46:42 2003
1514 +++ linux-2.4.19-root/mm/slab.c Sun Jan 19 19:46:42 2003
1515 @@ -1207,6 +1207,59 @@ failed:
1516   * Called with the cache-lock held.
1517   */
1518  
1519 +extern struct page *check_get_page(unsigned long kaddr);
1520 +struct page *page_mem_map(struct page *page);
1521 +static int kmem_check_cache_obj (kmem_cache_t * cachep,
1522 +                                slab_t *slabp, void * objp)
1523 +{
1524 +       int i;
1525 +       unsigned int objnr;
1526 +
1527 +#if DEBUG
1528 +       if (cachep->flags & SLAB_RED_ZONE) {
1529 +               objp -= BYTES_PER_WORD;
1530 +               if ( *(unsigned long *)objp != RED_MAGIC2)
1531 +                       /* Either write before start, or a double free. */
1532 +                       return 0;
1533 +               if (*(unsigned long *)(objp+cachep->objsize -
1534 +                               BYTES_PER_WORD) != RED_MAGIC2)
1535 +                       /* Either write past end, or a double free. */
1536 +                       return 0;
1537 +       }
1538 +#endif
1539 +
1540 +       objnr = (objp-slabp->s_mem)/cachep->objsize;
1541 +       if (objnr >= cachep->num)
1542 +               return 0;
1543 +       if (objp != slabp->s_mem + objnr*cachep->objsize)
1544 +               return 0;
1545 +
1546 +       /* Check slab's freelist to see if this obj is there. */
1547 +       for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
1548 +               if (i == objnr)
1549 +                       return 0;
1550 +       }
1551 +       return 1;
1552 +}
1553 +
1554 +
1555 +int kmem_cache_validate(kmem_cache_t *cachep, void *objp)
1556 +{
1557 +       struct page *page = check_get_page((unsigned long)objp);
1558 +
1559 +       if (!VALID_PAGE(page))
1560 +               return 0;
1561 +
1562 +       if (!PageSlab(page))
1563 +               return 0;
1564 +
1565 +       /* XXX check for freed slab objects ? */
1566 +       if (!kmem_check_cache_obj(cachep, GET_PAGE_SLAB(page), objp))
1567 +               return 0;
1568 +
1569 +       return (cachep == GET_PAGE_CACHE(page));
1570 +}
1571 +
1572  #if DEBUG
1573  static int kmem_extra_free_checks (kmem_cache_t * cachep,
1574                         slab_t *slabp, void * objp)
1575
1576 _