patch-2.4.0-test3 linux/include/linux/dcache.h

Next file: linux/include/linux/devfs_fs_kernel.h
Previous file: linux/include/linux/coda_psdev.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test2/linux/include/linux/dcache.h linux/include/linux/dcache.h
@@ -1,11 +1,11 @@
 #ifndef __LINUX_DCACHE_H
 #define __LINUX_DCACHE_H
 
+#ifdef __KERNEL__
+
 #include <asm/atomic.h>
 #include <linux/mount.h>
 
-#ifdef __KERNEL__
-
 /*
  * linux/include/linux/dcache.h
  *
@@ -57,7 +57,7 @@
 #define DNAME_INLINE_LEN 16
 
 struct dentry {
-	int d_count;
+	atomic_t d_count;
 	unsigned int d_flags;
 	struct inode  * d_inode;	/* Where the name belongs to - NULL is negative */
 	struct dentry * d_parent;	/* parent directory */
@@ -92,7 +92,16 @@
  * might be a negative dentry which has no information associated with
  * it */
 
-
+/*
+locking rules:
+		big lock	dcache_lock	may block
+d_revalidate:	no		no		yes
+d_hash		no		no		yes
+d_compare:	no		yes		no
+d_delete:	no		yes		no
+d_release:	no		no		yes
+d_iput:		no		no		yes
+ */
 
 /* d_flags entries */
 #define DCACHE_AUTOFS_PENDING 0x0001    /* autofs: "under construction" */
@@ -107,6 +116,8 @@
 					 * s_nfsd_free_path semaphore will be down
 					 */
 
+extern spinlock_t dcache_lock;
+
 /**
  * d_drop - drop a dentry
  * @dentry: dentry to drop
@@ -126,8 +137,10 @@
 
 static __inline__ void d_drop(struct dentry * dentry)
 {
+	spin_lock(&dcache_lock);
 	list_del(&dentry->d_hash);
 	INIT_LIST_HEAD(&dentry->d_hash);
+	spin_unlock(&dcache_lock);
 }
 
 static __inline__ int dname_external(struct dentry *d)
@@ -185,8 +198,8 @@
  
 static __inline__ void d_add(struct dentry * entry, struct inode * inode)
 {
-	d_rehash(entry);
 	d_instantiate(entry, inode);
+	d_rehash(entry);
 }
 
 /* used for rename() and baskets */
@@ -200,29 +213,34 @@
 
 extern char * __d_path(struct dentry *, struct vfsmount *, struct dentry *,
 	struct vfsmount *, char *, int);
-/* write full pathname into buffer and return start of pathname */
-#define d_path(dentry, vfsmnt, buffer, buflen) \
-	__d_path(dentry, vfsmnt, current->fs->root, current->fs->rootmnt, \
-	buffer, buflen)
   
 /* Allocation counts.. */
 
 /**
- *	dget	-	get a reference to a dentry
+ *	dget, dget_locked	-	get a reference to a dentry
  *	@dentry: dentry to get a reference to
  *
  *	Given a dentry or %NULL pointer increment the reference count
  *	if appropriate and return the dentry. A dentry will not be 
- *	destroyed when it has references.
+ *	destroyed when it has references. dget() should never be
+ *	called for dentries with zero reference counter. For these cases
+ *	(preferably none, functions in dcache.c are sufficient for normal
+ *	needs and they take necessary precautions) you should hold dcache_lock
+ *	and call dget_locked() instead of dget().
  */
  
 static __inline__ struct dentry * dget(struct dentry *dentry)
 {
-	if (dentry)
-		dentry->d_count++;
+	if (dentry) {
+		if (!atomic_read(&dentry->d_count))
+			BUG();
+		atomic_inc(&dentry->d_count);
+	}
 	return dentry;
 }
 
+extern struct dentry * dget_locked(struct dentry *);
+
 /**
  *	d_unhashed -	is dentry hashed
  *	@dentry: entry to check
@@ -241,7 +259,6 @@
 {
 	return !list_empty(&dentry->d_vfsmnt);
 }
-
 
 #endif /* __KERNEL__ */
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)