1 diff -Naurp linux-2.4.20-ck4/arch/ia64/kernel/sys_ia64.c linux-2.4.20-ck5/arch/ia64/kernel/sys_ia64.c
2 --- linux-2.4.20-ck4/arch/ia64/kernel/sys_ia64.c 2002-11-30 17:02:01.000000000 +1100
3 +++ linux-2.4.20-ck5/arch/ia64/kernel/sys_ia64.c 2003-04-08 10:52:50.000000000 +1000
4 @@ -280,120 +280,55 @@ ia64_create_module (const char *name_use
5 * call - it will be removed later once everybody migrates to the new
6 * kernel stat structure that matches the glibc one - Jes
9 -do_revalidate (struct dentry *dentry)
11 - struct inode * inode = dentry->d_inode;
12 - if (inode->i_op && inode->i_op->revalidate)
13 - return inode->i_op->revalidate(dentry);
18 -cp_ia64_old_stat (struct inode *inode, struct ia64_oldstat *statbuf)
19 +cp_ia64_old_stat (struct kstat *stat, struct ia64_oldstat *statbuf)
21 struct ia64_oldstat tmp;
22 - unsigned int blocks, indirect;
24 memset(&tmp, 0, sizeof(tmp));
25 - tmp.st_dev = kdev_t_to_nr(inode->i_dev);
26 - tmp.st_ino = inode->i_ino;
27 - tmp.st_mode = inode->i_mode;
28 - tmp.st_nlink = inode->i_nlink;
29 - SET_STAT_UID(tmp, inode->i_uid);
30 - SET_STAT_GID(tmp, inode->i_gid);
31 - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
32 - tmp.st_size = inode->i_size;
33 - tmp.st_atime = inode->i_atime;
34 - tmp.st_mtime = inode->i_mtime;
35 - tmp.st_ctime = inode->i_ctime;
37 - * st_blocks and st_blksize are approximated with a simple algorithm if
38 - * they aren't supported directly by the filesystem. The minix and msdos
39 - * filesystems don't keep track of blocks, so they would either have to
40 - * be counted explicitly (by delving into the file itself), or by using
41 - * this simple algorithm to get a reasonable (although not 100% accurate)
46 - * Use minix fs values for the number of direct and indirect blocks. The
47 - * count is now exact for the minix fs except that it counts zero blocks.
48 - * Everything is in units of BLOCK_SIZE until the assignment to
52 -#define I_B (BLOCK_SIZE / sizeof(unsigned short))
54 - if (!inode->i_blksize) {
55 - blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
57 - indirect = (blocks - D_B + I_B - 1) / I_B;
60 - indirect = (indirect - 1 + I_B - 1) / I_B;
66 - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
67 - tmp.st_blksize = BLOCK_SIZE;
69 - tmp.st_blocks = inode->i_blocks;
70 - tmp.st_blksize = inode->i_blksize;
72 + tmp.st_dev = stat->dev;
73 + tmp.st_ino = stat->ino;
74 + tmp.st_mode = stat->mode;
75 + tmp.st_nlink = stat->nlink;
76 + SET_STAT_UID(tmp, stat->uid);
77 + SET_STAT_GID(tmp, stat->gid);
78 + tmp.st_rdev = stat->rdev;
79 + tmp.st_size = stat->size;
80 + tmp.st_atime = stat->atime;
81 + tmp.st_mtime = stat->mtime;
82 + tmp.st_ctime = stat->ctime;
83 + tmp.st_blocks = stat->blocks;
84 + tmp.st_blksize = stat->blksize;
85 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
89 ia64_oldstat (char *filename, struct ia64_oldstat *statbuf)
91 - struct nameidata nd;
94 + int error = vfs_stat(filename, &stat);
96 - error = user_path_walk(filename, &nd);
98 - error = do_revalidate(nd.dentry);
100 - error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf);
104 + return error ? error : cp_ia64_old_stat(&stat, statbuf);
109 -ia64_oldlstat (char *filename, struct ia64_oldstat *statbuf) {
110 - struct nameidata nd;
113 - error = user_path_walk_link(filename, &nd);
115 - error = do_revalidate(nd.dentry);
117 - error = cp_ia64_old_stat(nd.dentry->d_inode, statbuf);
121 +ia64_oldlstat (char *filename, struct ia64_oldstat *statbuf)
124 + int error = vfs_lstat(filename, &stat);
126 + return error ? error : cp_ia64_old_stat(&stat, statbuf);
130 ia64_oldfstat (unsigned int fd, struct ia64_oldstat *statbuf)
135 + int error = vfs_fstat(fd, &stat);
139 - struct dentry * dentry = f->f_dentry;
141 - err = do_revalidate(dentry);
143 - err = cp_ia64_old_stat(dentry->d_inode, statbuf);
147 + return error ? error : cp_ia64_old_stat(&stat, statbuf);
151 diff -Naurp linux-2.4.20-ck4/arch/mips/kernel/sysirix.c linux-2.4.20-ck5/arch/mips/kernel/sysirix.c
152 --- linux-2.4.20-ck4/arch/mips/kernel/sysirix.c 2002-11-30 17:02:01.000000000 +1100
153 +++ linux-2.4.20-ck5/arch/mips/kernel/sysirix.c 2003-04-08 10:52:50.000000000 +1000
154 @@ -1178,8 +1178,9 @@ linux_to_irix_dev_t (dev_t t)
155 return MAJOR (t) << 18 | MINOR (t);
158 -static inline int irix_xstat32_xlate(struct stat *kb, void *ubuf)
159 +static inline int irix_xstat32_xlate(struct kstat *kb, void *ubuf)
163 u32 st_dev, st_pad1[3], st_ino, st_mode, st_nlink, st_uid, st_gid;
164 u32 st_rdev, st_pad2[2], st_size, st_pad3;
165 @@ -1191,29 +1192,30 @@ static inline int irix_xstat32_xlate(str
169 - ub.st_dev = linux_to_irix_dev_t (kb->st_dev);
170 - ub.st_ino = kb->st_ino;
171 - ub.st_mode = kb->st_mode;
172 - ub.st_nlink = kb->st_nlink;
173 - ub.st_uid = kb->st_uid;
174 - ub.st_gid = kb->st_gid;
175 - ub.st_rdev = linux_to_irix_dev_t (kb->st_rdev);
176 - ub.st_size = kb->st_size;
177 - ub.st_atime0 = kb->st_atime;
178 + ub.st_dev = linux_to_irix_dev_t (kb->dev);
179 + ub.st_ino = kb->ino;
180 + ub.st_mode = kb->mode;
181 + ub.st_nlink = kb->nlink;
182 + ub.st_uid = kb->uid;
183 + ub.st_gid = kb->gid;
184 + ub.st_rdev = linux_to_irix_dev_t (kb->rdev);
185 + ub.st_size = kb->size;
186 + ub.st_atime0 = kb->atime;
188 - ub.st_mtime0 = kb->st_mtime;
189 + ub.st_mtime0 = kb->mtime;
191 - ub.st_ctime0 = kb->st_ctime;
192 + ub.st_ctime0 = kb->ctime;
194 - ub.st_blksize = kb->st_blksize;
195 - ub.st_blocks = kb->st_blocks;
196 + ub.st_blksize = kb->blksize;
197 + ub.st_blocks = kb->blocks;
198 strcpy (ub.st_fstype, "efs");
200 return copy_to_user(ubuf, &ub, sizeof(ub)) ? -EFAULT : 0;
203 -static inline void irix_xstat64_xlate(struct stat *sb)
204 +static inline int irix_xstat64_xlate(struct kstat *sb, void *ubuf)
208 u32 st_dev; s32 st_pad1[3];
209 unsigned long long st_ino;
210 @@ -1229,38 +1231,37 @@ static inline void irix_xstat64_xlate(st
214 - ks.st_dev = linux_to_irix_dev_t (sb->st_dev);
215 + ks.st_dev = sb->dev;
216 ks.st_pad1[0] = ks.st_pad1[1] = ks.st_pad1[2] = 0;
217 - ks.st_ino = (unsigned long long) sb->st_ino;
218 - ks.st_mode = (u32) sb->st_mode;
219 - ks.st_nlink = (u32) sb->st_nlink;
220 - ks.st_uid = (s32) sb->st_uid;
221 - ks.st_gid = (s32) sb->st_gid;
222 - ks.st_rdev = linux_to_irix_dev_t (sb->st_rdev);
223 + ks.st_ino = (unsigned long long) sb->ino;
224 + ks.st_mode = (u32) sb->mode;
225 + ks.st_nlink = (u32) sb->nlink;
226 + ks.st_uid = (s32) sb->uid;
227 + ks.st_gid = (s32) sb->gid;
228 + ks.st_rdev = linux_to_irix_dev_t (sb->rdev);
229 ks.st_pad2[0] = ks.st_pad2[1] = 0;
230 - ks.st_size = (long long) sb->st_size;
231 + ks.st_size = (long long) sb->size;
234 /* XXX hackety hack... */
235 - ks.st_atime.tv_sec = (s32) sb->st_atime; ks.st_atime.tv_nsec = 0;
236 - ks.st_mtime.tv_sec = (s32) sb->st_atime; ks.st_mtime.tv_nsec = 0;
237 - ks.st_ctime.tv_sec = (s32) sb->st_atime; ks.st_ctime.tv_nsec = 0;
238 + ks.st_atime.tv_sec = (s32) sb->atime; ks.st_atime.tv_nsec = 0;
239 + ks.st_mtime.tv_sec = (s32) sb->atime; ks.st_mtime.tv_nsec = 0;
240 + ks.st_ctime.tv_sec = (s32) sb->atime; ks.st_ctime.tv_nsec = 0;
242 - ks.st_blksize = (s32) sb->st_blksize;
243 - ks.st_blocks = (long long) sb->st_blocks;
244 + ks.st_blksize = (s32) sb->blksize;
245 + ks.st_blocks = (long long) sb->blocks;
246 memset(ks.st_fstype, 0, 16);
247 ks.st_pad4[0] = ks.st_pad4[1] = ks.st_pad4[2] = ks.st_pad4[3] = 0;
248 ks.st_pad4[4] = ks.st_pad4[5] = ks.st_pad4[6] = ks.st_pad4[7] = 0;
250 /* Now write it all back. */
251 - copy_to_user(sb, &ks, sizeof(struct xstat64));
252 + copy_to_user(ubuf, &ks, sizeof(struct xstat64));
255 -extern asmlinkage int sys_newstat(char * filename, struct stat * statbuf);
257 asmlinkage int irix_xstat(int version, char *filename, struct stat *statbuf)
263 printk("[%s:%d] Wheee.. irix_xstat(%d,%s,%p) ",
264 @@ -1268,12 +1269,7 @@ asmlinkage int irix_xstat(int version, c
269 - mm_segment_t old_fs;
271 - old_fs = get_fs(); set_fs(get_ds());
272 - retval = sys_newstat(filename, &kb);
274 + retval = vfs_stat(filename, &kb);
276 printk("retval[%d]\n", retval);
278 @@ -1284,16 +1280,14 @@ asmlinkage int irix_xstat(int version, c
282 - retval = sys_newstat(filename, statbuf);
283 + retval = vfs_stat(filename, &kb);
285 printk("retval[%d]\n", retval);
290 - irix_xstat64_xlate(statbuf);
293 + retval = irix_xstat64_xlate(&kb, statbuf);
298 @@ -1305,11 +1299,10 @@ out:
302 -extern asmlinkage int sys_newlstat(char * filename, struct stat * statbuf);
304 asmlinkage int irix_lxstat(int version, char *filename, struct stat *statbuf)
310 printk("[%s:%d] Wheee.. irix_lxstat(%d,%s,%p) ",
311 @@ -1317,12 +1310,7 @@ asmlinkage int irix_lxstat(int version,
316 - mm_segment_t old_fs;
318 - old_fs = get_fs(); set_fs(get_ds());
319 - error = sys_newlstat(filename, &kb);
321 + error = vfs_lstat(filename, &kb);
323 printk("error[%d]\n", error);
325 @@ -1333,18 +1321,15 @@ asmlinkage int irix_lxstat(int version,
329 - error = sys_newlstat(filename, statbuf);
330 + error = vfs_lstat(filename, &kb);
332 printk("error[%d]\n", error);
337 - irix_xstat64_xlate(statbuf);
339 + error = irix_xstat64_xlate(&kb, statbuf);
346 @@ -1354,11 +1339,10 @@ out:
350 -extern asmlinkage int sys_newfstat(unsigned int fd, struct stat * statbuf);
352 asmlinkage int irix_fxstat(int version, int fd, struct stat *statbuf)
358 printk("[%s:%d] Wheee.. irix_fxstat(%d,%d,%p) ",
359 @@ -1366,12 +1350,7 @@ asmlinkage int irix_fxstat(int version,
364 - mm_segment_t old_fs;
366 - old_fs = get_fs(); set_fs(get_ds());
367 - error = sys_newfstat(fd, &kb);
369 + error = vfs_fstat(fd, &kb);
371 printk("error[%d]\n", error);
373 @@ -1382,15 +1361,13 @@ asmlinkage int irix_fxstat(int version,
377 - error = sys_newfstat(fd, statbuf);
378 + error = vfs_fstat(fd, &kb);
380 printk("error[%d]\n", error);
385 - irix_xstat64_xlate(statbuf);
387 + error = irix_xstat64_xlate(&kb, statbuf);
391 diff -Naurp linux-2.4.20-ck4/arch/mips64/kernel/linux32.c linux-2.4.20-ck5/arch/mips64/kernel/linux32.c
392 --- linux-2.4.20-ck4/arch/mips64/kernel/linux32.c 2002-11-30 17:02:02.000000000 +1100
393 +++ linux-2.4.20-ck5/arch/mips64/kernel/linux32.c 2003-04-08 10:52:50.000000000 +1000
395 #define merge_64(r1,r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
399 - * Revalidate the inode. This is required for proper NFS attribute caching.
401 -static __inline__ int
402 -do_revalidate(struct dentry *dentry)
404 - struct inode * inode = dentry->d_inode;
406 - if (inode->i_op && inode->i_op->revalidate)
407 - return inode->i_op->revalidate(dentry);
412 -static int cp_new_stat32(struct inode * inode, struct stat32 * statbuf)
413 +static int cp_new_stat32(struct kstat *stat, struct stat32 * statbuf)
417 - unsigned int blocks, indirect;
419 memset(&tmp, 0, sizeof(tmp));
420 - tmp.st_dev = kdev_t_to_nr(inode->i_dev);
421 - tmp.st_ino = inode->i_ino;
422 - tmp.st_mode = inode->i_mode;
423 - tmp.st_nlink = inode->i_nlink;
424 - SET_STAT_UID(tmp, inode->i_uid);
425 - SET_STAT_GID(tmp, inode->i_gid);
426 - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
427 - tmp.st_size = inode->i_size;
428 - tmp.st_atime = inode->i_atime;
429 - tmp.st_mtime = inode->i_mtime;
430 - tmp.st_ctime = inode->i_ctime;
433 - * st_blocks and st_blksize are approximated with a simple algorithm if
434 - * they aren't supported directly by the filesystem. The minix and msdos
435 - * filesystems don't keep track of blocks, so they would either have to
436 - * be counted explicitly (by delving into the file itself), or by using
437 - * this simple algorithm to get a reasonable (although not 100%
442 - * Use minix fs values for the number of direct and indirect blocks.
443 - * The count is now exact for the minix fs except that it counts zero
444 - * blocks. Everything is in units of BLOCK_SIZE until the assignment
445 - * to tmp.st_blksize.
448 -#define I_B (BLOCK_SIZE / sizeof(unsigned short))
450 - if (!inode->i_blksize) {
451 - blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
452 - if (blocks > D_B) {
453 - indirect = (blocks - D_B + I_B - 1) / I_B;
454 - blocks += indirect;
455 - if (indirect > 1) {
456 - indirect = (indirect - 1 + I_B - 1) / I_B;
457 - blocks += indirect;
462 - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
463 - tmp.st_blksize = BLOCK_SIZE;
465 - tmp.st_blocks = inode->i_blocks;
466 - tmp.st_blksize = inode->i_blksize;
468 + tmp.st_dev = stat->dev;
469 + tmp.st_ino = stat->ino;
470 + tmp.st_mode = stat->mode;
471 + tmp.st_nlink = stat->nlink;
472 + SET_STAT_UID(tmp, stat->uid);
473 + SET_STAT_GID(tmp, stat->gid);
474 + tmp.st_rdev = stat->rdev;
475 + tmp.st_size = stat->size;
476 + tmp.st_atime = stat->atime;
477 + tmp.st_mtime = stat->mtime;
478 + tmp.st_ctime = stat->ctime;
479 + tmp.st_blocks = stat->blocks;
480 + tmp.st_blksize = stat->blksize;
482 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
485 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
487 - struct nameidata nd;
490 + int error = vfs_stat(filename, &stat);
492 - error = user_path_walk(filename, &nd);
494 - error = do_revalidate(nd.dentry);
496 - error = cp_new_stat32(nd.dentry->d_inode, statbuf);
502 + return error ? cp_new_stat32(&stat, statbuf);
505 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
507 - struct nameidata nd;
510 - error = user_path_walk_link(filename, &nd);
512 - error = do_revalidate(nd.dentry);
514 - error = cp_new_stat32(nd.dentry->d_inode, statbuf);
519 + int error = vfs_lstat(filename, &stat);
522 + return error ? cp_new_stat32(&stat, statbuf);
525 asmlinkage long sys32_newfstat(unsigned int fd, struct stat32 * statbuf)
532 - struct dentry * dentry = f->f_dentry;
534 - err = do_revalidate(dentry);
536 - err = cp_new_stat32(dentry->d_inode, statbuf);
540 + int error = vfs_fstat(fd, &stat);
543 + return error ? cp_new_stat32(&stat, statbuf);
546 asmlinkage int sys_mmap2(void) {return 0;}
547 diff -Naurp linux-2.4.20-ck4/arch/parisc/hpux/fs.c linux-2.4.20-ck5/arch/parisc/hpux/fs.c
548 --- linux-2.4.20-ck4/arch/parisc/hpux/fs.c 2002-11-30 17:02:02.000000000 +1100
549 +++ linux-2.4.20-ck5/arch/parisc/hpux/fs.c 2003-04-08 10:52:50.000000000 +1000
550 @@ -120,110 +120,47 @@ int hpux_mount(const char *fs, const cha
554 -static int cp_hpux_stat(struct inode * inode, struct hpux_stat64 * statbuf)
555 +static int cp_hpux_stat(struct kstat *stat, struct hpux_stat64 * statbuf)
557 struct hpux_stat64 tmp;
558 - unsigned int blocks, indirect;
560 memset(&tmp, 0, sizeof(tmp));
561 - tmp.st_dev = kdev_t_to_nr(inode->i_dev);
562 - tmp.st_ino = inode->i_ino;
563 - tmp.st_mode = inode->i_mode;
564 - tmp.st_nlink = inode->i_nlink;
565 - tmp.st_uid = inode->i_uid;
566 - tmp.st_gid = inode->i_gid;
567 - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
568 - tmp.st_size = inode->i_size;
569 - tmp.st_atime = inode->i_atime;
570 - tmp.st_mtime = inode->i_mtime;
571 - tmp.st_ctime = inode->i_ctime;
574 -#define I_B (BLOCK_SIZE / sizeof(unsigned short))
576 - if (!inode->i_blksize) {
577 - blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
578 - if (blocks > D_B) {
579 - indirect = (blocks - D_B + I_B - 1) / I_B;
580 - blocks += indirect;
581 - if (indirect > 1) {
582 - indirect = (indirect - 1 + I_B - 1) / I_B;
583 - blocks += indirect;
588 - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
589 - tmp.st_blksize = BLOCK_SIZE;
591 - tmp.st_blocks = inode->i_blocks;
592 - tmp.st_blksize = inode->i_blksize;
594 + tmp.st_dev = stat->dev;
595 + tmp.st_ino = stat->ino;
596 + tmp.st_mode = stat->mode;
597 + tmp.st_nlink = stat->nlink;
598 + tmp.st_uid = stat->uid;
599 + tmp.st_gid = stat->gid;
600 + tmp.st_rdev = stat->rdev;
601 + tmp.st_size = stat->size;
602 + tmp.st_atime = stat->atime;
603 + tmp.st_mtime = stat->mtime;
604 + tmp.st_ctime = stat->ctime;
605 + tmp.st_blocks = stat->blocks;
606 + tmp.st_blksize = stat->blksize;
607 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
611 - * Revalidate the inode. This is required for proper NFS attribute caching.
612 - * Blatently copied wholesale from fs/stat.c
614 -static __inline__ int
615 -do_revalidate(struct dentry *dentry)
617 - struct inode * inode = dentry->d_inode;
618 - if (inode->i_op && inode->i_op->revalidate)
619 - return inode->i_op->revalidate(dentry);
623 long hpux_stat64(const char *path, struct hpux_stat64 *buf)
625 - struct nameidata nd;
628 + int error = vfs_stat(path, &stat);
631 - error = user_path_walk(path, &nd);
633 - error = do_revalidate(nd.dentry);
635 - error = cp_hpux_stat(nd.dentry->d_inode, buf);
640 + return error ? error : cp_hpux_stat(&stat, buf);
643 long hpux_fstat64(unsigned int fd, struct hpux_stat64 *statbuf)
648 + int error = vfs_fstat(fd, &stat);
653 - struct dentry * dentry = f->f_dentry;
655 - err = do_revalidate(dentry);
657 - err = cp_hpux_stat(dentry->d_inode, statbuf);
662 + return error ? error : cp_hpux_stat(&stat, buf);
665 long hpux_lstat64(char *filename, struct hpux_stat64 *statbuf)
667 - struct nameidata nd;
670 + int error = vfs_lstat(path, &stat);
673 - error = user_path_walk_link(filename, &nd);
675 - error = do_revalidate(nd.dentry);
677 - error = cp_hpux_stat(nd.dentry->d_inode, statbuf);
682 + return error ? error : cp_hpux_stat(&stat, buf);
684 diff -Naurp linux-2.4.20-ck4/arch/s390x/kernel/linux32.c linux-2.4.20-ck5/arch/s390x/kernel/linux32.c
685 --- linux-2.4.20-ck4/arch/s390x/kernel/linux32.c 2002-08-03 13:14:44.000000000 +1000
686 +++ linux-2.4.20-ck5/arch/s390x/kernel/linux32.c 2003-04-08 10:52:50.000000000 +1000
687 @@ -1486,76 +1486,27 @@ out_nofds:
691 -static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
692 +static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf)
694 - unsigned long ino, blksize, blocks;
701 - time_t atime, mtime, ctime;
705 - /* Stream the loads of inode data into the load buffer,
706 - * then we push it all into the store buffer below. This
707 - * should give optimal cache performance.
709 - ino = inode->i_ino;
710 - dev = inode->i_dev;
711 - mode = inode->i_mode;
712 - nlink = inode->i_nlink;
713 - uid = inode->i_uid;
714 - gid = inode->i_gid;
715 - rdev = inode->i_rdev;
716 - size = inode->i_size;
717 - atime = inode->i_atime;
718 - mtime = inode->i_mtime;
719 - ctime = inode->i_ctime;
720 - blksize = inode->i_blksize;
721 - blocks = inode->i_blocks;
723 - err = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
724 - err |= put_user(ino, &statbuf->st_ino);
725 - err |= put_user(mode, &statbuf->st_mode);
726 - err |= put_user(nlink, &statbuf->st_nlink);
727 - err |= put_user(high2lowuid(uid), &statbuf->st_uid);
728 - err |= put_user(high2lowgid(gid), &statbuf->st_gid);
729 - err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
730 - err |= put_user(size, &statbuf->st_size);
731 - err |= put_user(atime, &statbuf->st_atime);
732 + err = put_user(stat->dev, &statbuf->st_dev);
733 + err |= put_user(stat->ino, &statbuf->st_ino);
734 + err |= put_user(stat->mode, &statbuf->st_mode);
735 + err |= put_user(stat->nlink, &statbuf->st_nlink);
736 + err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
737 + err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
738 + err |= put_user(stat->rdev, &statbuf->st_rdev);
739 + err |= put_user(stat->size, &statbuf->st_size);
740 + err |= put_user(stat->atime, &statbuf->st_atime);
741 err |= put_user(0, &statbuf->__unused1);
742 - err |= put_user(mtime, &statbuf->st_mtime);
743 + err |= put_user(stat->mtime, &statbuf->st_mtime);
744 err |= put_user(0, &statbuf->__unused2);
745 - err |= put_user(ctime, &statbuf->st_ctime);
746 + err |= put_user(stat->ctime, &statbuf->st_ctime);
747 err |= put_user(0, &statbuf->__unused3);
749 - err |= put_user(blksize, &statbuf->st_blksize);
750 - err |= put_user(blocks, &statbuf->st_blocks);
752 - unsigned int tmp_blocks;
755 -#define I_B (BLOCK_SIZE / sizeof(unsigned short))
756 - tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
757 - if (tmp_blocks > D_B) {
758 - unsigned int indirect;
760 - indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
761 - tmp_blocks += indirect;
762 - if (indirect > 1) {
763 - indirect = (indirect - 1 + I_B - 1) / I_B;
764 - tmp_blocks += indirect;
769 - err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
770 - err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
774 + err |= put_user(stat->blksize, &statbuf->st_blksize);
775 + err |= put_user(stat->blocks, &statbuf->st_blocks);
777 err |= put_user(0, &statbuf->__unused4[0]);
778 err |= put_user(0, &statbuf->__unused4[1]);
779 @@ -1564,62 +1515,28 @@ static int cp_new_stat32(struct inode *i
783 -/* Perhaps this belongs in fs.h or similar. -DaveM */
784 -static __inline__ int
785 -do_revalidate(struct dentry *dentry)
787 - struct inode * inode = dentry->d_inode;
788 - if (inode->i_op && inode->i_op->revalidate)
789 - return inode->i_op->revalidate(dentry);
793 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
795 - struct nameidata nd;
798 + int error = vfs_stat(filename, &stat);
800 - error = user_path_walk(filename, &nd);
802 - error = do_revalidate(nd.dentry);
804 - error = cp_new_stat32(nd.dentry->d_inode, statbuf);
808 + return error ? error : cp_new_stat32(&stat, statbuf);
811 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
813 - struct nameidata nd;
816 + int error = vfs_lstat(filename, &stat);
818 - error = user_path_walk_link(filename, &nd);
820 - error = do_revalidate(nd.dentry);
822 - error = cp_new_stat32(nd.dentry->d_inode, statbuf);
827 + return error ? error : cp_new_stat32(&stat, statbuf);
830 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
837 - struct dentry * dentry = f->f_dentry;
839 + int error = vfs_fstat(fd, &stat);
841 - err = do_revalidate(dentry);
843 - err = cp_new_stat32(dentry->d_inode, statbuf);
847 + return error ? error : cp_new_stat32(&stat, statbuf);
850 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
851 @@ -4080,89 +3997,55 @@ struct stat64_emu31 {
855 -putstat64 (struct stat64_emu31 *ubuf, struct stat *kbuf)
856 +putstat64 (struct stat64_emu31 *ubuf, struct kstat *kbuf)
858 struct stat64_emu31 tmp;
860 memset(&tmp, 0, sizeof(tmp));
862 - tmp.st_dev = (unsigned short)kbuf->st_dev;
863 - tmp.st_ino = kbuf->st_ino;
864 - tmp.__st_ino = (u32)kbuf->st_ino;
865 - tmp.st_mode = kbuf->st_mode;
866 - tmp.st_nlink = (unsigned int)kbuf->st_nlink;
867 - tmp.st_uid = kbuf->st_uid;
868 - tmp.st_gid = kbuf->st_gid;
869 - tmp.st_rdev = (unsigned short)kbuf->st_rdev;
870 - tmp.st_size = kbuf->st_size;
871 - tmp.st_blksize = (u32)kbuf->st_blksize;
872 - tmp.st_blocks = (u32)kbuf->st_blocks;
873 - tmp.st_atime = (u32)kbuf->st_atime;
874 - tmp.st_mtime = (u32)kbuf->st_mtime;
875 - tmp.st_ctime = (u32)kbuf->st_ctime;
876 + tmp.st_dev = (unsigned short)kbuf->dev;
877 + tmp.st_ino = kbuf->ino;
878 + tmp.__st_ino = (u32)kbuf->ino;
879 + tmp.st_mode = kbuf->mode;
880 + tmp.st_nlink = (unsigned int)kbuf->nlink;
881 + tmp.st_uid = kbuf->uid;
882 + tmp.st_gid = kbuf->gid;
883 + tmp.st_rdev = (unsigned short)kbuf->rdev;
884 + tmp.st_size = kbuf->size;
885 + tmp.st_blksize = (u32)kbuf->blksize;
886 + tmp.st_blocks = (u32)kbuf->blocks;
887 + tmp.st_atime = (u32)kbuf->atime;
888 + tmp.st_mtime = (u32)kbuf->mtime;
889 + tmp.st_ctime = (u32)kbuf->ctime;
891 return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
894 -extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
896 asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf, long flags)
902 - mm_segment_t old_fs = get_fs();
904 - tmp = getname(filename);
905 - err = PTR_ERR(tmp);
909 - set_fs (KERNEL_DS);
910 - ret = sys_newstat(tmp, &s);
914 + int ret = vfs_stat(filename, &s);
916 if (putstat64 (statbuf, &s))
921 -extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
923 asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf, long flags)
929 - mm_segment_t old_fs = get_fs();
931 - tmp = getname(filename);
932 - err = PTR_ERR(tmp);
936 - set_fs (KERNEL_DS);
937 - ret = sys_newlstat(tmp, &s);
941 + int ret = vfs_lstat(filename, &s);
943 if (putstat64 (statbuf, &s))
948 -extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
950 asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf, long flags)
954 - mm_segment_t old_fs = get_fs();
956 - set_fs (KERNEL_DS);
957 - ret = sys_newfstat(fd, &s);
960 + int ret = vfs_fstat(fd, &s);
962 if (putstat64 (statbuf, &s))
965 diff -Naurp linux-2.4.20-ck4/arch/sparc64/kernel/sys_sparc32.c linux-2.4.20-ck5/arch/sparc64/kernel/sys_sparc32.c
966 --- linux-2.4.20-ck4/arch/sparc64/kernel/sys_sparc32.c 2002-11-30 17:02:06.000000000 +1100
967 +++ linux-2.4.20-ck5/arch/sparc64/kernel/sys_sparc32.c 2003-04-08 10:52:50.000000000 +1000
968 @@ -1475,138 +1475,54 @@ out_nofds:
972 -static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
973 +static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf)
975 - unsigned long ino, blksize, blocks;
982 - time_t atime, mtime, ctime;
986 - /* Stream the loads of inode data into the load buffer,
987 - * then we push it all into the store buffer below. This
988 - * should give optimal cache performance.
990 - ino = inode->i_ino;
991 - dev = inode->i_dev;
992 - mode = inode->i_mode;
993 - nlink = inode->i_nlink;
994 - uid = inode->i_uid;
995 - gid = inode->i_gid;
996 - rdev = inode->i_rdev;
997 - size = inode->i_size;
998 - atime = inode->i_atime;
999 - mtime = inode->i_mtime;
1000 - ctime = inode->i_ctime;
1001 - blksize = inode->i_blksize;
1002 - blocks = inode->i_blocks;
1004 - err = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
1005 - err |= put_user(ino, &statbuf->st_ino);
1006 - err |= put_user(mode, &statbuf->st_mode);
1007 - err |= put_user(nlink, &statbuf->st_nlink);
1008 - err |= put_user(high2lowuid(uid), &statbuf->st_uid);
1009 - err |= put_user(high2lowgid(gid), &statbuf->st_gid);
1010 - err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
1011 - err |= put_user(size, &statbuf->st_size);
1012 - err |= put_user(atime, &statbuf->st_atime);
1013 + err = put_user(stat->dev, &statbuf->st_dev);
1014 + err |= put_user(stat->ino, &statbuf->st_ino);
1015 + err |= put_user(stat->mode, &statbuf->st_mode);
1016 + err |= put_user(stat->nlink, &statbuf->st_nlink);
1017 + err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
1018 + err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
1019 + err |= put_user(kdev_t_to_nr(stat->rdev), &statbuf->st_rdev);
1020 + err |= put_user(stat->size, &statbuf->st_size);
1021 + err |= put_user(stat->atime, &statbuf->st_atime);
1022 err |= put_user(0, &statbuf->__unused1);
1023 - err |= put_user(mtime, &statbuf->st_mtime);
1024 + err |= put_user(stat->mtime, &statbuf->st_mtime);
1025 err |= put_user(0, &statbuf->__unused2);
1026 - err |= put_user(ctime, &statbuf->st_ctime);
1027 + err |= put_user(stat->ctime, &statbuf->st_ctime);
1028 err |= put_user(0, &statbuf->__unused3);
1030 - err |= put_user(blksize, &statbuf->st_blksize);
1031 - err |= put_user(blocks, &statbuf->st_blocks);
1033 - unsigned int tmp_blocks;
1036 -#define I_B (BLOCK_SIZE / sizeof(unsigned short))
1037 - tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
1038 - if (tmp_blocks > D_B) {
1039 - unsigned int indirect;
1041 - indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
1042 - tmp_blocks += indirect;
1043 - if (indirect > 1) {
1044 - indirect = (indirect - 1 + I_B - 1) / I_B;
1045 - tmp_blocks += indirect;
1050 - err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
1051 - err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
1055 + err |= put_user(stat->blksize, &statbuf->st_blksize);
1056 + err |= put_user(stat->blocks, &statbuf->st_blocks);
1057 err |= put_user(0, &statbuf->__unused4[0]);
1058 err |= put_user(0, &statbuf->__unused4[1]);
1063 -/* Perhaps this belongs in fs.h or similar. -DaveM */
1064 -static __inline__ int
1065 -do_revalidate(struct dentry *dentry)
1067 - struct inode * inode = dentry->d_inode;
1068 - if (inode->i_op && inode->i_op->revalidate)
1069 - return inode->i_op->revalidate(dentry);
1073 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
1075 - struct nameidata nd;
1078 - error = user_path_walk(filename, &nd);
1080 - error = do_revalidate(nd.dentry);
1082 - error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1083 - path_release(&nd);
1086 + struct kstat stat;
1087 + int error = vfs_stat(filename, &stat);
1089 + return error ? error : cp_new_stat32(&stat, statbuf);
1092 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
1094 - struct nameidata nd;
1096 + struct kstat stat;
1097 + int error = vfs_lstat(filename, &stat);
1099 - error = user_path_walk_link(filename, &nd);
1101 - error = do_revalidate(nd.dentry);
1103 - error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1105 - path_release(&nd);
1108 + return error ? error : cp_new_stat32(&stat, statbuf);
1111 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
1118 - struct dentry * dentry = f->f_dentry;
1120 - err = do_revalidate(dentry);
1122 - err = cp_new_stat32(dentry->d_inode, statbuf);
1126 + struct kstat stat;
1127 + int error = vfs_fstat(fd, &stat);
1129 + return error ? error : cp_new_stat32(&stat, statbuf);
1132 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
1133 diff -Naurp linux-2.4.20-ck4/arch/sparc64/solaris/fs.c linux-2.4.20-ck5/arch/sparc64/solaris/fs.c
1134 --- linux-2.4.20-ck4/arch/sparc64/solaris/fs.c 2001-09-21 07:11:57.000000000 +1000
1135 +++ linux-2.4.20-ck5/arch/sparc64/solaris/fs.c 2003-04-08 10:52:50.000000000 +1000
1136 @@ -79,47 +79,49 @@ struct sol_stat64 {
1138 #define UFSMAGIC (((unsigned)'u'<<24)||((unsigned)'f'<<16)||((unsigned)'s'<<8))
1140 -static inline int putstat(struct sol_stat *ubuf, struct stat *kbuf)
1141 +static inline int putstat(struct sol_stat *ubuf, struct kstat *kbuf)
1143 - if (put_user (R4_DEV(kbuf->st_dev), &ubuf->st_dev) ||
1144 - __put_user (kbuf->st_ino, &ubuf->st_ino) ||
1145 - __put_user (kbuf->st_mode, &ubuf->st_mode) ||
1146 - __put_user (kbuf->st_nlink, &ubuf->st_nlink) ||
1147 - __put_user (kbuf->st_uid, &ubuf->st_uid) ||
1148 - __put_user (kbuf->st_gid, &ubuf->st_gid) ||
1149 - __put_user (R4_DEV(kbuf->st_rdev), &ubuf->st_rdev) ||
1150 - __put_user (kbuf->st_size, &ubuf->st_size) ||
1151 - __put_user (kbuf->st_atime, &ubuf->st_atime.tv_sec) ||
1152 + /* XXX_UID, XXX_SIZE */
1153 + if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) ||
1154 + __put_user (kbuf->ino, &ubuf->st_ino) ||
1155 + __put_user (kbuf->mode, &ubuf->st_mode) ||
1156 + __put_user (kbuf->nlink, &ubuf->st_nlink) ||
1157 + __put_user (kbuf->uid, &ubuf->st_uid) ||
1158 + __put_user (kbuf->gid, &ubuf->st_gid) ||
1159 + __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev) ||
1160 + __put_user (kbuf->size, &ubuf->st_size) ||
1161 + __put_user (kbuf->atime, &ubuf->st_atime.tv_sec) ||
1162 __put_user (0, &ubuf->st_atime.tv_nsec) ||
1163 - __put_user (kbuf->st_mtime, &ubuf->st_mtime.tv_sec) ||
1164 + __put_user (kbuf->mtime, &ubuf->st_mtime.tv_sec) ||
1165 __put_user (0, &ubuf->st_mtime.tv_nsec) ||
1166 - __put_user (kbuf->st_ctime, &ubuf->st_ctime.tv_sec) ||
1167 + __put_user (kbuf->ctime, &ubuf->st_ctime.tv_sec) ||
1168 __put_user (0, &ubuf->st_ctime.tv_nsec) ||
1169 - __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
1170 - __put_user (kbuf->st_blocks, &ubuf->st_blocks) ||
1171 + __put_user (kbuf->blksize, &ubuf->st_blksize) ||
1172 + __put_user (kbuf->blocks, &ubuf->st_blocks) ||
1173 __put_user (UFSMAGIC, (unsigned *)ubuf->st_fstype))
1178 -static inline int putstat64(struct sol_stat64 *ubuf, struct stat *kbuf)
1179 +static inline int putstat64(struct sol_stat64 *ubuf, struct kstat *kbuf)
1181 - if (put_user (R4_DEV(kbuf->st_dev), &ubuf->st_dev) ||
1182 - __put_user (kbuf->st_ino, &ubuf->st_ino) ||
1183 - __put_user (kbuf->st_mode, &ubuf->st_mode) ||
1184 - __put_user (kbuf->st_nlink, &ubuf->st_nlink) ||
1185 - __put_user (kbuf->st_uid, &ubuf->st_uid) ||
1186 - __put_user (kbuf->st_gid, &ubuf->st_gid) ||
1187 - __put_user (R4_DEV(kbuf->st_rdev), &ubuf->st_rdev) ||
1188 - __put_user (kbuf->st_size, &ubuf->st_size) ||
1189 - __put_user (kbuf->st_atime, &ubuf->st_atime.tv_sec) ||
1190 + /* XXX_UID, XXX_SIZE */
1191 + if (put_user (R4_DEV(kbuf->dev), &ubuf->st_dev) ||
1192 + __put_user (kbuf->ino, &ubuf->st_ino) ||
1193 + __put_user (kbuf->mode, &ubuf->st_mode) ||
1194 + __put_user (kbuf->nlink, &ubuf->st_nlink) ||
1195 + __put_user (kbuf->uid, &ubuf->st_uid) ||
1196 + __put_user (kbuf->gid, &ubuf->st_gid) ||
1197 + __put_user (R4_DEV(kbuf->rdev), &ubuf->st_rdev) ||
1198 + __put_user (kbuf->size, &ubuf->st_size) ||
1199 + __put_user (kbuf->atime, &ubuf->st_atime.tv_sec) ||
1200 __put_user (0, &ubuf->st_atime.tv_nsec) ||
1201 - __put_user (kbuf->st_mtime, &ubuf->st_mtime.tv_sec) ||
1202 + __put_user (kbuf->mtime, &ubuf->st_mtime.tv_sec) ||
1203 __put_user (0, &ubuf->st_mtime.tv_nsec) ||
1204 - __put_user (kbuf->st_ctime, &ubuf->st_ctime.tv_sec) ||
1205 + __put_user (kbuf->ctime, &ubuf->st_ctime.tv_sec) ||
1206 __put_user (0, &ubuf->st_ctime.tv_nsec) ||
1207 - __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
1208 - __put_user (kbuf->st_blocks, &ubuf->st_blocks) ||
1209 + __put_user (kbuf->blksize, &ubuf->st_blksize) ||
1210 + __put_user (kbuf->blocks, &ubuf->st_blocks) ||
1211 __put_user (UFSMAGIC, (unsigned *)ubuf->st_fstype))
1214 @@ -127,23 +129,11 @@ static inline int putstat64(struct sol_s
1216 asmlinkage int solaris_stat(u32 filename, u32 statbuf)
1221 - mm_segment_t old_fs = get_fs();
1222 - int (*sys_newstat)(char *,struct stat *) =
1223 - (int (*)(char *,struct stat *))SYS(stat);
1225 - filenam = getname ((char *)A(filename));
1226 - ret = PTR_ERR(filenam);
1227 - if (!IS_ERR(filenam)) {
1228 - set_fs (KERNEL_DS);
1229 - ret = sys_newstat(filenam, &s);
1231 - putname (filenam);
1232 - if (putstat ((struct sol_stat *)A(statbuf), &s))
1236 + int ret = vfs_stat((char*)A(filename), &s);
1238 + if (putstat ((struct sol_stat *)A(statbuf), &s))
1243 @@ -155,45 +145,21 @@ asmlinkage int solaris_xstat(int vers, u
1245 asmlinkage int solaris_stat64(u32 filename, u32 statbuf)
1250 - mm_segment_t old_fs = get_fs();
1251 - int (*sys_newstat)(char *,struct stat *) =
1252 - (int (*)(char *,struct stat *))SYS(stat);
1254 - filenam = getname ((char *)A(filename));
1255 - ret = PTR_ERR(filenam);
1256 - if (!IS_ERR(filenam)) {
1257 - set_fs (KERNEL_DS);
1258 - ret = sys_newstat(filenam, &s);
1260 - putname (filenam);
1261 - if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
1265 + int ret = vfs_stat((char*)A(filename), &s);
1267 + if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
1272 asmlinkage int solaris_lstat(u32 filename, u32 statbuf)
1277 - mm_segment_t old_fs = get_fs();
1278 - int (*sys_newlstat)(char *,struct stat *) =
1279 - (int (*)(char *,struct stat *))SYS(lstat);
1281 - filenam = getname ((char *)A(filename));
1282 - ret = PTR_ERR(filenam);
1283 - if (!IS_ERR(filenam)) {
1284 - set_fs (KERNEL_DS);
1285 - ret = sys_newlstat(filenam, &s);
1287 - putname (filenam);
1288 - if (putstat ((struct sol_stat *)A(statbuf), &s))
1292 + int ret = vfs_lstat((char*)A(filename), &s);
1294 + if (putstat ((struct sol_stat *)A(statbuf), &s))
1299 @@ -204,37 +170,19 @@ asmlinkage int solaris_lxstat(int vers,
1301 asmlinkage int solaris_lstat64(u32 filename, u32 statbuf)
1306 - mm_segment_t old_fs = get_fs();
1307 - int (*sys_newlstat)(char *,struct stat *) =
1308 - (int (*)(char *,struct stat *))SYS(lstat);
1310 - filenam = getname ((char *)A(filename));
1311 - ret = PTR_ERR(filenam);
1312 - if (!IS_ERR(filenam)) {
1313 - set_fs (KERNEL_DS);
1314 - ret = sys_newlstat(filenam, &s);
1316 - putname (filenam);
1317 - if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
1321 + int ret = vfs_lstat((char*)A(filename), &s);
1323 + if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
1328 asmlinkage int solaris_fstat(unsigned int fd, u32 statbuf)
1332 - mm_segment_t old_fs = get_fs();
1333 - int (*sys_newfstat)(unsigned,struct stat *) =
1334 - (int (*)(unsigned,struct stat *))SYS(fstat);
1336 - set_fs (KERNEL_DS);
1337 - ret = sys_newfstat(fd, &s);
1340 + int ret = vfs_fstat(fd, &s);
1342 if (putstat ((struct sol_stat *)A(statbuf), &s))
1345 @@ -247,15 +195,9 @@ asmlinkage int solaris_fxstat(int vers,
1347 asmlinkage int solaris_fstat64(unsigned int fd, u32 statbuf)
1351 - mm_segment_t old_fs = get_fs();
1352 - int (*sys_newfstat)(unsigned,struct stat *) =
1353 - (int (*)(unsigned,struct stat *))SYS(fstat);
1355 - set_fs (KERNEL_DS);
1356 - ret = sys_newfstat(fd, &s);
1359 + int ret = vfs_fstat(fd, &s);
1361 if (putstat64 ((struct sol_stat64 *)A(statbuf), &s))
1364 diff -Naurp linux-2.4.20-ck4/Documentation/filesystems/00-INDEX linux-2.4.20-ck5/Documentation/filesystems/00-INDEX
1365 --- linux-2.4.20-ck4/Documentation/filesystems/00-INDEX 2002-11-30 17:02:00.000000000 +1100
1366 +++ linux-2.4.20-ck5/Documentation/filesystems/00-INDEX 2003-04-08 10:52:50.000000000 +1000
1367 @@ -36,6 +36,8 @@ romfs.txt
1368 - Description of the ROMFS filesystem.
1370 - info on using filesystems with the SMB protocol (Windows 3.11 and NT)
1372 + - info on using supermount for removable media.
1374 - info on the SystemV/V7/Xenix/Coherent filesystem.
1376 diff -Naurp linux-2.4.20-ck4/Documentation/filesystems/supermount.txt linux-2.4.20-ck5/Documentation/filesystems/supermount.txt
1377 --- linux-2.4.20-ck4/Documentation/filesystems/supermount.txt 1970-01-01 10:00:00.000000000 +1000
1378 +++ linux-2.4.20-ck5/Documentation/filesystems/supermount.txt 2003-04-08 10:52:50.000000000 +1000
1386 +To run supermount, compile and install a kernel with the supermount
1387 +patches and select "Y" to the question
1389 + Supermount removable media support (CONFIG_SUPERMOUNT) [Y/n/?]
1391 +when you run "make config". You set up a supermount filesystem with
1392 +the normal mount command, using the syntax:
1394 + mount -t supermount -o <superfs-options>,--,<subfs-options> <mpt> <mpt>
1398 + <superfs-options> are the options you want to pass to supermount
1399 + itself. These are described below.
1401 + <subfs-options> are the options you want supermount to pass to the
1402 + dismountable filesystem underneath.
1404 + <mpt> is the mount point where you want your removable media to be
1407 +Notice that you do not directly specify the block device you are going
1408 +to mount on the mount command line. This is because the supermount
1409 +filesystem is NOT connected to a block device; rather, supermount is
1410 +responsible for connecting a separate filesystem to the block device.
1411 +You specify the sub-filesystem and block device name by providing the
1412 +<superfs-options> field, where the following options are currently
1415 +* fs=<filesystem-type> [default is "auto"]
1417 + Specify the subfilesystem type. "msdos" and "iso9660" have
1418 + been tested. If you use auto, it will try the following
1419 + filesystems in order:
1427 +* dev=<block-device>
1429 + Specify the block device on which the subfs is to be mounted.
1435 + Enable debugging code in the supermount filesystem, if
1436 +the debug option was enabled at compile time. By default, debugging
1437 +code is compiled into the kernel but is disabled until a debug mount
1442 + All options after the option string '--' will be passed
1443 +directly to the subfilesystem when it gets mounted.
1446 diff -Naurp linux-2.4.20-ck4/drivers/block/paride/pcd.c linux-2.4.20-ck5/drivers/block/paride/pcd.c
1447 --- linux-2.4.20-ck4/drivers/block/paride/pcd.c 2002-11-30 17:02:06.000000000 +1100
1448 +++ linux-2.4.20-ck5/drivers/block/paride/pcd.c 2003-04-08 10:52:50.000000000 +1000
1449 @@ -271,6 +271,7 @@ static struct block_device_operations pc
1450 release: cdrom_release,
1452 check_media_change: cdrom_media_changed,
1453 + mediactl: cdrom_mediactl,
1456 static struct cdrom_device_ops pcd_dops = {
1457 diff -Naurp linux-2.4.20-ck4/drivers/cdrom/cdrom.c linux-2.4.20-ck5/drivers/cdrom/cdrom.c
1458 --- linux-2.4.20-ck4/drivers/cdrom/cdrom.c 2002-11-30 17:02:06.000000000 +1100
1459 +++ linux-2.4.20-ck5/drivers/cdrom/cdrom.c 2003-04-08 10:52:50.000000000 +1000
1460 @@ -908,6 +908,24 @@ void cdrom_count_tracks(struct cdrom_dev
1461 tracks->cdi, tracks->xa);
1464 +int cdrom_mediactl (kdev_t dev, int op, int optarg)
1466 + struct cdrom_device_info *cdi = cdrom_find_device(dev);
1467 + struct cdrom_device_ops *cdo = cdi->ops;
1471 + case MEDIA_UNLOCK:
1472 + if (cdo->capability & ~cdi->mask & CDC_LOCK &&
1473 + cdi->options & CDO_LOCK)
1474 + cdo->lock_door(cdi, (op == MEDIA_LOCK));
1482 /* Requests to the low-level drivers will /always/ be done in the
1483 following format convention:
1485 @@ -1492,10 +1510,26 @@ int cdrom_ioctl(struct inode *ip, struct
1489 +#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1490 + struct super_block *sb = get_super(dev);
1491 + int supermounted = sb ? sb->s_flags & MS_SUPERMOUNTED : 0;
1492 + int usagecount = cdi->use_count;
1494 + if (sb) drop_super(sb);
1495 + if (supermounted && usagecount < 2)
1498 cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n");
1499 if (!CDROM_CAN(CDC_OPEN_TRAY))
1501 - if (cdi->use_count != 1 || keeplocked)
1503 +#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1504 + || (supermounted && usagecount != 2)
1505 + || (!supermounted && usagecount != 1)
1507 + || (cdi->use_count != 1)
1511 if (CDROM_CAN(CDC_LOCK))
1512 if ((ret=cdo->lock_door(cdi, 0)))
1513 @@ -2364,7 +2398,7 @@ use_last_written:
1514 *next_writable += 7;
1520 EXPORT_SYMBOL(cdrom_get_disc_info);
1521 EXPORT_SYMBOL(cdrom_get_track_info);
1522 @@ -2377,6 +2411,7 @@ EXPORT_SYMBOL(cdrom_open);
1523 EXPORT_SYMBOL(cdrom_release);
1524 EXPORT_SYMBOL(cdrom_ioctl);
1525 EXPORT_SYMBOL(cdrom_media_changed);
1526 +EXPORT_SYMBOL(cdrom_mediactl);
1527 EXPORT_SYMBOL(cdrom_number_of_slots);
1528 EXPORT_SYMBOL(cdrom_select_disc);
1529 EXPORT_SYMBOL(cdrom_mode_select);
1530 diff -Naurp linux-2.4.20-ck4/drivers/cdrom/cdu31a.c linux-2.4.20-ck5/drivers/cdrom/cdu31a.c
1531 --- linux-2.4.20-ck4/drivers/cdrom/cdu31a.c 2002-11-30 17:02:06.000000000 +1100
1532 +++ linux-2.4.20-ck5/drivers/cdrom/cdu31a.c 2003-04-08 10:52:50.000000000 +1000
1533 @@ -3188,6 +3188,7 @@ struct block_device_operations scd_bdops
1534 release: cdrom_release,
1536 check_media_change: cdrom_media_changed,
1537 + mediactl: cdrom_mediactl,
1540 static struct cdrom_device_ops scd_dops = {
1541 diff -Naurp linux-2.4.20-ck4/drivers/cdrom/cm206.c linux-2.4.20-ck5/drivers/cdrom/cm206.c
1542 --- linux-2.4.20-ck4/drivers/cdrom/cm206.c 2001-10-26 06:58:35.000000000 +1000
1543 +++ linux-2.4.20-ck5/drivers/cdrom/cm206.c 2003-04-08 10:52:50.000000000 +1000
1544 @@ -772,6 +772,7 @@ struct block_device_operations cm206_bdo
1545 release: cdrom_release,
1547 check_media_change: cdrom_media_changed,
1548 + mediactl: cdrom_mediactl,
1551 /* The new open. The real opening strategy is defined in cdrom.c. */
1552 diff -Naurp linux-2.4.20-ck4/drivers/cdrom/mcd.c linux-2.4.20-ck5/drivers/cdrom/mcd.c
1553 --- linux-2.4.20-ck4/drivers/cdrom/mcd.c 2001-10-26 06:58:35.000000000 +1000
1554 +++ linux-2.4.20-ck5/drivers/cdrom/mcd.c 2003-04-08 10:52:51.000000000 +1000
1555 @@ -196,6 +196,7 @@ struct block_device_operations mcd_bdops
1556 release: cdrom_release,
1558 check_media_change: cdrom_media_changed,
1559 + mediactl: cdrom_mediactl,
1562 static struct timer_list mcd_timer;
1563 diff -Naurp linux-2.4.20-ck4/drivers/cdrom/mcdx.c linux-2.4.20-ck5/drivers/cdrom/mcdx.c
1564 --- linux-2.4.20-ck4/drivers/cdrom/mcdx.c 2001-10-26 06:58:35.000000000 +1000
1565 +++ linux-2.4.20-ck5/drivers/cdrom/mcdx.c 2003-04-08 10:52:51.000000000 +1000
1566 @@ -226,6 +226,7 @@ struct block_device_operations mcdx_bdop
1567 release: cdrom_release,
1569 check_media_change: cdrom_media_changed,
1570 + mediactl: cdrom_mediactl,
1574 diff -Naurp linux-2.4.20-ck4/drivers/cdrom/sbpcd.c linux-2.4.20-ck5/drivers/cdrom/sbpcd.c
1575 --- linux-2.4.20-ck4/drivers/cdrom/sbpcd.c 2001-10-26 06:58:35.000000000 +1000
1576 +++ linux-2.4.20-ck5/drivers/cdrom/sbpcd.c 2003-04-08 10:52:51.000000000 +1000
1577 @@ -5426,6 +5426,7 @@ static struct block_device_operations sb
1578 release: cdrom_release,
1580 check_media_change: cdrom_media_changed,
1581 + mediactl: cdrom_mediactl,
1583 /*==========================================================================*/
1585 diff -Naurp linux-2.4.20-ck4/drivers/ide/ide.c linux-2.4.20-ck5/drivers/ide/ide.c
1586 --- linux-2.4.20-ck4/drivers/ide/ide.c 2002-11-30 17:02:07.000000000 +1100
1587 +++ linux-2.4.20-ck5/drivers/ide/ide.c 2003-04-08 10:52:51.000000000 +1000
1588 @@ -2215,6 +2215,18 @@ jump_eight:
1589 #endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */
1592 +static int ide_mediactl (kdev_t i_rdev, int op, int optarg)
1594 + ide_drive_t *drive;
1596 + if ((drive = get_info_ptr(i_rdev)) == NULL)
1599 + if (drive->driver != NULL && DRIVER(drive)->mediactl != NULL)
1600 + return DRIVER(drive)->mediactl(drive, op, optarg);
1604 void ide_unregister (unsigned int index)
1607 @@ -3930,7 +3942,8 @@ struct block_device_operations ide_fops[
1608 release: ide_release,
1610 check_media_change: ide_check_media_change,
1611 - revalidate: ide_revalidate_disk
1612 + revalidate: ide_revalidate_disk,
1613 + mediactl: ide_mediactl
1616 EXPORT_SYMBOL(ide_hwifs);
1617 diff -Naurp linux-2.4.20-ck4/drivers/ide/ide-cd.c linux-2.4.20-ck5/drivers/ide/ide-cd.c
1618 --- linux-2.4.20-ck4/drivers/ide/ide-cd.c 2002-11-30 17:02:07.000000000 +1100
1619 +++ linux-2.4.20-ck5/drivers/ide/ide-cd.c 2003-04-08 10:52:51.000000000 +1000
1620 @@ -2875,6 +2875,18 @@ int ide_cdrom_ioctl (ide_drive_t *drive,
1621 return cdrom_ioctl (inode, file, cmd, arg);
1624 +int ide_cdrom_mediactl (ide_drive_t *drive, int op, int optarg)
1628 + case MEDIA_UNLOCK:
1629 + return cdrom_lockdoor (drive, op == MEDIA_LOCK, NULL);
1637 int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
1639 @@ -2989,6 +3001,7 @@ static ide_driver_t ide_cdrom_driver = {
1642 reinit: ide_cdrom_reinit,
1643 + mediactl: ide_cdrom_mediactl,
1644 ata_prebuilder: NULL,
1645 atapi_prebuilder: NULL,
1647 diff -Naurp linux-2.4.20-ck4/drivers/scsi/sd.c linux-2.4.20-ck5/drivers/scsi/sd.c
1648 --- linux-2.4.20-ck4/drivers/scsi/sd.c 2002-08-03 13:14:53.000000000 +1000
1649 +++ linux-2.4.20-ck5/drivers/scsi/sd.c 2003-04-08 10:52:51.000000000 +1000
1650 @@ -562,6 +562,32 @@ static int sd_release(struct inode *inod
1655 + * This function performs media control operations. Currently the
1656 + * only functions used are MEDIA_LOCK and MEDIA_UNLOCK, to lock and
1657 + * unlock the drive door.
1660 +static int sd_mediactl(kdev_t full_dev, int op, int optarg) {
1663 + target = DEVICE_NR(full_dev);
1665 + if (target >= sd_template.nr_dev) {
1666 + printk("CD-ROM request error: invalid device.\n");
1672 + return scsi_ioctl(rscsi_disks[target].device, SCSI_IOCTL_DOORLOCK, 0);
1673 + case MEDIA_UNLOCK:
1674 + return scsi_ioctl(rscsi_disks[target].device, SCSI_IOCTL_DOORUNLOCK, 0);
1680 static struct block_device_operations sd_fops =
1683 @@ -569,7 +595,8 @@ static struct block_device_operations sd
1684 release: sd_release,
1686 check_media_change: check_scsidisk_media_change,
1687 - revalidate: fop_revalidate_scsidisk
1688 + revalidate: fop_revalidate_scsidisk,
1689 + mediactl: sd_mediactl,
1693 diff -Naurp linux-2.4.20-ck4/drivers/scsi/sr.c linux-2.4.20-ck5/drivers/scsi/sr.c
1694 --- linux-2.4.20-ck4/drivers/scsi/sr.c 2002-11-30 17:02:09.000000000 +1100
1695 +++ linux-2.4.20-ck5/drivers/scsi/sr.c 2003-04-08 10:52:51.000000000 +1000
1696 @@ -512,6 +512,7 @@ struct block_device_operations sr_bdops
1697 release: cdrom_release,
1699 check_media_change: cdrom_media_changed,
1700 + mediactl: cdrom_mediactl,
1703 static int sr_open(struct cdrom_device_info *cdi, int purpose)
1704 diff -Naurp linux-2.4.20-ck4/fs/block_dev.c linux-2.4.20-ck5/fs/block_dev.c
1705 --- linux-2.4.20-ck4/fs/block_dev.c 2002-08-03 13:14:57.000000000 +1000
1706 +++ linux-2.4.20-ck5/fs/block_dev.c 2003-04-08 10:52:51.000000000 +1000
1707 @@ -508,36 +508,80 @@ int unregister_blkdev(unsigned int major
1708 * People changing diskettes in the middle of an operation deserve
1711 -int check_disk_change(kdev_t dev)
1712 +const struct block_device_operations *get_block_operations(kdev_t dev)
1715 + int major = MAJOR(dev);
1716 const struct block_device_operations * bdops = NULL;
1719 - if (i < MAX_BLKDEV)
1720 - bdops = blkdevs[i].bdops;
1721 + if (major < MAX_BLKDEV)
1722 + bdops = blkdevs[major].bdops;
1723 if (bdops == NULL) {
1726 - de = devfs_find_handle (NULL, NULL, i, MINOR (dev),
1727 + de = devfs_find_handle (NULL, NULL, major, MINOR (dev),
1728 DEVFS_SPECIAL_BLK, 0);
1730 bdops = devfs_get_ops (de);
1731 devfs_put_ops (de); /* We're running in owner module */
1734 - if (bdops == NULL)
1736 - if (bdops->check_media_change == NULL)
1738 - if (!bdops->check_media_change(dev))
1741 - if (invalidate_device(dev, 0))
1742 - printk("VFS: busy inodes on changed media.\n");
1747 + * This routine checks whether a removable media has been changed, and
1748 + * (for check_disk_change only) invalidate all buffer-cache-entries in
1749 + * that case. This is a relatively slow routine, so we have to try to
1750 + * minimize using it. Thus it is called only upon a 'mount' or
1751 + * 'open'. This is the best way of combining speed and utility, I
1752 + * think. People changing diskettes in the middle of an operation
1753 + * deserve to loose :-)
1756 +int query_disk_change(kdev_t dev)
1758 + const struct block_device_operations *
1759 + bdops = get_block_operations(dev);
1761 + if (bdops && bdops->check_media_change)
1762 + return (bdops->check_media_change(dev));
1767 + * invalidate_media
1768 + * destroy all the buffers of this device
1771 - if (bdops->revalidate)
1772 +void invalidate_media(kdev_t dev)
1774 + const struct block_device_operations *
1775 + bdops = get_block_operations(dev);
1777 + if (destroy_device(dev))
1778 + printk(KERN_INFO "VFS: busy inodes on changed media.\n");
1780 + if (bdops && bdops->revalidate)
1781 bdops->revalidate(dev);
1784 +int check_disk_change(kdev_t dev)
1786 + if (!query_disk_change(dev))
1789 +#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1791 + struct super_block *sb = get_super(dev);
1793 + sb->s_media_changed = 1;
1799 + invalidate_media(dev);
1803 diff -Naurp linux-2.4.20-ck4/fs/Config.in linux-2.4.20-ck5/fs/Config.in
1804 --- linux-2.4.20-ck4/fs/Config.in 2002-11-30 17:02:20.000000000 +1100
1805 +++ linux-2.4.20-ck5/fs/Config.in 2003-04-08 10:52:51.000000000 +1000
1806 @@ -12,6 +12,8 @@ tristate 'Reiserfs support' CONFIG_REISE
1807 dep_mbool ' Enable reiserfs debug mode' CONFIG_REISERFS_CHECK $CONFIG_REISERFS_FS
1808 dep_mbool ' Stats in /proc/fs/reiserfs' CONFIG_REISERFS_PROC_INFO $CONFIG_REISERFS_FS
1810 +tristate 'Supermount removable media support' CONFIG_SUPERMOUNT
1812 dep_tristate 'ADFS file system support (EXPERIMENTAL)' CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
1813 dep_mbool ' ADFS write support (DANGEROUS)' CONFIG_ADFS_FS_RW $CONFIG_ADFS_FS $CONFIG_EXPERIMENTAL
1815 diff -Naurp linux-2.4.20-ck4/fs/ext2/super.c linux-2.4.20-ck5/fs/ext2/super.c
1816 --- linux-2.4.20-ck4/fs/ext2/super.c 2002-11-30 17:02:20.000000000 +1100
1817 +++ linux-2.4.20-ck5/fs/ext2/super.c 2003-04-08 10:52:51.000000000 +1000
1818 @@ -274,6 +274,13 @@ static int parse_options (char * options
1819 || !strcmp (this_char, "quota")
1820 || !strcmp (this_char, "usrquota"))
1821 /* Don't do anything ;-) */ ;
1822 +#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
1823 + /* Silently ignore NLS options */
1824 + else if (!strcmp (this_char, "iocharset")
1825 + || !strcmp (this_char, "codepage")
1826 + || !strcmp (this_char, "mode"))
1827 + /* Don't do anything ;-) */ ;
1830 printk ("EXT2-fs: Unrecognized mount option %s\n", this_char);
1832 diff -Naurp linux-2.4.20-ck4/fs/fat/file.c linux-2.4.20-ck5/fs/fat/file.c
1833 --- linux-2.4.20-ck4/fs/fat/file.c 2001-08-13 03:56:56.000000000 +1000
1834 +++ linux-2.4.20-ck5/fs/fat/file.c 2003-04-08 10:52:51.000000000 +1000
1835 @@ -117,8 +117,17 @@ void fat_truncate(struct inode *inode)
1838 /* Why no return value? Surely the disk could fail... */
1841 + * Why do we need this check? VFS layer should already have
1842 + * checked user access before we ever get here; and we can
1843 + * get here from iput on read-only file system, consider
1844 + * remounting file system read-only after changing some file.
1845 + * That is exactly what happens with supermount and breaks it
1847 if (IS_RDONLY (inode))
1848 return /* -EPERM */;
1850 if (IS_IMMUTABLE(inode))
1851 return /* -EPERM */;
1852 cluster = 1 << sbi->cluster_bits;
1853 diff -Naurp linux-2.4.20-ck4/fs/inode.c linux-2.4.20-ck5/fs/inode.c
1854 --- linux-2.4.20-ck4/fs/inode.c 2003-04-08 10:50:36.000000000 +1000
1855 +++ linux-2.4.20-ck5/fs/inode.c 2003-04-08 10:52:51.000000000 +1000
1856 @@ -660,6 +660,22 @@ int invalidate_device(kdev_t dev, int do
1861 + * The device is a removable device, the device is not there anymore,
1862 + * we need to remove all its buffers
1865 +int destroy_device(kdev_t dev)
1867 + struct super_block *sb = get_super(dev);
1870 + res = invalidate_inodes(sb);
1873 + destroy_buffers(dev);
1878 * This is called with the inode lock held. It searches
1879 diff -Naurp linux-2.4.20-ck4/fs/Makefile linux-2.4.20-ck5/fs/Makefile
1880 --- linux-2.4.20-ck4/fs/Makefile 2002-11-30 17:02:20.000000000 +1100
1881 +++ linux-2.4.20-ck5/fs/Makefile 2003-04-08 10:52:51.000000000 +1000
1882 @@ -60,6 +60,7 @@ subdir-$(CONFIG_AFFS_FS) += affs
1883 subdir-$(CONFIG_ROMFS_FS) += romfs
1884 subdir-$(CONFIG_QNX4FS_FS) += qnx4
1885 subdir-$(CONFIG_UDF_FS) += udf
1886 +subdir-$(CONFIG_SUPERMOUNT) += supermount
1887 subdir-$(CONFIG_AUTOFS_FS) += autofs
1888 subdir-$(CONFIG_AUTOFS4_FS) += autofs4
1889 subdir-$(CONFIG_ADFS_FS) += adfs
1890 diff -Naurp linux-2.4.20-ck4/fs/namespace.c linux-2.4.20-ck5/fs/namespace.c
1891 --- linux-2.4.20-ck4/fs/namespace.c 2002-11-30 17:02:21.000000000 +1100
1892 +++ linux-2.4.20-ck5/fs/namespace.c 2003-04-08 10:52:51.000000000 +1000
1894 #include <linux/seq_file.h>
1895 #include <linux/namespace.h>
1897 -struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
1898 -int do_remount_sb(struct super_block *sb, int flags, void * data);
1899 void kill_super(struct super_block *sb);
1901 static struct list_head *mount_hashtable;
1902 diff -Naurp linux-2.4.20-ck4/fs/read_write.c linux-2.4.20-ck5/fs/read_write.c
1903 --- linux-2.4.20-ck4/fs/read_write.c 2002-08-03 13:14:58.000000000 +1000
1904 +++ linux-2.4.20-ck5/fs/read_write.c 2003-04-08 10:52:51.000000000 +1000
1905 @@ -91,7 +91,7 @@ loff_t default_llseek(struct file *file,
1909 -static inline loff_t llseek(struct file *file, loff_t offset, int origin)
1910 +loff_t vfs_llseek(struct file *file, loff_t offset, int origin)
1912 loff_t (*fn)(struct file *, loff_t, int);
1914 @@ -116,7 +116,7 @@ asmlinkage off_t sys_lseek(unsigned int
1918 - loff_t res = llseek(file, offset, origin);
1919 + loff_t res = vfs_llseek(file, offset, origin);
1921 if (res != (loff_t)retval)
1922 retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */
1923 @@ -143,7 +143,7 @@ asmlinkage long sys_llseek(unsigned int
1927 - offset = llseek(file, ((loff_t) offset_high << 32) | offset_low,
1928 + offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low,
1931 retval = (int)offset;
1932 diff -Naurp linux-2.4.20-ck4/fs/stat.c linux-2.4.20-ck5/fs/stat.c
1933 --- linux-2.4.20-ck4/fs/stat.c 2001-09-14 09:04:43.000000000 +1000
1934 +++ linux-2.4.20-ck5/fs/stat.c 2003-04-08 10:52:51.000000000 +1000
1935 @@ -25,222 +25,248 @@ do_revalidate(struct dentry *dentry)
1940 -#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
1943 - * For backward compatibility? Maybe this should be moved
1944 - * into arch/i386 instead?
1946 -static int cp_old_stat(struct inode * inode, struct __old_kernel_stat * statbuf)
1947 +int getattr_full(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
1949 - static int warncount = 5;
1950 - struct __old_kernel_stat tmp;
1952 - if (warncount > 0) {
1954 - printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
1956 - } else if (warncount < 0) {
1957 - /* it's laughable, but... */
1961 - tmp.st_dev = kdev_t_to_nr(inode->i_dev);
1962 - tmp.st_ino = inode->i_ino;
1963 - tmp.st_mode = inode->i_mode;
1964 - tmp.st_nlink = inode->i_nlink;
1965 - SET_OLDSTAT_UID(tmp, inode->i_uid);
1966 - SET_OLDSTAT_GID(tmp, inode->i_gid);
1967 - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
1968 -#if BITS_PER_LONG == 32
1969 - if (inode->i_size > MAX_NON_LFS)
1970 - return -EOVERFLOW;
1972 - tmp.st_size = inode->i_size;
1973 - tmp.st_atime = inode->i_atime;
1974 - tmp.st_mtime = inode->i_mtime;
1975 - tmp.st_ctime = inode->i_ctime;
1976 - return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
1977 + struct inode *inode = dentry->d_inode;
1978 + stat->dev = kdev_t_to_nr(inode->i_dev);
1979 + stat->ino = inode->i_ino;
1980 + stat->mode = inode->i_mode;
1981 + stat->nlink = inode->i_nlink;
1982 + stat->uid = inode->i_uid;
1983 + stat->gid = inode->i_gid;
1984 + stat->rdev = kdev_t_to_nr(inode->i_rdev);
1985 + stat->atime = inode->i_atime;
1986 + stat->mtime = inode->i_mtime;
1987 + stat->ctime = inode->i_ctime;
1988 + stat->size = inode->i_size;
1989 + stat->blocks = inode->i_blocks;
1990 + stat->blksize = inode->i_blksize;
1996 -static int cp_new_stat(struct inode * inode, struct stat * statbuf)
1997 +int getattr_minix(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
2000 + struct inode *inode = dentry->d_inode;
2001 unsigned int blocks, indirect;
2003 - memset(&tmp, 0, sizeof(tmp));
2004 - tmp.st_dev = kdev_t_to_nr(inode->i_dev);
2005 - tmp.st_ino = inode->i_ino;
2006 - tmp.st_mode = inode->i_mode;
2007 - tmp.st_nlink = inode->i_nlink;
2008 - SET_STAT_UID(tmp, inode->i_uid);
2009 - SET_STAT_GID(tmp, inode->i_gid);
2010 - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
2011 -#if BITS_PER_LONG == 32
2012 - if (inode->i_size > MAX_NON_LFS)
2013 - return -EOVERFLOW;
2015 - tmp.st_size = inode->i_size;
2016 - tmp.st_atime = inode->i_atime;
2017 - tmp.st_mtime = inode->i_mtime;
2018 - tmp.st_ctime = inode->i_ctime;
2020 - * st_blocks and st_blksize are approximated with a simple algorithm if
2021 - * they aren't supported directly by the filesystem. The minix and msdos
2022 - * filesystems don't keep track of blocks, so they would either have to
2023 - * be counted explicitly (by delving into the file itself), or by using
2024 - * this simple algorithm to get a reasonable (although not 100% accurate)
2029 - * Use minix fs values for the number of direct and indirect blocks. The
2030 - * count is now exact for the minix fs except that it counts zero blocks.
2031 - * Everything is in units of BLOCK_SIZE until the assignment to
2034 + stat->dev = kdev_t_to_nr(inode->i_dev);
2035 + stat->ino = inode->i_ino;
2036 + stat->mode = inode->i_mode;
2037 + stat->nlink = inode->i_nlink;
2038 + stat->uid = inode->i_uid;
2039 + stat->gid = inode->i_gid;
2040 + stat->rdev = kdev_t_to_nr(inode->i_rdev);
2041 + stat->atime = inode->i_atime;
2042 + stat->mtime = inode->i_mtime;
2043 + stat->ctime = inode->i_ctime;
2044 + stat->size = inode->i_size;
2046 #define I_B (BLOCK_SIZE / sizeof(unsigned short))
2048 - if (!inode->i_blksize) {
2049 - blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
2050 - if (blocks > D_B) {
2051 - indirect = (blocks - D_B + I_B - 1) / I_B;
2052 + blocks = (stat->size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
2053 + if (blocks > D_B) {
2054 + indirect = (blocks - D_B + I_B - 1) / I_B;
2055 + blocks += indirect;
2056 + if (indirect > 1) {
2057 + indirect = (indirect - 1 + I_B - 1) / I_B;
2059 - if (indirect > 1) {
2060 - indirect = (indirect - 1 + I_B - 1) / I_B;
2061 - blocks += indirect;
2068 - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
2069 - tmp.st_blksize = BLOCK_SIZE;
2071 - tmp.st_blocks = inode->i_blocks;
2072 - tmp.st_blksize = inode->i_blksize;
2074 - return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
2075 + stat->blocks = (BLOCK_SIZE / 512) * blocks;
2076 + stat->blksize = BLOCK_SIZE;
2081 -#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
2083 - * For backward compatibility? Maybe this should be moved
2084 - * into arch/i386 instead?
2086 -asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
2087 +int vfs_lstat(char * filename, struct kstat *stat)
2089 struct nameidata nd;
2092 - error = user_path_walk(filename, &nd);
2093 + error = user_path_walk_link(filename, &nd);
2097 + error = do_revalidate(nd.dentry);
2099 - error = do_revalidate(nd.dentry);
2101 - error = cp_old_stat(nd.dentry->d_inode, statbuf);
2102 + struct inode *inode = nd.dentry->d_inode;
2103 + if (inode->i_op->getattr)
2104 + error = inode->i_op->getattr(nd.mnt, nd.dentry, stat);
2106 + error = getattr_full(nd.mnt, nd.dentry, stat);
2113 -asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
2114 +int vfs_stat(char * filename, struct kstat *stat)
2116 struct nameidata nd;
2119 error = user_path_walk(filename, &nd);
2123 + error = do_revalidate(nd.dentry);
2125 - error = do_revalidate(nd.dentry);
2127 - error = cp_new_stat(nd.dentry->d_inode, statbuf);
2128 + struct inode *inode = nd.dentry->d_inode;
2129 + if (inode->i_op->getattr)
2130 + error = inode->i_op->getattr(nd.mnt, nd.dentry, stat);
2132 + error = getattr_full(nd.mnt, nd.dentry, stat);
2138 +int vfs_fstat(int fd, struct kstat *stat)
2140 + struct file *file = fget(fd);
2146 + error = do_revalidate(file->f_dentry);
2148 + struct inode *inode = file->f_dentry->d_inode;
2149 + if (inode->i_op->getattr)
2150 + error = inode->i_op->getattr(file->f_vfsmnt, file->f_dentry, stat);
2152 + error = getattr_full(file->f_vfsmnt, file->f_dentry, stat);
2158 #if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
2161 * For backward compatibility? Maybe this should be moved
2162 * into arch/i386 instead?
2164 -asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
2165 +static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat * statbuf)
2167 - struct nameidata nd;
2169 + static int warncount = 5;
2170 + struct __old_kernel_stat tmp;
2172 - error = user_path_walk_link(filename, &nd);
2174 - error = do_revalidate(nd.dentry);
2176 - error = cp_old_stat(nd.dentry->d_inode, statbuf);
2177 - path_release(&nd);
2178 + if (warncount > 0) {
2180 + printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
2182 + } else if (warncount < 0) {
2183 + /* it's laughable, but... */
2190 + tmp.st_dev = stat->dev;
2191 + tmp.st_ino = stat->ino;
2192 + tmp.st_mode = stat->mode;
2193 + tmp.st_nlink = stat->nlink;
2194 + SET_OLDSTAT_UID(tmp, stat->uid);
2195 + SET_OLDSTAT_GID(tmp, stat->gid);
2196 + tmp.st_rdev = stat->rdev;
2197 +#if BITS_PER_LONG == 32
2198 + if (stat->size > MAX_NON_LFS)
2199 + return -EOVERFLOW;
2201 + tmp.st_size = stat->size;
2202 + tmp.st_atime = stat->atime;
2203 + tmp.st_mtime = stat->mtime;
2204 + tmp.st_ctime = stat->ctime;
2205 + return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
2208 -asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
2209 +asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf)
2211 - struct nameidata nd;
2213 + struct kstat stat;
2214 + int error = vfs_stat(filename, &stat);
2216 - error = user_path_walk_link(filename, &nd);
2218 - error = do_revalidate(nd.dentry);
2220 - error = cp_new_stat(nd.dentry->d_inode, statbuf);
2221 - path_release(&nd);
2224 + return error ? error : cp_old_stat(&stat, statbuf);
2227 -#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__)
2228 +asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf)
2230 + struct kstat stat;
2231 + int error = vfs_lstat(filename, &stat);
2233 + return error ? error : cp_old_stat(&stat, statbuf);
2237 - * For backward compatibility? Maybe this should be moved
2238 - * into arch/i386 instead?
2240 asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat * statbuf)
2244 + struct kstat stat;
2245 + int error = vfs_fstat(fd, &stat);
2249 - struct dentry * dentry = f->f_dentry;
2251 - err = do_revalidate(dentry);
2253 - err = cp_old_stat(dentry->d_inode, statbuf);
2257 + return error ? error : cp_old_stat(&stat, statbuf);
2262 +static int cp_new_stat(struct kstat *stat, struct stat * statbuf)
2266 + memset(&tmp, 0, sizeof(tmp));
2267 + tmp.st_dev = stat->dev;
2268 + tmp.st_ino = stat->ino;
2269 + tmp.st_mode = stat->mode;
2270 + tmp.st_nlink = stat->nlink;
2271 + SET_STAT_UID(tmp, stat->uid);
2272 + SET_STAT_GID(tmp, stat->gid);
2273 + tmp.st_rdev = stat->rdev;
2274 +#if BITS_PER_LONG == 32
2275 + if (stat->size > MAX_NON_LFS)
2276 + return -EOVERFLOW;
2278 + tmp.st_size = stat->size;
2279 + tmp.st_atime = stat->atime;
2280 + tmp.st_mtime = stat->mtime;
2281 + tmp.st_ctime = stat->ctime;
2282 + tmp.st_blocks = stat->blocks;
2283 + tmp.st_blksize = stat->blksize;
2284 + return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
2287 +asmlinkage long sys_newstat(char * filename, struct stat * statbuf)
2289 + struct kstat stat;
2290 + int error = vfs_stat(filename, &stat);
2292 + return error ? error : cp_new_stat(&stat, statbuf);
2295 +asmlinkage long sys_newlstat(char * filename, struct stat * statbuf)
2297 + struct kstat stat;
2298 + int error = vfs_lstat(filename, &stat);
2300 + return error ? error : cp_new_stat(&stat, statbuf);
2303 asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf)
2307 + struct kstat stat;
2308 + int error = vfs_fstat(fd, &stat);
2310 + return error ? error : cp_new_stat(&stat, statbuf);
2312 +/* this function should be callled vfs_readlink & vfs_readlink
2313 + generic_readlink */
2315 +int vfs_readlink_real(struct dentry * dentry, char * buf, int bufsiz)
2317 + struct inode * inode = dentry->d_inode;
2318 + int error = -EINVAL;
2322 - struct dentry * dentry = f->f_dentry;
2324 - err = do_revalidate(dentry);
2326 - err = cp_new_stat(dentry->d_inode, statbuf);
2328 + if (inode->i_op && inode->i_op->readlink &&
2329 + !(error = do_revalidate(dentry))) {
2330 + UPDATE_ATIME(inode);
2331 + error = inode->i_op->readlink(dentry, buf, bufsiz);
2337 asmlinkage long sys_readlink(const char * path, char * buf, int bufsiz)
2338 @@ -253,127 +279,60 @@ asmlinkage long sys_readlink(const char
2340 error = user_path_walk_link(path, &nd);
2342 - struct inode * inode = nd.dentry->d_inode;
2345 - if (inode->i_op && inode->i_op->readlink &&
2346 - !(error = do_revalidate(nd.dentry))) {
2347 - UPDATE_ATIME(inode);
2348 - error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
2350 + error = vfs_readlink_real(nd.dentry, buf, bufsiz);
2357 /* ---------- LFS-64 ----------- */
2358 #if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips64) && !defined(__x86_64__) && !defined(CONFIG_ARCH_S390X)
2360 -static long cp_new_stat64(struct inode * inode, struct stat64 * statbuf)
2361 +static long cp_new_stat64(struct kstat *stat, struct stat64 * statbuf)
2364 - unsigned int blocks, indirect;
2366 memset(&tmp, 0, sizeof(tmp));
2367 - tmp.st_dev = kdev_t_to_nr(inode->i_dev);
2368 - tmp.st_ino = inode->i_ino;
2369 + tmp.st_dev = stat->dev;
2370 + tmp.st_ino = stat->ino;
2371 #ifdef STAT64_HAS_BROKEN_ST_INO
2372 - tmp.__st_ino = inode->i_ino;
2373 + tmp.__st_ino = stat->ino;
2375 - tmp.st_mode = inode->i_mode;
2376 - tmp.st_nlink = inode->i_nlink;
2377 - tmp.st_uid = inode->i_uid;
2378 - tmp.st_gid = inode->i_gid;
2379 - tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
2380 - tmp.st_atime = inode->i_atime;
2381 - tmp.st_mtime = inode->i_mtime;
2382 - tmp.st_ctime = inode->i_ctime;
2383 - tmp.st_size = inode->i_size;
2385 - * st_blocks and st_blksize are approximated with a simple algorithm if
2386 - * they aren't supported directly by the filesystem. The minix and msdos
2387 - * filesystems don't keep track of blocks, so they would either have to
2388 - * be counted explicitly (by delving into the file itself), or by using
2389 - * this simple algorithm to get a reasonable (although not 100% accurate)
2394 - * Use minix fs values for the number of direct and indirect blocks. The
2395 - * count is now exact for the minix fs except that it counts zero blocks.
2396 - * Everything is in units of BLOCK_SIZE until the assignment to
2400 -#define I_B (BLOCK_SIZE / sizeof(unsigned short))
2402 - if (!inode->i_blksize) {
2403 - blocks = (tmp.st_size + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
2404 - if (blocks > D_B) {
2405 - indirect = (blocks - D_B + I_B - 1) / I_B;
2406 - blocks += indirect;
2407 - if (indirect > 1) {
2408 - indirect = (indirect - 1 + I_B - 1) / I_B;
2409 - blocks += indirect;
2414 - tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
2415 - tmp.st_blksize = BLOCK_SIZE;
2417 - tmp.st_blocks = inode->i_blocks;
2418 - tmp.st_blksize = inode->i_blksize;
2420 + tmp.st_mode = stat->mode;
2421 + tmp.st_nlink = stat->nlink;
2422 + tmp.st_uid = stat->uid;
2423 + tmp.st_gid = stat->gid;
2424 + tmp.st_rdev = stat->rdev;
2425 + tmp.st_atime = stat->atime;
2426 + tmp.st_mtime = stat->mtime;
2427 + tmp.st_ctime = stat->ctime;
2428 + tmp.st_size = stat->size;
2429 + tmp.st_blocks = stat->blocks;
2430 + tmp.st_blksize = stat->blksize;
2431 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
2434 asmlinkage long sys_stat64(char * filename, struct stat64 * statbuf, long flags)
2436 - struct nameidata nd;
2438 + struct kstat stat;
2439 + int error = vfs_stat(filename, &stat);
2441 - error = user_path_walk(filename, &nd);
2443 - error = do_revalidate(nd.dentry);
2445 - error = cp_new_stat64(nd.dentry->d_inode, statbuf);
2446 - path_release(&nd);
2449 + return error ? error : cp_new_stat64(&stat, statbuf);
2452 asmlinkage long sys_lstat64(char * filename, struct stat64 * statbuf, long flags)
2454 - struct nameidata nd;
2456 + struct kstat stat;
2457 + int error = vfs_lstat(filename, &stat);
2459 - error = user_path_walk_link(filename, &nd);
2461 - error = do_revalidate(nd.dentry);
2463 - error = cp_new_stat64(nd.dentry->d_inode, statbuf);
2464 - path_release(&nd);
2467 + return error ? error : cp_new_stat64(&stat, statbuf);
2470 asmlinkage long sys_fstat64(unsigned long fd, struct stat64 * statbuf, long flags)
2474 + struct kstat stat;
2475 + int error = vfs_fstat(fd, &stat);
2479 - struct dentry * dentry = f->f_dentry;
2481 - err = do_revalidate(dentry);
2483 - err = cp_new_stat64(dentry->d_inode, statbuf);
2487 + return error ? error : cp_new_stat64(&stat, statbuf);
2491 diff -Naurp linux-2.4.20-ck4/fs/super.c linux-2.4.20-ck5/fs/super.c
2492 --- linux-2.4.20-ck4/fs/super.c 2002-11-30 17:02:22.000000000 +1100
2493 +++ linux-2.4.20-ck5/fs/super.c 2003-04-08 10:59:54.000000000 +1000
2494 @@ -844,10 +844,14 @@ void kill_super(struct super_block *sb)
2497 /* Forget any remaining inodes */
2498 +#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
2499 + invalidate_inodes(sb);
2501 if (invalidate_inodes(sb)) {
2502 printk(KERN_ERR "VFS: Busy inodes after unmount. "
2503 "Self-destruct in 5 seconds. Have a nice day...\n");
2509 diff -Naurp linux-2.4.20-ck4/fs/supermount/changelog linux-2.4.20-ck5/fs/supermount/changelog
2510 --- linux-2.4.20-ck4/fs/supermount/changelog 1970-01-01 10:00:00.000000000 +1000
2511 +++ linux-2.4.20-ck5/fs/supermount/changelog 2003-04-08 10:52:51.000000000 +1000
2514 diff -Naurp linux-2.4.20-ck4/fs/supermount/dentry_operations.c linux-2.4.20-ck5/fs/supermount/dentry_operations.c
2515 --- linux-2.4.20-ck4/fs/supermount/dentry_operations.c 1970-01-01 10:00:00.000000000 +1000
2516 +++ linux-2.4.20-ck5/fs/supermount/dentry_operations.c 2003-04-08 10:52:51.000000000 +1000
2519 + * linux/fs/supermount/revalidate.c
2521 + * Original version:
2522 + * Copyright (C) 1995
2523 + * Stephen Tweedie (sct@dcs.ed.ac.uk)
2525 + * Rewriten for kernel 2.2 & 2.4. (C) 1999, 2000 Alexis Mikhailov
2526 + * (alexis@abc.cap.ru)
2530 +#include <linux/errno.h>
2531 +#include <linux/fs.h>
2532 +#include <linux/sched.h>
2533 +#include "supermount_i.h"
2536 +supermount_dentry_revalidate(struct dentry *dentry, int flags)
2538 + struct dentry *subd;
2541 + if (subfs_go_online(dentry->d_sb))
2543 + spin_lock(&dcache_lock);
2544 + if (dentry->d_inode && is_inode_obsolete(dentry->d_inode)) {
2545 + spin_unlock(&dcache_lock);
2548 + spin_unlock(&dcache_lock);
2549 + subd = get_subfs_dentry(dentry);
2553 + if (subd->d_op && subd->d_op->d_revalidate)
2554 + rc = subd->d_op->d_revalidate(subd, flags);
2558 + subfs_go_inactive(dentry->d_sb);
2565 +struct dentry_operations supermount_dir_dops = {
2566 + .d_revalidate = supermount_dentry_revalidate,
2569 +struct dentry_operations supermount_file_dops = {
2570 + .d_revalidate = supermount_dentry_revalidate,
2572 diff -Naurp linux-2.4.20-ck4/fs/supermount/file_operations.c linux-2.4.20-ck5/fs/supermount/file_operations.c
2573 --- linux-2.4.20-ck4/fs/supermount/file_operations.c 1970-01-01 10:00:00.000000000 +1000
2574 +++ linux-2.4.20-ck5/fs/supermount/file_operations.c 2003-04-08 10:52:51.000000000 +1000
2577 + * linux/fs/supermount/file_operations.c
2579 + * Original version:
2580 + * Copyright (C) 1995, 1997
2581 + * Stephen Tweedie (sct@dcs.ed.ac.uk)
2585 + * linux/fs/minix/dir.c
2586 + * Copyright (C) 1991, 1992 Linus Torvalds
2590 + * linux/fs/ext2/dir.c
2591 + * Copyright (C) 1992, 1993, 1994, 1995 Remy Card
2593 + * Rewriten for kernel 2.2 & 2.4. (C) 1999, 2000 Alexis Mikhailov
2594 + * (alexis@abc.cap.ru)
2595 + * Rewriten for kernel 2.4. (C) 2001 MandrakeSoft Inc.
2596 + * Juan Quintela (quintela@mandrakesoft.com)
2600 +#include <linux/errno.h>
2601 +#include <linux/fs.h>
2602 +#include <linux/sched.h>
2603 +#include <linux/file.h>
2604 +#include <linux/poll.h>
2605 +#include <linux/slab.h>
2607 +#include "supermount_i.h"
2609 +#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)
2612 +supermount_llseek(struct file *file, loff_t offset, int origin)
2614 + struct file *subfile = get_subfile(file);
2617 + retval = vfs_llseek(subfile, offset, origin);
2618 + file->f_pos = subfile->f_pos;
2619 + file->f_reada = subfile->f_reada;
2620 + file->f_version = subfile->f_version;
2625 +supermount_read(struct file *file, char *buf, size_t count, loff_t * ppos)
2627 + struct file *subfile = get_subfile(file);
2631 + if (subfile->f_op && subfile->f_op->read)
2632 + rc = subfile->f_op->read(subfile, buf, count, ppos);
2634 + file->f_pos = subfile->f_pos = *ppos;
2639 +supermount_write(struct file *file, const char *buf,
2640 + size_t count, loff_t * ppos)
2642 + struct file *subfile = get_subfile(file);
2645 + if (subfile->f_op && subfile->f_op->write)
2646 + rc = subfile->f_op->write(subfile, buf, count, ppos);
2648 + struct inode *subinode = subfile->f_dentry->d_inode;
2650 + file->f_pos = subfile->f_pos = *ppos;
2651 + file->f_mode = subfile->f_mode;
2652 + file->f_dentry->d_inode->i_size = subinode->i_size;
2653 + file->f_dentry->d_inode->i_blocks = subinode->i_blocks;
2654 + file->f_dentry->d_inode->i_mode = subinode->i_mode;
2660 +supermount_readdir(struct file *file, void *buf, filldir_t fill_fn)
2662 + struct file *subfile = get_subfile(file);
2665 + rc = vfs_readdir(subfile, fill_fn, buf);
2666 + file->f_pos = subfile->f_pos; /* update position, nfs needs it */
2667 + UPDATE_ATIME(file->f_dentry->d_inode);
2671 +static unsigned int
2672 +supermount_poll(struct file *file, struct poll_table_struct *table)
2674 + struct file *subfile = get_subfile(file);
2675 + int rc = DEFAULT_POLLMASK;
2677 + if (subfile->f_op && subfile->f_op->poll)
2678 + rc = subfile->f_op->poll(subfile, table);
2684 +supermount_ioctl(struct inode *inode, struct file *file,
2685 + unsigned int cmd, unsigned long arg)
2687 + struct file *subfile = get_subfile(file);
2688 + struct inode *subinode;
2691 + subinode = subfile->f_dentry->d_inode;
2692 + if (subfile->f_op && subfile->f_op->ioctl)
2693 + rc = subfile->f_op->ioctl(subinode, subfile, cmd, arg);
2698 +supermount_open(struct inode *inode, struct file *file)
2700 + struct dentry *subdent;
2701 + struct file *subfile;
2702 + struct supermount_sb_info *sbi = supermount_sbi(inode->i_sb);
2703 + struct vfsmount *mnt;
2707 + if (subfs_go_online(inode->i_sb))
2710 + subdent = get_subfs_dentry(file->f_dentry);
2711 + rc = PTR_ERR(subdent);
2712 + if (IS_ERR(subdent))
2715 + if (!subdent->d_inode)
2718 + subfs_get_read_access(inode->i_sb);
2720 + if (file->f_mode & FMODE_WRITE) {
2721 + rc = subfs_get_write_access(inode->i_sb);
2726 + mnt = mntget(sbi->s_undermount);
2727 + subfile = dentry_open(subdent, mnt, file->f_flags);
2728 + rc = PTR_ERR(subfile);
2729 + if (IS_ERR(subfile))
2732 + put_subfile(file, subfile);
2733 + subfile->f_mode = file->f_mode;
2737 + subfs_go_inactive(inode->i_sb);
2741 + subfs_put_write_access(inode->i_sb);
2743 + subfs_put_read_access(inode->i_sb);
2749 +supermount_flush(struct file *file)
2751 + struct file *subfile = get_subfile(file);
2754 + if (subfile->f_op && subfile->f_op->flush)
2755 + rc = subfile->f_op->flush(subfile);
2760 +/* we want to maintain the numbers right indeed if we have an error
2764 +supermount_release(struct inode *inode, struct file *file)
2766 + struct file *subfile = get_subfile(file);
2767 + struct inode *subinode;
2772 + if (subfs_go_online(inode->i_sb))
2776 + subinode = subfile->f_dentry->d_inode;
2777 + if (!(file->f_mode & FMODE_WRITE) && subinode->i_nlink == 0) {
2778 + if (!subfs_get_write_access(inode->i_sb))
2783 + filp_close(subfile, current->files);
2784 + if ((file->f_mode & FMODE_WRITE) || write_on) {
2785 + mark_subfs_dirty(inode->i_sb);
2786 + subfs_put_write_access(inode->i_sb);
2789 + subfs_put_read_access(inode->i_sb);
2790 + subfs_go_inactive(inode->i_sb);
2796 +supermount_fsync(struct file *file, struct dentry *dentry, int datasync)
2798 + struct file *subfile = get_subfile(file);
2801 + if (subfile->f_op && subfile->f_op->fsync)
2802 + rc = subfile->f_op->fsync(subfile, subfile->f_dentry, datasync);
2808 +supermount_fasync(int fd, struct file *file, int on)
2810 + struct file *subfile = get_subfile(file);
2813 + if (subfile->f_op && subfile->f_op->fasync)
2814 + rc = subfile->f_op->fasync(fd, subfile, on);
2820 +supermount_lock(struct file *file, int cmd, struct file_lock *fl)
2822 + struct file *subfile = get_subfile(file);
2825 + if (subfile->f_op && subfile->f_op->lock)
2826 + rc = subfile->f_op->lock(subfile, cmd, fl);
2827 + else if (cmd == F_GETLK)
2828 + posix_test_lock(file, fl);
2833 + * readv: easy, export churnk from vfs
2834 + * writev: easy, export churnk from vfs
2835 + * sendpage: only used for networking, not needed
2836 + * get_unmmapped_area: only used for devices, not needed
2839 +struct file_operations supermount_dir_operations = {
2840 + .llseek = supermount_llseek,
2841 + .read = supermount_read,
2842 + .readdir = supermount_readdir,
2843 + .ioctl = supermount_ioctl,
2844 + .open = supermount_open,
2845 + .flush = supermount_flush,
2846 + .release = supermount_release,
2847 + .fsync = supermount_fsync,
2848 + .fasync = supermount_fasync,
2851 +struct file_operations supermount_file_operations = {
2852 + .llseek = supermount_llseek,
2853 + .read = supermount_read,
2854 + .write = supermount_write,
2855 + .poll = supermount_poll,
2856 + .ioctl = supermount_ioctl,
2857 + .mmap = generic_file_mmap,
2858 + .open = supermount_open,
2859 + .flush = supermount_flush,
2860 + .release = supermount_release,
2861 + .fsync = supermount_fsync,
2862 + .fasync = supermount_fasync,
2863 + .lock = supermount_lock,
2865 diff -Naurp linux-2.4.20-ck4/fs/supermount/init.c linux-2.4.20-ck5/fs/supermount/init.c
2866 --- linux-2.4.20-ck4/fs/supermount/init.c 1970-01-01 10:00:00.000000000 +1000
2867 +++ linux-2.4.20-ck5/fs/supermount/init.c 2003-04-08 10:52:51.000000000 +1000
2870 + * linux/fs/supermount/init.c
2872 + * (C) Copyright 2001-2002 Juan Quintela <quintela@mandrakesoft.com>
2873 + * Released unde GPL v2.
2877 +#include <linux/module.h>
2878 +#include <linux/init.h>
2879 +#include <linux/fs.h>
2881 +#include "supermount_i.h"
2883 +static DECLARE_FSTYPE(supermount_fs_type, "supermount",
2884 + supermount_read_super, 0);
2887 +init_supermount_fs(void)
2889 + return register_filesystem(&supermount_fs_type);
2893 +exit_supermount_fs(void)
2895 + unregister_filesystem(&supermount_fs_type);
2900 +MODULE_AUTHOR("Stephen Tweedie, Alexis Mikhailov, Juan Quintela and others");
2901 +MODULE_DESCRIPTION("Supermount");
2902 +MODULE_LICENSE("GPL");
2903 +module_init(init_supermount_fs);
2904 +module_exit(exit_supermount_fs);
2905 diff -Naurp linux-2.4.20-ck4/fs/supermount/inode_operations.c linux-2.4.20-ck5/fs/supermount/inode_operations.c
2906 --- linux-2.4.20-ck4/fs/supermount/inode_operations.c 1970-01-01 10:00:00.000000000 +1000
2907 +++ linux-2.4.20-ck5/fs/supermount/inode_operations.c 2003-04-08 10:52:51.000000000 +1000
2910 + * linux/fs/supermount/namei.c
2912 + * Original version:
2913 + * Copyright (C) 1995
2914 + * Stephen Tweedie (sct@dcs.ed.ac.uk)
2918 + * linux/fs/minix/namei.c
2919 + * Copyright (C) 1991, 1992 Linus Torvalds
2923 + * linux/fs/ext2/namei.c
2924 + * Copyright (C) 1992, 1993, 1994, 1995 Remy Card
2926 + * Rewriten for kernel 2.2 & 2.4. (C) 1999, 2000 Alexis Mikhailov
2927 + * (alexis@abc.cap.ru)
2931 +/* This file handles almost all of the normal filesystem running of
2932 + supermount. We don't have to deal to much with the subfs
2933 + interface, since we just pass subinodes out to the application on
2936 +#include <linux/errno.h>
2937 +#include <linux/fs.h>
2938 +#include <linux/sched.h>
2940 +#include "supermount_i.h"
2942 +static struct dentry *
2943 +get_subdent(struct dentry *subfs_dir, struct dentry *dentry)
2945 + struct dentry *subdent = get_subfs_dentry(dentry);
2946 + if (IS_ERR(subdent)) {
2947 + subdent = d_alloc(subfs_dir, &dentry->d_name);
2950 + subdent = ERR_PTR(-ENOMEM);
2956 +supermount_update_super_inode(struct inode *superi, struct inode *subi)
2958 + superi->i_mode = subi->i_mode;
2959 + superi->i_uid = subi->i_uid;
2960 + superi->i_gid = subi->i_gid;
2961 + superi->i_nlink = subi->i_nlink;
2962 + superi->i_size = subi->i_size;
2963 + superi->i_atime = subi->i_atime;
2964 + superi->i_ctime = subi->i_ctime;
2965 + superi->i_mtime = subi->i_mtime;
2966 + superi->i_blksize = subi->i_blksize;
2967 + superi->i_blocks = subi->i_blocks;
2968 + superi->i_rdev = subi->i_rdev;
2969 + superi->i_version++;
2971 + if (S_ISDIR(superi->i_mode)) {
2972 + superi->i_op = &supermount_dir_iops;
2973 + superi->i_fop = &supermount_dir_operations;
2974 + } else if (S_ISLNK(superi->i_mode)) {
2975 + superi->i_op = &supermount_symlink_iops;
2976 + superi->i_mapping = subi->i_mapping;
2978 + superi->i_op = &supermount_file_iops;
2979 + superi->i_fop = &supermount_file_operations;
2980 + superi->i_mapping = subi->i_mapping;
2985 + * Attach superinode to subinode and instantiate dentry with this inode
2989 +attach_and_prepare(struct super_block *sb,
2990 + struct dentry *dentry, struct dentry *subd, int create)
2992 + struct inode *superi, *subi = subd->d_inode;
2994 + if (dentry->d_inode)
2997 + superi = supermount_create_inode(sb);
2998 + supermount_update_super_inode(superi, subd->d_inode);
3001 + d_instantiate(dentry, superi);
3003 + d_add(dentry, superi);
3004 + supermount_i(superi)->i_dentry = dget(subd);
3006 + if (S_ISDIR(subi->i_mode))
3007 + dentry->d_op = &supermount_dir_dops;
3009 + dentry->d_op = &supermount_file_dops;
3014 +update_nlink(struct inode *superi, struct inode *subi)
3016 + superi->i_nlink = subi->i_nlink;
3020 +update_ctime(struct inode *superi, struct inode *subi)
3022 + superi->i_ctime = subi->i_ctime;
3026 +update_mtime(struct inode *superi, struct inode *subi)
3028 + superi->i_mtime = subi->i_mtime;
3031 +/* inode methods */
3034 +supermount_create(struct inode *dir, struct dentry *dentry, int mode)
3036 + struct dentry *subdent, *subfs_dir;
3039 + if (dentry->d_inode)
3042 + if (subfs_go_online(dir->i_sb))
3045 + subfs_dir = get_subfs_dentry_by_inode(dir);
3046 + rc = PTR_ERR(subfs_dir);
3047 + if (IS_ERR(subfs_dir))
3051 + if (!subfs_dir->d_inode)
3054 + subdent = get_subdent(subfs_dir, dentry);
3055 + rc = PTR_ERR(subdent);
3056 + if (IS_ERR(subdent))
3060 + if (subdent->d_inode)
3063 + rc = subfs_get_write_access(dir->i_sb);
3067 + rc = vfs_create(subfs_dir->d_inode, subdent, mode);
3069 + mark_subfs_dirty(dir->i_sb);
3070 + subfs_put_write_access(dir->i_sb);
3075 + if (!subdent->d_inode) {
3076 + d_instantiate(dentry, NULL);
3080 + /* It worked, so now create a shadow supermount inode for the
3083 + attach_and_prepare(dir->i_sb, dentry, subdent, 1);
3089 + subfs_go_inactive(dir->i_sb);
3093 +static struct dentry *
3094 +supermount_lookup(struct inode *dir, struct dentry *dentry)
3096 + struct dentry *err, *subdent, *subfs_dir;
3098 + if (dentry->d_inode)
3100 + err = ERR_PTR(-EIO);
3101 + if (subfs_go_online(dir->i_sb))
3103 + subfs_dir = get_subfs_dentry_by_inode(dir);
3105 + if (IS_ERR(subfs_dir))
3107 + err = ERR_PTR(-ENOENT);
3108 + if (!subfs_dir->d_inode)
3110 + subdent = lookup_one_len(dentry->d_name.name, subfs_dir,
3111 + dentry->d_name.len);
3113 + if (IS_ERR(subdent))
3117 + if (!subdent->d_inode) {
3119 + d_add(dentry, NULL);
3123 + /* It worked, so now create a shadow supermount inode for the
3125 + attach_and_prepare(dir->i_sb, dentry, subdent, 0);
3131 + subfs_go_inactive(dir->i_sb);
3136 +supermount_link(struct dentry *old_dentry, struct inode *dir,
3137 + struct dentry *new_dentry)
3139 + struct dentry *old_subdent, *subfs_dir, *new_subdent;
3143 + if (subfs_go_online(dir->i_sb))
3146 + subfs_dir = get_subfs_dentry_by_inode(dir);
3148 + if (IS_ERR(subfs_dir))
3152 + if (!subfs_dir->d_inode)
3155 + old_subdent = get_subdent(subfs_dir, old_dentry);
3156 + rc = PTR_ERR(old_subdent);
3157 + if (IS_ERR(old_subdent))
3161 + if (old_subdent->d_inode && !old_dentry->d_inode)
3162 + attach_and_prepare(dir->i_sb, old_dentry,
3165 + rc = subfs_get_write_access(dir->i_sb);
3168 + new_subdent = lookup_one_len(new_dentry->d_name.name, subfs_dir,
3169 + new_dentry->d_name.len);
3171 + if (IS_ERR(new_subdent)) {
3172 + rc = PTR_ERR(new_subdent);
3176 + rc = vfs_link(old_subdent, subfs_dir->d_inode, new_subdent);
3177 + /* Now we have subinode, attached to subdent. */
3179 + mark_subfs_dirty(dir->i_sb);
3180 + subfs_put_write_access(dir->i_sb);
3185 + if (!old_subdent->d_inode) {
3186 + d_instantiate(old_dentry, NULL);
3190 + /* It worked, so now create a shadow supermount inode for the
3192 + attach_and_prepare(dir->i_sb, new_dentry, new_subdent, 1);
3194 + dput(old_subdent);
3198 + subfs_go_inactive(dir->i_sb);
3201 + subfs_put_write_access(dir->i_sb);
3206 +supermount_unlink(struct inode *dir, struct dentry *dentry)
3208 + struct dentry *subfs_dir, *subdent;
3212 + if (subfs_go_online(dir->i_sb))
3215 + subfs_dir = get_subfs_dentry_by_inode(dir);
3217 + if (IS_ERR(subfs_dir))
3220 + if (!subfs_dir->d_inode)
3223 + subdent = get_subfs_dentry(dentry);
3225 + if (IS_ERR(subdent))
3228 + rc = subfs_get_write_access(dir->i_sb);
3232 + rc = vfs_unlink(subfs_dir->d_inode, subdent);
3234 + update_nlink(dir, subfs_dir->d_inode);
3235 + update_nlink(dentry->d_inode, subdent->d_inode);
3236 + update_ctime(dir, subfs_dir->d_inode);
3237 + update_mtime(dir, subfs_dir->d_inode);
3238 + update_ctime(dentry->d_inode, subdent->d_inode);
3240 + /* If subdent->d_count == 1 (which means that this function is the
3241 + * only holder of dentry then d_delete called a little earlier will
3242 + * dentry_iput subdent, so if its inode has no other links inode_delete
3243 + * will be called at this point, otherwise inode_delete will be
3244 + * called when other link(s) to this inode is deleted. So we
3245 + * can safely put_write_access now.
3247 + /* Then, if subdent->d_count != 1 then last iput will be called on last
3248 + * dput (if inode has no other links) so we will have to check for
3249 + * ->i_nlink == 0 in supermount_release
3252 + mark_subfs_dirty(dir->i_sb);
3253 + subfs_put_write_access(dir->i_sb);
3260 + subfs_go_inactive(dir->i_sb);
3265 +supermount_symlink(struct inode *dir, struct dentry *dentry,
3266 + const char *symname)
3268 + struct dentry *subdent, *subfs_dir;
3272 + if (subfs_go_online(dir->i_sb))
3275 + subfs_dir = get_subfs_dentry_by_inode(dir);
3276 + rc = PTR_ERR(subfs_dir);
3277 + if (IS_ERR(subfs_dir))
3281 + if (!subfs_dir->d_inode)
3284 + subdent = get_subdent(subfs_dir, dentry);
3285 + rc = PTR_ERR(subdent);
3286 + if (IS_ERR(subdent))
3290 + if (subdent->d_inode && !dentry->d_inode)
3293 + rc = subfs_get_write_access(dir->i_sb);
3297 + rc = vfs_symlink(subfs_dir->d_inode, subdent, symname);
3298 + /* Now we have subinode, attached to subdent. */
3300 + mark_subfs_dirty(dir->i_sb);
3301 + subfs_put_write_access(dir->i_sb);
3306 + if (!subdent->d_inode) {
3307 + d_instantiate(dentry, NULL);
3311 + /* It worked, so now create a shadow supermount inode for the
3314 + attach_and_prepare(dir->i_sb, dentry, subdent, 1);
3320 + subfs_go_inactive(dir->i_sb);
3325 +supermount_mkdir(struct inode *dir, struct dentry *dentry, int mode)
3327 + struct dentry *subdent, *subfs_dir;
3331 + if (subfs_go_online(dir->i_sb))
3334 + subfs_dir = get_subfs_dentry_by_inode(dir);
3336 + if (IS_ERR(subfs_dir))
3339 + if (!subfs_dir->d_inode)
3342 + subdent = get_subdent(subfs_dir, dentry);
3343 + rc = PTR_ERR(subdent);
3344 + if (IS_ERR(subdent))
3348 + if (subdent->d_inode && !dentry->d_inode)
3351 + rc = subfs_get_write_access(dir->i_sb);
3355 + rc = vfs_mkdir(subfs_dir->d_inode, subdent, mode);
3357 + update_nlink(dir, subfs_dir->d_inode);
3359 + mark_subfs_dirty(dir->i_sb);
3360 + subfs_put_write_access(dir->i_sb);
3365 + if (!subdent->d_inode) {
3366 + d_instantiate(dentry, NULL);
3370 + /* It worked, so now create a shadow supermount inode for the
3373 + attach_and_prepare(dir->i_sb, dentry, subdent, 1);
3377 + dput(subfs_dir); /* We don't need it anymore */
3379 + subfs_go_inactive(dir->i_sb);
3384 +supermount_rmdir(struct inode *dir, struct dentry *dentry)
3386 + struct dentry *subdent, *subfs_dir;
3389 + if (subfs_go_online(dir->i_sb))
3393 + subfs_dir = get_subfs_dentry_by_inode(dir);
3394 + if (IS_ERR(subfs_dir))
3397 + if (!subfs_dir->d_inode)
3400 + subdent = get_subfs_dentry(dentry);
3401 + if (IS_ERR(subdent))
3404 + rc = subfs_get_write_access(dir->i_sb);
3406 + goto dput_subdent;
3408 + rc = vfs_rmdir(subfs_dir->d_inode, subdent);
3410 + goto put_write_access;
3412 + update_nlink(dir, subfs_dir->d_inode);
3413 + update_nlink(dentry->d_inode, subdent->d_inode);
3414 + update_ctime(dir, subfs_dir->d_inode);
3415 + update_mtime(dir, subfs_dir->d_inode);
3416 + update_ctime(dentry->d_inode, subdent->d_inode);
3418 + mark_subfs_dirty(dir->i_sb);
3420 + subfs_put_write_access(dir->i_sb);
3426 + subfs_go_inactive(dir->i_sb);
3431 +supermount_mknod(struct inode *dir, struct dentry *dentry, int
3434 + struct dentry *subdent, *subfs_dir;
3437 + if (subfs_go_online(dir->i_sb))
3441 + subfs_dir = get_subfs_dentry_by_inode(dir);
3442 + if (IS_ERR(subfs_dir))
3445 + if (!subfs_dir->d_inode)
3448 + subdent = get_subdent(subfs_dir, dentry);
3449 + rc = PTR_ERR(subdent);
3450 + if (IS_ERR(subdent))
3454 + if (subdent->d_inode && !dentry->d_inode)
3457 + rc = subfs_get_write_access(dir->i_sb);
3461 + rc = vfs_mknod(subfs_dir->d_inode, subdent, mode, dev);
3462 + /* Now we have subinode, attached to subdent. */
3464 + mark_subfs_dirty(dir->i_sb);
3465 + subfs_put_write_access(dir->i_sb);
3470 + if (!subdent->d_inode) {
3471 + d_instantiate(dentry, NULL);
3475 + /* It worked, so now create a shadow supermount inode for the
3478 + attach_and_prepare(dir->i_sb, dentry, subdent, 1);
3484 + subfs_go_inactive(dir->i_sb);
3489 +supermount_rename(struct inode *olddir, struct dentry *olddentry,
3490 + struct inode *newdir, struct dentry *newdentry)
3492 + struct dentry *oldsubdent, *newsubdent, *oldsubfs_dir, *newsubfs_dir;
3495 + if (subfs_go_online(olddir->i_sb))
3499 + oldsubdent = get_subfs_dentry(olddentry);
3500 + if (IS_ERR(oldsubdent))
3503 + oldsubfs_dir = get_subfs_dentry_by_inode(olddir);
3504 + if (IS_ERR(oldsubfs_dir))
3507 + if (!oldsubfs_dir->d_inode)
3508 + goto olddirput_ret;
3510 + newsubfs_dir = get_subfs_dentry_by_inode(newdir);
3511 + if (IS_ERR(newsubfs_dir))
3512 + goto olddirput_ret;
3514 + newsubdent = get_subfs_dentry(newdentry);
3515 + if (IS_ERR(newsubdent)) {
3516 + rc = PTR_ERR(newsubdent);
3517 + goto newdirput_ret;
3520 + rc = subfs_get_write_access(olddir->i_sb);
3524 + rc = vfs_rename(oldsubfs_dir->d_inode, oldsubdent,
3525 + newsubfs_dir->d_inode, newsubdent);
3526 + update_nlink(olddir, oldsubfs_dir->d_inode);
3527 + update_nlink(newdir, newsubfs_dir->d_inode);
3528 + update_nlink(olddentry->d_inode, oldsubdent->d_inode);
3529 + update_ctime(olddir, oldsubfs_dir->d_inode);
3530 + update_mtime(olddir, oldsubfs_dir->d_inode);
3531 + update_ctime(olddentry->d_inode, oldsubdent->d_inode);
3533 + subfs_put_write_access(olddir->i_sb);
3537 + dput(newsubfs_dir);
3539 + dput(oldsubfs_dir);
3543 + subfs_go_inactive(olddir->i_sb);
3548 +supermount_readlink(struct dentry *dentry, char *buffer , int buflen)
3550 + struct dentry *subdent;
3553 + if (subfs_go_online(dentry->d_sb))
3556 + subdent = get_subfs_dentry(dentry);
3557 + if (IS_ERR(subdent))
3561 + if (!subdent->d_inode)
3564 + rc = vfs_readlink_real(subdent, buffer, buflen);
3568 + subfs_go_inactive(dentry->d_sb);
3573 +supermount_follow_link(struct dentry *dentry, struct nameidata *nd)
3575 + struct dentry *subdent = get_subfs_dentry(dentry);
3576 + int rc = PTR_ERR(subdent);
3578 + if (IS_ERR(subdent))
3582 + if (!subdent->d_inode)
3585 + if (subdent->d_inode && subdent->d_inode->i_op
3586 + && subdent->d_inode->i_op->follow_link)
3587 + rc = subdent->d_inode->i_op->follow_link(subdent, nd);
3598 + return vfs_follow_link(nd, ERR_PTR(rc));
3602 +supermount_permission(struct inode *inode, int mask)
3604 + struct inode *subi;
3605 + struct dentry *subdent;
3607 + int need_write_access;
3609 + if (subfs_go_online(inode->i_sb))
3612 + subdent = get_subfs_dentry_by_inode(inode);
3613 + if (IS_ERR(subdent)) {
3614 + rc = PTR_ERR(subdent);
3617 + subi = subdent->d_inode;
3620 + need_write_access = (mask & MAY_WRITE) && IS_RDONLY(subi);
3621 + if (need_write_access) {
3622 + rc = subfs_get_write_access(inode->i_sb);
3626 + rc = permission(subi, mask);
3627 + if (need_write_access)
3628 + subfs_put_write_access(inode->i_sb);
3632 + subfs_go_inactive(inode->i_sb);
3637 +supermount_setattr(struct dentry *dentry, struct iattr *attr)
3639 + struct inode *subi, *inode = dentry->d_inode;
3640 + struct dentry *subdent;
3647 + if (subfs_go_online(dentry->d_sb))
3650 + subdent = get_subfs_dentry(dentry);
3651 + if (IS_ERR(subdent)) {
3652 + rc = PTR_ERR(subdent);
3655 + subi = subdent->d_inode;
3659 + rc = subfs_get_write_access(inode->i_sb);
3663 + rc = notify_change(subdent, attr);
3667 + * If it worked, then we need to mark the modification
3668 + * to the subfs, and we also need to propogate the
3669 + * change up to the shadowing inode.
3671 + mark_subfs_dirty(inode->i_sb);
3672 + attr->ia_mode = subi->i_mode;
3673 + attr->ia_uid = subi->i_uid;
3674 + attr->ia_gid = subi->i_gid;
3675 + attr->ia_size = subi->i_size;
3676 + attr->ia_atime = subi->i_atime;
3677 + attr->ia_mtime = subi->i_mtime;
3678 + attr->ia_ctime = subi->i_ctime;
3680 + ATTR_UID | ATTR_GID | ATTR_MODE | ATTR_SIZE |
3681 + ATTR_ATIME | ATTR_MTIME | ATTR_CTIME;
3682 + inode_setattr(inode, attr);
3685 + subfs_put_write_access(inode->i_sb);
3689 + subfs_go_inactive(inode->i_sb);
3694 +supermount_getattr(struct vfsmount *mnt, struct dentry *dentry,
3695 + struct kstat *stat)
3697 + struct inode *subi, *inode = dentry->d_inode;
3698 + struct dentry *subdent;
3705 + if (subfs_go_online(dentry->d_sb))
3709 + subdent = get_subfs_dentry(dentry);
3710 + if (IS_ERR(subdent)) {
3711 + rc = PTR_ERR(subdent);
3714 + subi = subdent->d_inode;
3718 + getattr_full(mnt, dentry, stat);
3719 + stat->ino = subi->i_ino;
3724 + subfs_go_inactive(inode->i_sb);
3729 +supermount_root_getattr(struct vfsmount *mnt, struct dentry *dentry,
3730 + struct kstat *stat)
3732 + struct supermount_sb_info *sbi;
3733 + struct inode *inode = dentry->d_inode;
3739 + sbi = supermount_sbi(dentry->d_sb);
3740 + if (subfs_is_mounted(sbi))
3741 + retval = supermount_getattr(mnt, dentry, stat);
3745 + if (retval == -EIO)
3746 + /* there are problems for mounting */
3747 + return getattr_full(mnt, dentry, stat);
3753 + * directories can handle most operations... supermount/namei.c just
3754 + * passes them through to the underlying subfs, except for lookup().
3757 +/* truncate: is not necesary, handled with setattr
3758 + * revalidate: only needed by nfs
3759 + * FixMe: implement accl functions
3761 +struct inode_operations supermount_root_iops = {
3762 + .create = supermount_create,
3763 + .lookup = supermount_lookup,
3764 + .link = supermount_link,
3765 + .unlink = supermount_unlink,
3766 + .symlink = supermount_symlink,
3767 + .mkdir = supermount_mkdir,
3768 + .rmdir = supermount_rmdir,
3769 + .mknod = supermount_mknod,
3770 + .rename = supermount_rename,
3771 + .permission = supermount_permission,
3772 + .setattr = supermount_setattr,
3773 + .getattr = supermount_root_getattr,
3776 +struct inode_operations supermount_dir_iops = {
3777 + .create = supermount_create,
3778 + .lookup = supermount_lookup,
3779 + .link = supermount_link,
3780 + .unlink = supermount_unlink,
3781 + .symlink = supermount_symlink,
3782 + .mkdir = supermount_mkdir,
3783 + .rmdir = supermount_rmdir,
3784 + .mknod = supermount_mknod,
3785 + .rename = supermount_rename,
3786 + .permission = supermount_permission,
3787 + .setattr = supermount_setattr,
3788 + .getattr = supermount_getattr,
3791 +struct inode_operations supermount_symlink_iops = {
3792 + .readlink = supermount_readlink,
3793 + .follow_link = supermount_follow_link,
3794 + .setattr = supermount_setattr,
3795 + .getattr = supermount_getattr,
3798 +struct inode_operations supermount_file_iops = {
3799 + .setattr = supermount_setattr,
3800 + .getattr = supermount_getattr,
3802 diff -Naurp linux-2.4.20-ck4/fs/supermount/Makefile linux-2.4.20-ck5/fs/supermount/Makefile
3803 --- linux-2.4.20-ck4/fs/supermount/Makefile 1970-01-01 10:00:00.000000000 +1000
3804 +++ linux-2.4.20-ck5/fs/supermount/Makefile 2003-04-08 10:52:51.000000000 +1000
3807 +# Makefile for the linux supermounting routines.
3810 +O_TARGET := supermount.o
3812 +obj-y := super.o init.o mediactl.o translation.o super_operations.o \
3813 + file_operations.o inode_operations.o \
3814 + dentry_operations.o
3816 +obj-m := $(O_TARGET)
3818 +include $(TOPDIR)/Rules.make
3819 diff -Naurp linux-2.4.20-ck4/fs/supermount/mediactl.c linux-2.4.20-ck5/fs/supermount/mediactl.c
3820 --- linux-2.4.20-ck4/fs/supermount/mediactl.c 1970-01-01 10:00:00.000000000 +1000
3821 +++ linux-2.4.20-ck5/fs/supermount/mediactl.c 2003-04-08 10:52:51.000000000 +1000
3824 + * linux/fs/supermount/mediactl.c
3826 + * Original version:
3827 + * Copyright (C) 1995, 1997
3828 + * Stephen Tweedie (sct@dcs.ed.ac.uk)
3830 + * Rewriten for kernel 2.2, 2.4. (C) 1999, 2000 Alexis Mikhailov
3831 + * (alexis@abc.cap.ru)
3835 +#include <linux/errno.h>
3836 +#include <linux/fs.h>
3837 +#include <linux/major.h>
3838 +#include <linux/cdrom.h>
3840 +#include "supermount_i.h"
3843 + * Try to lock the drive door. This is not guaranteed to work on all
3844 + * hardware, but we try any tricks we know of anyway.
3847 +supermount_handle_door(struct super_block *sb, int operation)
3851 + const struct block_device_operations *fops;
3852 + struct supermount_sb_info *sbi = supermount_sbi(sb);
3853 + struct super_block *subsb = supermount_subfs_sb(sbi);
3855 + dev = subsb->s_dev;
3856 + major = MAJOR(dev);
3857 + if (major >= MAX_BLKDEV || !(fops = get_blkfops(major)))
3859 + if (!fops->mediactl)
3861 + fops->mediactl(dev, operation, 0);
3863 diff -Naurp linux-2.4.20-ck4/fs/supermount/super.c linux-2.4.20-ck5/fs/supermount/super.c
3864 --- linux-2.4.20-ck4/fs/supermount/super.c 1970-01-01 10:00:00.000000000 +1000
3865 +++ linux-2.4.20-ck5/fs/supermount/super.c 2003-04-08 10:52:51.000000000 +1000
3868 + * linux/fs/supermount/super.c
3870 + * Original version:
3871 + * Copyright (C) 1995, 1997
3872 + * Stephen Tweedie (sct@dcs.ed.ac.uk)
3876 + * linux/fs/minix/inode.c
3877 + * Copyright (C) 1991, 1992 Linus Torvalds
3881 + * linux/fs/ext2/super.c
3882 + * Copyright (C) 1992, 1993, 1994, 1995 Remy Card
3884 + * Rewriten for kernel 2.2, 2.4. (C) 1999, 2000 Alexis Mikhailov
3885 + * (alexis@abc.cap.ru)
3889 +#include <linux/errno.h>
3890 +#include <linux/fs.h>
3891 +#include <linux/list.h>
3892 +#include <linux/locks.h>
3894 +#include "supermount_i.h"
3897 +supermount_create_inode(struct super_block *s)
3899 + struct inode *inode = new_inode(s);
3900 + struct supermount_sb_info *sbi = supermount_sbi(s);
3905 + inode->i_mode = sbi->s_default_mode;
3907 + inode->i_uid = s->s_root->d_inode->i_uid;
3908 + inode->i_gid = s->s_root->d_inode->i_gid;
3913 + inode->i_blksize = inode->i_sb->s_blocksize;
3914 + inode->i_rdev = 0;
3915 + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
3916 + supermount_i(inode)->i_sb_version = sbi->s_version;
3917 + list_add(&(supermount_i(inode)->i_fs), &sbi->s_inodes);
3923 +supermount_clean_inodes(struct super_block *sb)
3925 + struct supermount_sb_info *sbi = supermount_sbi(sb);
3926 + struct list_head *ptr;
3927 + struct supermount_inode_info *info;
3929 + list_for_each(ptr, &sbi->s_inodes) {
3930 + info = list_entry(ptr, struct supermount_inode_info, i_fs);
3933 + if (!info->i_dentry)
3935 + dput(info->i_dentry);
3936 + info->i_dentry = NULL;
3941 + * Cut off busy dentries unless mounted over. They go away when
3942 + * their owners die
3943 + * We run under mutex or sb lock so nobody can change directory structure
3944 + * d_drop holds dcache lock for us
3945 + * FIXME: it probably should unmount submounts
3948 +supermount_drop_dentries(struct super_block *sb)
3951 + struct list_head *ptr;
3956 + list_for_each(ptr, &sb->s_root->d_subdirs) {
3957 + d = list_entry(ptr, struct dentry, d_child);
3959 + if (!have_submounts(d))
3965 +subfs_umount(struct super_block *sb)
3967 + struct supermount_sb_info *sbi = supermount_sbi(sb);
3968 + struct vfsmount *mnt = sbi->s_undermount;
3969 + struct inode *root_inode;
3972 + root_inode = sb->s_root->d_inode;
3973 + if (!supermount_i(root_inode)->i_dentry)
3975 + dput(supermount_i(root_inode)->i_dentry);
3976 + supermount_i(root_inode)->i_dentry = NULL;
3978 + shrink_dcache_sb(sb);
3979 + supermount_clean_inodes(sb);
3980 + supermount_drop_dentries(sb);
3983 + sbi->s_state = SUPERMOUNT_UNMOUNTED;
3984 + sbi->s_undermount = NULL;
3986 + sb->s_flags = sbi->s_mflags;
3990 +subfs_remount(struct super_block *sb, int flags)
3992 + struct supermount_sb_info *sbi = supermount_sbi(sb);
3993 + struct super_block *subsb = supermount_subfs_sb(sbi);
3994 + int real_flags = (sb->s_flags | flags) & MS_RMT_MASK;
3997 + retval = do_remount_sb(subsb, real_flags, NULL);
3998 + if (flags & MS_RDONLY)
3999 + fsync_dev(subsb->s_dev);
4004 +subfs_remount_ro(struct super_block *sb)
4006 + int retval = subfs_remount(sb, MS_RDONLY);
4010 + unmark_subfs_rw(sb);
4015 +subfs_remount_rw(struct super_block *sb)
4017 + int retval = subfs_remount(sb, 0);
4021 + mark_subfs_rw(sb);
4026 +subfs_real_mount(struct super_block *sb, char *type)
4028 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4029 + struct vfsmount *mnt;
4032 + if (sbi->s_data_copy)
4033 + strcpy(sbi->s_data, sbi->s_data_copy);
4035 + mnt = do_kern_mount(type,
4036 + sb->s_flags | MS_MGC_VAL | MS_SUPERMOUNTED,
4037 + sbi->s_devname, sbi->s_data);
4039 + if (IS_ERR(mnt)) {
4040 + retval = PTR_ERR(mnt);
4043 + mnt->mnt_sb->s_media_changed = 0;
4044 + sbi->s_undermount = mnt;
4050 +subfs_real_mount2(struct super_block *sb, char *type)
4052 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4053 + struct inode *root_inode;
4056 + sb->s_flags = sbi->s_mflags;
4058 + retval = subfs_real_mount(sb, type);
4060 + if (retval == -EROFS) {
4061 + sb->s_flags |= MS_RDONLY;
4062 + retval = subfs_real_mount(sb, type);
4064 + goto assign_root_inode;
4069 + if (!(sb->s_flags & MS_RDONLY)) {
4070 + retval = subfs_remount_ro(sb);
4075 + root_inode = sb->s_root->d_inode;
4076 + if (supermount_i(root_inode)->i_dentry)
4078 + supermount_i(root_inode)->i_dentry = dget(sbi->s_undermount->mnt_root);
4083 +static char *types_in_order[] = {
4098 +subfs_mount(struct super_block *sb)
4100 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4101 + int retval = -ENODEV;
4102 + char **type = types_in_order;
4104 + if (sbi->s_type && strcmp(sbi->s_type, "auto"))
4105 + return subfs_real_mount2(sb, sbi->s_type);
4107 + while (*type && retval
4108 + && retval != -ENXIO
4109 + && retval != -ENOMEDIUM
4110 + && retval != -ENOENT) {
4111 + retval = subfs_real_mount2(sb, *type);
4118 +/* We used not to check the medium if we was already mounted, this
4119 + * provoked problems in floppies & things that don't have a working
4120 + * locking mechanism, now we _always_ check if the medium has changed.
4123 +/* Return 0 (OK) if medium is valid. */
4125 +subfs_go_online(struct super_block *sb)
4128 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4132 + if (subfs_is_mounted(sbi)) {
4133 + struct super_block *subsb = supermount_subfs_sb(sbi);
4134 + kdev_t dev = subsb->s_dev;
4137 + * check for disk change or disk not present
4139 + * FIXME there is a race here; check must be protected
4140 + * with mutex; currently it is possible that media changed
4144 + if (!(subsb->s_media_changed || query_disk_change(dev)))
4147 + /* We have a disk change! Unmount the subfs */
4149 + /* The call to disk_changed may clear the media-
4150 + changed flag on the device, so we need to force a
4151 + media invalidation. We don't want to do this
4152 + before unmounting the subfs, naturally! */
4153 + invalidate_media(dev);
4155 + /* OK, we're unmounted now --- can we remount? Please? */
4156 + if (sbi->s_undermount)
4159 + retval = subfs_mount(sb);
4165 + supermount_i(sb->s_root->d_inode)->i_sb_version = sbi->s_version;
4166 + unmark_subfs_rw(sb);
4167 + sbi->s_state = SUPERMOUNT_SUSPENDED;
4169 + switch (sbi->s_state) {
4170 + case SUPERMOUNT_UNMOUNTED:
4172 + case SUPERMOUNT_SUSPENDED:
4173 + supermount_lock_door(sb);
4174 + sbi->s_state = SUPERMOUNT_ONLINE;
4176 + case SUPERMOUNT_ONLINE:
4177 + /* No need to do anything */ ;
4180 + atomic_inc(&sbi->s_opencount);
4186 + * Check the state of the supermount filesystem after it has been
4187 + * released by some inode. If it is no longer active, do the necessary
4188 + * cleanup: fsync the disk, remount it readonly if appropriate, and
4189 + * unlock the drive door if possible.
4193 +subfs_go_inactive(struct super_block *sb)
4195 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4199 + /* there was a problem mounting */
4200 + if (!subfs_is_mounted(sbi))
4203 + if ((atomic_read(&sbi->s_opencount) > 1))
4207 + * Do an initial fsync_dev. We do this before locking the
4208 + * superblock to minimise the duration of the lock.
4210 + if (subfs_is_dirty(sbi)) {
4211 + fsync_dev(sb->s_dev);
4212 + mark_subfs_clean(sb);
4216 + * First thing is, has the filesystem been made
4217 + * read-write since it became active? If so, now is the
4218 + * time to retire it back to read-only state.
4221 + if (subfs_is_rw(sbi)) {
4222 + int retval = subfs_remount_ro(sb);
4225 + supermount_unlock_door(sb);
4226 + sbi->s_state = SUPERMOUNT_SUSPENDED;
4228 + atomic_dec(&sbi->s_opencount);
4233 + * Try to put the filesystem into writable mode for the duration of
4234 + * an open(O_RDWR) or an inode operation requiring write access.
4238 +subfs_get_write_access(struct super_block *sb)
4241 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4244 + if (!subfs_is_online(sbi))
4248 + if (atomic_read(&sbi->s_writecount) == 0) {
4250 + * We may already have write access to the filesystem
4252 + if (!subfs_is_rw(sbi)) {
4253 + if (sb->s_flags & MS_RDONLY)
4256 + retval = subfs_remount_rw(sb);
4261 + atomic_inc(&sbi->s_writecount);
4268 + * Once we're done, release write access.
4271 +subfs_put_write_access(struct super_block *sb)
4273 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4276 + if (!subfs_is_rw(sbi))
4279 + BUG_ON(atomic_read(&sbi->s_writecount) == 0);
4280 + atomic_dec(&sbi->s_writecount);
4284 +/* Supermount open/close inode. These functions maintain the
4285 + superblock reference counts of active inodes; the subfs is
4286 + suspended when that count reaches zero.
4288 + Files are opened on any significant reference, and are not closed
4289 + until they become fully dereferenced (during the last iput).
4290 + Directories, on the other hand, are always closed unless they are
4291 + active and opened; a directory referenced as CWD is not open.
4295 +subfs_get_read_access(struct super_block *sb)
4297 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4300 + BUG_ON(!subfs_is_online(sbi));
4301 + atomic_inc(&sbi->s_opencount);
4305 +/* we can't check here for subfs_is_online, because in the case of one
4306 + * error, system will call ->release() on inodes, where subfs is not
4311 +subfs_put_read_access(struct super_block *sb)
4313 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4316 + atomic_dec(&sbi->s_opencount);
4319 diff -Naurp linux-2.4.20-ck4/fs/supermount/supermount_i.h linux-2.4.20-ck5/fs/supermount/supermount_i.h
4320 --- linux-2.4.20-ck4/fs/supermount/supermount_i.h 1970-01-01 10:00:00.000000000 +1000
4321 +++ linux-2.4.20-ck5/fs/supermount/supermount_i.h 2003-04-08 10:52:51.000000000 +1000
4323 +#ifndef _SUPERMOUNT_I_H
4324 +#define _SUPERMOUNT_I_H
4326 +#define SUPERMOUNT_DEBUG
4329 + * The supermount superblock magic number
4332 +#define SUPERMOUNT_SUPER_MAGIC 0x9fa1
4335 +is_inode_supermounted(struct inode *inode)
4337 + return (inode->i_sb &&
4338 + (inode->i_sb->s_magic == SUPERMOUNT_SUPER_MAGIC));
4342 +is_dentry_supermounted(struct dentry *dentry)
4344 + return (dentry->d_inode && is_inode_supermounted(dentry->d_inode));
4347 +#define SUPERMOUNT_VERSION "0.7"
4350 + * The difference between SUSPENDED and ONLINE is that in SUSPENDED
4351 + * the door is unlocked, and in ONLINE it is locked.
4355 + SUPERMOUNT_UNMOUNTED, /* No media mounted */
4356 + SUPERMOUNT_SUSPENDED, /* Mounted but suspended because
4358 + SUPERMOUNT_ONLINE, /* Mounted and active */
4362 + * supermount super-block data in memory
4364 +struct supermount_sb_info {
4365 + sm_state_t s_state;
4366 + int s_version; /* Used to indicate obsolete inodes */
4367 + mode_t s_default_mode; /* Default mode for supermount root */
4369 + char *s_type; /* Type of fs to be sub-mounted */
4370 + char *s_devname; /* Where to mount the subfs from */
4372 + int s_mflags; /* Flags to pass when mounting subfs */
4373 + char *s_data; /* Data to pass when mounting subfs */
4374 + char *s_data_copy; /* copy of previous data. FS
4375 + destroy that data, and we
4376 + need to mount several
4377 + times. We could allocate
4379 + supermount_mount, but then
4380 + we have more possible
4382 + struct vfsmount *s_undermount; /* Mount point for subfs */
4383 + atomic_t s_opencount; /* Refcount of opened inodes
4384 + (an inode in use as cwd
4385 + does not count as open) */
4386 + atomic_t s_writecount; /* Refcount of write accesses
4387 + on the filesystem */
4389 + int s_dirty:1; /* Do we need to fsync() the subfs? */
4390 + int s_rw:1; /* Is the subfs mounted read/write? */
4391 + struct list_head s_inodes;
4392 + struct semaphore sem;
4395 +static inline struct supermount_inode_info *
4396 +supermount_i(struct inode *inode)
4398 + return (&inode->u.supermount_i);
4401 +static inline struct supermount_sb_info *
4402 +supermount_sbi(struct super_block *sb)
4406 + return (struct supermount_sb_info *) (sb->u.generic_sbp);
4409 +static inline struct super_block *
4410 +supermount_subfs_sb(struct supermount_sb_info *sbi)
4412 + return sbi->s_undermount->mnt_sb;
4416 + * Function prototypes
4419 +static inline struct file *
4420 +get_subfile(struct file *file)
4422 + struct file *subfile = (struct file *) file->private_data;
4429 +put_subfile(struct file *file, struct file *subfile)
4431 + file->private_data = (void *) subfile;
4434 +/* How to test if an inode is obsolete: */
4436 +is_inode_obsolete(struct inode *inode)
4438 + struct supermount_sb_info *sbi = supermount_sbi(inode->i_sb);
4440 + return (supermount_i(inode)->i_sb_version != sbi->s_version);
4443 +/* Manage the subfs dirty flag */
4445 +mark_subfs_dirty(struct super_block *sb)
4447 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4452 +mark_subfs_clean(struct super_block *sb)
4454 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4459 +subfs_is_dirty(struct supermount_sb_info *sbi)
4461 + return (sbi->s_dirty);
4464 +/* Manage the subfs rw flag */
4466 +mark_subfs_rw(struct super_block *sb)
4468 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4473 +unmark_subfs_rw(struct super_block *sb)
4475 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4480 +subfs_is_rw(struct supermount_sb_info *sbi)
4482 + return (sbi->s_rw);
4486 +subfs_is_online(struct supermount_sb_info *sbi)
4488 + return (sbi->s_state == SUPERMOUNT_ONLINE);
4492 +subfs_is_mounted(struct supermount_sb_info *sbi)
4494 + return (sbi->s_state != SUPERMOUNT_UNMOUNTED);
4498 +extern struct inode *supermount_create_inode(struct super_block *s);
4499 +extern void subfs_umount(struct super_block *sb);
4500 +extern int subfs_go_online(struct super_block *);
4501 +extern void subfs_go_inactive(struct super_block *);
4502 +extern int subfs_get_write_access(struct super_block *);
4503 +extern void subfs_put_write_access(struct super_block *);
4504 +extern void subfs_get_read_access(struct super_block *);
4505 +extern void subfs_put_read_access(struct super_block *);
4507 +extern struct dentry *get_subfs_dentry(struct dentry *dentry);
4508 +extern struct dentry *get_subfs_dentry_by_inode(struct inode *inode);
4510 +extern void supermount_handle_door(struct super_block *, int);
4512 +supermount_lock_door(struct super_block *sb)
4514 + supermount_handle_door(sb, MEDIA_LOCK);
4517 +supermount_unlock_door(struct super_block *sb)
4519 + supermount_handle_door(sb, MEDIA_UNLOCK);
4522 +/* inode_operations.c */
4523 +extern struct inode_operations supermount_root_iops;
4524 +extern struct inode_operations supermount_dir_iops;
4525 +extern struct inode_operations supermount_file_iops;
4526 +extern struct inode_operations supermount_symlink_iops;
4527 +/* super_operations.c */
4528 +extern struct super_block *supermount_read_super(struct super_block *,
4530 +/* file_operations.c */
4531 +extern struct file_operations supermount_dir_operations;
4532 +extern struct file_operations supermount_file_operations;
4533 +/* dentry_operations.c */
4534 +extern struct dentry_operations supermount_file_dops;
4535 +extern struct dentry_operations supermount_dir_dops;
4537 +#endif /* _SUPERMOUNT_I_H */
4538 diff -Naurp linux-2.4.20-ck4/fs/supermount/super_operations.c linux-2.4.20-ck5/fs/supermount/super_operations.c
4539 --- linux-2.4.20-ck4/fs/supermount/super_operations.c 1970-01-01 10:00:00.000000000 +1000
4540 +++ linux-2.4.20-ck5/fs/supermount/super_operations.c 2003-04-08 10:52:51.000000000 +1000
4543 + * linux/fs/supermount/super_operations.c
4545 + * Original version:
4546 + * Copyright (C) 1995, 1997
4547 + * Stephen Tweedie (sct@dcs.ed.ac.uk)
4551 + * linux/fs/minix/inode.c
4552 + * Copyright (C) 1991, 1992 Linus Torvalds
4556 + * linux/fs/ext2/super.c
4557 + * Copyright (C) 1992, 1993, 1994, 1995 Remy Card
4559 + * Rewriten for kernel 2.2, 2.4. (C) 1999, 2000 Alexis Mikhailov
4560 + * (alexis@abc.cap.ru)
4564 +#include <linux/errno.h>
4565 +#include <linux/fs.h>
4566 +#include <linux/list.h>
4567 +#include <linux/slab.h>
4569 +#include "supermount_i.h"
4571 +static struct super_operations supermount_sops;
4574 +supermount_write_inode(struct inode *inode, int sync)
4576 + struct supermount_sb_info *sbi = supermount_sbi(inode->i_sb);
4577 + struct super_block *subsb;
4578 + struct dentry *dent;
4579 + struct inode *subi;
4582 + if (subfs_go_online(inode->i_sb))
4586 + dent = get_subfs_dentry_by_inode(inode);
4589 + subi = dent->d_inode;
4592 + subsb = supermount_subfs_sb(sbi);
4593 + if (subi && subsb && subsb->s_op && subsb->s_op->write_inode) {
4594 + subi->i_mode = inode->i_mode;
4595 + subi->i_uid = inode->i_uid;
4596 + subi->i_gid = inode->i_gid;
4597 + subi->i_size = inode->i_size;
4598 + subi->i_atime = inode->i_atime;
4599 + subi->i_mtime = inode->i_mtime;
4600 + subi->i_ctime = inode->i_ctime;
4601 + rc = subfs_get_write_access(inode->i_sb);
4604 + subi->i_state |= I_LOCK;
4605 + subsb->s_op->write_inode(subi, sync);
4606 + subi->i_state &= ~I_LOCK;
4607 + mark_subfs_dirty(inode->i_sb);
4608 + subfs_put_write_access(inode->i_sb);
4613 + subfs_go_inactive(inode->i_sb);
4617 +supermount_clear_inode(struct inode *inode)
4619 + dput(supermount_i(inode)->i_dentry);
4620 + list_del(&supermount_i(inode)->i_fs);
4623 +static struct supermount_sb_info *
4624 +create_sbi(struct super_block *sb)
4626 + struct supermount_sb_info *sbi = kmalloc(sizeof (*sbi), GFP_KERNEL);
4631 + memset(sbi, 0, sizeof (*sbi));
4633 + sbi->s_state = SUPERMOUNT_UNMOUNTED;
4634 + sbi->s_default_mode = 0777 | S_IFDIR;
4635 + atomic_set(&sbi->s_opencount, 0);
4636 + atomic_set(&sbi->s_writecount, 0);
4637 + sbi->s_mflags = sb->s_flags & MS_RMT_MASK;
4638 + INIT_LIST_HEAD(&sbi->s_inodes);
4639 + sema_init(&sbi->sem, 1);
4644 +free_sbi(struct supermount_sb_info *sbi)
4647 + kfree(sbi->s_type);
4648 + if (sbi->s_devname)
4649 + kfree(sbi->s_devname);
4651 + kfree(sbi->s_data);
4652 + if (sbi->s_data_copy)
4653 + kfree(sbi->s_data_copy);
4658 +/* Release the superblock and any resources it has reserved
4659 + * it is called with the sb locked
4663 +supermount_put_super(struct super_block *sb)
4665 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4667 + if (subfs_is_mounted(sbi))
4670 + sb->u.generic_sbp = 0;
4676 +copy_option(char **option, const char *val)
4679 + if (!val || !*val)
4681 + tmp = kmalloc(1 + strlen(val), GFP_KERNEL);
4690 +parse_options(char *options, struct supermount_sb_info *sbi)
4698 + while ((this_char = options)) {
4699 + if (!strncmp(this_char, "--", 2))
4703 + if (*this_char == ',') {
4704 + /* An empty option, or the option "--",
4705 + introduces options to be passed through to
4707 + return copy_option(&sbi->s_data, ++this_char);
4709 + if ((options = strchr(this_char, ',')))
4712 + if ((value = strchr(this_char, '=')))
4715 + if (!strcmp(this_char, "fs")) {
4716 + rc = copy_option(&sbi->s_type, value);
4719 + } else if (!strcmp(this_char, "dev")) {
4720 + rc = copy_option(&sbi->s_devname, value);
4724 + printk(KERN_DEBUG "Unrecognized mount option %s",
4732 +static struct inode *
4733 +supermount_root_inode(struct super_block *s)
4735 + struct inode *inode = supermount_create_inode(s);
4740 + inode->i_version = 0;
4741 + inode->i_op = &supermount_root_iops;
4742 + inode->i_fop = &supermount_dir_operations;
4747 +/* read_super: the main mount() entry point into the VFS layer. */
4748 +struct super_block *
4749 +supermount_read_super(struct super_block *s, void *data, int silent)
4751 + struct inode *root_inode;
4752 + struct dentry *root;
4753 + struct supermount_sb_info *sbi = create_sbi(s);
4756 + goto fail_no_memory;
4758 + if (parse_options((char *) data, sbi))
4759 + goto fail_free_sbi;
4761 + if (!sbi->s_devname) {
4762 + printk(KERN_ERR "%s: no dev=<filesystem> option", __FUNCTION__);
4763 + goto fail_free_sbi;
4765 + if (sbi->s_data) {
4766 + sbi->s_data_copy = kmalloc(1 + strlen(sbi->s_data), GFP_KERNEL);
4767 + if (!sbi->s_data_copy) {
4768 + printk(KERN_ERR "%s: not enough memory", __FUNCTION__);
4769 + goto fail_free_sbi;
4771 + strcpy(sbi->s_data_copy, sbi->s_data);
4773 + sbi->s_data_copy = NULL;
4775 + s->s_blocksize = 1024;
4776 + s->s_blocksize_bits = 10;
4777 + s->s_magic = SUPERMOUNT_SUPER_MAGIC;
4778 + s->s_op = &supermount_sops;
4779 + s->u.generic_sbp = sbi;
4781 + root_inode = supermount_root_inode(s);
4783 + goto fail_free_sbi;
4785 + root = d_alloc_root(root_inode);
4787 + goto fail_free_root_inode;
4790 + s->s_root->d_op = &supermount_dir_dops;
4795 +fail_free_root_inode:
4805 + * called with lock_super held
4809 +supermount_write_super(struct super_block *sb)
4811 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4813 + if (subfs_is_online(sbi) && subfs_is_rw(sbi)) {
4814 + struct super_block *subsb = supermount_subfs_sb(sbi);
4815 + if (subsb && subsb->s_op && subsb->s_op->write_super)
4816 + subsb->s_op->write_super(subsb);
4817 + mark_subfs_clean(sb);
4822 +supermount_statfs(struct super_block *sb, struct statfs *buf)
4825 + struct supermount_sb_info *sbi = supermount_sbi(sb);
4827 + if (subfs_is_online(sbi)) {
4828 + struct super_block *subsb = supermount_subfs_sb(sbi);
4829 + if (subsb->s_op && subsb->s_op->statfs)
4830 + rc = subsb->s_op->statfs(subsb, buf);
4832 + buf->f_type = SUPERMOUNT_SUPER_MAGIC;
4836 +static struct super_operations supermount_sops = {
4837 + .write_inode = supermount_write_inode,
4838 + .clear_inode = supermount_clear_inode,
4839 + .put_super = supermount_put_super,
4840 + .write_super = supermount_write_super,
4841 + .statfs = supermount_statfs,
4843 diff -Naurp linux-2.4.20-ck4/fs/supermount/translation.c linux-2.4.20-ck5/fs/supermount/translation.c
4844 --- linux-2.4.20-ck4/fs/supermount/translation.c 1970-01-01 10:00:00.000000000 +1000
4845 +++ linux-2.4.20-ck5/fs/supermount/translation.c 2003-04-08 10:52:51.000000000 +1000
4848 + * linux/fs/supermount/translate.c
4850 + * Original version:
4851 + * Copyright (C) 1995, 1997
4852 + * Stephen Tweedie (sct@dcs.ed.ac.uk)
4856 + * linux/fs/minix/dir.c
4857 + * Copyright (C) 1991, 1992 Linus Torvalds
4861 + * linux/fs/ext2/dir.c
4862 + * Copyright (C) 1992, 1993, 1994, 1995 Remy Card
4864 + * Rewriten for kernel 2.2 & 2.4. (C) 1999, 2000 Alexis Mikhailov
4865 + * (alexis@abc.cap.ru)
4866 + * Rewriten for kernel 2.4. (C) 2001 MandrakeSoft Inc.
4867 + * Juan Quintela (quintela@mandrakesoft.com)
4871 +#include <linux/errno.h>
4872 +#include <linux/fs.h>
4873 +#include <linux/slab.h>
4874 +#include <linux/string.h>
4876 +#include "supermount_i.h"
4879 +unwalk_dentry(struct dentry *dentry, char *name)
4885 + path = name + PATH_MAX;
4888 + spin_lock(&dcache_lock);
4890 + if (dentry->d_parent == dentry)
4892 + path -= dentry->d_name.len + 1;
4895 + memcpy(path + 1, dentry->d_name.name, dentry->d_name.len);
4898 + dentry = dentry->d_parent;
4900 + spin_unlock(&dcache_lock);
4902 + /* we need to removing leading '\0' */
4906 + while (path <= name + PATH_MAX)
4912 + spin_unlock(&dcache_lock);
4916 +static struct dentry *
4917 +walk_path(struct dentry *root, char *path, int number)
4919 + struct dentry *base = root;
4921 + while (number-- && !IS_ERR(base)) {
4922 + struct dentry *subdent;
4923 + int len = strlen(path);
4924 + subdent = lookup_one_len(path, base, len);
4932 +static struct dentry *
4933 +__get_subfs_dentry(struct dentry *dentry)
4935 + struct supermount_sb_info *sbi;
4936 + struct dentry *subdent = ERR_PTR(-EINVAL);
4937 + struct dentry *root;
4940 + struct vfsmount *mnt;
4942 + name = __getname();
4944 + return ERR_PTR(-ENOMEM);
4946 + sbi = supermount_sbi(dentry->d_sb);
4947 + number = unwalk_dentry(dentry, name);
4949 + subdent = ERR_PTR(number);
4952 + mnt = mntget(sbi->s_undermount);
4956 + root = dget(mnt->mnt_sb->s_root);
4957 + subdent = walk_path(root, name, number);
4965 +get_subfs_dentry_by_inode(struct inode *inode)
4967 + struct dentry *dentry;
4968 + struct supermount_sb_info *sbi;
4971 + BUG_ON(!is_inode_supermounted(inode));
4973 + if (is_inode_obsolete(inode))
4974 + return ERR_PTR(-ESTALE);
4976 + sbi = supermount_sbi(inode->i_sb);
4977 + if (!subfs_is_mounted(sbi))
4978 + return ERR_PTR(-EINVAL);
4980 + dentry = dget(supermount_i(inode)->i_dentry);
4988 +get_subfs_dentry(struct dentry *dentry)
4990 + struct dentry *subdent;
4993 + BUG_ON(dentry->d_inode && !is_dentry_supermounted(dentry));
4995 + if (dentry->d_inode && !is_inode_obsolete(dentry->d_inode))
4996 + subdent = get_subfs_dentry_by_inode(dentry->d_inode);
4998 + subdent = __get_subfs_dentry(dentry);
5002 diff -Naurp linux-2.4.20-ck4/fs/udf/super.c linux-2.4.20-ck5/fs/udf/super.c
5003 --- linux-2.4.20-ck4/fs/udf/super.c 2002-08-03 13:14:59.000000000 +1000
5004 +++ linux-2.4.20-ck5/fs/udf/super.c 2003-04-08 10:52:51.000000000 +1000
5005 @@ -268,6 +268,11 @@ udf_parse_options(char *options, struct
5006 uopt->nls_map = load_nls(val);
5007 uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
5009 +#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
5010 + /* Silently ignore NLS option */
5011 + else if (!strcmp (opt, "codepage"))
5012 + /* Don't do anything ;-) */ ;
5015 else if (!strcmp(opt, "utf8") && !val)
5016 uopt->flags |= (1 << UDF_FLAG_UTF8);
5017 diff -Naurp linux-2.4.20-ck4/include/linux/cdrom.h linux-2.4.20-ck5/include/linux/cdrom.h
5018 --- linux-2.4.20-ck4/include/linux/cdrom.h 2001-11-23 06:47:04.000000000 +1100
5019 +++ linux-2.4.20-ck5/include/linux/cdrom.h 2003-04-08 10:52:51.000000000 +1000
5020 @@ -781,6 +781,7 @@ extern int cdrom_open(struct inode *, st
5021 extern int cdrom_release(struct inode *, struct file *);
5022 extern int cdrom_ioctl(struct inode *, struct file *, unsigned, unsigned long);
5023 extern int cdrom_media_changed(kdev_t);
5024 +extern int cdrom_mediactl (kdev_t dev, int op, int optarg);
5026 extern int register_cdrom(struct cdrom_device_info *cdi);
5027 extern int unregister_cdrom(struct cdrom_device_info *cdi);
5028 diff -Naurp linux-2.4.20-ck4/include/linux/fs.h linux-2.4.20-ck5/include/linux/fs.h
5029 --- linux/include/linux/fs.h.orig Mon Apr 14 09:03:15 2003
5030 +++ linux/include/linux/fs.h Sat Apr 19 11:11:59 2003
5032 #define MS_REC 16384
5033 #define MS_VERBOSE 32768
5034 #define MS_POSIXACL 65536 /* VFS does not apply the umask */
5035 +#define MS_SUPERMOUNTED (1<<17)
5036 #define MS_ACTIVE (1<<30)
5037 #define MS_NOUSER (1<<31)
5042 #include <linux/pipe_fs_i.h>
5043 +#include <linux/supermount_fs_i.h>
5044 #include <linux/minix_fs_i.h>
5045 #include <linux/ext2_fs_i.h>
5046 #include <linux/ext3_fs_i.h>
5048 struct usbdev_inode_info usbdev_i;
5049 struct jffs2_inode_info jffs2_i;
5050 struct squashfs_inode_info squashfs_i;
5051 + struct supermount_inode_info supermount_i;
5056 * non-directories) are allowed, but not unconnected diretories.
5058 struct semaphore s_nfsd_free_path_sem;
5059 +#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
5060 + int s_media_changed;
5065 @@ -825,6 +831,23 @@
5066 extern int vfs_unlink(struct inode *, struct dentry *);
5067 extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
5082 + unsigned long blksize;
5083 + unsigned long blocks;
5089 @@ -853,6 +876,16 @@
5090 int (*check_media_change) (kdev_t);
5091 int (*revalidate) (kdev_t);
5092 struct module *owner;
5093 + int (*mediactl) (kdev_t dev, int op, int optarg);
5097 + * These are the "op" operation codes for mediactl() media control
5098 + * calls for device special files
5101 + MEDIA_LOCK = 1234, /* Lock the drive door */
5102 + MEDIA_UNLOCK /* Unlock the drive door */
5107 int (*permission) (struct inode *, int);
5108 int (*revalidate) (struct dentry *);
5109 int (*setattr) (struct dentry *, struct iattr *);
5110 - int (*getattr) (struct dentry *, struct iattr *);
5111 + int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
5112 int (*setxattr) (struct dentry *, const char *, const void *, size_t, int);
5113 ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
5114 ssize_t (*listxattr) (struct dentry *, char *, size_t);
5115 @@ -1030,6 +1063,8 @@
5116 extern struct vfsmount *kern_mount(struct file_system_type *);
5117 extern int may_umount(struct vfsmount *);
5118 extern long do_mount(char *, char *, char *, unsigned long, void *);
5119 +extern struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data);
5120 +extern int do_remount_sb(struct super_block *sb, int flags, void * data);
5122 #define kern_umount mntput
5124 @@ -1254,8 +1289,11 @@
5125 extern void set_buffer_flushtime(struct buffer_head *);
5126 extern void balance_dirty(void);
5127 extern int check_disk_change(kdev_t);
5128 +extern int query_disk_change(kdev_t dev);
5129 +extern void invalidate_media(kdev_t dev);
5130 extern int invalidate_inodes(struct super_block *);
5131 extern int invalidate_device(kdev_t, int);
5132 +extern int destroy_device(kdev_t);
5133 extern void invalidate_inode_pages(struct inode *);
5134 extern void invalidate_inode_pages2(struct address_space *);
5135 extern void invalidate_inode_buffers(struct inode *);
5136 @@ -1516,12 +1554,14 @@
5137 extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
5138 extern loff_t no_llseek(struct file *file, loff_t offset, int origin);
5139 extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
5140 +extern loff_t vfs_llseek(struct file *file, loff_t loffset, int origin);
5141 extern ssize_t generic_read_dir(struct file *, char *, size_t, loff_t *);
5142 extern int generic_file_open(struct inode * inode, struct file * filp);
5144 extern struct file_operations generic_ro_fops;
5146 extern int vfs_readlink(struct dentry *, char *, int, const char *);
5147 +extern int vfs_readlink_real(struct dentry *, char *, int);
5148 extern int vfs_follow_link(struct nameidata *, const char *);
5149 extern int page_readlink(struct dentry *, char *, int);
5150 extern int page_follow_link(struct dentry *, struct nameidata *);
5151 @@ -1535,6 +1575,13 @@
5152 extern int dcache_readdir(struct file *, void *, filldir_t);
5153 extern struct file_operations dcache_dir_ops;
5155 +int getattr_full(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
5156 +int getattr_minix(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
5158 +extern int vfs_stat(char *, struct kstat *);
5159 +extern int vfs_lstat(char *, struct kstat *);
5160 +extern int vfs_fstat(int, struct kstat *);
5162 extern struct file_system_type *get_fs_type(const char *name);
5163 extern struct super_block *get_super(kdev_t);
5164 extern void drop_super(struct super_block *sb);
5165 diff -Naurp linux-2.4.20-ck4/include/linux/ide.h linux-2.4.20-ck5/include/linux/ide.h
5166 --- linux-2.4.20-ck4/include/linux/ide.h 2002-11-30 17:02:23.000000000 +1100
5167 +++ linux-2.4.20-ck5/include/linux/ide.h 2003-04-08 10:52:51.000000000 +1000
5168 @@ -726,6 +726,7 @@ typedef struct ide_driver_s {
5169 ide_special_proc *special;
5170 ide_proc_entry_t *proc;
5171 ide_reinit_proc *reinit;
5172 + int (*mediactl)(ide_drive_t *, int, int);
5173 ata_prebuilder_proc *ata_prebuilder;
5174 atapi_prebuilder_proc *atapi_prebuilder;
5176 @@ -1062,6 +1063,7 @@ int idedisk_init (void);
5177 #ifdef CONFIG_BLK_DEV_IDECD
5178 int ide_cdrom_reinit (ide_drive_t *drive);
5179 int ide_cdrom_init (void);
5180 +int ide_cdrom_mediactl (ide_drive_t *, int, int);
5181 #endif /* CONFIG_BLK_DEV_IDECD */
5182 #ifdef CONFIG_BLK_DEV_IDETAPE
5183 int idetape_reinit (ide_drive_t *drive);
5184 diff -Naurp linux-2.4.20-ck4/include/linux/supermount_fs_i.h linux-2.4.20-ck5/include/linux/supermount_fs_i.h
5185 --- linux-2.4.20-ck4/include/linux/supermount_fs_i.h 1970-01-01 10:00:00.000000000 +1000
5186 +++ linux-2.4.20-ck5/include/linux/supermount_fs_i.h 2003-04-08 10:52:51.000000000 +1000
5188 +#ifndef _LINUX_SUPERMOUNT_FS_I_H
5189 +#define _LINUX_SUPERMOUNT_FS_I_H
5191 +struct supermount_inode_info {
5193 + struct dentry * i_dentry;
5194 + struct list_head i_fs;
5198 diff -Naurp linux-2.4.20-ck4/kernel/ksyms.c linux-2.4.20-ck5/kernel/ksyms.c
5199 --- linux-2.4.20-ck4/kernel/ksyms.c 2003-04-08 10:50:37.000000000 +1000
5200 +++ linux-2.4.20-ck5/kernel/ksyms.c 2003-04-08 10:52:51.000000000 +1000
5201 @@ -177,10 +177,13 @@ EXPORT_SYMBOL(filp_close);
5202 EXPORT_SYMBOL(put_filp);
5203 EXPORT_SYMBOL(files_lock);
5204 EXPORT_SYMBOL(check_disk_change);
5205 +EXPORT_SYMBOL(query_disk_change);
5206 +EXPORT_SYMBOL(invalidate_media);
5207 EXPORT_SYMBOL(__invalidate_buffers);
5208 EXPORT_SYMBOL(invalidate_bdev);
5209 EXPORT_SYMBOL(invalidate_inodes);
5210 EXPORT_SYMBOL(invalidate_device);
5211 +EXPORT_SYMBOL(destroy_device);
5212 EXPORT_SYMBOL(invalidate_inode_pages);
5213 EXPORT_SYMBOL(truncate_inode_pages);
5214 EXPORT_SYMBOL(fsync_dev);
5215 @@ -254,9 +257,12 @@ EXPORT_SYMBOL(vfs_rmdir);
5216 EXPORT_SYMBOL(vfs_unlink);
5217 EXPORT_SYMBOL(vfs_rename);
5218 EXPORT_SYMBOL(vfs_statfs);
5219 +EXPORT_SYMBOL(getattr_full);
5220 +EXPORT_SYMBOL(getattr_minix);
5221 EXPORT_SYMBOL(generic_read_dir);
5222 EXPORT_SYMBOL(generic_file_llseek);
5223 EXPORT_SYMBOL(no_llseek);
5224 +EXPORT_SYMBOL(vfs_llseek);
5225 EXPORT_SYMBOL(__pollwait);
5226 EXPORT_SYMBOL(poll_freewait);
5227 EXPORT_SYMBOL(ROOT_DEV);
5228 @@ -267,6 +273,7 @@ EXPORT_SYMBOL(grab_cache_page_nowait);
5229 EXPORT_SYMBOL(read_cache_page);
5230 EXPORT_SYMBOL(set_page_dirty);
5231 EXPORT_SYMBOL(vfs_readlink);
5232 +EXPORT_SYMBOL(vfs_readlink_real);
5233 EXPORT_SYMBOL(vfs_follow_link);
5234 EXPORT_SYMBOL(page_readlink);
5235 EXPORT_SYMBOL(page_follow_link);
5236 @@ -300,6 +307,7 @@ EXPORT_SYMBOL(register_chrdev);
5237 EXPORT_SYMBOL(unregister_chrdev);
5238 EXPORT_SYMBOL(register_blkdev);
5239 EXPORT_SYMBOL(unregister_blkdev);
5240 +EXPORT_SYMBOL(get_blkfops);
5241 EXPORT_SYMBOL(tty_register_driver);
5242 EXPORT_SYMBOL(tty_unregister_driver);
5243 EXPORT_SYMBOL(tty_std_termios);
5244 @@ -341,6 +349,8 @@ EXPORT_SYMBOL(unregister_filesystem);
5245 EXPORT_SYMBOL(kern_mount);
5246 EXPORT_SYMBOL(__mntput);
5247 EXPORT_SYMBOL(may_umount);
5248 +EXPORT_SYMBOL(do_kern_mount);
5249 +EXPORT_SYMBOL(do_remount_sb);
5251 /* executable format registration */
5252 EXPORT_SYMBOL(register_binfmt);