diff options
-rw-r--r-- | fs/nfs/localio.c | 4 | ||||
-rw-r--r-- | fs/nfs_common/nfslocalio.c | 5 | ||||
-rw-r--r-- | fs/nfsd/filecache.c | 21 | ||||
-rw-r--r-- | fs/nfsd/filecache.h | 1 | ||||
-rw-r--r-- | fs/nfsd/localio.c | 9 | ||||
-rw-r--r-- | include/linux/nfslocalio.h | 3 |
6 files changed, 34 insertions, 9 deletions
diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 7a33da477da3..86df8d2cd22e 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -211,12 +211,12 @@ EXPORT_SYMBOL_GPL(nfs_local_probe_async); static inline struct nfsd_file *nfs_local_file_get(struct nfsd_file *nf) { - return nfs_to->nfsd_file_get(nf); + return nfs_to->nfsd_file_get_local(nf); } static inline void nfs_local_file_put(struct nfsd_file *nf) { - nfs_to->nfsd_file_put(nf); + nfs_to_nfsd_file_put_local(nf); } /* diff --git a/fs/nfs_common/nfslocalio.c b/fs/nfs_common/nfslocalio.c index bdf251332b6b..f6821b2c87a2 100644 --- a/fs/nfs_common/nfslocalio.c +++ b/fs/nfs_common/nfslocalio.c @@ -262,9 +262,8 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid, /* We have an implied reference to net thanks to nfsd_net_try_get */ localio = nfs_to->nfsd_open_local_fh(net, uuid->dom, rpc_clnt, cred, nfs_fh, fmode); - if (IS_ERR(localio)) - nfs_to_nfsd_net_put(net); - else + nfs_to_nfsd_net_put(net); + if (!IS_ERR(localio)) nfs_uuid_add_file(uuid, nfl); return localio; diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index ab85e6a2454f..eedf2af8ee6e 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -387,6 +387,27 @@ nfsd_file_put_local(struct nfsd_file *nf) } /** + * nfsd_file_get_local - get nfsd_file reference and reference to net + * @nf: nfsd_file of which to put the reference + * + * Get reference to both the nfsd_file and nf->nf_net. + */ +struct nfsd_file * +nfsd_file_get_local(struct nfsd_file *nf) +{ + struct net *net = nf->nf_net; + + if (nfsd_net_try_get(net)) { + nf = nfsd_file_get(nf); + if (!nf) + nfsd_net_put(net); + } else { + nf = NULL; + } + return nf; +} + +/** * nfsd_file_file - get the backing file of an nfsd_file * @nf: nfsd_file of which to access the backing file. * diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h index 5865f9c72712..cd02f91aaef1 100644 --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -63,6 +63,7 @@ int nfsd_file_cache_start_net(struct net *net); void nfsd_file_cache_shutdown_net(struct net *net); void nfsd_file_put(struct nfsd_file *nf); struct net *nfsd_file_put_local(struct nfsd_file *nf); +struct nfsd_file *nfsd_file_get_local(struct nfsd_file *nf); struct nfsd_file *nfsd_file_get(struct nfsd_file *nf); struct file *nfsd_file_file(struct nfsd_file *nf); void nfsd_file_close_inode_sync(struct inode *inode); diff --git a/fs/nfsd/localio.c b/fs/nfsd/localio.c index 238647fa379e..2c0afd1067ea 100644 --- a/fs/nfsd/localio.c +++ b/fs/nfsd/localio.c @@ -29,8 +29,7 @@ static const struct nfsd_localio_operations nfsd_localio_ops = { .nfsd_net_put = nfsd_net_put, .nfsd_open_local_fh = nfsd_open_local_fh, .nfsd_file_put_local = nfsd_file_put_local, - .nfsd_file_get = nfsd_file_get, - .nfsd_file_put = nfsd_file_put, + .nfsd_file_get_local = nfsd_file_get_local, .nfsd_file_file = nfsd_file_file, }; @@ -71,6 +70,9 @@ nfsd_open_local_fh(struct net *net, struct auth_domain *dom, if (nfs_fh->size > NFS4_FHSIZE) return ERR_PTR(-EINVAL); + if (!nfsd_net_try_get(net)) + return ERR_PTR(-ENXIO); + /* nfs_fh -> svc_fh */ fh_init(&fh, NFS4_FHSIZE); fh.fh_handle.fh_size = nfs_fh->size; @@ -92,6 +94,9 @@ nfsd_open_local_fh(struct net *net, struct auth_domain *dom, if (rq_cred.cr_group_info) put_group_info(rq_cred.cr_group_info); + if (IS_ERR(localio)) + nfsd_net_put(net); + return localio; } EXPORT_SYMBOL_GPL(nfsd_open_local_fh); diff --git a/include/linux/nfslocalio.h b/include/linux/nfslocalio.h index 9aa8a43843d7..c3f34bae60e1 100644 --- a/include/linux/nfslocalio.h +++ b/include/linux/nfslocalio.h @@ -66,8 +66,7 @@ struct nfsd_localio_operations { const struct nfs_fh *, const fmode_t); struct net *(*nfsd_file_put_local)(struct nfsd_file *); - struct nfsd_file *(*nfsd_file_get)(struct nfsd_file *); - void (*nfsd_file_put)(struct nfsd_file *); + struct nfsd_file *(*nfsd_file_get_local)(struct nfsd_file *); struct file *(*nfsd_file_file)(struct nfsd_file *); } ____cacheline_aligned; |