Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions fs/nfsd/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,24 @@
#define EXPKEY_HASHMAX (1 << EXPKEY_HASHBITS)
#define EXPKEY_HASHMASK (EXPKEY_HASHMAX -1)

static void expkey_put(struct kref *ref)
static void expkey_put_work(struct work_struct *work)
{
struct svc_expkey *key = container_of(ref, struct svc_expkey, h.ref);
struct svc_expkey *key =
container_of(to_rcu_work(work), struct svc_expkey, ek_rcu_work);

if (test_bit(CACHE_VALID, &key->h.flags) &&
!test_bit(CACHE_NEGATIVE, &key->h.flags))
path_put(&key->ek_path);
auth_domain_put(key->ek_client);
kfree_rcu(key, ek_rcu);
kfree(key);
}

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)
Expand Down Expand Up @@ -351,16 +360,26 @@ static void export_stats_destroy(struct export_stats *stats)
EXP_STATS_COUNTERS_NUM);
}

static void svc_export_put(struct kref *ref)
static void svc_export_put_work(struct work_struct *work)
{
struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
struct svc_export *exp =
container_of(to_rcu_work(work), struct svc_export, ex_rcu_work);

path_put(&exp->ex_path);
auth_domain_put(exp->ex_client);
nfsd4_fslocs_free(&exp->ex_fslocs);
export_stats_destroy(exp->ex_stats);
kfree(exp->ex_stats);
kfree(exp->ex_uuid);
kfree_rcu(exp, ex_rcu);
kfree(exp);
}

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)
Expand Down
4 changes: 2 additions & 2 deletions fs/nfsd/export.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct svc_export {
u32 ex_layout_types;
struct nfsd4_deviceid_map *ex_devid_map;
struct cache_detail *cd;
struct rcu_head ex_rcu;
struct rcu_work ex_rcu_work;
unsigned long ex_xprtsec_modes;
struct export_stats *ex_stats;
};
Expand All @@ -92,7 +92,7 @@ struct svc_expkey {
u32 ek_fsid[6];

struct path ek_path;
struct rcu_head ek_rcu;
struct rcu_work ek_rcu_work;
};

#define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC))
Expand Down
Loading