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

📄 nfs4xdr.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */		WRITE64((u64)0); /* clientid */		WRITE32(0); /* length of owner name */	}	ADJUST_ARGS();}static voidnfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock){	ENCODE_SEQID_OP_HEAD;	if (!nfserr) {		RESERVE_SPACE(4 + sizeof(stateid_t));		WRITE32(lock->lk_resp_stateid.si_generation);		WRITEMEM(&lock->lk_resp_stateid.si_opaque, sizeof(stateid_opaque_t));		ADJUST_ARGS();	} else if (nfserr == nfserr_denied)		nfsd4_encode_lock_denied(resp, &lock->lk_denied);	ENCODE_SEQID_OP_TAIL(lock->lk_replay_owner);}static voidnfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt){	if (nfserr == nfserr_denied)		nfsd4_encode_lock_denied(resp, &lockt->lt_denied);}static voidnfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku){	ENCODE_SEQID_OP_HEAD;	if (!nfserr) {		RESERVE_SPACE(sizeof(stateid_t));		WRITE32(locku->lu_stateid.si_generation);		WRITEMEM(&locku->lu_stateid.si_opaque, sizeof(stateid_opaque_t));		ADJUST_ARGS();	}				        	ENCODE_SEQID_OP_TAIL(locku->lu_stateowner);}static voidnfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link){	ENCODE_HEAD;	if (!nfserr) {		RESERVE_SPACE(20);		WRITECINFO(link->li_cinfo);		ADJUST_ARGS();	}}static voidnfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open){	ENCODE_SEQID_OP_HEAD;	if (nfserr)		goto out;	RESERVE_SPACE(36 + sizeof(stateid_t));	WRITE32(open->op_stateid.si_generation);	WRITEMEM(&open->op_stateid.si_opaque, sizeof(stateid_opaque_t));	WRITECINFO(open->op_cinfo);	WRITE32(open->op_rflags);	WRITE32(2);	WRITE32(open->op_bmval[0]);	WRITE32(open->op_bmval[1]);	WRITE32(open->op_delegate_type);	ADJUST_ARGS();	switch (open->op_delegate_type) {	case NFS4_OPEN_DELEGATE_NONE:		break;	case NFS4_OPEN_DELEGATE_READ:		RESERVE_SPACE(20 + sizeof(stateid_t));		WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t));		WRITE32(open->op_recall);		/*		 * TODO: ACE's in delegations		 */		WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);		WRITE32(0);		WRITE32(0);		WRITE32(0);   /* XXX: is NULL principal ok? */		ADJUST_ARGS();		break;	case NFS4_OPEN_DELEGATE_WRITE:		RESERVE_SPACE(32 + sizeof(stateid_t));		WRITEMEM(&open->op_delegate_stateid, sizeof(stateid_t));		WRITE32(0);		/*		 * TODO: space_limit's in delegations		 */		WRITE32(NFS4_LIMIT_SIZE);		WRITE32(~(u32)0);		WRITE32(~(u32)0);		/*		 * TODO: ACE's in delegations		 */		WRITE32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);		WRITE32(0);		WRITE32(0);		WRITE32(0);   /* XXX: is NULL principal ok? */		ADJUST_ARGS();		break;	default:		BUG();	}	/* XXX save filehandle here */out:	ENCODE_SEQID_OP_TAIL(open->op_stateowner);}static voidnfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc){	ENCODE_SEQID_OP_HEAD;				        	if (!nfserr) {		RESERVE_SPACE(sizeof(stateid_t));		WRITE32(oc->oc_resp_stateid.si_generation);		WRITEMEM(&oc->oc_resp_stateid.si_opaque, sizeof(stateid_opaque_t));		ADJUST_ARGS();	}	ENCODE_SEQID_OP_TAIL(oc->oc_stateowner);}static voidnfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od){	ENCODE_SEQID_OP_HEAD;				        	if (!nfserr) {		RESERVE_SPACE(sizeof(stateid_t));		WRITE32(od->od_stateid.si_generation);		WRITEMEM(&od->od_stateid.si_opaque, sizeof(stateid_opaque_t));		ADJUST_ARGS();	}	ENCODE_SEQID_OP_TAIL(od->od_stateowner);}static __be32nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,		  struct nfsd4_read *read){	u32 eof;	int v, pn;	unsigned long maxcount; 	long len;	ENCODE_HEAD;	if (nfserr)		return nfserr;	if (resp->xbuf->page_len)		return nfserr_resource;	RESERVE_SPACE(8); /* eof flag and byte count */	maxcount = svc_max_payload(resp->rqstp);	if (maxcount > read->rd_length)		maxcount = read->rd_length;	len = maxcount;	v = 0;	while (len > 0) {		pn = resp->rqstp->rq_resused++;		resp->rqstp->rq_vec[v].iov_base =			page_address(resp->rqstp->rq_respages[pn]);		resp->rqstp->rq_vec[v].iov_len =			len < PAGE_SIZE ? len : PAGE_SIZE;		v++;		len -= PAGE_SIZE;	}	read->rd_vlen = v;	nfserr = nfsd_read(read->rd_rqstp, read->rd_fhp, read->rd_filp,			read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen,			&maxcount);	if (nfserr == nfserr_symlink)		nfserr = nfserr_inval;	if (nfserr)		return nfserr;	eof = (read->rd_offset + maxcount >=	       read->rd_fhp->fh_dentry->d_inode->i_size);	WRITE32(eof);	WRITE32(maxcount);	ADJUST_ARGS();	resp->xbuf->head[0].iov_len = (char*)p					- (char*)resp->xbuf->head[0].iov_base;	resp->xbuf->page_len = maxcount;	/* Use rest of head for padding and remaining ops: */	resp->xbuf->tail[0].iov_base = p;	resp->xbuf->tail[0].iov_len = 0;	if (maxcount&3) {		RESERVE_SPACE(4);		WRITE32(0);		resp->xbuf->tail[0].iov_base += maxcount&3;		resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);		ADJUST_ARGS();	}	return 0;}static __be32nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink){	int maxcount;	char *page;	ENCODE_HEAD;	if (nfserr)		return nfserr;	if (resp->xbuf->page_len)		return nfserr_resource;	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);	maxcount = PAGE_SIZE;	RESERVE_SPACE(4);	/*	 * XXX: By default, the ->readlink() VFS op will truncate symlinks	 * if they would overflow the buffer.  Is this kosher in NFSv4?  If	 * not, one easy fix is: if ->readlink() precisely fills the buffer,	 * assume that truncation occurred, and return NFS4ERR_RESOURCE.	 */	nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp, page, &maxcount);	if (nfserr == nfserr_isdir)		return nfserr_inval;	if (nfserr)		return nfserr;	WRITE32(maxcount);	ADJUST_ARGS();	resp->xbuf->head[0].iov_len = (char*)p				- (char*)resp->xbuf->head[0].iov_base;	resp->xbuf->page_len = maxcount;	/* Use rest of head for padding and remaining ops: */	resp->xbuf->tail[0].iov_base = p;	resp->xbuf->tail[0].iov_len = 0;	if (maxcount&3) {		RESERVE_SPACE(4);		WRITE32(0);		resp->xbuf->tail[0].iov_base += maxcount&3;		resp->xbuf->tail[0].iov_len = 4 - (maxcount&3);		ADJUST_ARGS();	}	return 0;}static __be32nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir){	int maxcount;	loff_t offset;	__be32 *page, *savep, *tailbase;	ENCODE_HEAD;	if (nfserr)		return nfserr;	if (resp->xbuf->page_len)		return nfserr_resource;	RESERVE_SPACE(8);  /* verifier */	savep = p;	/* XXX: Following NFSv3, we ignore the READDIR verifier for now. */	WRITE32(0);	WRITE32(0);	ADJUST_ARGS();	resp->xbuf->head[0].iov_len = ((char*)resp->p) - (char*)resp->xbuf->head[0].iov_base;	tailbase = p;	maxcount = PAGE_SIZE;	if (maxcount > readdir->rd_maxcount)		maxcount = readdir->rd_maxcount;	/*	 * Convert from bytes to words, account for the two words already	 * written, make sure to leave two words at the end for the next	 * pointer and eof field.	 */	maxcount = (maxcount >> 2) - 4;	if (maxcount < 0) {		nfserr =  nfserr_toosmall;		goto err_no_verf;	}	page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]);	readdir->common.err = 0;	readdir->buflen = maxcount;	readdir->buffer = page;	readdir->offset = NULL;	offset = readdir->rd_cookie;	nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,			      &offset,			      &readdir->common, nfsd4_encode_dirent);	if (nfserr == nfs_ok &&	    readdir->common.err == nfserr_toosmall &&	    readdir->buffer == page) 		nfserr = nfserr_toosmall;	if (nfserr == nfserr_symlink)		nfserr = nfserr_notdir;	if (nfserr)		goto err_no_verf;	if (readdir->offset)		xdr_encode_hyper(readdir->offset, offset);	p = readdir->buffer;	*p++ = 0;	/* no more entries */	*p++ = htonl(readdir->common.err == nfserr_eof);	resp->xbuf->page_len = ((char*)p) - (char*)page_address(		resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);	/* Use rest of head for padding and remaining ops: */	resp->xbuf->tail[0].iov_base = tailbase;	resp->xbuf->tail[0].iov_len = 0;	resp->p = resp->xbuf->tail[0].iov_base;	resp->end = resp->p + (PAGE_SIZE - resp->xbuf->head[0].iov_len)/4;	return 0;err_no_verf:	p = savep;	ADJUST_ARGS();	return nfserr;}static voidnfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove){	ENCODE_HEAD;	if (!nfserr) {		RESERVE_SPACE(20);		WRITECINFO(remove->rm_cinfo);		ADJUST_ARGS();	}}static voidnfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename){	ENCODE_HEAD;	if (!nfserr) {		RESERVE_SPACE(40);		WRITECINFO(rename->rn_sinfo);		WRITECINFO(rename->rn_tinfo);		ADJUST_ARGS();	}}static voidnfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,		     struct nfsd4_secinfo *secinfo){	int i = 0;	struct svc_export *exp = secinfo->si_exp;	u32 nflavs;	struct exp_flavor_info *flavs;	struct exp_flavor_info def_flavs[2];	ENCODE_HEAD;	if (nfserr)		goto out;	if (exp->ex_nflavors) {		flavs = exp->ex_flavors;		nflavs = exp->ex_nflavors;	} else { /* Handling of some defaults in absence of real secinfo: */		flavs = def_flavs;		if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {			nflavs = 2;			flavs[0].pseudoflavor = RPC_AUTH_UNIX;			flavs[1].pseudoflavor = RPC_AUTH_NULL;		} else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {			nflavs = 1;			flavs[0].pseudoflavor					= svcauth_gss_flavor(exp->ex_client);		} else {			nflavs = 1;			flavs[0].pseudoflavor					= exp->ex_client->flavour->flavour;		}	}	RESERVE_SPACE(4);	WRITE32(nflavs);	ADJUST_ARGS();	for (i = 0; i < nflavs; i++) {		u32 flav = flavs[i].pseudoflavor;		struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);		if (gm) {			RESERVE_SPACE(4);			WRITE32(RPC_AUTH_GSS);			ADJUST_ARGS();			RESERVE_SPACE(4 + gm->gm_oid.len);			WRITE32(gm->gm_oid.len);			WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);			ADJUST_ARGS();			RESERVE_SPACE(4);			WRITE32(0); /* qop */			ADJUST_ARGS();			RESERVE_SPACE(4);			WRITE32(gss_pseudoflavor_to_service(gm, flav));			ADJUST_ARGS();			gss_mech_put(gm);		} else {			RESERVE_SPACE(4);			WRITE32(flav);			ADJUST_ARGS();		}	}out:	if (exp)		exp_put(exp);}/* * The SETATTR encode routine is special -- it always encodes a bitmap, * regardless of the error status. */static voidnfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr){	ENCODE_HEAD;	RESERVE_SPACE(12);	if (nfserr) {		WRITE32(2);		WRITE32(0);		WRITE32(0);	}	else {		WRITE32(2);		WRITE32(setattr->sa_bmval[0]);		WRITE32(setattr->sa_bmval[1]);	}	ADJUST_ARGS();}static voidnfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd){	ENCODE_HEAD;	if (!nfserr) {		RESERVE_SPACE(8 + sizeof(nfs4_verifier));		WRITEMEM(&scd->se_clientid, 8);		WRITEMEM(&scd->se_confirm, sizeof(nfs4_verifier));		ADJUST_ARGS();	}	else if (nfserr == nfserr_clid_inuse) {		RESERVE_SPACE(8);		WRITE32(0);		WRITE32(0);		ADJUST_ARGS();	}}static voidnfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write){	ENCODE_HEAD;	if (!nfserr) {		RESERVE_SPACE(16);		WRITE32(write->wr_bytes_written);		WRITE32(write->wr_how_written);		WRITEMEM(write->wr_verifier.data, 8);		ADJUST_ARGS();	}}voidnfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op){	__be32 *statp;	ENCODE_HEAD;	RESERVE_SPACE(8);	WRITE32(op->opnum);	statp = p++;	/* to be backfilled at the end */	ADJUST_ARGS();	switch (op->opnum) {	case OP_ACCESS:		nfsd4_encode_access(resp, op->status, &op->u.access);		break;	case OP_CLOSE:		nfsd4_encode_close(resp, op->status, &op->u.close);		break;	case OP_COMMIT:		nfsd4_encode_commit(resp, op->status, &op->u.commit);		break;	case OP_CREATE:		nfsd4_encode_create(resp, op->status, &op->u.create);		break;	case OP_DELEGRETUR

⌨️ 快捷键说明

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