Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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"

+17 -35
+6 -25
fs/nfsd/export.c
··· 40 40 #define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS) 41 41 #define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1) 42 42 43 - static void expkey_put_work(struct work_struct *work) 43 + static void expkey_put(struct kref *ref) 44 44 { 45 - struct svc_expkey *key = 46 - container_of(to_rcu_work(work), struct svc_expkey, ek_rcu_work); 45 + struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); 47 46 48 47 if (test_bit(CACHE_VALID, &key->h.flags) && 49 48 !test_bit(CACHE_NEGATIVE, &key->h.flags)) 50 49 path_put(&key->ek_path); 51 50 auth_domain_put(key->ek_client); 52 - kfree(key); 53 - } 54 - 55 - static void expkey_put(struct kref *ref) 56 - { 57 - struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref); 58 - 59 - INIT_RCU_WORK(&key->ek_rcu_work, expkey_put_work); 60 - queue_rcu_work(system_wq, &key->ek_rcu_work); 51 + kfree_rcu(key, ek_rcu); 61 52 } 62 53 63 54 static int expkey_upcall(struct cache_detail *cd, struct cache_head *h) ··· 355 364 EXP_STATS_COUNTERS_NUM); 356 365 } 357 366 358 - static void svc_export_put_work(struct work_struct *work) 367 + static void svc_export_put(struct kref *ref) 359 368 { 360 - struct svc_export *exp = 361 - container_of(to_rcu_work(work), struct svc_export, ex_rcu_work); 362 - 369 + struct svc_export *exp = container_of(ref, struct svc_export, h.ref); 363 370 path_put(&exp->ex_path); 364 371 auth_domain_put(exp->ex_client); 365 372 nfsd4_fslocs_free(&exp->ex_fslocs); 366 373 export_stats_destroy(exp->ex_stats); 367 374 kfree(exp->ex_stats); 368 375 kfree(exp->ex_uuid); 369 - kfree(exp); 370 - } 371 - 372 - static void svc_export_put(struct kref *ref) 373 - { 374 - struct svc_export *exp = container_of(ref, struct svc_export, h.ref); 375 - 376 - INIT_RCU_WORK(&exp->ex_rcu_work, svc_export_put_work); 377 - queue_rcu_work(system_wq, &exp->ex_rcu_work); 376 + kfree_rcu(exp, ex_rcu); 378 377 } 379 378 380 379 static int svc_export_upcall(struct cache_detail *cd, struct cache_head *h)
+2 -2
fs/nfsd/export.h
··· 75 75 u32 ex_layout_types; 76 76 struct nfsd4_deviceid_map *ex_devid_map; 77 77 struct cache_detail *cd; 78 - struct rcu_work ex_rcu_work; 78 + struct rcu_head ex_rcu; 79 79 unsigned long ex_xprtsec_modes; 80 80 struct export_stats *ex_stats; 81 81 }; ··· 92 92 u32 ek_fsid[6]; 93 93 94 94 struct path ek_path; 95 - struct rcu_work ek_rcu_work; 95 + struct rcu_head ek_rcu; 96 96 }; 97 97 98 98 #define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
+1 -3
fs/nfsd/nfs4callback.c
··· 1100 1100 args.authflavor = clp->cl_cred.cr_flavor; 1101 1101 clp->cl_cb_ident = conn->cb_ident; 1102 1102 } else { 1103 - if (!conn->cb_xprt) 1103 + if (!conn->cb_xprt || !ses) 1104 1104 return -EINVAL; 1105 1105 clp->cl_cb_session = ses; 1106 1106 args.bc_xprt = conn->cb_xprt; ··· 1522 1522 ses = c->cn_session; 1523 1523 } 1524 1524 spin_unlock(&clp->cl_lock); 1525 - if (!c) 1526 - return; 1527 1525 1528 1526 err = setup_callback_client(clp, &conn, ses); 1529 1527 if (err) {
+8 -5
fs/nfsd/nfs4proc.c
··· 1347 1347 { 1348 1348 if (!refcount_dec_and_test(&copy->refcount)) 1349 1349 return; 1350 - atomic_dec(&copy->cp_nn->pending_async_copies); 1351 1350 kfree(copy->cp_src); 1352 1351 kfree(copy); 1353 1352 } ··· 1869 1870 set_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags); 1870 1871 trace_nfsd_copy_async_done(copy); 1871 1872 nfsd4_send_cb_offload(copy); 1873 + atomic_dec(&copy->cp_nn->pending_async_copies); 1872 1874 return 0; 1873 1875 } 1874 1876 ··· 1927 1927 /* Arbitrary cap on number of pending async copy operations */ 1928 1928 if (atomic_inc_return(&nn->pending_async_copies) > 1929 1929 (int)rqstp->rq_pool->sp_nrthreads) 1930 - goto out_err; 1930 + goto out_dec_async_copy_err; 1931 1931 async_copy->cp_src = kmalloc(sizeof(*async_copy->cp_src), GFP_KERNEL); 1932 1932 if (!async_copy->cp_src) 1933 - goto out_err; 1933 + goto out_dec_async_copy_err; 1934 1934 if (!nfs4_init_copy_state(nn, copy)) 1935 - goto out_err; 1935 + goto out_dec_async_copy_err; 1936 1936 memcpy(&result->cb_stateid, &copy->cp_stateid.cs_stid, 1937 1937 sizeof(result->cb_stateid)); 1938 1938 dup_copy_fields(copy, async_copy); 1939 1939 async_copy->copy_task = kthread_create(nfsd4_do_async_copy, 1940 1940 async_copy, "%s", "copy thread"); 1941 1941 if (IS_ERR(async_copy->copy_task)) 1942 - goto out_err; 1942 + goto out_dec_async_copy_err; 1943 1943 spin_lock(&async_copy->cp_clp->async_lock); 1944 1944 list_add(&async_copy->copies, 1945 1945 &async_copy->cp_clp->async_copies); ··· 1954 1954 trace_nfsd_copy_done(copy, status); 1955 1955 release_copy_files(copy); 1956 1956 return status; 1957 + out_dec_async_copy_err: 1958 + if (async_copy) 1959 + atomic_dec(&nn->pending_async_copies); 1957 1960 out_err: 1958 1961 if (nfsd4_ssc_is_inter(copy)) { 1959 1962 /*