The new cramfs_unlink function replaces an existing dentry with a pinned negative dentry in cramfs, so that lookup does not find it any more. The readdir function gets changed here to no longer show the file if a negative dentry exists. Signed-off-by: Arnd Bergmann --- fs/cramfs/inode.c | 27 ++++++++++++++++++++++++++- 1 files changed, 26 insertions(+), 1 deletions(-) diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 8aa04d7..6b9f21f 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -348,12 +348,14 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) copied = 0; while (offset < inode->i_size) { + struct qstr qstr = { .name = buf, }; struct cramfs_inode *de; unsigned long nextoffset; char *name; ino_t ino; mode_t mode; int namelen, error; + struct dentry *dentry; mutex_lock(&read_mutex); de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN); @@ -379,7 +381,15 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) break; namelen--; } - error = filldir(dirent, buf, namelen, offset, ino, mode >> 12); + qstr.len = namelen; + dentry = d_hash_and_lookup(filp->f_path.dentry, &qstr); + + error = 0; + if (!dentry || (dentry->d_inode)) + error = filldir(dirent, buf, namelen, offset, + ino, mode >> 12); + + dput(dentry); if (error) break; @@ -391,6 +401,19 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) return 0; } +int cramfs_unlink(struct inode *dir, struct dentry *dentry) +{ + struct inode *inode = dentry->d_inode; + struct dentry *new; + + inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; + drop_nlink(inode); + new = d_alloc(dentry->d_parent, &dentry->d_name); + d_add(new, NULL); + + dget(dentry); + return 0; +} /* * Lookup and fill in the inode data.. */ @@ -512,10 +535,12 @@ static const struct file_operations cramfs_directory_operations = { }; static const struct inode_operations cramfs_dir_inode_operations = { + .unlink = cramfs_unlink, .lookup = cramfs_lookup, }; static const struct super_operations cramfs_ops = { + .drop_inode = generic_delete_inode, .put_super = cramfs_put_super, .remount_fs = cramfs_remount, .statfs = cramfs_statfs, -- 1.5.4.3 -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/