Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 111769
b: refs/heads/master
c: 5c18245
h: refs/heads/master
i:
  111767: 336fbf0
v: v3
  • Loading branch information
Herbert Xu authored and David S. Miller committed Sep 23, 2008
1 parent 996028b commit 8a58b1e
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fcaa40669cd798ca2ac0d15441e8a1d1145f2b16
refs/heads/master: 5c1824587f0797373c95719a196f6098f7c6d20c
2 changes: 1 addition & 1 deletion trunk/include/linux/netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ struct netlink_callback
int (*dump)(struct sk_buff * skb, struct netlink_callback *cb);
int (*done)(struct netlink_callback *cb);
int family;
long args[6];
long args[7];
};

struct netlink_notify
Expand Down
10 changes: 3 additions & 7 deletions trunk/include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,8 @@ struct xfrm6_tunnel {
};

struct xfrm_state_walk {
struct list_head list;
unsigned long genid;
struct xfrm_state *state;
int count;
u8 proto;
Expand Down Expand Up @@ -1281,13 +1283,7 @@ static inline void xfrm6_fini(void)
extern int xfrm_proc_init(void);
#endif

static inline void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
{
walk->proto = proto;
walk->state = NULL;
walk->count = 0;
}

extern void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto);
extern int xfrm_state_walk(struct xfrm_state_walk *walk,
int (*func)(struct xfrm_state *, int, void*), void *);
extern void xfrm_state_walk_done(struct xfrm_state_walk *walk);
Expand Down
39 changes: 30 additions & 9 deletions trunk/net/xfrm/xfrm_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ static unsigned long xfrm_state_walk_ongoing;
/* Counter indicating walk completion, protected by xfrm_cfg_mutex. */
static unsigned long xfrm_state_walk_completed;

/* List of outstanding state walks used to set the completed counter. */
static LIST_HEAD(xfrm_state_walks);

static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);

Expand Down Expand Up @@ -1584,7 +1587,6 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,
if (err) {
xfrm_state_hold(last);
walk->state = last;
xfrm_state_walk_ongoing++;
goto out;
}
}
Expand All @@ -1599,25 +1601,44 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,
err = func(last, 0, data);
out:
spin_unlock_bh(&xfrm_state_lock);
if (old != NULL) {
if (old != NULL)
xfrm_state_put(old);
xfrm_state_walk_completed++;
if (!list_empty(&xfrm_state_gc_leftovers))
schedule_work(&xfrm_state_gc_work);
}
return err;
}
EXPORT_SYMBOL(xfrm_state_walk);

void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
{
walk->proto = proto;
walk->state = NULL;
walk->count = 0;
list_add_tail(&walk->list, &xfrm_state_walks);
walk->genid = ++xfrm_state_walk_ongoing;
}
EXPORT_SYMBOL(xfrm_state_walk_init);

void xfrm_state_walk_done(struct xfrm_state_walk *walk)
{
struct list_head *prev;

if (walk->state != NULL) {
xfrm_state_put(walk->state);
walk->state = NULL;
xfrm_state_walk_completed++;
if (!list_empty(&xfrm_state_gc_leftovers))
schedule_work(&xfrm_state_gc_work);
}

prev = walk->list.prev;
list_del(&walk->list);

if (prev != &xfrm_state_walks) {
list_entry(prev, struct xfrm_state_walk, list)->genid =
walk->genid;
return;
}

xfrm_state_walk_completed = walk->genid;

if (!list_empty(&xfrm_state_gc_leftovers))
schedule_work(&xfrm_state_gc_work);
}
EXPORT_SYMBOL(xfrm_state_walk_done);

Expand Down

0 comments on commit 8a58b1e

Please sign in to comment.