[PATCH 11/12] HPPFS: add dentry_ops->d_revalidate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Paolo 'Blaisorblade' Giarrusso <[email protected]>

We might need to revalidate a dentry (for instance when a process dies), so
call the underlying d_revalidate if it is defined, on the underlying
dentry.

Also, when we find a dentry in the dcache, we must call d_revalidate
ourselves.

BUT: for now, this is done with a NULL nameidata (which is only safe by
chance, given the current code). While looking into this, I realized that
the nameidata handling in calls to the underlying FS are bogus. I'm going
to fix this in next patch.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[email protected]>
---

 fs/hppfs/hppfs_kern.c |   42 +++++++++++++++++++++++++++++++++++++-----
 1 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -104,7 +104,22 @@ static char *dentry_name(struct dentry *
 	return(name);
 }
 
+static int hppfs_d_revalidate(struct dentry * dentry, struct nameidata * nd)
+{
+	int (*d_revalidate)(struct dentry *, struct nameidata *);
+	struct dentry *proc_dentry;
+
+	proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
+	if (proc_dentry->d_op && proc_dentry->d_op->d_revalidate)
+		d_revalidate = proc_dentry->d_op->d_revalidate;
+	else
+		return 1; /* "Still valid" code */
+
+	return (*d_revalidate)(proc_dentry, nd);
+}
+
 static struct dentry_operations hppfs_dentry_ops = {
+	.d_revalidate = hppfs_d_revalidate,
 };
 
 static int file_removed(struct dentry *dentry, const char *file)
@@ -157,7 +172,7 @@ static void hppfs_read_inode(struct inod
 	ino->i_blocks = proc_ino->i_blocks;
 }
 
-static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
+static struct dentry *hppfs_lookup(struct inode *parent_ino, struct dentry *dentry,
                                   struct nameidata *nd)
 {
 	struct dentry *proc_dentry, *new, *parent;
@@ -171,10 +186,18 @@ static struct dentry *hppfs_lookup(struc
 		return(ERR_PTR(-ENOENT));
 
 	err = -ENOMEM;
-	parent = HPPFS_I(ino)->proc_dentry;
+	parent = HPPFS_I(parent_ino)->proc_dentry;
+	
+	/* This more or less matches fs/namei.c:real_lookup() - we don't have
+	 * the fast path which looks up the dentry without the directory
+	 * semaphore. Please keep in sync. */
+
+	/* XXX: The only difference is nameidata: we pass NULL instead of nd.
+	 * Not normally allowed, would Oops if proc ever uses nd, and can Oops /
+	 * leak entries if we pass the same nd we got. */
 	down(&parent->d_inode->i_sem);
 	proc_dentry = d_lookup(parent, &dentry->d_name);
-	if(proc_dentry == NULL){
+	if (!proc_dentry) {
 		proc_dentry = d_alloc(parent, &dentry->d_name);
 		if(proc_dentry == NULL){
 			up(&parent->d_inode->i_sem);
@@ -186,13 +209,22 @@ static struct dentry *hppfs_lookup(struc
 			dput(proc_dentry);
 			proc_dentry = new;
 		}
+		up(&parent->d_inode->i_sem);
+	} else {
+		up(&parent->d_inode->i_sem);
+		if (proc_dentry->d_op && proc_dentry->d_op->d_revalidate) {
+			if (!proc_dentry->d_op->d_revalidate(proc_dentry, NULL) &&
+					!d_invalidate(proc_dentry)) {
+				dput(proc_dentry);
+				proc_dentry = ERR_PTR(-ENOENT);
+			}
+		}
 	}
-	up(&parent->d_inode->i_sem);
 
 	if(IS_ERR(proc_dentry))
 		return(proc_dentry);
 
-	inode = iget(ino->i_sb, 0);
+	inode = iget(parent_ino->i_sb, 0);
 	if(inode == NULL)
 		goto out_dput;
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux