Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 226726
b: refs/heads/master
c: 5f57cbc
h: refs/heads/master
v: v3
  • Loading branch information
Nick Piggin committed Jan 7, 2011
1 parent dd651fe commit a0417da
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c28cc36469554dc55540f059fbdc7fa22a2c31fc
refs/heads/master: 5f57cbcc02cf18f6b22ef4066bb10afeb8f930ff
13 changes: 11 additions & 2 deletions trunk/fs/autofs4/expire.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,9 @@ struct dentry *autofs4_expire_direct(struct super_block *sb,
struct autofs_info *ino = autofs4_dentry_ino(root);
if (d_mountpoint(root)) {
ino->flags |= AUTOFS_INF_MOUNTPOINT;
root->d_mounted--;
spin_lock(&root->d_lock);
root->d_flags &= ~DCACHE_MOUNTED;
spin_unlock(&root->d_lock);
}
ino->flags |= AUTOFS_INF_EXPIRING;
init_completion(&ino->expire_complete);
Expand Down Expand Up @@ -503,7 +505,14 @@ int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,

spin_lock(&sbi->fs_lock);
if (ino->flags & AUTOFS_INF_MOUNTPOINT) {
sb->s_root->d_mounted++;
spin_lock(&sb->s_root->d_lock);
/*
* If we haven't been expired away, then reset
* mounted status.
*/
if (mnt->mnt_parent != mnt)
sb->s_root->d_flags |= DCACHE_MOUNTED;
spin_unlock(&sb->s_root->d_lock);
ino->flags &= ~AUTOFS_INF_MOUNTPOINT;
}
ino->flags &= ~AUTOFS_INF_EXPIRING;
Expand Down
1 change: 0 additions & 1 deletion trunk/fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,6 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
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);
Expand Down
29 changes: 26 additions & 3 deletions trunk/fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,27 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
}
}

/*
* Clear dentry's mounted state if it has no remaining mounts.
* vfsmount_lock must be held for write.
*/
static void dentry_reset_mounted(struct vfsmount *mnt, struct dentry *dentry)
{
unsigned u;

for (u = 0; u < HASH_SIZE; u++) {
struct vfsmount *p;

list_for_each_entry(p, &mount_hashtable[u], mnt_hash) {
if (p->mnt_mountpoint == dentry)
return;
}
}
spin_lock(&dentry->d_lock);
dentry->d_flags &= ~DCACHE_MOUNTED;
spin_unlock(&dentry->d_lock);
}

/*
* vfsmount lock must be held for write
*/
Expand All @@ -502,7 +523,7 @@ static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
mnt->mnt_mountpoint = mnt->mnt_root;
list_del_init(&mnt->mnt_child);
list_del_init(&mnt->mnt_hash);
old_path->dentry->d_mounted--;
dentry_reset_mounted(old_path->mnt, old_path->dentry);
}

/*
Expand All @@ -513,7 +534,9 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
{
child_mnt->mnt_parent = mntget(mnt);
child_mnt->mnt_mountpoint = dget(dentry);
dentry->d_mounted++;
spin_lock(&dentry->d_lock);
dentry->d_flags |= DCACHE_MOUNTED;
spin_unlock(&dentry->d_lock);
}

/*
Expand Down Expand Up @@ -1073,7 +1096,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
list_del_init(&p->mnt_child);
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);
}
Expand Down
42 changes: 21 additions & 21 deletions trunk/include/linux/dcache.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ struct dentry {
unsigned int d_flags; /* protected by d_lock */
spinlock_t d_lock; /* per dentry lock */
seqcount_t d_seq; /* per dentry seqlock */
int d_mounted;
struct inode *d_inode; /* Where the name belongs to - NULL is
* negative */
/*
Expand Down Expand Up @@ -156,33 +155,34 @@ struct dentry_operations {

/* 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_CANT_MOUNT 0x0100
#define DCACHE_GENOCIDE 0x0200
#define DCACHE_MOUNTED 0x0400 /* is a mountpoint */


extern spinlock_t dcache_inode_lock;
extern seqlock_t rename_lock;
Expand Down Expand Up @@ -372,7 +372,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 *);
Expand Down

0 comments on commit a0417da

Please sign in to comment.