+static struct mountpoint *new_mountpoint(struct dentry *dentry)
+{
+ struct list_head *chain = mountpoint_hashtable + hash(NULL, dentry);
+ struct mountpoint *mp;
+
+ list_for_each_entry(mp, chain, m_hash) {
+ if (mp->m_dentry == dentry) {
+ /* might be worth a WARN_ON() */
+ if (d_unlinked(dentry))
+ return ERR_PTR(-ENOENT);
+ mp->m_count++;
+ return mp;
+ }
+ }
+
+ mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL);
+ if (!mp)
+ return ERR_PTR(-ENOMEM);
+
+ spin_lock(&dentry->d_lock);
+ if (d_unlinked(dentry)) {
+ spin_unlock(&dentry->d_lock);
+ kfree(mp);
+ return ERR_PTR(-ENOENT);
+ }
+ dentry->d_flags |= DCACHE_MOUNTED;
+ spin_unlock(&dentry->d_lock);
+ mp->m_dentry = dentry;
+ mp->m_count = 1;
+ list_add(&mp->m_hash, chain);
+ return mp;
+}
+
+static void put_mountpoint(struct mountpoint *mp)
+{
+ if (!--mp->m_count) {
+ struct dentry *dentry = mp->m_dentry;
+ spin_lock(&dentry->d_lock);
+ dentry->d_flags &= ~DCACHE_MOUNTED;
+ spin_unlock(&dentry->d_lock);
+ list_del(&mp->m_hash);
+ kfree(mp);
+ }
+}
+