diff options
-rw-r--r-- | fs/sysfs/symlink.c | 1 | ||||
-rw-r--r-- | net/bridge/br_if.c | 2 | ||||
-rw-r--r-- | net/bridge/br_notify.c | 7 | ||||
-rw-r--r-- | net/bridge/br_private.h | 6 | ||||
-rw-r--r-- | net/bridge/br_sysfs_if.c | 32 |
5 files changed, 42 insertions, 6 deletions
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index b93ec51fa7ac..942f239a2132 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -261,3 +261,4 @@ const struct inode_operations sysfs_symlink_inode_operations = { | |||
261 | 261 | ||
262 | EXPORT_SYMBOL_GPL(sysfs_create_link); | 262 | EXPORT_SYMBOL_GPL(sysfs_create_link); |
263 | EXPORT_SYMBOL_GPL(sysfs_remove_link); | 263 | EXPORT_SYMBOL_GPL(sysfs_remove_link); |
264 | EXPORT_SYMBOL_GPL(sysfs_rename_link); | ||
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 45f3f8871149..f25e3c92bd72 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -133,7 +133,7 @@ static void del_nbp(struct net_bridge_port *p) | |||
133 | struct net_bridge *br = p->br; | 133 | struct net_bridge *br = p->br; |
134 | struct net_device *dev = p->dev; | 134 | struct net_device *dev = p->dev; |
135 | 135 | ||
136 | sysfs_remove_link(br->ifobj, dev->name); | 136 | sysfs_remove_link(br->ifobj, p->sysfs_name); |
137 | 137 | ||
138 | dev_set_promiscuity(dev, -1); | 138 | dev_set_promiscuity(dev, -1); |
139 | 139 | ||
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 1413b72acc7f..717e1fd6133c 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
@@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
34 | struct net_device *dev = ptr; | 34 | struct net_device *dev = ptr; |
35 | struct net_bridge_port *p = dev->br_port; | 35 | struct net_bridge_port *p = dev->br_port; |
36 | struct net_bridge *br; | 36 | struct net_bridge *br; |
37 | int err; | ||
37 | 38 | ||
38 | /* not a port of a bridge */ | 39 | /* not a port of a bridge */ |
39 | if (p == NULL) | 40 | if (p == NULL) |
@@ -83,6 +84,12 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
83 | br_del_if(br, dev); | 84 | br_del_if(br, dev); |
84 | break; | 85 | break; |
85 | 86 | ||
87 | case NETDEV_CHANGENAME: | ||
88 | err = br_sysfs_renameif(p); | ||
89 | if (err) | ||
90 | return notifier_from_errno(err); | ||
91 | break; | ||
92 | |||
86 | case NETDEV_PRE_TYPE_CHANGE: | 93 | case NETDEV_PRE_TYPE_CHANGE: |
87 | /* Forbid underlaying device to change its type. */ | 94 | /* Forbid underlaying device to change its type. */ |
88 | return NOTIFY_BAD; | 95 | return NOTIFY_BAD; |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 79a13d1c2573..0f4a74bc6a9b 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -139,6 +139,10 @@ struct net_bridge_port | |||
139 | struct hlist_head mglist; | 139 | struct hlist_head mglist; |
140 | struct hlist_node rlist; | 140 | struct hlist_node rlist; |
141 | #endif | 141 | #endif |
142 | |||
143 | #ifdef CONFIG_SYSFS | ||
144 | char sysfs_name[IFNAMSIZ]; | ||
145 | #endif | ||
142 | }; | 146 | }; |
143 | 147 | ||
144 | struct br_cpu_netstats { | 148 | struct br_cpu_netstats { |
@@ -480,6 +484,7 @@ extern void br_ifinfo_notify(int event, struct net_bridge_port *port); | |||
480 | /* br_sysfs_if.c */ | 484 | /* br_sysfs_if.c */ |
481 | extern const struct sysfs_ops brport_sysfs_ops; | 485 | extern const struct sysfs_ops brport_sysfs_ops; |
482 | extern int br_sysfs_addif(struct net_bridge_port *p); | 486 | extern int br_sysfs_addif(struct net_bridge_port *p); |
487 | extern int br_sysfs_renameif(struct net_bridge_port *p); | ||
483 | 488 | ||
484 | /* br_sysfs_br.c */ | 489 | /* br_sysfs_br.c */ |
485 | extern int br_sysfs_addbr(struct net_device *dev); | 490 | extern int br_sysfs_addbr(struct net_device *dev); |
@@ -488,6 +493,7 @@ extern void br_sysfs_delbr(struct net_device *dev); | |||
488 | #else | 493 | #else |
489 | 494 | ||
490 | #define br_sysfs_addif(p) (0) | 495 | #define br_sysfs_addif(p) (0) |
496 | #define br_sysfs_renameif(p) (0) | ||
491 | #define br_sysfs_addbr(dev) (0) | 497 | #define br_sysfs_addbr(dev) (0) |
492 | #define br_sysfs_delbr(dev) do { } while(0) | 498 | #define br_sysfs_delbr(dev) do { } while(0) |
493 | #endif /* CONFIG_SYSFS */ | 499 | #endif /* CONFIG_SYSFS */ |
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 0b9916489d6b..fd5799c9bc8d 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c | |||
@@ -246,7 +246,7 @@ const struct sysfs_ops brport_sysfs_ops = { | |||
246 | /* | 246 | /* |
247 | * Add sysfs entries to ethernet device added to a bridge. | 247 | * Add sysfs entries to ethernet device added to a bridge. |
248 | * Creates a brport subdirectory with bridge attributes. | 248 | * Creates a brport subdirectory with bridge attributes. |
249 | * Puts symlink in bridge's brport subdirectory | 249 | * Puts symlink in bridge's brif subdirectory |
250 | */ | 250 | */ |
251 | int br_sysfs_addif(struct net_bridge_port *p) | 251 | int br_sysfs_addif(struct net_bridge_port *p) |
252 | { | 252 | { |
@@ -257,15 +257,37 @@ int br_sysfs_addif(struct net_bridge_port *p) | |||
257 | err = sysfs_create_link(&p->kobj, &br->dev->dev.kobj, | 257 | err = sysfs_create_link(&p->kobj, &br->dev->dev.kobj, |
258 | SYSFS_BRIDGE_PORT_LINK); | 258 | SYSFS_BRIDGE_PORT_LINK); |
259 | if (err) | 259 | if (err) |
260 | goto out2; | 260 | return err; |
261 | 261 | ||
262 | for (a = brport_attrs; *a; ++a) { | 262 | for (a = brport_attrs; *a; ++a) { |
263 | err = sysfs_create_file(&p->kobj, &((*a)->attr)); | 263 | err = sysfs_create_file(&p->kobj, &((*a)->attr)); |
264 | if (err) | 264 | if (err) |
265 | goto out2; | 265 | return err; |
266 | } | 266 | } |
267 | 267 | ||
268 | err = sysfs_create_link(br->ifobj, &p->kobj, p->dev->name); | 268 | strlcpy(p->sysfs_name, p->dev->name, IFNAMSIZ); |
269 | out2: | 269 | return sysfs_create_link(br->ifobj, &p->kobj, p->sysfs_name); |
270 | } | ||
271 | |||
272 | /* Rename bridge's brif symlink */ | ||
273 | int br_sysfs_renameif(struct net_bridge_port *p) | ||
274 | { | ||
275 | struct net_bridge *br = p->br; | ||
276 | int err; | ||
277 | |||
278 | /* If a rename fails, the rollback will cause another | ||
279 | * rename call with the existing name. | ||
280 | */ | ||
281 | if (!strncmp(p->sysfs_name, p->dev->name, IFNAMSIZ)) | ||
282 | return 0; | ||
283 | |||
284 | err = sysfs_rename_link(br->ifobj, &p->kobj, | ||
285 | p->sysfs_name, p->dev->name); | ||
286 | if (err) | ||
287 | netdev_notice(br->dev, "unable to rename link %s to %s", | ||
288 | p->sysfs_name, p->dev->name); | ||
289 | else | ||
290 | strlcpy(p->sysfs_name, p->dev->name, IFNAMSIZ); | ||
291 | |||
270 | return err; | 292 | return err; |
271 | } | 293 | } |