Skip to content
Snippets Groups Projects
nfs4xdr.c 115 KiB
Newer Older
  • Learn to ignore specific revisions
  • Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, __be32 *p, struct nfs_open_confirmres *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
            struct xdr_stream xdr;
            struct compound_hdr hdr;
            int status;
    
            xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
            status = decode_compound_hdr(&xdr, &hdr);
            if (status)
                    goto out;
            status = decode_putfh(&xdr);
            if (status)
                    goto out;
            status = decode_open_confirm(&xdr, res);
    out:
            return status;
    }
    
    /*
     * Decode OPEN response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
            struct xdr_stream xdr;
            struct compound_hdr hdr;
            int status;
    
            xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
            status = decode_compound_hdr(&xdr, &hdr);
            if (status)
                    goto out;
            status = decode_putfh(&xdr);
            if (status)
                    goto out;
            status = decode_open(&xdr, res);
    
            if (status)
                    goto out;
    	decode_getfattr(&xdr, res->f_attr, res->server);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    out:
            return status;
    }
    
    /*
     * Decode SETATTR response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_setattrres *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
            struct xdr_stream xdr;
            struct compound_hdr hdr;
            int status;
    
            xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
            status = decode_compound_hdr(&xdr, &hdr);
            if (status)
                    goto out;
            status = decode_putfh(&xdr);
            if (status)
                    goto out;
            status = decode_setattr(&xdr, res);
            if (status)
                    goto out;
    	status = decode_getfattr(&xdr, res->fattr, res->server);
    	if (status == NFS4ERR_DELAY)
    		status = 0;
    out:
            return status;
    }
    
    /*
     * Decode LOCK response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_res *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (status)
    		goto out;
    	status = decode_putfh(&xdr);
    	if (status)
    		goto out;
    	status = decode_lock(&xdr, res);
    out:
    	return status;
    }
    
    /*
     * Decode LOCKT response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lockt_res *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (status)
    		goto out;
    	status = decode_putfh(&xdr);
    	if (status)
    		goto out;
    	status = decode_lockt(&xdr, res);
    out:
    	return status;
    }
    
    /*
     * Decode LOCKU response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_locku_res *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (status)
    		goto out;
    	status = decode_putfh(&xdr);
    	if (status)
    		goto out;
    	status = decode_locku(&xdr, res);
    out:
    	return status;
    }
    
    /*
     * Decode READLINK response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (status)
    		goto out;
    	status = decode_putfh(&xdr);
    	if (status)
    		goto out;
    	status = decode_readlink(&xdr, rqstp);
    out:
    	return status;
    }
    
    /*
     * Decode READDIR response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_readdir_res *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (status)
    		goto out;
    	status = decode_putfh(&xdr);
    	if (status)
    		goto out;
    	status = decode_readdir(&xdr, rqstp, res);
    out:
    	return status;
    }
    
    /*
     * Decode Read response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readres *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (status)
    		goto out;
    	status = decode_putfh(&xdr);
    	if (status)
    		goto out;
    	status = decode_read(&xdr, rqstp, res);
    	if (!status)
    		status = res->count;
    out:
    	return status;
    }
    
    /*
     * Decode WRITE response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (status)
    		goto out;
    	status = decode_putfh(&xdr);
    	if (status)
    		goto out;
    	status = decode_write(&xdr, res);
    
    	if (status)
    		goto out;
    	decode_getfattr(&xdr, res->fattr, res->server);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	if (!status)
    		status = res->count;
    out:
    	return status;
    }
    
    /*
     * Decode COMMIT response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (status)
    		goto out;
    	status = decode_putfh(&xdr);
    	if (status)
    		goto out;
    	status = decode_commit(&xdr, res);
    
    	if (status)
    		goto out;
    	decode_getfattr(&xdr, res->fattr, res->server);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    out:
    	return status;
    }
    
    /*
     * FSINFO request
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (!status)
    		status = decode_putfh(&xdr);
    	if (!status)
    		status = decode_fsinfo(&xdr, fsinfo);
    	if (!status)
    
    		status = -nfs4_stat_to_errno(hdr.status);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	return status;
    }
    
    /*
     * PATHCONF request
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *pathconf)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (!status)
    		status = decode_putfh(&xdr);
    	if (!status)
    		status = decode_pathconf(&xdr, pathconf);
    	return status;
    }
    
    /*
     * STATFS request
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *fsstat)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (!status)
    		status = decode_putfh(&xdr);
    	if (!status)
    		status = decode_statfs(&xdr, fsstat);
    	return status;
    }
    
    /*
     * GETATTR_BITMAP request
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4_server_caps_res *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
    	if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
    		goto out;
    	if ((status = decode_putfh(&xdr)) != 0)
    		goto out;
    	status = decode_server_caps(&xdr, res);
    out:
    	return status;
    }
    
    /*
     * Decode RENEW response
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (!status)
    		status = decode_renew(&xdr);
    	return status;
    }
    
    /*
     * a SETCLIENTID request
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
    
    		struct nfs_client *clp)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (!status)
    		status = decode_setclientid(&xdr, clp);
    	if (!status)
    
    		status = -nfs4_stat_to_errno(hdr.status);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	return status;
    }
    
    /*
     * a SETCLIENTID_CONFIRM request
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (!status)
    		status = decode_setclientid_confirm(&xdr);
    	if (!status)
    		status = decode_putrootfh(&xdr);
    	if (!status)
    		status = decode_fsinfo(&xdr, fsinfo);
    	if (!status)
    
    		status = -nfs4_stat_to_errno(hdr.status);
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	return status;
    }
    
    /*
     * DELEGRETURN request
     */
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_delegreturnres *res)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    
    	if (status != 0)
    		goto out;
    	status = decode_putfh(&xdr);
    	if (status != 0)
    		goto out;
    	status = decode_delegreturn(&xdr);
    	decode_getfattr(&xdr, res->fattr, res->server);
    out:
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	return status;
    }
    
    
    Al Viro's avatar
    Al Viro committed
    static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations *res)
    
    {
    	struct xdr_stream xdr;
    	struct compound_hdr hdr;
    	int status;
    
    	xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
    	status = decode_compound_hdr(&xdr, &hdr);
    	if (status != 0)
    		goto out;
    	if ((status = decode_putfh(&xdr)) != 0)
    		goto out;
    	if ((status = decode_lookup(&xdr)) != 0)
    		goto out;
    	xdr_enter_page(&xdr, PAGE_SIZE);
    	status = decode_getfattr(&xdr, &res->fattr, res->server);
    out:
    	return status;
    }
    
    
    __be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	uint32_t bitmap[2] = {0};
    	uint32_t len;
    
    	if (!*p++) {
    		if (!*p)
    			return ERR_PTR(-EAGAIN);
    		entry->eof = 1;
    		return ERR_PTR(-EBADCOOKIE);
    	}
    
    	entry->prev_cookie = entry->cookie;
    	p = xdr_decode_hyper(p, &entry->cookie);
    	entry->len = ntohl(*p++);
    	entry->name = (const char *) p;
    	p += XDR_QUADLEN(entry->len);
    
    	/*
    	 * In case the server doesn't return an inode number,
    	 * we fake one here.  (We don't use inode number 0,
    	 * since glibc seems to choke on it...)
    	 */
    	entry->ino = 1;
    
    	len = ntohl(*p++);		/* bitmap length */
    	if (len-- > 0) {
    		bitmap[0] = ntohl(*p++);
    		if (len-- > 0) {
    			bitmap[1] = ntohl(*p++);
    			p += len;
    		}
    	}
    	len = XDR_QUADLEN(ntohl(*p++));	/* attribute buffer length */
    	if (len > 0) {
    
    		if (bitmap[0] & FATTR4_WORD0_RDATTR_ERROR) {
    			bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
    			/* Ignore the return value of rdattr_error for now */
    			p++;
    			len--;
    		}
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    		if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID)
    			xdr_decode_hyper(p, &entry->ino);
    		else if (bitmap[0] == FATTR4_WORD0_FILEID)
    			xdr_decode_hyper(p, &entry->ino);
    		p += len;
    	}
    
    	entry->eof = !p[0] && p[1];
    	return p;
    }
    
    /*
     * We need to translate between nfs status return values and
     * the local errno values which may not be the same.
     */
    static struct {
    	int stat;
    	int errno;
    } nfs_errtbl[] = {
    	{ NFS4_OK,		0		},
    	{ NFS4ERR_PERM,		EPERM		},
    	{ NFS4ERR_NOENT,	ENOENT		},
    	{ NFS4ERR_IO,		errno_NFSERR_IO	},
    	{ NFS4ERR_NXIO,		ENXIO		},
    	{ NFS4ERR_ACCESS,	EACCES		},
    	{ NFS4ERR_EXIST,	EEXIST		},
    	{ NFS4ERR_XDEV,		EXDEV		},
    	{ NFS4ERR_NOTDIR,	ENOTDIR		},
    	{ NFS4ERR_ISDIR,	EISDIR		},
    	{ NFS4ERR_INVAL,	EINVAL		},
    	{ NFS4ERR_FBIG,		EFBIG		},
    	{ NFS4ERR_NOSPC,	ENOSPC		},
    	{ NFS4ERR_ROFS,		EROFS		},
    	{ NFS4ERR_MLINK,	EMLINK		},
    	{ NFS4ERR_NAMETOOLONG,	ENAMETOOLONG	},
    	{ NFS4ERR_NOTEMPTY,	ENOTEMPTY	},
    	{ NFS4ERR_DQUOT,	EDQUOT		},
    	{ NFS4ERR_STALE,	ESTALE		},
    	{ NFS4ERR_BADHANDLE,	EBADHANDLE	},
    
    	{ NFS4ERR_BADOWNER,	EINVAL		},
    	{ NFS4ERR_BADNAME,	EINVAL		},
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	{ NFS4ERR_BAD_COOKIE,	EBADCOOKIE	},
    	{ NFS4ERR_NOTSUPP,	ENOTSUPP	},
    	{ NFS4ERR_TOOSMALL,	ETOOSMALL	},
    	{ NFS4ERR_SERVERFAULT,	ESERVERFAULT	},
    	{ NFS4ERR_BADTYPE,	EBADTYPE	},
    	{ NFS4ERR_LOCKED,	EAGAIN		},
    	{ NFS4ERR_RESOURCE,	EREMOTEIO	},
    	{ NFS4ERR_SYMLINK,	ELOOP		},
    	{ NFS4ERR_OP_ILLEGAL,	EOPNOTSUPP	},
    	{ NFS4ERR_DEADLOCK,	EDEADLK		},
    	{ NFS4ERR_WRONGSEC,	EPERM		}, /* FIXME: this needs
    						    * to be handled by a
    						    * middle-layer.
    						    */
    	{ -1,			EIO		}
    };
    
    /*
     * Convert an NFS error code to a local one.
     * This one is used jointly by NFSv2 and NFSv3.
     */
    static int
    
    nfs4_stat_to_errno(int stat)
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    {
    	int i;
    	for (i = 0; nfs_errtbl[i].stat != -1; i++) {
    		if (nfs_errtbl[i].stat == stat)
    			return nfs_errtbl[i].errno;
    	}
    	if (stat <= 10000 || stat > 10100) {
    		/* The server is looney tunes. */
    		return ESERVERFAULT;
    	}
    	/* If we cannot translate the error, the recovery routines should
    	 * handle it.
    	 * Note: remaining NFSv4 error codes have values > 10000, so should
    	 * not conflict with native Linux error codes.
    	 */
    	return stat;
    }
    
    #ifndef MAX
    # define MAX(a, b)	(((a) > (b))? (a) : (b))
    #endif
    
    #define PROC(proc, argtype, restype)				\
    [NFSPROC4_CLNT_##proc] = {					\
    	.p_proc   = NFSPROC4_COMPOUND,				\
    	.p_encode = (kxdrproc_t) nfs4_xdr_##argtype,		\
    	.p_decode = (kxdrproc_t) nfs4_xdr_##restype,		\
    	.p_bufsiz = MAX(NFS4_##argtype##_sz,NFS4_##restype##_sz) << 2,	\
    
    	.p_statidx = NFSPROC4_CLNT_##proc,			\
    	.p_name   = #proc,					\
    
    Linus Torvalds's avatar
    Linus Torvalds committed
        }
    
    struct rpc_procinfo	nfs4_procedures[] = {
      PROC(READ,		enc_read,	dec_read),
      PROC(WRITE,		enc_write,	dec_write),
      PROC(COMMIT,		enc_commit,	dec_commit),
      PROC(OPEN,		enc_open,	dec_open),
      PROC(OPEN_CONFIRM,	enc_open_confirm,	dec_open_confirm),
      PROC(OPEN_NOATTR,	enc_open_noattr,	dec_open_noattr),
      PROC(OPEN_DOWNGRADE,	enc_open_downgrade,	dec_open_downgrade),
      PROC(CLOSE,		enc_close,	dec_close),
      PROC(SETATTR,		enc_setattr,	dec_setattr),
      PROC(FSINFO,		enc_fsinfo,	dec_fsinfo),
      PROC(RENEW,		enc_renew,	dec_renew),
      PROC(SETCLIENTID,	enc_setclientid,	dec_setclientid),
      PROC(SETCLIENTID_CONFIRM,	enc_setclientid_confirm,	dec_setclientid_confirm),
      PROC(LOCK,            enc_lock,       dec_lock),
      PROC(LOCKT,           enc_lockt,      dec_lockt),
      PROC(LOCKU,           enc_locku,      dec_locku),
      PROC(ACCESS,		enc_access,	dec_access),
      PROC(GETATTR,		enc_getattr,	dec_getattr),
      PROC(LOOKUP,		enc_lookup,	dec_lookup),
      PROC(LOOKUP_ROOT,	enc_lookup_root,	dec_lookup_root),
      PROC(REMOVE,		enc_remove,	dec_remove),
      PROC(RENAME,		enc_rename,	dec_rename),
      PROC(LINK,		enc_link,	dec_link),
      PROC(SYMLINK,		enc_symlink,	dec_symlink),
      PROC(CREATE,		enc_create,	dec_create),
      PROC(PATHCONF,	enc_pathconf,	dec_pathconf),
      PROC(STATFS,		enc_statfs,	dec_statfs),
      PROC(READLINK,	enc_readlink,	dec_readlink),
      PROC(READDIR,		enc_readdir,	dec_readdir),
      PROC(SERVER_CAPS,	enc_server_caps, dec_server_caps),
      PROC(DELEGRETURN,	enc_delegreturn, dec_delegreturn),
    
      PROC(GETACL,		enc_getacl,	dec_getacl),
    
      PROC(SETACL,		enc_setacl,	dec_setacl),
    
      PROC(FS_LOCATIONS,	enc_fs_locations, dec_fs_locations),
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    };
    
    struct rpc_version		nfs_version4 = {
    	.number			= 4,
    
    	.nrprocs		= ARRAY_SIZE(nfs4_procedures),
    
    Linus Torvalds's avatar
    Linus Torvalds committed
    	.procs			= nfs4_procedures
    };
    
    /*
     * Local variables:
     *  c-basic-offset: 8
     * End:
     */