Messages in this thread Patch in this message | | | Date | Thu, 21 May 1998 16:27:41 +0200 | From | ak@muc ... | Subject | Re: 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
| |