lkml.org 
[lkml]   [1998]   [Jul]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectpatch for 2.1.109 knfsd filehandles
The attached patch redefines the fields in the knfsd filehandle to avoid
present and future problems related to type size changes.

The patch uses fixed size __u32 fields for all inode number and device
number fields, leaving only the dentry cookie as a pointer. This will
give a maximum size of 5*4+8=28 bytes to guarantee a fit in the 32 byte
limit.

I've defined conversion functions to go to/from the u32 fields, e.g.
u32_to_kdev_t(). These are currently just casts, but can be easily
changed as needed. For example, if kdev_t becomes a pointer to a table
entry, the conversion functions can be changed to add or subtract the
table base.

The casts from 64-bit ino_t fields will work OK as long as the
filesystems in question don't go beyond using the low-order 32 bits.
I've added a load-time warning if sizeof(ino_t) is > 4.

I've tested it here and all is working OK, but would appreciate some
testing on 64-bit systems.

Regards,
Bill--- linux-2.1.109/include/linux/nfsd/nfsfh.h.old Fri Jul 17 13:22:46 1998
+++ linux-2.1.109/include/linux/nfsd/nfsfh.h Mon Jul 20 18:52:07 1998
@@ -27,12 +27,12 @@
* ino/dev of the exported inode.
*/
struct nfs_fhbase {
- struct dentry * fb_dentry; /* dentry cookie */
- ino_t fb_ino; /* our inode number */
- ino_t fb_dirino; /* dir inode number */
- kdev_t fb_dev; /* our device */
- kdev_t fb_xdev;
- ino_t fb_xino;
+ struct dentry * fb_dentry; /* dentry cookie */
+ __u32 fb_ino; /* our inode number */
+ __u32 fb_dirino; /* dir inode number */
+ __u32 fb_dev; /* our device */
+ __u32 fb_xdev;
+ __u32 fb_xino;
};

#define NFS_FH_PADDING (NFS_FHSIZE - sizeof(struct nfs_fhbase))
@@ -49,6 +49,29 @@
#define fh_xino fh_base.fb_xino

#ifdef __KERNEL__
+
+/*
+ * Conversion macros for the filehandle fields.
+ */
+extern inline __u32 kdev_t_to_u32(kdev_t dev)
+{
+ return (__u32) dev;
+}
+
+extern inline kdev_t u32_to_kdev_t(__u32 udev)
+{
+ return (kdev_t) udev;
+}
+
+extern inline __u32 ino_t_to_u32(ino_t ino)
+{
+ return (__u32) ino;
+}
+
+extern inline ino_t u32_to_ino_t(__u32 uino)
+{
+ return (ino_t) uino;
+}

/*
* This is the internal representation of an NFS handle used in knfsd.
--- linux-2.1.109/fs/nfsd/nfsfh.c.old Fri Jul 3 10:32:32 1998
+++ linux-2.1.109/fs/nfsd/nfsfh.c Mon Jul 20 21:05:02 1998
@@ -98,7 +98,9 @@
{
struct nfsd_fixup *fp;

- fp = find_cached_lookup(fh->fh_dev, fh->fh_dirino, fh->fh_ino);
+ fp = find_cached_lookup(u32_to_kdev_t(fh->fh_dev),
+ u32_to_ino_t(fh->fh_dirino),
+ u32_to_ino_t(fh->fh_ino));
if (fp) {
fp->dentry = dentry;
return;
@@ -111,9 +113,9 @@
*/
fp = kmalloc(sizeof(struct nfsd_fixup), GFP_KERNEL);
if (fp) {
- fp->dir = fh->fh_dirino;
- fp->ino = fh->fh_ino;
- fp->dev = fh->fh_dev;
+ fp->dir = u32_to_kdev_t(fh->fh_dirino);
+ fp->ino = u32_to_ino_t(fh->fh_ino);
+ fp->dev = u32_to_ino_t(fh->fh_dev);
fp->dentry = dentry;
fp->reftime = jiffies;
list_add(&fp->lru, &fixup_head);
@@ -763,7 +765,9 @@
#endif
goto out;
}
- if (inode->i_ino != fh->fh_ino || inode->i_dev != fh->fh_dev)
+ if (inode->i_ino != u32_to_ino_t(fh->fh_ino))
+ goto out;
+ if (inode->i_dev != u32_to_kdev_t(fh->fh_dev))
goto out;

fhe->dentry = NULL;
@@ -839,7 +843,9 @@
{
struct nfsd_fixup *fp;

- fp = find_cached_lookup(fh->fh_dev, fh->fh_dirino, fh->fh_ino);
+ fp = find_cached_lookup(u32_to_kdev_t(fh->fh_dev),
+ u32_to_ino_t(fh->fh_dirino),
+ u32_to_ino_t(fh->fh_ino));
if (fp)
return fp->dentry;
return NULL;
@@ -893,13 +899,14 @@
if (nfsd_d_validate(dentry)) {
struct inode * dir = dentry->d_parent->d_inode;

- if (dir->i_ino == fh->fh_dirino && dir->i_dev == fh->fh_dev) {
+ if (dir->i_ino == u32_to_ino_t(fh->fh_dirino) &&
+ dir->i_dev == u32_to_kdev_t(fh->fh_dev)) {
struct inode * inode = dentry->d_inode;
/*
* NFS file handles must always have an inode,
* so we won't accept a negative dentry.
*/
- if (inode && inode->i_ino == fh->fh_ino) {
+ if (inode && inode->i_ino == u32_to_ino_t(fh->fh_ino)) {
dget(dentry);
#ifdef NFSD_DEBUG_VERBOSE
printk("find_fh_dentry: validated %s/%s, ino=%ld\n",
@@ -932,14 +939,16 @@
* numbers. This should work for all Unix-like filesystems.
*/
looked_up = 1;
- dentry = lookup_inode(fh->fh_dev, fh->fh_dirino, fh->fh_ino);
+ dentry = lookup_inode(u32_to_kdev_t(fh->fh_dev),
+ u32_to_ino_t(fh->fh_dirino),
+ u32_to_ino_t(fh->fh_ino));
if (!IS_ERR(dentry)) {
struct inode * inode = dentry->d_inode;
#ifdef NFSD_DEBUG_VERBOSE
printk("find_fh_dentry: looked up %s/%s\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
#endif
- if (inode && inode->i_ino == fh->fh_ino) {
+ if (inode && inode->i_ino == u32_to_ino_t(fh->fh_ino)) {
nfsdstats.fh_lookup++;
goto out;
}
@@ -953,12 +962,13 @@
/*
* Stage 4: Look for the parent dentry in the fhcache ...
*/
- parent = find_dentry_by_ino(fh->fh_dev, fh->fh_dirino);
+ parent = find_dentry_by_ino(u32_to_kdev_t(fh->fh_dev),
+ u32_to_ino_t(fh->fh_dirino));
if (parent) {
/*
* ... then search for the inode in the parent directory.
*/
- dentry = lookup_by_inode(parent, fh->fh_ino);
+ dentry = lookup_by_inode(parent, u32_to_ino_t(fh->fh_ino));
dput(parent);
if (dentry)
goto out;
@@ -968,8 +978,8 @@
* Stage 5: Search the whole volume.
*/
#ifdef NFSD_PARANOIA
-printk("find_fh_dentry: %s, %ld/%ld not found -- need full search!\n",
-kdevname(fh->fh_dev), fh->fh_dirino, fh->fh_ino);
+printk("find_fh_dentry: %s, %u/%u not found -- need full search!\n",
+kdevname(u32_to_kdev_t(fh->fh_dev)), fh->fh_dirino, fh->fh_ino);
#endif
dentry = NULL;
nfsdstats.fh_stale++;
@@ -1006,7 +1016,7 @@
struct inode *inode;
u32 error = 0;

- dprintk("nfsd: fh_verify(exp %x/%ld cookie %p)\n",
+ dprintk("nfsd: fh_verify(exp %x/%u cookie %p)\n",
fh->fh_xdev, fh->fh_xino, fh->fh_dcookie);

if(fhp->fh_dverified)
@@ -1015,7 +1025,9 @@
* Look up the export entry.
*/
error = nfserr_stale;
- exp = exp_get(rqstp->rq_client, fh->fh_xdev, fh->fh_xino);
+ exp = exp_get(rqstp->rq_client,
+ u32_to_kdev_t(fh->fh_xdev),
+ u32_to_ino_t(fh->fh_xino));
if (!exp) /* export entry revoked */
goto out;

@@ -1091,6 +1103,7 @@
fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry)
{
struct inode * inode = dentry->d_inode;
+ struct dentry *parent = dentry->d_parent;

dprintk("nfsd: fh_compose(exp %x/%ld %s/%s, ino=%ld)\n",
exp->ex_dev, exp->ex_ino,
@@ -1105,12 +1118,12 @@
fh_init(fhp);
fhp->fh_handle.fh_dcookie = dentry;
if (inode) {
- fhp->fh_handle.fh_ino = inode->i_ino;
+ fhp->fh_handle.fh_ino = ino_t_to_u32(inode->i_ino);
}
- fhp->fh_handle.fh_dirino = dentry->d_parent->d_inode->i_ino;
- fhp->fh_handle.fh_dev = dentry->d_parent->d_inode->i_dev;
- fhp->fh_handle.fh_xdev = exp->ex_dev;
- fhp->fh_handle.fh_xino = exp->ex_ino;
+ fhp->fh_handle.fh_dirino = ino_t_to_u32(parent->d_inode->i_ino);
+ fhp->fh_handle.fh_dev = kdev_t_to_u32(parent->d_inode->i_dev);
+ fhp->fh_handle.fh_xdev = kdev_t_to_u32(exp->ex_dev);
+ fhp->fh_handle.fh_xino = ino_t_to_u32(exp->ex_ino);

fhp->fh_dentry = dentry; /* our internal copy */
fhp->fh_export = exp;
@@ -1129,21 +1142,24 @@
struct dentry *dentry;
struct inode *inode;

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

dentry = fhp->fh_dentry;
inode = dentry->d_inode;
- if (!inode) {
- printk(KERN_DEBUG "fh_update: %s/%s still negative!\n",
- dentry->d_parent->d_name.name, dentry->d_name.name);
- goto out;
- }
- fhp->fh_handle.fh_ino = inode->i_ino;
+ if (!inode)
+ goto out_negative;
+ fhp->fh_handle.fh_ino = ino_t_to_u32(inode->i_ino);
out:
return;
+
+out_bad:
+ printk(KERN_ERR "fh_update: fh not verified!\n");
+ goto out;
+out_negative:
+ printk(KERN_ERR "fh_update: %s/%s still negative!\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name);
+ goto out;
}

/*
@@ -1153,20 +1169,23 @@
void
fh_put(struct svc_fh *fhp)
{
+ struct dentry * dentry = fhp->fh_dentry;
if (fhp->fh_dverified) {
- struct dentry * dentry = fhp->fh_dentry;
fh_unlock(fhp);
fhp->fh_dverified = 0;
- if (!dentry->d_count) {
- printk(KERN_DEBUG "fh_put: %s/%s has d_count 0!\n",
- dentry->d_parent->d_name.name, dentry->d_name.name);
- return;
- }
+ if (!dentry->d_count)
+ goto out_bad;
if (!dentry->d_inode || !add_to_fhcache(dentry, 0)) {
dput(dentry);
nfsd_nr_put++;
}
}
+ return;
+
+out_bad:
+ printk(KERN_ERR "fh_put: %s/%s has d_count 0!\n",
+ dentry->d_parent->d_name.name, dentry->d_name.name);
+ return;
}

/*
@@ -1288,5 +1307,13 @@
INIT_LIST_HEAD(&path_inuse);
INIT_LIST_HEAD(&fixup_head);

- printk(KERN_DEBUG "nfsd_init: initialized fhcache, entries=%lu\n", NFSD_MAXFH);
+ printk(KERN_DEBUG
+ "nfsd_init: initialized fhcache, entries=%lu\n", NFSD_MAXFH);
+ /*
+ * Display a warning if the ino_t is larger than 32 bits.
+ */
+ if (sizeof(ino_t) > sizeof(__u32))
+ printk(KERN_INFO
+ "NFSD: ino_t is %d bytes, using lower 4 bytes\n",
+ sizeof(ino_t));
}
--- linux-2.1.109/fs/lockd/svcsubs.c.old Wed Dec 10 00:12:14 1997
+++ linux-2.1.109/fs/lockd/svcsubs.c Mon Jul 20 19:36:15 1998
@@ -48,13 +48,15 @@
nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
struct nfs_fh *f)
{
- struct nlm_file *file;
struct knfs_fh *fh = (struct knfs_fh *) f;
- unsigned int hash = file_hash(fh->fh_dev, fh->fh_ino);
+ struct nlm_file *file;
+ unsigned int hash;
u32 nfserr;

- dprintk("lockd: nlm_file_lookup(%s/%ld)\n",
- kdevname(fh->fh_dev), fh->fh_ino);
+ dprintk("lockd: nlm_file_lookup(%s/%u)\n",
+ kdevname(u32_to_kdev_t(fh->fh_dev)), fh->fh_ino);
+
+ hash = file_hash(u32_to_kdev_t(fh->fh_dev), u32_to_ino_t(fh->fh_ino));

/* Lock file table */
down(&nlm_file_sema);
@@ -65,8 +67,8 @@
goto found;
}

- dprintk("lockd: creating file for %s/%ld\n",
- kdevname(fh->fh_dev), fh->fh_ino);
+ dprintk("lockd: creating file for %s/%u\n",
+ kdevname(u32_to_kdev_t(fh->fh_dev)), fh->fh_ino);
nfserr = nlm_lck_denied_nolocks;
file = (struct nlm_file *) kmalloc(sizeof(*file), GFP_KERNEL);
if (!file)
\
 
 \ /
  Last update: 2005-03-22 13:43    [W:0.034 / U:1.532 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site