diff options
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 59 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 17 | ||||
-rw-r--r-- | fs/nfsd/nfsxdr.c | 4 | ||||
-rw-r--r-- | include/linux/nfsd/nfsfh.h | 42 | ||||
-rw-r--r-- | include/linux/nfsd/xdr4.h | 4 |
5 files changed, 45 insertions, 81 deletions
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 10f6e7dcf633..2d116d2298f8 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -174,9 +174,6 @@ static __be32 * encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat) { - struct dentry *dentry = fhp->fh_dentry; - struct timespec time; - *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); *p++ = htonl((u32) stat->mode); *p++ = htonl((u32) stat->nlink); @@ -191,10 +188,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, *p++ = htonl((u32) MAJOR(stat->rdev)); *p++ = htonl((u32) MINOR(stat->rdev)); p = encode_fsid(p, fhp); - p = xdr_encode_hyper(p, (u64) stat->ino); + p = xdr_encode_hyper(p, stat->ino); p = encode_time3(p, &stat->atime); - lease_get_mtime(dentry->d_inode, &time); - p = encode_time3(p, &time); + p = encode_time3(p, &stat->mtime); p = encode_time3(p, &stat->ctime); return p; @@ -203,31 +199,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, static __be32 * encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) { - struct inode *inode = fhp->fh_dentry->d_inode; - /* Attributes to follow */ *p++ = xdr_one; - - *p++ = htonl(nfs3_ftypes[(fhp->fh_post_mode & S_IFMT) >> 12]); - *p++ = htonl((u32) fhp->fh_post_mode); - *p++ = htonl((u32) fhp->fh_post_nlink); - *p++ = htonl((u32) nfsd_ruid(rqstp, fhp->fh_post_uid)); - *p++ = htonl((u32) nfsd_rgid(rqstp, fhp->fh_post_gid)); - if (S_ISLNK(fhp->fh_post_mode) && fhp->fh_post_size > NFS3_MAXPATHLEN) { - p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); - } else { - p = xdr_encode_hyper(p, (u64) fhp->fh_post_size); - } - p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9); - *p++ = fhp->fh_post_rdev[0]; - *p++ = fhp->fh_post_rdev[1]; - p = encode_fsid(p, fhp); - p = xdr_encode_hyper(p, (u64) inode->i_ino); - p = encode_time3(p, &fhp->fh_post_atime); - p = encode_time3(p, &fhp->fh_post_mtime); - p = encode_time3(p, &fhp->fh_post_ctime); - - return p; + return encode_fattr3(rqstp, p, fhp, &fhp->fh_post_attr); } /* @@ -246,6 +220,7 @@ encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) err = vfs_getattr(fhp->fh_export->ex_mnt, dentry, &stat); if (!err) { *p++ = xdr_one; /* attributes follow */ + lease_get_mtime(dentry->d_inode, &stat.mtime); return encode_fattr3(rqstp, p, fhp, &stat); } } @@ -284,6 +259,23 @@ encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) return encode_post_op_attr(rqstp, p, fhp); } +/* + * Fill in the post_op attr for the wcc data + */ +void fill_post_wcc(struct svc_fh *fhp) +{ + int err; + + if (fhp->fh_post_saved) + printk("nfsd: inode locked twice during operation.\n"); + + err = vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, + &fhp->fh_post_attr); + if (err) + fhp->fh_post_saved = 0; + else + fhp->fh_post_saved = 1; +} /* * XDR decode functions @@ -643,8 +635,11 @@ int nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, struct nfsd3_attrstat *resp) { - if (resp->status == 0) + if (resp->status == 0) { + lease_get_mtime(resp->fh.fh_dentry->d_inode, + &resp->stat.mtime); p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat); + } return xdr_ressize_check(rqstp, p); } @@ -802,7 +797,7 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, static __be32 * encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, - int namlen, ino_t ino) + int namlen, u64 ino) { *p++ = xdr_one; /* mark entry present */ p = xdr_encode_hyper(p, ino); /* file id */ @@ -873,7 +868,7 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2)) static int encode_entry(struct readdir_cd *ccd, const char *name, int namlen, - loff_t offset, ino_t ino, unsigned int d_type, int plus) + loff_t offset, u64 ino, unsigned int d_type, int plus) { struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, common); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8ef0964179bc..9cf900740c76 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1679,7 +1679,7 @@ out_acl: if (bmval0 & FATTR4_WORD0_FILEID) { if ((buflen -= 8) < 0) goto out_resource; - WRITE64((u64) stat.ino); + WRITE64(stat.ino); } if (bmval0 & FATTR4_WORD0_FILES_AVAIL) { if ((buflen -= 8) < 0) @@ -1821,16 +1821,15 @@ out_acl: WRITE32(stat.mtime.tv_nsec); } if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) { - struct dentry *mnt_pnt, *mnt_root; - if ((buflen -= 8) < 0) goto out_resource; - mnt_root = exp->ex_mnt->mnt_root; - if (mnt_root->d_inode == dentry->d_inode) { - mnt_pnt = exp->ex_mnt->mnt_mountpoint; - WRITE64((u64) mnt_pnt->d_inode->i_ino); - } else - WRITE64((u64) stat.ino); + if (exp->ex_mnt->mnt_root->d_inode == dentry->d_inode) { + err = vfs_getattr(exp->ex_mnt->mnt_parent, + exp->ex_mnt->mnt_mountpoint, &stat); + if (err) + goto out_nfserr; + } + WRITE64(stat.ino); } *attrlenp = htonl((char *)p - (char *)attrlenp - 4); *countp = p - buffer; diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index cb3e7fadb772..986f9b32083c 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -523,6 +523,10 @@ nfssvc_encode_entry(void *ccdv, const char *name, cd->common.err = nfserr_toosmall; return -EINVAL; } + if (ino > ~((u32) 0)) { + cd->common.err = nfserr_fbig; + return -EINVAL; + } *p++ = xdr_one; /* mark entry present */ *p++ = htonl((u32) ino); /* file id */ p = xdr_encode_array(p, name, namlen);/* name length & name */ diff --git a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h index 11e568ee0eeb..d1941cb965e9 100644 --- a/include/linux/nfsd/nfsfh.h +++ b/include/linux/nfsd/nfsfh.h @@ -150,17 +150,7 @@ typedef struct svc_fh { struct timespec fh_pre_ctime; /* ctime before oper */ /* Post-op attributes saved in fh_unlock */ - umode_t fh_post_mode; /* i_mode */ - nlink_t fh_post_nlink; /* i_nlink */ - uid_t fh_post_uid; /* i_uid */ - gid_t fh_post_gid; /* i_gid */ - __u64 fh_post_size; /* i_size */ - unsigned long fh_post_blocks; /* i_blocks */ - unsigned long fh_post_blksize;/* i_blksize */ - __be32 fh_post_rdev[2];/* i_rdev */ - struct timespec fh_post_atime; /* i_atime */ - struct timespec fh_post_mtime; /* i_mtime */ - struct timespec fh_post_ctime; /* i_ctime */ + struct kstat fh_post_attr; /* full attrs after operation */ #endif /* CONFIG_NFSD_V3 */ } svc_fh; @@ -297,36 +287,12 @@ fill_pre_wcc(struct svc_fh *fhp) if (!fhp->fh_pre_saved) { fhp->fh_pre_mtime = inode->i_mtime; fhp->fh_pre_ctime = inode->i_ctime; - fhp->fh_pre_size = inode->i_size; - fhp->fh_pre_saved = 1; + fhp->fh_pre_size = inode->i_size; + fhp->fh_pre_saved = 1; } } -/* - * Fill in the post_op attr for the wcc data - */ -static inline void -fill_post_wcc(struct svc_fh *fhp) -{ - struct inode *inode = fhp->fh_dentry->d_inode; - - if (fhp->fh_post_saved) - printk("nfsd: inode locked twice during operation.\n"); - - fhp->fh_post_mode = inode->i_mode; - fhp->fh_post_nlink = inode->i_nlink; - fhp->fh_post_uid = inode->i_uid; - fhp->fh_post_gid = inode->i_gid; - fhp->fh_post_size = inode->i_size; - fhp->fh_post_blksize = BLOCK_SIZE; - fhp->fh_post_blocks = inode->i_blocks; - fhp->fh_post_rdev[0] = htonl((u32)imajor(inode)); - fhp->fh_post_rdev[1] = htonl((u32)iminor(inode)); - fhp->fh_post_atime = inode->i_atime; - fhp->fh_post_mtime = inode->i_mtime; - fhp->fh_post_ctime = inode->i_ctime; - fhp->fh_post_saved = 1; -} +extern void fill_post_wcc(struct svc_fh *); #else #define fill_pre_wcc(ignored) #define fill_post_wcc(notused) diff --git a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h index 1b653267133a..b0ddfb41c790 100644 --- a/include/linux/nfsd/xdr4.h +++ b/include/linux/nfsd/xdr4.h @@ -428,8 +428,8 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) cinfo->atomic = 1; cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; - cinfo->after_ctime_sec = fhp->fh_post_ctime.tv_sec; - cinfo->after_ctime_nsec = fhp->fh_post_ctime.tv_nsec; + cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; + cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; } int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); |