git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git]
/
fs
/
nfs
/
idmap.c
diff --git
a/fs/nfs/idmap.c
b/fs/nfs/idmap.c
index
87f4f9a
..
3fab5b0
100644
(file)
--- a/
fs/nfs/idmap.c
+++ b/
fs/nfs/idmap.c
@@
-35,6
+35,7
@@
*/
#include <linux/module.h>
*/
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
@@
-50,10
+51,15
@@
#include <linux/nfs_fs.h>
#include <linux/nfs_idmap.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_idmap.h>
+#include "nfs4_fs.h"
#define IDMAP_HASH_SZ 128
#define IDMAP_HASH_SZ 128
+/* Default cache timeout is 10 minutes */
+unsigned int nfs_idmap_cache_timeout = 600 * HZ;
+
struct idmap_hashent {
struct idmap_hashent {
+ unsigned long ih_expires;
__u32 ih_id;
int ih_namelen;
char ih_name[IDMAP_NAMESZ];
__u32 ih_id;
int ih_namelen;
char ih_name[IDMAP_NAMESZ];
@@
-69,8
+75,8
@@
struct idmap {
struct dentry *idmap_dentry;
wait_queue_head_t idmap_wq;
struct idmap_msg idmap_im;
struct dentry *idmap_dentry;
wait_queue_head_t idmap_wq;
struct idmap_msg idmap_im;
- struct
semaphore
idmap_lock; /* Serializes upcalls */
- struct
semaphore
idmap_im_lock; /* Protects the hashtable */
+ struct
mutex
idmap_lock; /* Serializes upcalls */
+ struct
mutex
idmap_im_lock; /* Protects the hashtable */
struct idmap_hashtable idmap_user_hash;
struct idmap_hashtable idmap_group_hash;
};
struct idmap_hashtable idmap_user_hash;
struct idmap_hashtable idmap_group_hash;
};
@@
-96,11
+102,9
@@
nfs_idmap_new(struct nfs4_client *clp)
if (clp->cl_idmap != NULL)
return;
if (clp->cl_idmap != NULL)
return;
- if ((idmap = k
m
alloc(sizeof(*idmap), GFP_KERNEL)) == NULL)
+ if ((idmap = k
z
alloc(sizeof(*idmap), GFP_KERNEL)) == NULL)
return;
return;
- memset(idmap, 0, sizeof(*idmap));
-
snprintf(idmap->idmap_path, sizeof(idmap->idmap_path),
"%s/idmap", clp->cl_rpcclient->cl_pathname);
snprintf(idmap->idmap_path, sizeof(idmap->idmap_path),
"%s/idmap", clp->cl_rpcclient->cl_pathname);
@@
-111,8
+115,8
@@
nfs_idmap_new(struct nfs4_client *clp)
return;
}
return;
}
-
init_MUTEX
(&idmap->idmap_lock);
-
init_MUTEX
(&idmap->idmap_im_lock);
+
mutex_init
(&idmap->idmap_lock);
+
mutex_init
(&idmap->idmap_im_lock);
init_waitqueue_head(&idmap->idmap_wq);
idmap->idmap_user_hash.h_type = IDMAP_TYPE_USER;
idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP;
init_waitqueue_head(&idmap->idmap_wq);
idmap->idmap_user_hash.h_type = IDMAP_TYPE_USER;
idmap->idmap_group_hash.h_type = IDMAP_TYPE_GROUP;
@@
-127,6
+131,8
@@
nfs_idmap_delete(struct nfs4_client *clp)
if (!idmap)
return;
if (!idmap)
return;
+ dput(idmap->idmap_dentry);
+ idmap->idmap_dentry = NULL;
rpc_unlink(idmap->idmap_path);
clp->cl_idmap = NULL;
kfree(idmap);
rpc_unlink(idmap->idmap_path);
clp->cl_idmap = NULL;
kfree(idmap);
@@
-148,6
+154,8
@@
idmap_lookup_name(struct idmap_hashtable *h, const char *name, size_t len)
if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0)
return NULL;
if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0)
return NULL;
+ if (time_after(jiffies, he->ih_expires))
+ return NULL;
return he;
}
return he;
}
@@
-163,6
+171,8
@@
idmap_lookup_id(struct idmap_hashtable *h, __u32 id)
struct idmap_hashent *he = idmap_id_hash(h, id);
if (he->ih_id != id || he->ih_namelen == 0)
return NULL;
struct idmap_hashent *he = idmap_id_hash(h, id);
if (he->ih_id != id || he->ih_namelen == 0)
return NULL;
+ if (time_after(jiffies, he->ih_expires))
+ return NULL;
return he;
}
return he;
}
@@
-191,6
+201,7
@@
idmap_update_entry(struct idmap_hashent *he, const char *name,
memcpy(he->ih_name, name, namelen);
he->ih_name[namelen] = '\0';
he->ih_namelen = namelen;
memcpy(he->ih_name, name, namelen);
he->ih_name[namelen] = '\0';
he->ih_namelen = namelen;
+ he->ih_expires = jiffies + nfs_idmap_cache_timeout;
}
/*
}
/*
@@
-222,8
+233,8
@@
nfs_idmap_id(struct idmap *idmap, struct idmap_hashtable *h,
if (namelen >= IDMAP_NAMESZ)
return -EINVAL;
if (namelen >= IDMAP_NAMESZ)
return -EINVAL;
-
down
(&idmap->idmap_lock);
-
down
(&idmap->idmap_im_lock);
+
mutex_lock
(&idmap->idmap_lock);
+
mutex_lock
(&idmap->idmap_im_lock);
he = idmap_lookup_name(h, name, namelen);
if (he != NULL) {
he = idmap_lookup_name(h, name, namelen);
if (he != NULL) {
@@
-249,11
+260,11
@@
nfs_idmap_id(struct idmap *idmap, struct idmap_hashtable *h,
}
set_current_state(TASK_UNINTERRUPTIBLE);
}
set_current_state(TASK_UNINTERRUPTIBLE);
-
up
(&idmap->idmap_im_lock);
+
mutex_unlock
(&idmap->idmap_im_lock);
schedule();
current->state = TASK_RUNNING;
remove_wait_queue(&idmap->idmap_wq, &wq);
schedule();
current->state = TASK_RUNNING;
remove_wait_queue(&idmap->idmap_wq, &wq);
-
down
(&idmap->idmap_im_lock);
+
mutex_lock
(&idmap->idmap_im_lock);
if (im->im_status & IDMAP_STATUS_SUCCESS) {
*id = im->im_id;
if (im->im_status & IDMAP_STATUS_SUCCESS) {
*id = im->im_id;
@@
-262,8
+273,8
@@
nfs_idmap_id(struct idmap *idmap, struct idmap_hashtable *h,
out:
memset(im, 0, sizeof(*im));
out:
memset(im, 0, sizeof(*im));
-
up
(&idmap->idmap_im_lock);
-
up
(&idmap->idmap_lock);
+
mutex_unlock
(&idmap->idmap_im_lock);
+
mutex_unlock
(&idmap->idmap_lock);
return (ret);
}
return (ret);
}
@@
-283,8
+294,8
@@
nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
im = &idmap->idmap_im;
im = &idmap->idmap_im;
-
down
(&idmap->idmap_lock);
-
down
(&idmap->idmap_im_lock);
+
mutex_lock
(&idmap->idmap_lock);
+
mutex_lock
(&idmap->idmap_im_lock);
he = idmap_lookup_id(h, id);
if (he != 0) {
he = idmap_lookup_id(h, id);
if (he != 0) {
@@
-310,11
+321,11
@@
nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
}
set_current_state(TASK_UNINTERRUPTIBLE);
}
set_current_state(TASK_UNINTERRUPTIBLE);
-
up
(&idmap->idmap_im_lock);
+
mutex_unlock
(&idmap->idmap_im_lock);
schedule();
current->state = TASK_RUNNING;
remove_wait_queue(&idmap->idmap_wq, &wq);
schedule();
current->state = TASK_RUNNING;
remove_wait_queue(&idmap->idmap_wq, &wq);
-
down
(&idmap->idmap_im_lock);
+
mutex_lock
(&idmap->idmap_im_lock);
if (im->im_status & IDMAP_STATUS_SUCCESS) {
if ((len = strnlen(im->im_name, IDMAP_NAMESZ)) == 0)
if (im->im_status & IDMAP_STATUS_SUCCESS) {
if ((len = strnlen(im->im_name, IDMAP_NAMESZ)) == 0)
@@
-325,8
+336,8
@@
nfs_idmap_name(struct idmap *idmap, struct idmap_hashtable *h,
out:
memset(im, 0, sizeof(*im));
out:
memset(im, 0, sizeof(*im));
-
up
(&idmap->idmap_im_lock);
-
up
(&idmap->idmap_lock);
+
mutex_unlock
(&idmap->idmap_im_lock);
+
mutex_unlock
(&idmap->idmap_lock);
return ret;
}
return ret;
}
@@
-370,7
+381,7
@@
idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
if (copy_from_user(&im_in, src, mlen) != 0)
return (-EFAULT);
if (copy_from_user(&im_in, src, mlen) != 0)
return (-EFAULT);
-
down
(&idmap->idmap_im_lock);
+
mutex_lock
(&idmap->idmap_im_lock);
ret = mlen;
im->im_status = im_in.im_status;
ret = mlen;
im->im_status = im_in.im_status;
@@
-430,7
+441,7
@@
idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
idmap_update_entry(he, im_in.im_name, namelen_in, im_in.im_id);
ret = mlen;
out:
idmap_update_entry(he, im_in.im_name, namelen_in, im_in.im_id);
ret = mlen;
out:
-
up
(&idmap->idmap_im_lock);
+
mutex_unlock
(&idmap->idmap_im_lock);
return ret;
}
return ret;
}
@@
-442,10
+453,10
@@
idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg)
if (msg->errno >= 0)
return;
if (msg->errno >= 0)
return;
-
down
(&idmap->idmap_im_lock);
+
mutex_lock
(&idmap->idmap_im_lock);
im->im_status = IDMAP_STATUS_LOOKUPFAIL;
wake_up(&idmap->idmap_wq);
im->im_status = IDMAP_STATUS_LOOKUPFAIL;
wake_up(&idmap->idmap_wq);
-
up
(&idmap->idmap_im_lock);
+
mutex_unlock
(&idmap->idmap_im_lock);
}
/*
}
/*