mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 09:16:33 +00:00
nfsd-6.13 fixes:
- Revert one v6.13 fix at the author's request - Fix a minor problem with recent NFSv4.2 COPY enhancements - Fix an NFSv4.0 callback bug introduced in the v6.13 merge window -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEKLLlsBKG3yQ88j7+M2qzM29mf5cFAmdpsPkACgkQM2qzM29m f5cddw//XUVunVAhTb6PYBNwiOxD0NpTpIjFPiwIZPnpWexQYBBaU9VKekcM//RR MSuvvbOYeqHtGUefVcs3NTONvtguNUn9fjvud+A7RFTr/a6QQjl34i4BWXKpqEFj WXxlpjBQmLotyxe13d/rqnAu9i13MOzCdOs7O7+Wt81Pk21HNrwlbXQQmyH/e8/p 5FM2+pbj0W+XdRDkMAZZBM1cbczhDYqaf/8owmLtHs2vqbyHUDs/4AFVdQmySOV7 FbdvrEo+7O5WCAAxeGxRgS2Ym5D/mll3FPoXziabG0UIxQG6uZVqReuOq8wybgTM e4RRa2+HgOi7/AZalvMsBU7Wg2xFyd6nIV5gT4adj/1N8ZeT2MI2IClahEp+DyFY uTapapERHXUzMhIl+OtNnHY4gJ/NEJUzCmhUATZVw2l6zBZaQBhu4a4PZvDNvI8g 4TwS7SzDBVcOg+mzPtbtQxDjBUqsV1e+ROg1ouVWydJGDVSvoMRYzkS27M88DSNT SLHVpwbNPzEbXv9su3MOCAaf1Q26/qZMNMA7P1sYfCASA8IHrRuAOFrC6Mm7B64V TB7LOe4s6LIzDNU6ZNWXKwT3PxF/G+R5Y0VKqrfXop46DAPP3UlI7TRA8JuS9QGO r84QoC/63MTK9666DWyy3EIU7se19QQzo7GsluDXzmI/dwTsAew= =v4iF -----END PGP SIGNATURE----- Merge tag 'nfsd-6.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux Pull nfsd fixes from Chuck Lever:: - Revert one v6.13 fix at the author's request (to be done differently) - Fix a minor problem with recent NFSv4.2 COPY enhancements - Fix an NFSv4.0 callback bug introduced in the v6.13 merge window * tag 'nfsd-6.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: nfsd: restore callback functionality for NFSv4.0 NFSD: fix management of pending async copies nfsd: Revert "nfsd: release svc_expkey/svc_export with rcu_work"
This commit is contained in:
commit
f07044dd0d
@ -40,24 +40,15 @@
|
|||||||
#define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
|
#define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
|
||||||
#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
|
#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)
|
||||||
|
|
||||||
static void expkey_put_work(struct work_struct *work)
|
static void expkey_put(struct kref *ref)
|
||||||
{
|
{
|
||||||
struct svc_expkey *key =
|
struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
|
||||||
container_of(to_rcu_work(work), struct svc_expkey, ek_rcu_work);
|
|
||||||
|
|
||||||
if (test_bit(CACHE_VALID, &key->h.flags) &&
|
if (test_bit(CACHE_VALID, &key->h.flags) &&
|
||||||
!test_bit(CACHE_NEGATIVE, &key->h.flags))
|
!test_bit(CACHE_NEGATIVE, &key->h.flags))
|
||||||
path_put(&key->ek_path);
|
path_put(&key->ek_path);
|
||||||
auth_domain_put(key->ek_client);
|
auth_domain_put(key->ek_client);
|
||||||
kfree(key);
|
kfree_rcu(key, ek_rcu);
|
||||||
}
|
|
||||||
|
|
||||||
static void expkey_put(struct kref *ref)
|
|
||||||
{
|
|
||||||
struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
|
|
||||||
|
|
||||||
INIT_RCU_WORK(&key->ek_rcu_work, expkey_put_work);
|
|
||||||
queue_rcu_work(system_wq, &key->ek_rcu_work);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
|
static int expkey_upcall(struct cache_detail *cd, struct cache_head *h)
|
||||||
@ -364,26 +355,16 @@ static void export_stats_destroy(struct export_stats *stats)
|
|||||||
EXP_STATS_COUNTERS_NUM);
|
EXP_STATS_COUNTERS_NUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void svc_export_put_work(struct work_struct *work)
|
static void svc_export_put(struct kref *ref)
|
||||||
{
|
{
|
||||||
struct svc_export *exp =
|
struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
|
||||||
container_of(to_rcu_work(work), struct svc_export, ex_rcu_work);
|
|
||||||
|
|
||||||
path_put(&exp->ex_path);
|
path_put(&exp->ex_path);
|
||||||
auth_domain_put(exp->ex_client);
|
auth_domain_put(exp->ex_client);
|
||||||
nfsd4_fslocs_free(&exp->ex_fslocs);
|
nfsd4_fslocs_free(&exp->ex_fslocs);
|
||||||
export_stats_destroy(exp->ex_stats);
|
export_stats_destroy(exp->ex_stats);
|
||||||
kfree(exp->ex_stats);
|
kfree(exp->ex_stats);
|
||||||
kfree(exp->ex_uuid);
|
kfree(exp->ex_uuid);
|
||||||
kfree(exp);
|
kfree_rcu(exp, ex_rcu);
|
||||||
}
|
|
||||||
|
|
||||||
static void svc_export_put(struct kref *ref)
|
|
||||||
{
|
|
||||||
struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
|
|
||||||
|
|
||||||
INIT_RCU_WORK(&exp->ex_rcu_work, svc_export_put_work);
|
|
||||||
queue_rcu_work(system_wq, &exp->ex_rcu_work);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
|
static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
|
||||||
|
@ -75,7 +75,7 @@ struct svc_export {
|
|||||||
u32 ex_layout_types;
|
u32 ex_layout_types;
|
||||||
struct nfsd4_deviceid_map *ex_devid_map;
|
struct nfsd4_deviceid_map *ex_devid_map;
|
||||||
struct cache_detail *cd;
|
struct cache_detail *cd;
|
||||||
struct rcu_work ex_rcu_work;
|
struct rcu_head ex_rcu;
|
||||||
unsigned long ex_xprtsec_modes;
|
unsigned long ex_xprtsec_modes;
|
||||||
struct export_stats *ex_stats;
|
struct export_stats *ex_stats;
|
||||||
};
|
};
|
||||||
@ -92,7 +92,7 @@ struct svc_expkey {
|
|||||||
u32 ek_fsid[6];
|
u32 ek_fsid[6];
|
||||||
|
|
||||||
struct path ek_path;
|
struct path ek_path;
|
||||||
struct rcu_work ek_rcu_work;
|
struct rcu_head ek_rcu;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
|
#define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
|
||||||
|
@ -1100,7 +1100,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
|
|||||||
args.authflavor = clp->cl_cred.cr_flavor;
|
args.authflavor = clp->cl_cred.cr_flavor;
|
||||||
clp->cl_cb_ident = conn->cb_ident;
|
clp->cl_cb_ident = conn->cb_ident;
|
||||||
} else {
|
} else {
|
||||||
if (!conn->cb_xprt)
|
if (!conn->cb_xprt || !ses)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
clp->cl_cb_session = ses;
|
clp->cl_cb_session = ses;
|
||||||
args.bc_xprt = conn->cb_xprt;
|
args.bc_xprt = conn->cb_xprt;
|
||||||
@ -1522,8 +1522,6 @@ static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
|
|||||||
ses = c->cn_session;
|
ses = c->cn_session;
|
||||||
}
|
}
|
||||||
spin_unlock(&clp->cl_lock);
|
spin_unlock(&clp->cl_lock);
|
||||||
if (!c)
|
|
||||||
return;
|
|
||||||
|
|
||||||
err = setup_callback_client(clp, &conn, ses);
|
err = setup_callback_client(clp, &conn, ses);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -1347,7 +1347,6 @@ static void nfs4_put_copy(struct nfsd4_copy *copy)
|
|||||||
{
|
{
|
||||||
if (!refcount_dec_and_test(©->refcount))
|
if (!refcount_dec_and_test(©->refcount))
|
||||||
return;
|
return;
|
||||||
atomic_dec(©->cp_nn->pending_async_copies);
|
|
||||||
kfree(copy->cp_src);
|
kfree(copy->cp_src);
|
||||||
kfree(copy);
|
kfree(copy);
|
||||||
}
|
}
|
||||||
@ -1870,6 +1869,7 @@ static int nfsd4_do_async_copy(void *data)
|
|||||||
set_bit(NFSD4_COPY_F_COMPLETED, ©->cp_flags);
|
set_bit(NFSD4_COPY_F_COMPLETED, ©->cp_flags);
|
||||||
trace_nfsd_copy_async_done(copy);
|
trace_nfsd_copy_async_done(copy);
|
||||||
nfsd4_send_cb_offload(copy);
|
nfsd4_send_cb_offload(copy);
|
||||||
|
atomic_dec(©->cp_nn->pending_async_copies);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1927,19 +1927,19 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
/* Arbitrary cap on number of pending async copy operations */
|
/* Arbitrary cap on number of pending async copy operations */
|
||||||
if (atomic_inc_return(&nn->pending_async_copies) >
|
if (atomic_inc_return(&nn->pending_async_copies) >
|
||||||
(int)rqstp->rq_pool->sp_nrthreads)
|
(int)rqstp->rq_pool->sp_nrthreads)
|
||||||
goto out_err;
|
goto out_dec_async_copy_err;
|
||||||
async_copy->cp_src = kmalloc(sizeof(*async_copy->cp_src), GFP_KERNEL);
|
async_copy->cp_src = kmalloc(sizeof(*async_copy->cp_src), GFP_KERNEL);
|
||||||
if (!async_copy->cp_src)
|
if (!async_copy->cp_src)
|
||||||
goto out_err;
|
goto out_dec_async_copy_err;
|
||||||
if (!nfs4_init_copy_state(nn, copy))
|
if (!nfs4_init_copy_state(nn, copy))
|
||||||
goto out_err;
|
goto out_dec_async_copy_err;
|
||||||
memcpy(&result->cb_stateid, ©->cp_stateid.cs_stid,
|
memcpy(&result->cb_stateid, ©->cp_stateid.cs_stid,
|
||||||
sizeof(result->cb_stateid));
|
sizeof(result->cb_stateid));
|
||||||
dup_copy_fields(copy, async_copy);
|
dup_copy_fields(copy, async_copy);
|
||||||
async_copy->copy_task = kthread_create(nfsd4_do_async_copy,
|
async_copy->copy_task = kthread_create(nfsd4_do_async_copy,
|
||||||
async_copy, "%s", "copy thread");
|
async_copy, "%s", "copy thread");
|
||||||
if (IS_ERR(async_copy->copy_task))
|
if (IS_ERR(async_copy->copy_task))
|
||||||
goto out_err;
|
goto out_dec_async_copy_err;
|
||||||
spin_lock(&async_copy->cp_clp->async_lock);
|
spin_lock(&async_copy->cp_clp->async_lock);
|
||||||
list_add(&async_copy->copies,
|
list_add(&async_copy->copies,
|
||||||
&async_copy->cp_clp->async_copies);
|
&async_copy->cp_clp->async_copies);
|
||||||
@ -1954,6 +1954,9 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||||||
trace_nfsd_copy_done(copy, status);
|
trace_nfsd_copy_done(copy, status);
|
||||||
release_copy_files(copy);
|
release_copy_files(copy);
|
||||||
return status;
|
return status;
|
||||||
|
out_dec_async_copy_err:
|
||||||
|
if (async_copy)
|
||||||
|
atomic_dec(&nn->pending_async_copies);
|
||||||
out_err:
|
out_err:
|
||||||
if (nfsd4_ssc_is_inter(copy)) {
|
if (nfsd4_ssc_is_inter(copy)) {
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user