162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * This file contains all the stubs needed when communicating with lockd. 462306a36Sopenharmony_ci * This level of indirection is necessary so we can run nfsd+lockd without 562306a36Sopenharmony_ci * requiring the nfs client to be compiled in/loaded, and vice versa. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/file.h> 1162306a36Sopenharmony_ci#include <linux/lockd/bind.h> 1262306a36Sopenharmony_ci#include "nfsd.h" 1362306a36Sopenharmony_ci#include "vfs.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define NFSDDBG_FACILITY NFSDDBG_LOCKD 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#ifdef CONFIG_LOCKD_V4 1862306a36Sopenharmony_ci#define nlm_stale_fh nlm4_stale_fh 1962306a36Sopenharmony_ci#define nlm_failed nlm4_failed 2062306a36Sopenharmony_ci#else 2162306a36Sopenharmony_ci#define nlm_stale_fh nlm_lck_denied_nolocks 2262306a36Sopenharmony_ci#define nlm_failed nlm_lck_denied_nolocks 2362306a36Sopenharmony_ci#endif 2462306a36Sopenharmony_ci/* 2562306a36Sopenharmony_ci * Note: we hold the dentry use count while the file is open. 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_cistatic __be32 2862306a36Sopenharmony_cinlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp, 2962306a36Sopenharmony_ci int mode) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci __be32 nfserr; 3262306a36Sopenharmony_ci int access; 3362306a36Sopenharmony_ci struct svc_fh fh; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci /* must initialize before using! but maxsize doesn't matter */ 3662306a36Sopenharmony_ci fh_init(&fh,0); 3762306a36Sopenharmony_ci fh.fh_handle.fh_size = f->size; 3862306a36Sopenharmony_ci memcpy(&fh.fh_handle.fh_raw, f->data, f->size); 3962306a36Sopenharmony_ci fh.fh_export = NULL; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci access = (mode == O_WRONLY) ? NFSD_MAY_WRITE : NFSD_MAY_READ; 4262306a36Sopenharmony_ci access |= NFSD_MAY_LOCK; 4362306a36Sopenharmony_ci nfserr = nfsd_open(rqstp, &fh, S_IFREG, access, filp); 4462306a36Sopenharmony_ci fh_put(&fh); 4562306a36Sopenharmony_ci /* We return nlm error codes as nlm doesn't know 4662306a36Sopenharmony_ci * about nfsd, but nfsd does know about nlm.. 4762306a36Sopenharmony_ci */ 4862306a36Sopenharmony_ci switch (nfserr) { 4962306a36Sopenharmony_ci case nfs_ok: 5062306a36Sopenharmony_ci return 0; 5162306a36Sopenharmony_ci case nfserr_dropit: 5262306a36Sopenharmony_ci return nlm_drop_reply; 5362306a36Sopenharmony_ci case nfserr_stale: 5462306a36Sopenharmony_ci return nlm_stale_fh; 5562306a36Sopenharmony_ci default: 5662306a36Sopenharmony_ci return nlm_failed; 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic void 6162306a36Sopenharmony_cinlm_fclose(struct file *filp) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci fput(filp); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic const struct nlmsvc_binding nfsd_nlm_ops = { 6762306a36Sopenharmony_ci .fopen = nlm_fopen, /* open file for locking */ 6862306a36Sopenharmony_ci .fclose = nlm_fclose, /* close file */ 6962306a36Sopenharmony_ci}; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_civoid 7262306a36Sopenharmony_cinfsd_lockd_init(void) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci dprintk("nfsd: initializing lockd\n"); 7562306a36Sopenharmony_ci nlmsvc_ops = &nfsd_nlm_ops; 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_civoid 7962306a36Sopenharmony_cinfsd_lockd_shutdown(void) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci nlmsvc_ops = NULL; 8262306a36Sopenharmony_ci} 83