Hi, I'd just like to ask you to look at autofs4 in the context of this change. I don't really know what needs to be considered there. If this is a generally visible dentry that any other users may mount filesystems on, then this might be difficult to get working here. I'm not quite sure what games you're playing here with d_mounted... In the simplest case we might be able to just remove DCACHE_MOUNTED. Anyway this would be great if we can make it work so I can replace the member with d_seq for my path walk patches and not bloat dentry. Can you take a look please if you have a chance? -- XXX: breaks autofs4, have to work out what it is doing. We can get a mounted count if needed by counting the hashtable. --- fs/dcache.c | 1 - fs/namespace.c | 19 +++++++++++++++---- include/linux/dcache.h | 42 +++++++++++++++++++++--------------------- 3 files changed, 36 insertions(+), 26 deletions(-) Index: linux-2.6/fs/dcache.c =================================================================== --- linux-2.6.orig/fs/dcache.c +++ linux-2.6/fs/dcache.c @@ -1192,7 +1192,6 @@ struct dentry *d_alloc(struct dentry * p dentry->d_sb = NULL; dentry->d_op = NULL; dentry->d_fsdata = NULL; - dentry->d_mounted = 0; INIT_HLIST_NODE(&dentry->d_hash); INIT_LIST_HEAD(&dentry->d_lru); INIT_LIST_HEAD(&dentry->d_subdirs); Index: linux-2.6/fs/namespace.c =================================================================== --- linux-2.6.orig/fs/namespace.c +++ linux-2.6/fs/namespace.c @@ -574,6 +574,15 @@ static void __touch_mnt_namespace(struct } } +static void dentry_reset_mounted(struct vfsmount *mnt, struct dentry *dentry) +{ + if (!__lookup_mnt(mnt, dentry, 0)) { + spin_lock(&dentry->d_lock); + dentry->d_flags &= ~DCACHE_MOUNTED; + spin_unlock(&dentry->d_lock); + } +} + static void detach_mnt(struct vfsmount *mnt, struct path *old_path) { old_path->dentry = mnt->mnt_mountpoint; @@ -582,7 +591,7 @@ static void detach_mnt(struct vfsmount * mnt->mnt_mountpoint = mnt->mnt_root; list_del_init(&mnt->mnt_hash); list_del_init(&mnt->mnt_child); - old_path->dentry->d_mounted--; + dentry_reset_mounted(old_path->mnt, old_path->dentry); WARN_ON(mnt->mnt_mounted != 1); mnt->mnt_mounted--; } @@ -591,8 +600,10 @@ void mnt_set_mountpoint(struct vfsmount struct vfsmount *child_mnt) { child_mnt->mnt_parent = mntget(mnt); - child_mnt->mnt_mountpoint = dget(dentry); - dentry->d_mounted++; + spin_lock(&dentry->d_lock); + child_mnt->mnt_mountpoint = dget_dlock(dentry); + dentry->d_flags |= DCACHE_MOUNTED; + spin_unlock(&dentry->d_lock); } static void attach_mnt(struct vfsmount *mnt, struct path *path) @@ -1170,7 +1181,7 @@ void umount_tree(struct vfsmount *mnt, i p->mnt_mounted--; if (p->mnt_parent != p) { p->mnt_parent->mnt_ghosts++; - p->mnt_mountpoint->d_mounted--; + dentry_reset_mounted(p->mnt_parent, p->mnt_mountpoint); } change_mnt_propagation(p, MS_PRIVATE); } Index: linux-2.6/include/linux/dcache.h =================================================================== --- linux-2.6.orig/include/linux/dcache.h +++ linux-2.6/include/linux/dcache.h @@ -83,14 +83,13 @@ full_name_hash(const unsigned char *name #ifdef CONFIG_64BIT #define DNAME_INLINE_LEN_MIN 32 /* 192 bytes */ #else -#define DNAME_INLINE_LEN_MIN 40 /* 128 bytes */ +#define DNAME_INLINE_LEN_MIN 44 /* 128 bytes */ #endif struct dentry { unsigned int d_count; /* protected by d_lock */ unsigned int d_flags; /* protected by d_lock */ spinlock_t d_lock; /* per dentry lock */ - int d_mounted; struct inode *d_inode; /* Where the name belongs to - NULL is * negative */ /* @@ -161,30 +160,31 @@ d_iput: no no yes /* d_flags entries */ #define DCACHE_AUTOFS_PENDING 0x0001 /* autofs: "under construction" */ -#define DCACHE_NFSFS_RENAMED 0x0002 /* this dentry has been "silly - * renamed" and has to be - * deleted on the last dput() - */ -#define DCACHE_DISCONNECTED 0x0004 - /* This dentry is possibly not currently connected to the dcache tree, - * in which case its parent will either be itself, or will have this - * flag as well. nfsd will not use a dentry with this bit set, but will - * first endeavour to clear the bit either by discovering that it is - * connected, or by performing lookup operations. Any filesystem which - * supports nfsd_operations MUST have a lookup function which, if it finds - * a directory inode with a DCACHE_DISCONNECTED dentry, will d_move - * that dentry into place and return that dentry rather than the passed one, - * typically using d_splice_alias. - */ +#define DCACHE_NFSFS_RENAMED 0x0002 + /* this dentry has been "silly renamed" and has to be deleted on the last + * dput() */ + +#define DCACHE_DISCONNECTED 0x0004 + /* This dentry is possibly not currently connected to the dcache tree, in + * which case its parent will either be itself, or will have this flag as + * well. nfsd will not use a dentry with this bit set, but will first + * endeavour to clear the bit either by discovering that it is connected, + * or by performing lookup operations. Any filesystem which supports + * nfsd_operations MUST have a lookup function which, if it finds a + * directory inode with a DCACHE_DISCONNECTED dentry, will d_move that + * dentry into place and return that dentry rather than the passed one, + * typically using d_splice_alias. */ #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ #define DCACHE_UNHASHED 0x0010 - -#define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched by inotify */ +#define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 + /* Parent inode is watched by inotify */ #define DCACHE_COOKIE 0x0040 /* For use by dcookie subsystem */ +#define DCACHE_FSNOTIFY_PARENT_WATCHED 0x0080 + /* Parent inode is watched by some fsnotify listener */ -#define DCACHE_FSNOTIFY_PARENT_WATCHED 0x0080 /* Parent inode is watched by some fsnotify listener */ +#define DCACHE_MOUNTED 0x0100 /* is a mountpoint */ extern seqlock_t rename_lock; @@ -349,7 +349,7 @@ extern void dput(struct dentry *); static inline int d_mountpoint(struct dentry *dentry) { - return dentry->d_mounted; + return dentry->d_flags & DCACHE_MOUNTED; } extern struct vfsmount *lookup_mnt(struct path *); -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html