From: NeilBrown Date: Fri, 26 Jan 2007 08:57:10 +0000 (-0800) Subject: [PATCH] knfsd: Fix type mismatch with filldir_t used by nfsd X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=a0ad13ef643a5829d63c456ab6143bbda60b44a9;p=openwrt%2Fstaging%2Fblogic.git [PATCH] knfsd: Fix type mismatch with filldir_t used by nfsd nfsd defines a type 'encode_dent_fn' which is much like 'filldir_t' except that the first pointer is 'struct readdir_cd *' rather than 'void *'. It then casts encode_dent_fn points to 'filldir_t' as needed. This hides any other type mismatches between the two such as the fact that the 'ino' arg recently changed from ino_t to u64. So: get rid of 'encode_dent_fn', get rid of the cast of the function type, change the first arg of various functions from 'struct readdir_cd *' to 'void *', and live with the fact that we have a little less type checking on the calling of these functions now. Less internal (to nfsd) checking offset by more external checking, which is more important. Thanks to Gabriel Paubert for discovering this and providing an initial patch. Signed-off-by: Gabriel Paubert Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 277df40f098d..e695660921ec 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -990,15 +990,16 @@ encode_entry(struct readdir_cd *ccd, const char *name, } int -nfs3svc_encode_entry(struct readdir_cd *cd, const char *name, - int namlen, loff_t offset, ino_t ino, unsigned int d_type) +nfs3svc_encode_entry(void *cd, const char *name, + int namlen, loff_t offset, u64 ino, unsigned int d_type) { return encode_entry(cd, name, namlen, offset, ino, d_type, 0); } int -nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name, - int namlen, loff_t offset, ino_t ino, unsigned int d_type) +nfs3svc_encode_entry_plus(void *cd, const char *name, + int namlen, loff_t offset, u64 ino, + unsigned int d_type) { return encode_entry(cd, name, namlen, offset, ino, d_type, 1); } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index fea46368afb2..18aa9440df14 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1880,9 +1880,10 @@ nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr) } static int -nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type) +nfsd4_encode_dirent(void *ccdv, const char *name, int namlen, + loff_t offset, u64 ino, unsigned int d_type) { + struct readdir_cd *ccd = ccdv; struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); int buflen; __be32 *p = cd->buffer; diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index f5243f943996..6555c50d9006 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -462,9 +462,10 @@ nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_entry(struct readdir_cd *ccd, const char *name, - int namlen, loff_t offset, ino_t ino, unsigned int d_type) +nfssvc_encode_entry(void *ccdv, const char *name, + int namlen, loff_t offset, u64 ino, unsigned int d_type) { + struct readdir_cd *ccd = ccdv; struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common); __be32 *p = cd->buffer; int buflen, slen; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 4dd49d6e90cd..5d32e5fa697e 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1716,7 +1716,7 @@ out: */ __be32 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, - struct readdir_cd *cdp, encode_dent_fn func) + struct readdir_cd *cdp, filldir_t func) { __be32 err; int host_err; @@ -1741,7 +1741,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, do { cdp->err = nfserr_eof; /* will be cleared on successful read */ - host_err = vfs_readdir(file, (filldir_t) func, cdp); + host_err = vfs_readdir(file, func, cdp); } while (host_err >=0 && cdp->err == nfs_ok); if (host_err) err = nfserrno(host_err); diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h index 0727774772ba..4b7c4b568f6d 100644 --- a/include/linux/nfsd/nfsd.h +++ b/include/linux/nfsd/nfsd.h @@ -52,8 +52,6 @@ struct readdir_cd { __be32 err; /* 0, nfserr, or nfserr_eof */ }; -typedef int (*encode_dent_fn)(struct readdir_cd *, const char *, - int, loff_t, ino_t, unsigned int); typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); extern struct svc_program nfsd_program; @@ -117,7 +115,7 @@ __be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, int nfsd_truncate(struct svc_rqst *, struct svc_fh *, unsigned long size); __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, - loff_t *, struct readdir_cd *, encode_dent_fn); + loff_t *, struct readdir_cd *, filldir_t); __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, struct kstatfs *); diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h index 877192d3ae79..67885d5e6e50 100644 --- a/include/linux/nfsd/xdr.h +++ b/include/linux/nfsd/xdr.h @@ -165,8 +165,8 @@ int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *); int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); -int nfssvc_encode_entry(struct readdir_cd *, const char *name, - int namlen, loff_t offset, ino_t ino, unsigned int); +int nfssvc_encode_entry(void *, const char *name, + int namlen, loff_t offset, u64 ino, unsigned int); int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h index 79963867b0d7..89d9d6061a62 100644 --- a/include/linux/nfsd/xdr3.h +++ b/include/linux/nfsd/xdr3.h @@ -331,11 +331,11 @@ int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd3_attrstat *); int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, struct nfsd3_fhandle_pair *); -int nfs3svc_encode_entry(struct readdir_cd *, const char *name, - int namlen, loff_t offset, ino_t ino, +int nfs3svc_encode_entry(void *, const char *name, + int namlen, loff_t offset, u64 ino, unsigned int); -int nfs3svc_encode_entry_plus(struct readdir_cd *, const char *name, - int namlen, loff_t offset, ino_t ino, +int nfs3svc_encode_entry_plus(void *, const char *name, + int namlen, loff_t offset, u64 ino, unsigned int); /* Helper functions for NFSv3 ACL code */ __be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p,