patch-2.1.79 linux/fs/nfs/dir.c
Next file: linux/fs/nfs/inode.c
Previous file: linux/fs/namei.c
Back to the patch index
Back to the overall index
- Lines: 140
- Date:
Mon Jan 12 14:38:40 1998
- Orig file:
v2.1.78/linux/fs/nfs/dir.c
- Orig date:
Tue Jan 6 09:37:37 1998
diff -u --recursive --new-file v2.1.78/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
@@ -35,6 +35,7 @@
extern void nfs_renew_times(struct dentry *);
#define NFS_PARANOIA 1
+/* #define NFS_DEBUG_VERBOSE 1 */
/*
* Head for a dircache entry. Currently still very simple; when
@@ -458,6 +459,28 @@
}
/*
+ * Called to free the inode from the dentry. We must flush
+ * any pending writes for this dentry before freeing the inode.
+ */
+static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
+{
+ if (NFS_WRITEBACK(inode)) {
+#ifdef NFS_PARANOIA
+printk("nfs_dentry_iput: pending writes for %s/%s, i_count=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, inode->i_count);
+#endif
+ while (nfs_find_dentry_request(inode, dentry)) {
+#ifdef NFS_PARANOIA
+printk("nfs_dentry_iput: flushing %s/%s\n",
+dentry->d_parent->d_name.name, dentry->d_name.name);
+#endif
+ nfs_flush_dirty_pages(inode, 0, 0, 0);
+ }
+ }
+ iput(inode);
+}
+
+/*
* Called when the dentry is being freed to release private memory.
*/
static void nfs_dentry_release(struct dentry *dentry)
@@ -471,9 +494,53 @@
NULL, /* d_hash */
NULL, /* d_compare */
nfs_dentry_delete, /* d_delete(struct dentry *) */
+ nfs_dentry_iput, /* d_iput(struct dentry *, struct inode *) */
nfs_dentry_release /* d_release(struct dentry *) */
};
+#ifdef NFS_PARANOIA
+/*
+ * Display all dentries holding the specified inode.
+ */
+static void show_dentry(struct inode * inode)
+{
+ struct dentry *parent = inode->i_sb->s_root;
+ struct dentry *this_parent = parent;
+ struct list_head *next;
+
+repeat:
+ next = this_parent->d_subdirs.next;
+resume:
+ while (next != &this_parent->d_subdirs) {
+ struct list_head *tmp = next;
+ struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+ next = tmp->next;
+ if (dentry->d_inode == inode) {
+ int unhashed = list_empty(&dentry->d_hash);
+ printk("show_dentry: %s/%s, d_count=%d%s\n",
+ dentry->d_parent->d_name.name,
+ dentry->d_name.name, dentry->d_count,
+ unhashed ? "(unhashed)" : "");
+ }
+ /*
+ * Descend a level if the d_subdirs list is non-empty.
+ */
+ if (!list_empty(&dentry->d_subdirs)) {
+ this_parent = dentry;
+ goto repeat;
+ }
+ }
+ /*
+ * All done at this level ... ascend and resume the search.
+ */
+ if (this_parent != parent) {
+ next = this_parent->d_child.next;
+ this_parent = this_parent->d_parent;
+ goto resume;
+ }
+}
+#endif
+
/*
* Whenever a lookup succeeds, we know the parent directories
* are all valid, so we want to update the dentry timestamps.
@@ -531,10 +598,12 @@
inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
if (inode) {
#ifdef NFS_PARANOIA
-if (inode->i_count > (S_ISDIR(inode->i_mode) ? 1 : inode->i_nlink))
+if (inode->i_count > (S_ISDIR(inode->i_mode) ? 1 : inode->i_nlink)) {
printk("nfs_lookup: %s/%s ino=%ld in use, count=%d, nlink=%d\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
inode->i_ino, inode->i_count, inode->i_nlink);
+show_dentry(inode);
+}
#endif
no_entry:
d_add(dentry, inode);
@@ -564,10 +633,12 @@
inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
if (inode) {
#ifdef NFS_PARANOIA
-if (inode->i_count > (S_ISDIR(inode->i_mode) ? 1 : inode->i_nlink))
+if (inode->i_count > (S_ISDIR(inode->i_mode) ? 1 : inode->i_nlink)) {
printk("nfs_instantiate: %s/%s ino=%ld in use, count=%d, nlink=%d\n",
dentry->d_parent->d_name.name, dentry->d_name.name,
inode->i_ino, inode->i_count, inode->i_nlink);
+show_dentry(inode);
+}
#endif
d_instantiate(dentry, inode);
nfs_renew_times(dentry);
@@ -682,10 +753,6 @@
sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
- nfs_invalidate_dircache(dir);
- error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dentry->d_parent),
- dentry->d_name.name, &sattr, &fhandle, &fattr);
-
/*
* Always drop the dentry, we can't always depend on
* the fattr returned by the server (AIX seems to be
@@ -693,6 +760,9 @@
* depending on potentially bogus information.
*/
d_drop(dentry);
+ nfs_invalidate_dircache(dir);
+ error = nfs_proc_mkdir(NFS_DSERVER(dentry), NFS_FH(dentry->d_parent),
+ dentry->d_name.name, &sattr, &fhandle, &fattr);
out:
return error;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov