⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nfs4xdr.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (bmval0 & FATTR4_WORD0_SIZE) {		if ((buflen -= 8) < 0)			goto out_resource;		WRITE64(stat.size);	}	if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(1);	}	if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(1);	}	if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(0);	}	if (bmval0 & FATTR4_WORD0_FSID) {		if ((buflen -= 16) < 0)			goto out_resource;		if (exp->ex_fslocs.migrated) {			WRITE64(NFS4_REFERRAL_FSID_MAJOR);			WRITE64(NFS4_REFERRAL_FSID_MINOR);		} else switch(fsid_source(fhp)) {		case FSIDSOURCE_FSID:			WRITE64((u64)exp->ex_fsid);			WRITE64((u64)0);			break;		case FSIDSOURCE_DEV:			WRITE32(0);			WRITE32(MAJOR(stat.dev));			WRITE32(0);			WRITE32(MINOR(stat.dev));			break;		case FSIDSOURCE_UUID:			WRITEMEM(exp->ex_uuid, 16);			break;		}	}	if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(0);	}	if (bmval0 & FATTR4_WORD0_LEASE_TIME) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(NFSD_LEASE_TIME);	}	if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(rdattr_err);	}	if (bmval0 & FATTR4_WORD0_ACL) {		struct nfs4_ace *ace;		if (acl == NULL) {			if ((buflen -= 4) < 0)				goto out_resource;			WRITE32(0);			goto out_acl;		}		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(acl->naces);		for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {			if ((buflen -= 4*3) < 0)				goto out_resource;			WRITE32(ace->type);			WRITE32(ace->flag);			WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL);			status = nfsd4_encode_aclname(rqstp, ace->whotype,				ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP,				&p, &buflen);			if (status == nfserr_resource)				goto out_resource;			if (status)				goto out;		}	}out_acl:	if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(aclsupport ?			ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);	}	if (bmval0 & FATTR4_WORD0_CANSETTIME) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(1);	}	if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(1);	}	if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(1);	}	if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(1);	}	if (bmval0 & FATTR4_WORD0_FILEHANDLE) {		buflen -= (XDR_QUADLEN(fhp->fh_handle.fh_size) << 2) + 4;		if (buflen < 0)			goto out_resource;		WRITE32(fhp->fh_handle.fh_size);		WRITEMEM(&fhp->fh_handle.fh_base, fhp->fh_handle.fh_size);	}	if (bmval0 & FATTR4_WORD0_FILEID) {		if ((buflen -= 8) < 0)			goto out_resource;		WRITE64(stat.ino);	}	if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {		if ((buflen -= 8) < 0)			goto out_resource;		WRITE64((u64) statfs.f_ffree);	}	if (bmval0 & FATTR4_WORD0_FILES_FREE) {		if ((buflen -= 8) < 0)			goto out_resource;		WRITE64((u64) statfs.f_ffree);	}	if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {		if ((buflen -= 8) < 0)			goto out_resource;		WRITE64((u64) statfs.f_files);	}	if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {		status = nfsd4_encode_fs_locations(rqstp, exp, &p, &buflen);		if (status == nfserr_resource)			goto out_resource;		if (status)			goto out;	}	if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(1);	}	if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {		if ((buflen -= 8) < 0)			goto out_resource;		WRITE64(~(u64)0);	}	if (bmval0 & FATTR4_WORD0_MAXLINK) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(255);	}	if (bmval0 & FATTR4_WORD0_MAXNAME) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(statfs.f_namelen);	}	if (bmval0 & FATTR4_WORD0_MAXREAD) {		if ((buflen -= 8) < 0)			goto out_resource;		WRITE64((u64) svc_max_payload(rqstp));	}	if (bmval0 & FATTR4_WORD0_MAXWRITE) {		if ((buflen -= 8) < 0)			goto out_resource;		WRITE64((u64) svc_max_payload(rqstp));	}	if (bmval1 & FATTR4_WORD1_MODE) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(stat.mode & S_IALLUGO);	}	if (bmval1 & FATTR4_WORD1_NO_TRUNC) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(1);	}	if (bmval1 & FATTR4_WORD1_NUMLINKS) {		if ((buflen -= 4) < 0)			goto out_resource;		WRITE32(stat.nlink);	}	if (bmval1 & FATTR4_WORD1_OWNER) {		status = nfsd4_encode_user(rqstp, stat.uid, &p, &buflen);		if (status == nfserr_resource)			goto out_resource;		if (status)			goto out;	}	if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {		status = nfsd4_encode_group(rqstp, stat.gid, &p, &buflen);		if (status == nfserr_resource)			goto out_resource;		if (status)			goto out;	}	if (bmval1 & FATTR4_WORD1_RAWDEV) {		if ((buflen -= 8) < 0)			goto out_resource;		WRITE32((u32) MAJOR(stat.rdev));		WRITE32((u32) MINOR(stat.rdev));	}	if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {		if ((buflen -= 8) < 0)			goto out_resource;		dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;		WRITE64(dummy64);	}	if (bmval1 & FATTR4_WORD1_SPACE_FREE) {		if ((buflen -= 8) < 0)			goto out_resource;		dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;		WRITE64(dummy64);	}	if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {		if ((buflen -= 8) < 0)			goto out_resource;		dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;		WRITE64(dummy64);	}	if (bmval1 & FATTR4_WORD1_SPACE_USED) {		if ((buflen -= 8) < 0)			goto out_resource;		dummy64 = (u64)stat.blocks << 9;		WRITE64(dummy64);	}	if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {		if ((buflen -= 12) < 0)			goto out_resource;		WRITE32(0);		WRITE32(stat.atime.tv_sec);		WRITE32(stat.atime.tv_nsec);	}	if (bmval1 & FATTR4_WORD1_TIME_DELTA) {		if ((buflen -= 12) < 0)			goto out_resource;		WRITE32(0);		WRITE32(1);		WRITE32(0);	}	if (bmval1 & FATTR4_WORD1_TIME_METADATA) {		if ((buflen -= 12) < 0)			goto out_resource;		WRITE32(0);		WRITE32(stat.ctime.tv_sec);		WRITE32(stat.ctime.tv_nsec);	}	if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {		if ((buflen -= 12) < 0)			goto out_resource;		WRITE32(0);		WRITE32(stat.mtime.tv_sec);		WRITE32(stat.mtime.tv_nsec);	}	if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {		if ((buflen -= 8) < 0)                	goto out_resource;		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;	status = nfs_ok;out:	kfree(acl);	if (fhp == &tempfh)		fh_put(&tempfh);	return status;out_nfserr:	status = nfserrno(err);	goto out;out_resource:	*countp = 0;	status = nfserr_resource;	goto out;out_serverfault:	status = nfserr_serverfault;	goto out;}static __be32nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,		const char *name, int namlen, __be32 *p, int *buflen){	struct svc_export *exp = cd->rd_fhp->fh_export;	struct dentry *dentry;	__be32 nfserr;	dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);	if (IS_ERR(dentry))		return nfserrno(PTR_ERR(dentry));	exp_get(exp);	if (d_mountpoint(dentry)) {		int err;		/*		 * Why the heck aren't we just using nfsd_lookup??		 * Different "."/".." handling?  Something else?		 * At least, add a comment here to explain....		 */		err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);		if (err) {			nfserr = nfserrno(err);			goto out_put;		}		nfserr = check_nfsd_access(exp, cd->rd_rqstp);		if (nfserr)			goto out_put;	}	nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,					cd->rd_rqstp);out_put:	dput(dentry);	exp_put(exp);	return nfserr;}static __be32 *nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr){	__be32 *attrlenp;	if (buflen < 6)		return NULL;	*p++ = htonl(2);	*p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */	*p++ = htonl(0);			 /* bmval1 */	attrlenp = p++;	*p++ = nfserr;       /* no htonl */	*attrlenp = htonl((char *)p - (char *)attrlenp - 4);	return p;}static intnfsd4_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;	__be32 nfserr = nfserr_toosmall;	/* In nfsv4, "." and ".." never make it onto the wire.. */	if (name && isdotent(name, namlen)) {		cd->common.err = nfs_ok;		return 0;	}	if (cd->offset)		xdr_encode_hyper(cd->offset, (u64) offset);	buflen = cd->buflen - 4 - XDR_QUADLEN(namlen);	if (buflen < 0)		goto fail;	*p++ = xdr_one;                             /* mark entry present */	cd->offset = p;                             /* remember pointer */	p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */	p = xdr_encode_array(p, name, namlen);      /* name length & name */	nfserr = nfsd4_encode_dirent_fattr(cd, name, namlen, p, &buflen);	switch (nfserr) {	case nfs_ok:		p += buflen;		break;	case nfserr_resource:		nfserr = nfserr_toosmall;		goto fail;	case nfserr_dropit:		goto fail;	default:		/*		 * If the client requested the RDATTR_ERROR attribute,		 * we stuff the error code into this attribute		 * and continue.  If this attribute was not requested,		 * then in accordance with the spec, we fail the		 * entire READDIR operation(!)		 */		if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))			goto fail;		p = nfsd4_encode_rdattr_error(p, buflen, nfserr);		if (p == NULL) {			nfserr = nfserr_toosmall;			goto fail;		}	}	cd->buflen -= (p - cd->buffer);	cd->buffer = p;	cd->common.err = nfs_ok;	return 0;fail:	cd->common.err = nfserr;	return -EINVAL;}static voidnfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access){	ENCODE_HEAD;	if (!nfserr) {		RESERVE_SPACE(8);		WRITE32(access->ac_supported);		WRITE32(access->ac_resp_access);		ADJUST_ARGS();	}}static voidnfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close){	ENCODE_SEQID_OP_HEAD;	if (!nfserr) {		RESERVE_SPACE(sizeof(stateid_t));		WRITE32(close->cl_stateid.si_generation);		WRITEMEM(&close->cl_stateid.si_opaque, sizeof(stateid_opaque_t));		ADJUST_ARGS();	}	ENCODE_SEQID_OP_TAIL(close->cl_stateowner);}static voidnfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit){	ENCODE_HEAD;	if (!nfserr) {		RESERVE_SPACE(8);		WRITEMEM(commit->co_verf.data, 8);		ADJUST_ARGS();	}}static voidnfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create){	ENCODE_HEAD;	if (!nfserr) {		RESERVE_SPACE(32);		WRITECINFO(create->cr_cinfo);		WRITE32(2);		WRITE32(create->cr_bmval[0]);		WRITE32(create->cr_bmval[1]);		ADJUST_ARGS();	}}static __be32nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr){	struct svc_fh *fhp = getattr->ga_fhp;	int buflen;	if (nfserr)		return nfserr;	buflen = resp->end - resp->p - (COMPOUND_ERR_SLACK_SPACE >> 2);	nfserr = nfsd4_encode_fattr(fhp, fhp->fh_export, fhp->fh_dentry,				    resp->p, &buflen, getattr->ga_bmval,				    resp->rqstp);	if (!nfserr)		resp->p += buflen;	return nfserr;}static voidnfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh *fhp){	unsigned int len;	ENCODE_HEAD;	if (!nfserr) {		len = fhp->fh_handle.fh_size;		RESERVE_SPACE(len + 4);		WRITE32(len);		WRITEMEM(&fhp->fh_handle.fh_base, len);		ADJUST_ARGS();	}}/** Including all fields other than the name, a LOCK4denied structure requires*   8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.*/static voidnfsd4_encode_lock_denied(struct nfsd4_compoundres *resp, struct nfsd4_lock_denied *ld){	ENCODE_HEAD;	RESERVE_SPACE(32 + XDR_LEN(ld->ld_sop ? ld->ld_sop->so_owner.len : 0));	WRITE64(ld->ld_start);	WRITE64(ld->ld_length);	WRITE32(ld->ld_type);	if (ld->ld_sop) {		WRITEMEM(&ld->ld_clientid, 8);		WRITE32(ld->ld_sop->so_owner.len);		WRITEMEM(ld->ld_sop->so_owner.data, ld->ld_sop->so_owner.len);		kref_put(&ld->ld_sop->so_ref, nfs4_free_stateowner);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -