static inline u32 * encode_fattr(struct svc_rqst *rqstp, u32 *p, struct inode *inode) { if (!inode) return 0; *p++ = htonl(nfs_ftypes[(inode->i_mode & S_IFMT) >> 12]); *p++ = htonl((u32) inode->i_mode); *p++ = htonl((u32) inode->i_nlink); *p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid)); *p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid)); if (S_ISLNK(inode->i_mode) && inode->i_size > NFS_MAXPATHLEN) { *p++ = htonl(NFS_MAXPATHLEN); } else { *p++ = htonl((u32) inode->i_size); } *p++ = htonl((u32) inode->i_blksize); *p++ = htonl((u32) inode->i_rdev); *p++ = htonl((u32) inode->i_blocks); *p++ = htonl((u32) inode->i_dev); *p++ = htonl((u32) inode->i_ino); *p++ = htonl((u32) inode->i_atime); *p++ = 0; *p++ = htonl((u32) lease_get_mtime(inode)); *p++ = 0; *p++ = htonl((u32) inode->i_ctime); *p++ = 0; return p; }
static inline u32 * encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { struct inode *inode = fhp->fh_dentry->d_inode; *p++ = htonl(nfs3_ftypes[(inode->i_mode & S_IFMT) >> 12]); *p++ = htonl((u32) inode->i_mode); *p++ = htonl((u32) inode->i_nlink); *p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid)); *p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid)); if (S_ISLNK(inode->i_mode) && inode->i_size > NFS3_MAXPATHLEN) { p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); } else { p = xdr_encode_hyper(p, (u64) inode->i_size); } if (inode->i_blksize == 0 && inode->i_blocks == 0) /* Minix file system(?) i_size is (hopefully) close enough */ p = xdr_encode_hyper(p, (u64)(inode->i_size +511)& ~511); else p = xdr_encode_hyper(p, ((u64)inode->i_blocks) << 9); *p++ = htonl((u32) MAJOR(inode->i_rdev)); *p++ = htonl((u32) MINOR(inode->i_rdev)); if (rqstp->rq_reffh->fh_version == 1 && rqstp->rq_reffh->fh_fsid_type == 1 && (fhp->fh_export->ex_flags & NFSEXP_FSID)) p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid); else p = xdr_encode_hyper(p, (u64) inode->i_dev); p = xdr_encode_hyper(p, (u64) inode->i_ino); p = encode_time3(p, inode->i_atime); p = encode_time3(p, lease_get_mtime(inode)); p = encode_time3(p, inode->i_ctime); return p; }
static inline u32 * encode_fattr(struct svc_rqst *rqstp, u32 *p, struct inode *inode) { int type = (inode->i_mode & S_IFMT); *p++ = htonl(nfs_ftypes[type >> 12]); *p++ = htonl((u32) inode->i_mode); *p++ = htonl((u32) inode->i_nlink); *p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid)); *p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid)); if (S_ISLNK(type) && inode->i_size > NFS_MAXPATHLEN) { *p++ = htonl(NFS_MAXPATHLEN); } else { *p++ = htonl((u32) inode->i_size); } *p++ = htonl((u32) inode->i_blksize); if (S_ISCHR(type) || S_ISBLK(type)) *p++ = htonl((u32) kdev_t_to_nr(inode->i_rdev)); else *p++ = htonl(0xffffffff); *p++ = htonl((u32) inode->i_blocks); *p++ = htonl((u32) kdev_t_to_nr(inode->i_dev)); *p++ = htonl((u32) inode->i_ino); *p++ = htonl((u32) inode->i_atime); *p++ = 0; *p++ = htonl((u32) lease_get_mtime(inode)); *p++ = 0; *p++ = htonl((u32) inode->i_ctime); *p++ = 0; return p; }
static __be32 * encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat) { struct dentry *dentry = fhp->fh_dentry; int type; struct timespec64 time; u32 f; type = (stat->mode & S_IFMT); *p++ = htonl(nfs_ftypes[type >> 12]); *p++ = htonl((u32) stat->mode); *p++ = htonl((u32) stat->nlink); *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid)); *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid)); if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { *p++ = htonl(NFS_MAXPATHLEN); } else { *p++ = htonl((u32) stat->size); } *p++ = htonl((u32) stat->blksize); if (S_ISCHR(type) || S_ISBLK(type)) *p++ = htonl(new_encode_dev(stat->rdev)); else *p++ = htonl(0xffffffff); *p++ = htonl((u32) stat->blocks); switch (fsid_source(fhp)) { default: case FSIDSOURCE_DEV: *p++ = htonl(new_encode_dev(stat->dev)); break; case FSIDSOURCE_FSID: *p++ = htonl((u32) fhp->fh_export->ex_fsid); break; case FSIDSOURCE_UUID: f = ((u32*)fhp->fh_export->ex_uuid)[0]; f ^= ((u32*)fhp->fh_export->ex_uuid)[1]; f ^= ((u32*)fhp->fh_export->ex_uuid)[2]; f ^= ((u32*)fhp->fh_export->ex_uuid)[3]; *p++ = htonl(f); break; } *p++ = htonl((u32) stat->ino); *p++ = htonl((u32) stat->atime.tv_sec); *p++ = htonl(stat->atime.tv_nsec ? stat->atime.tv_nsec / 1000 : 0); time = stat->mtime; lease_get_mtime(d_inode(dentry), &time); *p++ = htonl((u32) time.tv_sec); *p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0); *p++ = htonl((u32) stat->ctime.tv_sec); *p++ = htonl(stat->ctime.tv_nsec ? stat->ctime.tv_nsec / 1000 : 0); return p; }
/* GETATTR */ int nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p) { struct nfsd3_attrstat *resp = rqstp->rq_resp; if (resp->status == 0) { lease_get_mtime(d_inode(resp->fh.fh_dentry), &resp->stat.mtime); p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat); } return xdr_ressize_check(rqstp, p); }
/* * Encode post-operation attributes. * The inode may be NULL if the call failed because of a stale file * handle. In this case, no attributes are returned. */ static __be32 * encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) { struct dentry *dentry = fhp->fh_dentry; if (dentry && d_really_is_positive(dentry)) { __be32 err; struct kstat stat; err = fh_getattr(fhp, &stat); if (!err) { *p++ = xdr_one; /* attributes follow */ lease_get_mtime(d_inode(dentry), &stat.mtime); return encode_fattr3(rqstp, p, fhp, &stat); } } *p++ = xdr_zero; return p; }
static __be32 * encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat) { struct dentry *dentry = fhp->fh_dentry; int type; struct timespec time; type = (stat->mode & S_IFMT); *p++ = htonl(nfs_ftypes[type >> 12]); *p++ = htonl((u32) stat->mode); *p++ = htonl((u32) stat->nlink); *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { *p++ = htonl(NFS_MAXPATHLEN); } else { *p++ = htonl((u32) stat->size); } *p++ = htonl((u32) stat->blksize); if (S_ISCHR(type) || S_ISBLK(type)) *p++ = htonl(new_encode_dev(stat->rdev)); else *p++ = htonl(0xffffffff); *p++ = htonl((u32) stat->blocks); if (is_fsid(fhp, rqstp->rq_reffh)) *p++ = htonl((u32) fhp->fh_export->ex_fsid); else *p++ = htonl(new_encode_dev(stat->dev)); *p++ = htonl((u32) stat->ino); *p++ = htonl((u32) stat->atime.tv_sec); *p++ = htonl(stat->atime.tv_nsec ? stat->atime.tv_nsec / 1000 : 0); lease_get_mtime(dentry->d_inode, &time); *p++ = htonl((u32) time.tv_sec); *p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0); *p++ = htonl((u32) stat->ctime.tv_sec); *p++ = htonl(stat->ctime.tv_nsec ? stat->ctime.tv_nsec / 1000 : 0); return p; }