lkml.org 
[lkml]   [1998]   [May]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: knfsd problem in late 2.1

Ok, this patch fixes knfsd. It does the following:

- Changes all internal interfaces to use kdev_t (including the
nfs filehandle cookie).
- Convert dev_t to kdev_t in all interfaces to usermode (nfsctl()).
The only exception is in the nfsfh cookie that is passed for a mount
request, but mountd should treat that as opaque anyways so it should
be no problem.
- Add some KERN_DEBUGs to printk()s. There are still some missing, and
far too many of them too (currently when I kill all nfsds in my shutdown
script I get half a screenfull of crap)
- Make linux/sunrpc/sched.h compile without -D__KERNEL__ [needed by
the user tools].

Linux, please add this patch to the next 2.1 kernel.

Thanks,

-Andi

diff -u -u -r1.13 linux/fs/nfsd/export.c
--- linux/fs/nfsd/export.c 07:40:28 1.13
+++ linux/fs/nfsd/export.c 13:42:58
@@ -32,8 +32,8 @@
typedef struct svc_client svc_client;
typedef struct svc_export svc_export;

-static svc_export * exp_find(svc_client *clp, dev_t dev);
-static svc_export * exp_parent(svc_client *clp, dev_t dev);
+static svc_export * exp_find(svc_client *clp, kdev_t dev);
+static svc_export * exp_parent(svc_client *clp, kdev_t dev);
static void exp_unexport_all(svc_client *clp);
static void exp_do_unexport(svc_export *unexp);
static svc_client * exp_getclientbyname(char *name);
@@ -46,6 +46,7 @@
#define CLIENT_HASHMASK (CLIENT_HASHMAX - 1)
#define CLIENT_HASH(a) \
((((a)>>24) ^ ((a)>>16) ^ ((a)>>8) ^(a)) & CLIENT_HASHMASK)
+/* XXX: is this adequate for 32bit kdev_t ? */
#define EXPORT_HASH(dev) ((dev) & (NFSCLNT_EXPMAX - 1))

struct svc_clnthash {
@@ -69,7 +70,7 @@
* Find a client's export for a device.
*/
static inline svc_export *
-exp_find(svc_client *clp, dev_t dev)
+exp_find(svc_client *clp, kdev_t dev)
{
svc_export * exp;

@@ -83,7 +84,7 @@
* Find the client's export entry matching xdev/xino.
*/
svc_export *
-exp_get(svc_client *clp, dev_t dev, ino_t ino)
+exp_get(svc_client *clp, kdev_t dev, ino_t ino)
{
svc_export * exp;

@@ -97,7 +98,7 @@
* Check whether there are any exports for a device.
*/
static int
-exp_device_in_use(dev_t dev)
+exp_device_in_use(kdev_t dev)
{
struct svc_client *clp;

@@ -112,7 +113,7 @@
* Look up the device of the parent fs.
*/
static inline int
-nfsd_parentdev(dev_t *devp)
+nfsd_parentdev(kdev_t *devp)
{
struct super_block *sb;

@@ -129,10 +130,10 @@
* only by the export syscall to keep the export tree consistent.
*/
static svc_export *
-exp_parent(svc_client *clp, dev_t dev)
+exp_parent(svc_client *clp, kdev_t dev)
{
svc_export *exp;
- dev_t xdev = dev;
+ kdev_t xdev = dev;

do {
exp = exp_find(clp, xdev);
@@ -155,7 +156,7 @@
struct dentry *dentry = NULL;
struct inode *inode = NULL;
int i, err;
- dev_t dev;
+ kdev_t dev;
ino_t ino;

/* Consistency check */
@@ -166,7 +167,7 @@
dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n",
nxp->ex_client, nxp->ex_path,
nxp->ex_dev, nxp->ex_ino, nxp->ex_flags);
- dev = nxp->ex_dev;
+ dev = to_kdev_t(nxp->ex_dev);
ino = nxp->ex_ino;

/* Try to lock the export table for update */
@@ -205,7 +206,10 @@
if(!inode)
goto finish;
err = -EINVAL;
- if(inode->i_dev != nxp->ex_dev || inode->i_ino != nxp->ex_ino) {
+ if(inode->i_dev != dev || inode->i_ino != nxp->ex_ino) {
+
+ printk(KERN_DEBUG "exp_export: i_dev = %x, dev = %x\n",
+ inode->i_dev, dev);
/* I'm just being paranoid... */
goto finish;
}
@@ -386,7 +390,7 @@
* since its harder to fool a kernel module than a user space program.
*/
int
-exp_rootfh(struct svc_client *clp, dev_t dev, ino_t ino, struct knfs_fh *f)
+exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino, struct knfs_fh *f)
{
struct svc_export *exp = NULL;
struct svc_fh fh;
Index: linux/fs/nfsd/nfsctl.c
===================================================================
RCS file: /vger/u4/cvs/linux/fs/nfsd/nfsctl.c,v
retrieving revision 1.8
diff -u -u -r1.8 linux/fs/nfsd/nfsctl.c
--- linux/fs/nfsd/nfsctl.c 21:05:00 1.8
+++ linux/fs/nfsd/nfsctl.c 13:42:59
@@ -124,7 +124,7 @@
if (!(clp = exp_getclient(sin)))
err = -EPERM;
else
- err = exp_rootfh(clp, data->gf_dev, data->gf_ino, res);
+ err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, res);
exp_unlock();

return err;
Index: linux/fs/nfsd/nfsfh.c
===================================================================
RCS file: /vger/u4/cvs/linux/fs/nfsd/nfsfh.c,v
retrieving revision 1.10
diff -u -u -r1.10 linux/fs/nfsd/nfsfh.c
--- linux/fs/nfsd/nfsfh.c 08:01:59 1.10
+++ linux/fs/nfsd/nfsfh.c 13:42:59
@@ -29,7 +29,7 @@
struct dentry * dentry;
unsigned long reftime;
ino_t ino;
- dev_t dev;
+ kdev_t dev;
};

#define NFSD_MAXFH PAGE_SIZE/sizeof(struct fh_entry)
@@ -42,7 +42,7 @@

static int add_to_fhcache(struct dentry *, int);
static int nfsd_d_validate(struct dentry *);
-struct dentry * lookup_inode(dev_t, ino_t, ino_t);
+struct dentry * lookup_inode(kdev_t, ino_t, ino_t);

static LIST_HEAD(fixup_head);
static LIST_HEAD(path_inuse);
@@ -55,7 +55,7 @@
struct list_head lru;
ino_t dir;
ino_t ino;
- dev_t dev;
+ kdev_t dev;
struct dentry *dentry;
unsigned long reftime;
};
@@ -65,11 +65,11 @@
unsigned long reftime;
int users;
ino_t ino;
- dev_t dev;
+ kdev_t dev;
char name[1];
};

-static struct nfsd_fixup * find_cached_lookup(dev_t dev, ino_t dir, ino_t ino)
+static struct nfsd_fixup * find_cached_lookup(kdev_t dev, ino_t dir, ino_t ino)
{
struct list_head *tmp = fixup_head.next;

@@ -226,14 +226,14 @@
*/
retry:
kfree(new);
- printk("add_to_path_cache: path length changed, retrying\n");
+ printk(KERN_DEBUG "add_to_path_cache: path length changed, retrying\n");
goto restart;
}

/*
* Search for a path entry for the specified (dev, inode).
*/
-struct nfsd_path *get_path_entry(dev_t dev, ino_t ino)
+struct nfsd_path *get_path_entry(kdev_t dev, ino_t ino)
{
struct nfsd_path *pe;
struct list_head *tmp;
@@ -264,7 +264,7 @@
static void free_path_entry(struct nfsd_path *pe)
{
if (pe->users)
- printk("free_path_entry: %s in use, users=%d\n",
+ printk(KERN_DEBUG "free_path_entry: %s in use, users=%d\n",
pe->name, pe->users);
list_del(&pe->lru);
kfree(pe);
@@ -381,7 +381,7 @@
* searching for a dentry given the inode: as we walk up the tree,
* it's likely that a dentry exists before we reach the root.
*/
-struct dentry * lookup_inode(dev_t dev, ino_t dirino, ino_t ino)
+struct dentry * lookup_inode(kdev_t dev, ino_t dirino, ino_t ino)
{
struct super_block *sb;
struct dentry *root, *dentry, *result;
@@ -457,7 +457,8 @@
* Make sure we can't get caught in a loop ...
*/
if (dirino == dirent.ino && dirino != root_ino) {
- printk("lookup_inode: looping?? (ino=%ld, path=%s)\n",
+ printk(KERN_DEBUG
+ "lookup_inode: looping?? (ino=%ld, path=%s)\n",
dirino, name);
goto out_root;
}
@@ -649,7 +650,7 @@
/*
* Find an entry in the dir cache for the specified inode number.
*/
-static struct fh_entry *find_fhe_by_ino(dev_t dev, ino_t ino)
+static struct fh_entry *find_fhe_by_ino(kdev_t dev, ino_t ino)
{
struct fh_entry * fhe = &dirstable[0];
int i;
@@ -667,7 +668,7 @@
* Find the (directory) dentry with the specified (dev, inode) number.
* Note: this leaves the dentry in the cache.
*/
-static struct dentry *find_dentry_by_ino(dev_t dev, ino_t ino)
+static struct dentry *find_dentry_by_ino(kdev_t dev, ino_t ino)
{
struct fh_entry *fhe;
struct nfsd_path *pe;
@@ -1129,14 +1130,14 @@
struct inode *inode;

if (!fhp->fh_dverified) {
- printk("fh_update: fh not verified!\n");
+ printk(KERN_DEBUG "fh_update: fh not verified!\n");
goto out;
}

dentry = fhp->fh_dentry;
inode = dentry->d_inode;
if (!inode) {
- printk("fh_update: %s/%s still negative!\n",
+ printk(KERN_DEBUG "fh_update: %s/%s still negative!\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
goto out;
}
@@ -1157,7 +1158,7 @@
fh_unlock(fhp);
fhp->fh_dverified = 0;
if (!dentry->d_count) {
- printk("fh_put: %s/%s has d_count 0!\n",
+ printk(KERN_DEBUG "fh_put: %s/%s has d_count 0!\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
return;
}
@@ -1209,10 +1210,10 @@
return valid;

bad_addr:
- printk("nfsd_d_validate: invalid address %lx\n", dent_addr);
+ printk(KERN_DEBUG "nfsd_d_validate: invalid address %lx\n", dent_addr);
goto out;
bad_align:
- printk("nfsd_d_validate: unaligned address %lx\n", dent_addr);
+ printk(KERN_DEBUG "nfsd_d_validate: unaligned address %lx\n", dent_addr);
goto out;
}

@@ -1223,7 +1224,7 @@
* This is called when revoking the last export for a
* device, so that it can be unmounted cleanly.
*/
-void nfsd_fh_flush(dev_t dev)
+void nfsd_fh_flush(kdev_t dev)
{
struct fh_entry *fhe;
int i, pass = 2;
@@ -1265,7 +1266,7 @@
free_fixup_entry(fp);
i++;
}
- printk("nfsd_fh_free: %d fixups freed\n", i);
+ printk(KERN_DEBUG "nfsd_fh_free: %d fixups freed\n", i);

i = 0;
while ((tmp = path_inuse.next) != &path_inuse) {
@@ -1274,18 +1275,23 @@
free_path_entry(pe);
i++;
}
- printk("nfsd_fh_free: %d paths freed\n", i);
+ printk(KERN_DEBUG "nfsd_fh_free: %d paths freed\n", i);

- printk("nfsd_fh_free: verified %d, put %d\n",
+ printk(KERN_DEBUG "nfsd_fh_free: verified %d, put %d\n",
nfsd_nr_verified, nfsd_nr_put);
}

void nfsd_fh_init(void)
{
+ /* Sanity check */
+ extern void __my_nfsfh_is_too_big(void);
+ if (sizeof(struct nfs_fhbase) > 32)
+ __my_nfsfh_is_too_big();
+
memset(filetable, 0, NFSD_MAXFH*sizeof(struct fh_entry));
memset(dirstable, 0, NFSD_MAXFH*sizeof(struct fh_entry));
INIT_LIST_HEAD(&path_inuse);
INIT_LIST_HEAD(&fixup_head);

- printk("nfsd_init: initialized fhcache, entries=%lu\n", NFSD_MAXFH);
+ printk(KERN_DEBUG "nfsd_init: initialized fhcache, entries=%lu\n", NFSD_MAXFH);
}
diff -u -u -r1.2 linux/include/linux/nfsd/export.h
--- linux/include/linux/nfsd/export.h 11:11:30 1.2
+++ linux/include/linux/nfsd/export.h 13:44:19
@@ -60,7 +60,7 @@
struct svc_client * ex_client;
int ex_flags;
struct dentry * ex_dentry;
- dev_t ex_dev;
+ kdev_t ex_dev;
ino_t ex_ino;
uid_t ex_anon_uid;
gid_t ex_anon_gid;
@@ -84,8 +84,8 @@
void exp_unlock(void);
struct svc_client * exp_getclient(struct sockaddr_in *sin);
void exp_putclient(struct svc_client *clp);
-struct svc_export * exp_get(struct svc_client *clp, dev_t dev, ino_t ino);
-int exp_rootfh(struct svc_client *, dev_t, ino_t,
+struct svc_export * exp_get(struct svc_client *clp, kdev_t dev, ino_t ino);
+int exp_rootfh(struct svc_client *, kdev_t, ino_t,
struct knfs_fh *);
int nfserrno(int errno);
void exp_nlmdetach(void);
Index: linux/include/linux/nfsd/nfsfh.h
===================================================================
RCS file: /vger/u4/cvs/linux/include/linux/nfsd/nfsfh.h,v
retrieving revision 1.9
diff -u -u -r1.9 linux/include/linux/nfsd/nfsfh.h
--- linux/include/linux/nfsd/nfsfh.h 08:03:05 1.9
+++ linux/include/linux/nfsd/nfsfh.h 13:44:22
@@ -30,8 +30,8 @@
struct dentry * fb_dentry; /* dentry cookie */
ino_t fb_ino; /* our inode number */
ino_t fb_dirino; /* dir inode number */
- dev_t fb_dev; /* our device */
- dev_t fb_xdev;
+ kdev_t fb_dev; /* our device */
+ kdev_t fb_xdev;
ino_t fb_xino;
};

@@ -80,7 +80,7 @@
void fh_compose(struct svc_fh *, struct svc_export *, struct dentry *);
void fh_update(struct svc_fh *);
void fh_put(struct svc_fh *);
-void nfsd_fh_flush(dev_t);
+void nfsd_fh_flush(kdev_t);
void nfsd_fh_init(void);
void nfsd_fh_free(void);

Index: linux/include/linux/sunrpc/sched.h
===================================================================
RCS file: /vger/u4/cvs/linux/include/linux/sunrpc/sched.h,v
retrieving revision 1.3
diff -u -u -r1.3 linux/include/linux/sunrpc/sched.h
--- linux/include/linux/sunrpc/sched.h 15:42:49 1.3
+++ linux/include/linux/sunrpc/sched.h 13:44:26
@@ -39,11 +39,11 @@
/*
* RPC call state
*/
- u32 tk_proc; /* procedure number */
- u32 * tk_buffer; /* XDR buffer */
+ __u32 tk_proc; /* procedure number */
+ __u32 * tk_buffer; /* XDR buffer */
void * tk_argp; /* argument storage */
void * tk_resp; /* result storage */
- u8 tk_garb_retry,
+ __u8 tk_garb_retry,
tk_cred_retry,
tk_suid_retry;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 13:42    [W:1.300 / U:0.876 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site