📄 nfsproc.c
字号:
/* we've used the SIZE information, so discard it */ attr->ia_valid &= ~ATTR_SIZE; /* Make sure the type and device matches */ nfserr = nfserr_exist; if (inode && type != (inode->i_mode & S_IFMT)) goto out_unlock; } nfserr = 0; if (!inode) { /* File doesn't exist. Create it and set attrs */ nfserr = nfsd_create(rqstp, dirfhp, argp->name, argp->len, attr, type, rdev, newfhp); } else if (type == S_IFREG) { dprintk("nfsd: existing %s, valid=%x, size=%ld\n", argp->name, attr->ia_valid, (long) attr->ia_size); /* File already exists. We ignore all attributes except * size, so that creat() behaves exactly like * open(..., O_CREAT|O_TRUNC|O_WRONLY). */ attr->ia_valid &= ATTR_SIZE; if (attr->ia_valid) nfserr = nfsd_setattr(rqstp, newfhp, attr, 0, (time_t)0); }out_unlock: /* We don't really need to unlock, as fh_put does it. */ fh_unlock(dirfhp);done: fh_put(dirfhp); return nfsd_return_dirop(nfserr, resp);}static __be32nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, void *resp){ __be32 nfserr; dprintk("nfsd: REMOVE %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); /* Unlink. -SIFDIR means file must not be a directory */ nfserr = nfsd_unlink(rqstp, &argp->fh, -S_IFDIR, argp->name, argp->len); fh_put(&argp->fh); return nfserr;}static __be32nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp, void *resp){ __be32 nfserr; dprintk("nfsd: RENAME %s %.*s -> \n", SVCFH_fmt(&argp->ffh), argp->flen, argp->fname); dprintk("nfsd: -> %s %.*s\n", SVCFH_fmt(&argp->tfh), argp->tlen, argp->tname); nfserr = nfsd_rename(rqstp, &argp->ffh, argp->fname, argp->flen, &argp->tfh, argp->tname, argp->tlen); fh_put(&argp->ffh); fh_put(&argp->tfh); return nfserr;}static __be32nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp, void *resp){ __be32 nfserr; dprintk("nfsd: LINK %s ->\n", SVCFH_fmt(&argp->ffh)); dprintk("nfsd: %s %.*s\n", SVCFH_fmt(&argp->tfh), argp->tlen, argp->tname); nfserr = nfsd_link(rqstp, &argp->tfh, argp->tname, argp->tlen, &argp->ffh); fh_put(&argp->ffh); fh_put(&argp->tfh); return nfserr;}static __be32nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp, void *resp){ struct svc_fh newfh; __be32 nfserr; dprintk("nfsd: SYMLINK %s %.*s -> %.*s\n", SVCFH_fmt(&argp->ffh), argp->flen, argp->fname, argp->tlen, argp->tname); fh_init(&newfh, NFS_FHSIZE); /* * Create the link, look up new file and set attrs. */ nfserr = nfsd_symlink(rqstp, &argp->ffh, argp->fname, argp->flen, argp->tname, argp->tlen, &newfh, &argp->attrs); fh_put(&argp->ffh); fh_put(&newfh); return nfserr;}/* * Make directory. This operation is not idempotent. * N.B. After this call resp->fh needs an fh_put */static __be32nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp, struct nfsd_diropres *resp){ __be32 nfserr; dprintk("nfsd: MKDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); if (resp->fh.fh_dentry) { printk(KERN_WARNING "nfsd_proc_mkdir: response already verified??\n"); } argp->attrs.ia_valid &= ~ATTR_SIZE; fh_init(&resp->fh, NFS_FHSIZE); nfserr = nfsd_create(rqstp, &argp->fh, argp->name, argp->len, &argp->attrs, S_IFDIR, 0, &resp->fh); fh_put(&argp->fh); return nfsd_return_dirop(nfserr, resp);}/* * Remove a directory */static __be32nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, void *resp){ __be32 nfserr; dprintk("nfsd: RMDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); nfserr = nfsd_unlink(rqstp, &argp->fh, S_IFDIR, argp->name, argp->len); fh_put(&argp->fh); return nfserr;}/* * Read a portion of a directory. */static __be32nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp, struct nfsd_readdirres *resp){ int count; __be32 nfserr; loff_t offset; dprintk("nfsd: READDIR %s %d bytes at %d\n", SVCFH_fmt(&argp->fh), argp->count, argp->cookie); /* Shrink to the client read size */ count = (argp->count >> 2) - 2; /* Make sure we've room for the NULL ptr & eof flag */ count -= 2; if (count < 0) count = 0; resp->buffer = argp->buffer; resp->offset = NULL; resp->buflen = count; resp->common.err = nfs_ok; /* Read directory and encode entries on the fly */ offset = argp->cookie; nfserr = nfsd_readdir(rqstp, &argp->fh, &offset, &resp->common, nfssvc_encode_entry); resp->count = resp->buffer - argp->buffer; if (resp->offset) *resp->offset = htonl(offset); fh_put(&argp->fh); return nfserr;}/* * Get file system info */static __be32nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, struct nfsd_statfsres *resp){ __be32 nfserr; dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh)); nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats); fh_put(&argp->fh); return nfserr;}/* * NFSv2 Server procedures. * Only the results of non-idempotent operations are cached. */#define nfsd_proc_none NULL#define nfssvc_release_none NULLstruct nfsd_void { int dummy; };#define PROC(name, argt, rest, relt, cache, respsize) \ { (svc_procfunc) nfsd_proc_##name, \ (kxdrproc_t) nfssvc_decode_##argt, \ (kxdrproc_t) nfssvc_encode_##rest, \ (kxdrproc_t) nfssvc_release_##relt, \ sizeof(struct nfsd_##argt), \ sizeof(struct nfsd_##rest), \ 0, \ cache, \ respsize, \ }#define ST 1 /* status */#define FH 8 /* filehandle */#define AT 18 /* attributes */static struct svc_procedure nfsd_procedures2[18] = { PROC(null, void, void, none, RC_NOCACHE, ST), PROC(getattr, fhandle, attrstat, fhandle, RC_NOCACHE, ST+AT), PROC(setattr, sattrargs, attrstat, fhandle, RC_REPLBUFF, ST+AT), PROC(none, void, void, none, RC_NOCACHE, ST), PROC(lookup, diropargs, diropres, fhandle, RC_NOCACHE, ST+FH+AT), PROC(readlink, readlinkargs, readlinkres, none, RC_NOCACHE, ST+1+NFS_MAXPATHLEN/4), PROC(read, readargs, readres, fhandle, RC_NOCACHE, ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4), PROC(none, void, void, none, RC_NOCACHE, ST), PROC(write, writeargs, attrstat, fhandle, RC_REPLBUFF, ST+AT), PROC(create, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT), PROC(remove, diropargs, void, none, RC_REPLSTAT, ST), PROC(rename, renameargs, void, none, RC_REPLSTAT, ST), PROC(link, linkargs, void, none, RC_REPLSTAT, ST), PROC(symlink, symlinkargs, void, none, RC_REPLSTAT, ST), PROC(mkdir, createargs, diropres, fhandle, RC_REPLBUFF, ST+FH+AT), PROC(rmdir, diropargs, void, none, RC_REPLSTAT, ST), PROC(readdir, readdirargs, readdirres, none, RC_NOCACHE, 0), PROC(statfs, fhandle, statfsres, none, RC_NOCACHE, ST+5),};struct svc_version nfsd_version2 = { .vs_vers = 2, .vs_nproc = 18, .vs_proc = nfsd_procedures2, .vs_dispatch = nfsd_dispatch, .vs_xdrsize = NFS2_SVC_XDRSIZE,};/* * Map errnos to NFS errnos. */__be32nfserrno (int errno){ static struct { __be32 nfserr; int syserr; } nfs_errtbl[] = { { nfs_ok, 0 }, { nfserr_perm, -EPERM }, { nfserr_noent, -ENOENT }, { nfserr_io, -EIO }, { nfserr_nxio, -ENXIO }, { nfserr_acces, -EACCES }, { nfserr_exist, -EEXIST }, { nfserr_xdev, -EXDEV }, { nfserr_mlink, -EMLINK }, { nfserr_nodev, -ENODEV }, { nfserr_notdir, -ENOTDIR }, { nfserr_isdir, -EISDIR }, { nfserr_inval, -EINVAL }, { nfserr_fbig, -EFBIG }, { nfserr_nospc, -ENOSPC }, { nfserr_rofs, -EROFS }, { nfserr_mlink, -EMLINK }, { nfserr_nametoolong, -ENAMETOOLONG }, { nfserr_notempty, -ENOTEMPTY },#ifdef EDQUOT { nfserr_dquot, -EDQUOT },#endif { nfserr_stale, -ESTALE }, { nfserr_jukebox, -ETIMEDOUT }, { nfserr_dropit, -EAGAIN }, { nfserr_dropit, -ENOMEM }, { nfserr_badname, -ESRCH }, { nfserr_io, -ETXTBSY }, { nfserr_notsupp, -EOPNOTSUPP }, }; int i; for (i = 0; i < ARRAY_SIZE(nfs_errtbl); i++) { if (nfs_errtbl[i].syserr == errno) return nfs_errtbl[i].nfserr; } printk (KERN_INFO "nfsd: non-standard errno: %d\n", errno); return nfserr_io;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -