diff -NurpP --minimal linux-2.6.12.2-vs2.0-rc5/fs/devpts/inode.c linux-2.6.12.2-vs2.0-rc5.1/fs/devpts/inode.c --- linux-2.6.12.2-vs2.0-rc5/fs/devpts/inode.c 2005-07-02 22:38:30 +0200 +++ linux-2.6.12.2-vs2.0-rc5.1/fs/devpts/inode.c 2005-07-05 02:16:19 +0200 @@ -96,58 +96,14 @@ static int devpts_remount(struct super_b return 0; } -static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir) +static int devpts_filter(struct dentry *de) { - struct dentry *dentry = filp->f_dentry; - struct dentry *cursor = filp->private_data; - struct list_head *p, *q = &cursor->d_child; - ino_t ino; - int i = filp->f_pos; - - switch (i) { - case 0: - ino = dentry->d_inode->i_ino; - if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) - break; - filp->f_pos++; - i++; - /* fallthrough */ - case 1: - ino = parent_ino(dentry); - if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0) - break; - filp->f_pos++; - i++; - /* fallthrough */ - default: - spin_lock(&dcache_lock); - if (filp->f_pos == 2) { - list_del(q); - list_add(q, &dentry->d_subdirs); - } - for (p=q->next; p != &dentry->d_subdirs; p=p->next) { - struct dentry *next; - next = list_entry(p, struct dentry, d_child); - if (d_unhashed(next) || !next->d_inode) - continue; - if (!vx_check(next->d_inode->i_xid, VX_IDENT)) - continue; + return vx_check(de->d_inode->i_xid, VX_IDENT); +} - spin_unlock(&dcache_lock); - if (filldir(dirent, next->d_name.name, - next->d_name.len, filp->f_pos, - next->d_inode->i_ino, DT_CHR) < 0) - return 0; - spin_lock(&dcache_lock); - /* next is still alive */ - list_del(q); - list_add(q, p); - p = q; - filp->f_pos++; - } - spin_unlock(&dcache_lock); - } - return 0; +static int devpts_readdir(struct file * filp, void * dirent, filldir_t filldir) +{ + return dcache_readdir_filter(filp, dirent, filldir, devpts_filter); } static struct file_operations devpts_dir_operations = { diff -NurpP --minimal linux-2.6.12.2-vs2.0-rc5/fs/libfs.c linux-2.6.12.2-vs2.0-rc5.1/fs/libfs.c --- linux-2.6.12.2-vs2.0-rc5/fs/libfs.c 2005-03-02 12:38:44 +0100 +++ linux-2.6.12.2-vs2.0-rc5.1/fs/libfs.c 2005-07-05 02:13:21 +0200 @@ -122,7 +122,8 @@ static inline unsigned char dt_type(stru * both impossible due to the lock on directory. */ -int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) +int dcache_readdir_filter(struct file * filp, void * dirent, filldir_t filldir, + int (*filter)(struct dentry *dentry)) { struct dentry *dentry = filp->f_dentry; struct dentry *cursor = filp->private_data; @@ -156,6 +157,8 @@ int dcache_readdir(struct file * filp, v next = list_entry(p, struct dentry, d_child); if (d_unhashed(next) || !next->d_inode) continue; + if (filter && !filter(next)) + continue; spin_unlock(&dcache_lock); if (filldir(dirent, next->d_name.name, next->d_name.len, filp->f_pos, next->d_inode->i_ino, dt_type(next->d_inode)) < 0) @@ -172,6 +175,12 @@ int dcache_readdir(struct file * filp, v return 0; } +int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir) +{ + return dcache_readdir_filter(filp, dirent, filldir, NULL); +} + + ssize_t generic_read_dir(struct file *filp, char __user *buf, size_t siz, loff_t *ppos) { return -EISDIR; diff -NurpP --minimal linux-2.6.12.2-vs2.0-rc5/include/linux/fs.h linux-2.6.12.2-vs2.0-rc5.1/include/linux/fs.h --- linux-2.6.12.2-vs2.0-rc5/include/linux/fs.h 2005-07-02 22:38:30 +0200 +++ linux-2.6.12.2-vs2.0-rc5.1/include/linux/fs.h 2005-07-05 02:17:32 +0200 @@ -1595,6 +1595,7 @@ extern int dcache_dir_open(struct inode extern int dcache_dir_close(struct inode *, struct file *); extern loff_t dcache_dir_lseek(struct file *, loff_t, int); extern int dcache_readdir(struct file *, void *, filldir_t); +extern int dcache_readdir_filter(struct file *, void *, filldir_t, int (*)(struct dentry *)); extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int simple_statfs(struct super_block *, struct kstatfs *); extern int simple_link(struct dentry *, struct inode *, struct dentry *);