Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 2599

kernel-2.6.18-194.11.1.el5.src.rpm

From: Steve Dickson <SteveD@redhat.com>
Date: Wed, 21 Nov 2007 11:30:50 -0500
Subject: [nfs] infrastructure changes for silly renames
Message-id: 47445D3A.5010808@RedHat.com
O-Subject: [RHEL5.2/RHEL5.1-z] [2/5] NFS: silly rename races with umounts
Bugzilla: 253663

Again more infrastructure changes needed for the next two
patches.

commit 3062c532ad410fe0e8320566fe2879a396be6701
Author: Trond Myklebust <Trond.Myklebust@netapp.com>
Date:   Sat Jul 14 17:36:45 2007 -0400

    NFS: Use dentry->d_time to store the parent directory verifier.

    This will free up the d_fsdata field for other use.

    Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

commit 77a55a1fe8f26f7d022986a599b68002e21d968a
Author: Chuck Lever <chuck.lever@oracle.com>
Date:   Mon Sep 24 15:40:11 2007 -0400

    NFS: Eliminate nfs_renew_times()

    The nfs_renew_times() function plants the current time in jiffies in
    dentry->d_time.  But a call to nfs_renew_times() is always followed by
    another call that overwrites dentry->d_time.  Get rid of the
    nfs_renew_times() calls.

    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
    Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

commit d75340cc4de5c187fbf0bba234309ca86cf0a2fb
Author: Trond Myklebust <Trond.Myklebust@netapp.com>
Date:   Mon Oct 1 21:42:01 2007 -0400

    NFSv4: Fix nfs_atomic_open() to set the verifier on negative dentries too

    Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 0cf8e85..6d699ea 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -645,20 +645,6 @@ static inline int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
 	return nfs_verify_change_attribute(dir, (unsigned long)dentry->d_fsdata);
 }
 
-static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
-{
-	dentry->d_fsdata = (void *)verf;
-}
-
-/*
- * Whenever an NFS operation succeeds, we know that the dentry
- * is valid, so we update the revalidation timestamp.
- */
-static inline void nfs_renew_times(struct dentry * dentry)
-{
-	dentry->d_time = jiffies;
-}
-
 /*
  * Return the intent data that applies to this particular path component
  *
@@ -782,7 +768,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
 	if ((error = nfs_refresh_inode(inode, &fattr)) != 0)
 		goto out_bad;
 
-	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, verifier);
  out_valid:
 	unlock_kernel();
@@ -848,7 +833,6 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
 		unlock_kernel();
 	}
 	/* When creating a negative dentry, we want to renew d_time */
-	nfs_renew_times(dentry);
 	iput(inode);
 }
 
@@ -937,7 +921,6 @@ no_entry:
 			goto out_unlock;
 		dentry = res;
 	}
-	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 out_unlock:
 	unlock_kernel();
@@ -1032,8 +1015,6 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
 		}
 	} else if (res != NULL)
 		dentry = res;
-	nfs_renew_times(dentry);
-	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 out:
 	return res;
 no_open:
@@ -1075,8 +1056,6 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
 	lock_kernel();
 	verifier = nfs_save_change_attribute(dir);
 	ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
-	if (!ret)
-		nfs_set_verifier(dentry, verifier);
 	unlock_kernel();
 out:
 	dput(parent);
@@ -1151,7 +1130,6 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
 	}
 
 out_renew:
-	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 	return dentry;
 }
@@ -1218,7 +1196,6 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
 	nfs_end_data_update(dir);
 	if (error != 0)
 		goto out_err;
-	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 	unlock_kernel();
 	return 0;
@@ -1252,7 +1229,6 @@ nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
 	nfs_end_data_update(dir);
 	if (status != 0)
 		goto out_err;
-	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 	unlock_kernel();
 	return 0;
@@ -1282,7 +1258,6 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 	nfs_end_data_update(dir);
 	if (error != 0)
 		goto out_err;
-	nfs_renew_times(dentry);
 	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 	unlock_kernel();
 	return 0;
@@ -1380,7 +1355,6 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
 				dir, &qsilly);
 	nfs_end_data_update(dir);
 	if (!error) {
-		nfs_renew_times(dentry);
 		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 		d_move(dentry, sdentry);
 		error = nfs_async_unlink(dentry);
@@ -1461,7 +1435,6 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
 	spin_unlock(&dcache_lock);
 	error = nfs_safe_remove(dentry);
 	if (!error) {
-		nfs_renew_times(dentry);
 		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 	} else if (need_rehash)
 		d_rehash(dentry);
@@ -1691,7 +1664,6 @@ out:
 	if (!error) {
 		if (!S_ISDIR(old_inode->i_mode))
 			d_move(old_dentry, new_dentry);
-		nfs_renew_times(new_dentry);
 		nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir));
 	}
 
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2972d5a..8bf2c61 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1304,13 +1304,16 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
 	state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred);
 	put_rpccred(cred);
 	if (IS_ERR(state)) {
-		if (PTR_ERR(state) == -ENOENT)
+		if (PTR_ERR(state) == -ENOENT) {
 			d_add(dentry, NULL);
+			nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+		}
 		return (struct dentry *)state;
 	}
 	res = d_add_unique(dentry, igrab(state->inode));
 	if (res != NULL)
 		dentry = res;
+	nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir));
 	nfs4_intent_set_file(nd, &path, state);
 	return res;
 }
@@ -1348,6 +1351,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
 		goto out_drop;
 	}
 	if (state->inode == dentry->d_inode) {
+		nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 		nfs4_intent_set_file(nd, &path, state);
 		return 1;
 	}
@@ -1926,6 +1930,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
 		goto out;
 	}
 	d_instantiate(dentry, igrab(state->inode));
+	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 	if (flags & O_EXCL) {
 		struct nfs_fattr fattr;
 		status = nfs4_do_setattr(state->inode, &fattr, sattr, state);
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index bca3a1f..90f59da 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -276,6 +276,11 @@ static inline int NFS_USE_READDIRPLUS(struct inode *inode)
 	return test_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
 }
 
+static inline void nfs_set_verifier(struct dentry * dentry, unsigned long verf)
+{
+	dentry->d_time = verf;
+}
+
 /**
  * nfs_save_change_attribute - Returns the inode attribute change cookie
  * @inode - pointer to inode