From: David Howells <dhowells@redhat.com>
To: torvalds@osdl.org, akpm@osdl.org
Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
netdev@vger.kernel.org, dhowells@redhat.com
Subject: [PATCH 7/8] AFS: Permit key to be cached in nameidata
Date: Wed, 11 Apr 2007 20:10:32 +0100 [thread overview]
Message-ID: <20070411191032.15499.78083.stgit@warthog.cambridge.redhat.com> (raw)
In-Reply-To: <20070411190956.15499.55352.stgit@warthog.cambridge.redhat.com>
Permit a key to be cached in the nameidata struct so that it only needs to be
looked up once when doing the sequence of d_revalidate(), permission(),
follow_link() and lookup() calls involved in a pathwalk.
This is used by the AFS filesystem to avoid repeatedly having to call
request_key(). Once looked up, the key is then available as the kernel walks
to the tree until such a time as the kernel crosses to a non-AFS mountpoint or
an AFS mountpoint in a different cell.
The cache works like this:
(1) The nameidata::key pointer is initialised to NULL at the start of the
pathwalk (do_path_lookup()). path_release() and co. release the key it
points to.
(2) Any filesystem operation performed during the pathwalk that has access to
the nameidata (lookup, permission, follow_link, d_revalidate) can look at
the key - if non-NULL - and if it's what they're looking for they can use
it.
If there's a key there of potential interest, the key's type and
description should be checked to make sure the key is permissible.
If of interest, key_validate() should be called to make sure the key is
still usable. If it isn't, the error should be passed back rather than
the key lookup being redone on the basis that some earlier step is now no
longer valid.
(3) Any operation that is not interested in the key can either ignore it or
release it and clear the pointer.
(4) If an operation wants to put its own key there, it should release the old
key and set the pointer to point to its own key with the key's usage count
incremented. This could be encapsulated in a function something like
this:
void set_nd_key(struct nameidata *nd, struct key *key)
{
key_put(nd->key);
nd->key = key_get(key);
}
Unfortunately there isn't currently a way to pass the key onto the inode
operations for create(), link(), unlink(), and suchlike, nor is there a way to
pass it to the open() file op without adding a struct key pointer argument to
each of these.
This might also be useful for NFS and CIFS.
Signed-Off-By: David Howells <dhowells@redhat.com>
---
fs/namei.c | 5 +++++
fs/open.c | 7 +++++--
include/linux/namei.h | 1 +
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index ee60cc4..7a59d12 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -350,6 +350,8 @@ void path_release(struct nameidata *nd)
{
dput(nd->dentry);
mntput(nd->mnt);
+ key_put(nd->key);
+ nd->key = NULL;
}
/*
@@ -360,6 +362,8 @@ void path_release_on_umount(struct nameidata *nd)
{
dput(nd->dentry);
mntput_no_expire(nd->mnt);
+ key_put(nd->key);
+ nd->key = NULL;
}
/**
@@ -1108,6 +1112,7 @@ static int fastcall do_path_lookup(int dfd, const char *name,
struct file *file;
struct fs_struct *fs = current->fs;
+ nd->key = NULL;
nd->last_type = LAST_ROOT; /* if there are only slashes... */
nd->flags = flags;
nd->depth = 0;
diff --git a/fs/open.c b/fs/open.c
index c989fb4..77bd2a5 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -822,10 +822,13 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
/* Pick up the filp from the open intent */
filp = nd->intent.open.file;
/* Has the filesystem initialised the file for us? */
- if (filp->f_path.dentry == NULL)
+ if (filp->f_path.dentry == NULL) {
filp = __dentry_open(nd->dentry, nd->mnt, flags, filp, NULL);
- else
+ key_put(nd->key);
+ nd->key = NULL;
+ } else {
path_release(nd);
+ }
return filp;
}
diff --git a/include/linux/namei.h b/include/linux/namei.h
index d39a5a6..d677408 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -17,6 +17,7 @@ enum { MAX_NESTED_LINKS = 8 };
struct nameidata {
struct dentry *dentry;
struct vfsmount *mnt;
+ struct key *key;
struct qstr last;
unsigned int flags;
int last_type;
next prev parent reply other threads:[~2007-04-11 19:11 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-11 19:09 [PATCH 0/8] AFS: Add security support and fix bugs David Howells
2007-04-11 19:10 ` [PATCH 1/8] AF_RXRPC: Use own workqueues David Howells
2007-04-11 19:10 ` [PATCH 2/8] AF_RXRPC: Lower dead call timeout and fix available call counting on connections David Howells
2007-04-11 19:10 ` [PATCH 3/8] AFS: Fix callback aggregator work item deadlock David Howells
2007-04-11 19:10 ` [PATCH 4/8] AFS: Correctly alter relocation state after update and show state in /proc David Howells
2007-04-11 19:10 ` [PATCH 5/8] AFS: Handle multiple mounts of an AFS superblock correctly David Howells
2007-04-11 19:10 ` [PATCH 6/8] AFS: AF_RXRPC key changes David Howells
2007-04-11 19:10 ` David Howells [this message]
2007-04-11 19:10 ` [PATCH 8/8] AFS: Add security support David Howells
2007-04-11 19:38 ` J. Bruce Fields
2007-04-11 20:10 ` David Howells
2007-04-11 20:17 ` J. Bruce Fields
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070411191032.15499.78083.stgit@warthog.cambridge.redhat.com \
--to=dhowells@redhat.com \
--cc=akpm@osdl.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome