* [PATCH 7/7] sysfs: @name comes before @ns
From: Tejun Heo @ 2013-09-12 2:29 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, kay, ebiederm, netdev, lizefan, Tejun Heo
In-Reply-To: <1378952949-7900-1-git-send-email-tj@kernel.org>
Some internal sysfs functions which take explicit namespace argument
are weird in that they place the optional @ns in front of @name which
is contrary to the established convention. This is confusing and
error-prone especially as @ns and @name may be interchanged without
causing compilation warning.
Swap the positions of @name and @ns in the following internal
functions.
sysfs_find_dirent()
sysfs_rename()
sysfs_hash_and_remove()
sysfs_name_hash()
sysfs_name_compare()
create_dir()
This patch doesn't introduce any functional changes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Kay Sievers <kay@vrfy.org>
---
fs/sysfs/bin.c | 2 +-
fs/sysfs/dir.c | 45 +++++++++++++++++++++++----------------------
fs/sysfs/file.c | 10 +++++-----
fs/sysfs/group.c | 12 ++++++------
fs/sysfs/inode.c | 6 +++---
fs/sysfs/symlink.c | 6 +++---
fs/sysfs/sysfs.h | 10 +++++-----
7 files changed, 46 insertions(+), 45 deletions(-)
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index c590cab..d49e6ca 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -497,6 +497,6 @@ EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
void sysfs_remove_bin_file(struct kobject *kobj,
const struct bin_attribute *attr)
{
- sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name);
+ sysfs_hash_and_remove(kobj->sd, attr->attr.name, NULL);
}
EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 3dacce0..d41b555 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -35,12 +35,12 @@ static DEFINE_IDA(sysfs_ino_ida);
/**
* sysfs_name_hash
- * @ns: Namespace tag to hash
* @name: Null terminated string to hash
+ * @ns: Namespace tag to hash
*
* Returns 31 bit hash of ns + name (so it fits in an off_t )
*/
-static unsigned int sysfs_name_hash(const void *ns, const char *name)
+static unsigned int sysfs_name_hash(const char *name, const void *ns)
{
unsigned long hash = init_name_hash();
unsigned int len = strlen(name);
@@ -56,8 +56,8 @@ static unsigned int sysfs_name_hash(const void *ns, const char *name)
return hash;
}
-static int sysfs_name_compare(unsigned int hash, const void *ns,
- const char *name, const struct sysfs_dirent *sd)
+static int sysfs_name_compare(unsigned int hash, const char *name,
+ const void *ns, const struct sysfs_dirent *sd)
{
if (hash != sd->s_hash)
return hash - sd->s_hash;
@@ -69,7 +69,7 @@ static int sysfs_name_compare(unsigned int hash, const void *ns,
static int sysfs_sd_compare(const struct sysfs_dirent *left,
const struct sysfs_dirent *right)
{
- return sysfs_name_compare(left->s_hash, left->s_ns, left->s_name,
+ return sysfs_name_compare(left->s_hash, left->s_name, left->s_ns,
right);
}
@@ -451,7 +451,7 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
struct sysfs_inode_attrs *ps_iattr;
int ret;
- sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name);
+ sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
sd->s_parent = sysfs_get(acxt->parent_sd);
ret = sysfs_link_sibling(sd);
@@ -596,6 +596,7 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
* sysfs_find_dirent - find sysfs_dirent with the given name
* @parent_sd: sysfs_dirent to search under
* @name: name to look for
+ * @ns: the namespace tag to use
*
* Look for sysfs_dirent with name @name under @parent_sd.
*
@@ -606,19 +607,19 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
* Pointer to sysfs_dirent if found, NULL if not.
*/
struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
- const void *ns,
- const unsigned char *name)
+ const unsigned char *name,
+ const void *ns)
{
struct rb_node *node = parent_sd->s_dir.children.rb_node;
unsigned int hash;
- hash = sysfs_name_hash(ns, name);
+ hash = sysfs_name_hash(name, ns);
while (node) {
struct sysfs_dirent *sd;
int result;
sd = to_sysfs_dirent(node);
- result = sysfs_name_compare(hash, ns, name, sd);
+ result = sysfs_name_compare(hash, name, ns, sd);
if (result < 0)
node = node->rb_left;
else if (result > 0)
@@ -651,7 +652,7 @@ struct sysfs_dirent *sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd,
struct sysfs_dirent *sd;
mutex_lock(&sysfs_mutex);
- sd = sysfs_find_dirent(parent_sd, ns, name);
+ sd = sysfs_find_dirent(parent_sd, name, ns);
sysfs_get(sd);
mutex_unlock(&sysfs_mutex);
@@ -660,7 +661,8 @@ struct sysfs_dirent *sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd,
EXPORT_SYMBOL_GPL(sysfs_get_dirent);
static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
- const void *ns, const char *name, struct sysfs_dirent **p_sd)
+ const char *name, const void *ns,
+ struct sysfs_dirent **p_sd)
{
umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
struct sysfs_addrm_cxt acxt;
@@ -691,7 +693,7 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
int sysfs_create_subdir(struct kobject *kobj, const char *name,
struct sysfs_dirent **p_sd)
{
- return create_dir(kobj, kobj->sd, NULL, name, p_sd);
+ return create_dir(kobj, kobj->sd, name, NULL, p_sd);
}
/**
@@ -714,7 +716,7 @@ int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
if (!parent_sd)
return -ENOENT;
- error = create_dir(kobj, parent_sd, ns, kobject_name(kobj), &sd);
+ error = create_dir(kobj, parent_sd, kobject_name(kobj), ns, &sd);
if (!error)
kobj->sd = sd;
return error;
@@ -735,7 +737,7 @@ static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry,
if (parent_sd->s_flags & SYSFS_FLAG_HAS_NS)
ns = sysfs_info(dir->i_sb)->ns;
- sd = sysfs_find_dirent(parent_sd, ns, dentry->d_name.name);
+ sd = sysfs_find_dirent(parent_sd, dentry->d_name.name, ns);
/* no such entry */
if (!sd) {
@@ -823,9 +825,8 @@ void sysfs_remove_dir(struct kobject *kobj)
__sysfs_remove_dir(sd);
}
-int sysfs_rename(struct sysfs_dirent *sd,
- struct sysfs_dirent *new_parent_sd, const void *new_ns,
- const char *new_name)
+int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,
+ const char *new_name, const void *new_ns)
{
int error;
@@ -837,7 +838,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
goto out; /* nothing to rename */
error = -EEXIST;
- if (sysfs_find_dirent(new_parent_sd, new_ns, new_name))
+ if (sysfs_find_dirent(new_parent_sd, new_name, new_ns))
goto out;
/* rename sysfs_dirent */
@@ -858,7 +859,7 @@ int sysfs_rename(struct sysfs_dirent *sd,
sysfs_get(new_parent_sd);
sysfs_put(sd->s_parent);
sd->s_ns = new_ns;
- sd->s_hash = sysfs_name_hash(sd->s_ns, sd->s_name);
+ sd->s_hash = sysfs_name_hash(sd->s_name, sd->s_ns);
sd->s_parent = new_parent_sd;
sysfs_link_sibling(sd);
@@ -873,7 +874,7 @@ int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
{
struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
- return sysfs_rename(kobj->sd, parent_sd, new_ns, new_name);
+ return sysfs_rename(kobj->sd, parent_sd, new_name, new_ns);
}
int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
@@ -886,7 +887,7 @@ int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
new_parent_kobj->sd : &sysfs_root;
- return sysfs_rename(sd, new_parent_sd, new_ns, sd->s_name);
+ return sysfs_rename(sd, new_parent_sd, sd->s_name, new_ns);
}
/* Relationship between s_mode and the DT_xxx types */
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 0f3214a..4697019 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -466,9 +466,9 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
mutex_lock(&sysfs_mutex);
if (sd && dir)
- sd = sysfs_find_dirent(sd, NULL, dir);
+ sd = sysfs_find_dirent(sd, dir, NULL);
if (sd && attr)
- sd = sysfs_find_dirent(sd, NULL, attr);
+ sd = sysfs_find_dirent(sd, attr, NULL);
if (sd)
sysfs_notify_dirent(sd);
@@ -594,7 +594,7 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
mutex_lock(&sysfs_mutex);
rc = -ENOENT;
- sd = sysfs_find_dirent(kobj->sd, NULL, attr->name);
+ sd = sysfs_find_dirent(kobj->sd, attr->name, NULL);
if (!sd)
goto out;
@@ -621,7 +621,7 @@ void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
{
struct sysfs_dirent *dir_sd = kobj->sd;
- sysfs_hash_and_remove(dir_sd, ns, attr->name);
+ sysfs_hash_and_remove(dir_sd, attr->name, ns);
}
EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
@@ -649,7 +649,7 @@ void sysfs_remove_file_from_group(struct kobject *kobj,
else
dir_sd = sysfs_get(kobj->sd);
if (dir_sd) {
- sysfs_hash_and_remove(dir_sd, NULL, attr->name);
+ sysfs_hash_and_remove(dir_sd, attr->name, NULL);
sysfs_put(dir_sd);
}
}
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 2110215..2dae55c 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -26,7 +26,7 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
if (grp->attrs)
for (attr = grp->attrs; *attr; attr++)
- sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
+ sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL);
if (grp->bin_attrs)
for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++)
sysfs_remove_bin_file(kobj, *bin_attr);
@@ -49,8 +49,8 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
* re-adding (if required) the file.
*/
if (update)
- sysfs_hash_and_remove(dir_sd, NULL,
- (*attr)->name);
+ sysfs_hash_and_remove(dir_sd, (*attr)->name,
+ NULL);
if (grp->is_visible) {
mode = grp->is_visible(kobj, *attr, i);
if (!mode)
@@ -270,7 +270,7 @@ int sysfs_merge_group(struct kobject *kobj,
error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR);
if (error) {
while (--i >= 0)
- sysfs_hash_and_remove(dir_sd, NULL, (*--attr)->name);
+ sysfs_hash_and_remove(dir_sd, (*--attr)->name, NULL);
}
sysfs_put(dir_sd);
@@ -292,7 +292,7 @@ void sysfs_unmerge_group(struct kobject *kobj,
dir_sd = sysfs_get_dirent(kobj->sd, grp->name);
if (dir_sd) {
for (attr = grp->attrs; *attr; ++attr)
- sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
+ sysfs_hash_and_remove(dir_sd, (*attr)->name, NULL);
sysfs_put(dir_sd);
}
}
@@ -335,7 +335,7 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
dir_sd = sysfs_get_dirent(kobj->sd, group_name);
if (dir_sd) {
- sysfs_hash_and_remove(dir_sd, NULL, link_name);
+ sysfs_hash_and_remove(dir_sd, link_name, NULL);
sysfs_put(dir_sd);
}
}
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 963f910..07193d7 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -314,8 +314,8 @@ void sysfs_evict_inode(struct inode *inode)
sysfs_put(sd);
}
-int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns,
- const char *name)
+int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name,
+ const void *ns)
{
struct sysfs_addrm_cxt acxt;
struct sysfs_dirent *sd;
@@ -328,7 +328,7 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns,
sysfs_addrm_start(&acxt, dir_sd);
- sd = sysfs_find_dirent(dir_sd, ns, name);
+ sd = sysfs_find_dirent(dir_sd, name, ns);
if (sd)
sysfs_remove_one(&acxt, sd);
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index c96b31a..88c8bc5 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -144,7 +144,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ,
if (targ->sd)
ns = targ->sd->s_ns;
spin_unlock(&sysfs_assoc_lock);
- sysfs_hash_and_remove(kobj->sd, ns, name);
+ sysfs_hash_and_remove(kobj->sd, name, ns);
}
/**
@@ -161,7 +161,7 @@ void sysfs_remove_link(struct kobject *kobj, const char *name)
else
parent_sd = kobj->sd;
- sysfs_hash_and_remove(parent_sd, NULL, name);
+ sysfs_hash_and_remove(parent_sd, name, NULL);
}
EXPORT_SYMBOL_GPL(sysfs_remove_link);
@@ -201,7 +201,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ,
if (sd->s_symlink.target_sd->s_dir.kobj != targ)
goto out;
- result = sysfs_rename(sd, parent_sd, new_ns, new);
+ result = sysfs_rename(sd, parent_sd, new, new_ns);
out:
sysfs_put(sd);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 6faacaf..ee44fde 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -162,8 +162,8 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
- const void *ns,
- const unsigned char *name);
+ const unsigned char *name,
+ const void *ns);
struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type);
void release_sysfs_dirent(struct sysfs_dirent *sd);
@@ -173,7 +173,7 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
void sysfs_remove_subdir(struct sysfs_dirent *sd);
int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd,
- const void *ns, const char *new_name);
+ const char *new_name, const void *new_ns);
static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
{
@@ -204,8 +204,8 @@ int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,
size_t size, int flags);
-int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns,
- const char *name);
+int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name,
+ const void *ns);
int sysfs_inode_init(void);
/*
--
1.8.3.1
^ permalink raw reply related
* [PATCH 6/7] sysfs: clean up sysfs_get_dirent()
From: Tejun Heo @ 2013-09-12 2:29 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, kay, ebiederm, netdev, lizefan, Tejun Heo
In-Reply-To: <1378952949-7900-1-git-send-email-tj@kernel.org>
The pre-existing sysfs interfaces which take explicit namespace
argument are weird in that they place the optional @ns in front of
@name which is contrary to the established convention. For example,
we end up forcing vast majority of sysfs_get_dirent() users to do
sysfs_get_dirent(parent, NULL, name), which is silly and error-prone
especially as @ns and @name may be interchanged without causing
compilation warning.
This renames sysfs_get_dirent() to sysfs_get_dirent_ns() and swap the
positions of @name and @ns, and sysfs_get_dirent() is now a wrapper
around sysfs_get_dirent_ns(). This makes confusions a lot less
likely.
There are other interfaces which take @ns before @name. They'll be
updated by following patches.
This patch doesn't introduce any functional changes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Kay Sievers <kay@vrfy.org>
---
drivers/gpio/gpiolib.c | 2 +-
drivers/md/bitmap.c | 4 ++--
drivers/md/md.c | 2 +-
drivers/md/md.h | 2 +-
fs/sysfs/dir.c | 9 +++++----
fs/sysfs/file.c | 4 ++--
fs/sysfs/group.c | 10 +++++-----
fs/sysfs/symlink.c | 2 +-
fs/sysfs/sysfs.h | 3 ---
include/linux/sysfs.h | 19 ++++++++++++-------
10 files changed, 30 insertions(+), 27 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 86ef346..a094356 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -408,7 +408,7 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev,
IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING;
if (!value_sd) {
- value_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value");
+ value_sd = sysfs_get_dirent(dev->kobj.sd, "value");
if (!value_sd) {
ret = -ENODEV;
goto err_out;
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index a7fd821..12dc29b 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1654,9 +1654,9 @@ int bitmap_create(struct mddev *mddev)
bitmap->mddev = mddev;
if (mddev->kobj.sd)
- bm = sysfs_get_dirent(mddev->kobj.sd, NULL, "bitmap");
+ bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap");
if (bm) {
- bitmap->sysfs_can_clear = sysfs_get_dirent(bm, NULL, "can_clear");
+ bitmap->sysfs_can_clear = sysfs_get_dirent(bm, "can_clear");
sysfs_put(bm);
} else
bitmap->sysfs_can_clear = NULL;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index adf4d7e..8a0d762 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3555,7 +3555,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
printk(KERN_WARNING
"md: cannot register extra attributes for %s\n",
mdname(mddev));
- mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, NULL, "sync_action");
+ mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action");
}
if (mddev->pers->sync_request != NULL &&
pers->sync_request == NULL) {
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 608050c..b0051f2 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -501,7 +501,7 @@ extern struct attribute_group md_bitmap_group;
static inline struct sysfs_dirent *sysfs_get_dirent_safe(struct sysfs_dirent *sd, char *name)
{
if (sd)
- return sysfs_get_dirent(sd, NULL, name);
+ return sysfs_get_dirent(sd, name);
return sd;
}
static inline void sysfs_notify_dirent_safe(struct sysfs_dirent *sd)
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 1dfb4aa..3dacce0 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -630,9 +630,10 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
}
/**
- * sysfs_get_dirent - find and get sysfs_dirent with the given name
+ * sysfs_get_dirent_ns - find and get sysfs_dirent with the given name
* @parent_sd: sysfs_dirent to search under
* @name: name to look for
+ * @ns: the namespace tag to use
*
* Look for sysfs_dirent with name @name under @parent_sd and get
* it if found.
@@ -643,9 +644,9 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
* RETURNS:
* Pointer to sysfs_dirent if found, NULL if not.
*/
-struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
- const void *ns,
- const unsigned char *name)
+struct sysfs_dirent *sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd,
+ const unsigned char *name,
+ const void *ns)
{
struct sysfs_dirent *sd;
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index e784340..0f3214a 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -563,7 +563,7 @@ int sysfs_add_file_to_group(struct kobject *kobj,
int error;
if (group)
- dir_sd = sysfs_get_dirent(kobj->sd, NULL, group);
+ dir_sd = sysfs_get_dirent(kobj->sd, group);
else
dir_sd = sysfs_get(kobj->sd);
@@ -645,7 +645,7 @@ void sysfs_remove_file_from_group(struct kobject *kobj,
struct sysfs_dirent *dir_sd;
if (group)
- dir_sd = sysfs_get_dirent(kobj->sd, NULL, group);
+ dir_sd = sysfs_get_dirent(kobj->sd, group);
else
dir_sd = sysfs_get(kobj->sd);
if (dir_sd) {
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 25c78f2..2110215 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -207,7 +207,7 @@ void sysfs_remove_group(struct kobject *kobj,
struct sysfs_dirent *sd;
if (grp->name) {
- sd = sysfs_get_dirent(dir_sd, NULL, grp->name);
+ sd = sysfs_get_dirent(dir_sd, grp->name);
if (!sd) {
WARN(!sd, KERN_WARNING
"sysfs group %p not found for kobject '%s'\n",
@@ -262,7 +262,7 @@ int sysfs_merge_group(struct kobject *kobj,
struct attribute *const *attr;
int i;
- dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
+ dir_sd = sysfs_get_dirent(kobj->sd, grp->name);
if (!dir_sd)
return -ENOENT;
@@ -289,7 +289,7 @@ void sysfs_unmerge_group(struct kobject *kobj,
struct sysfs_dirent *dir_sd;
struct attribute *const *attr;
- dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name);
+ dir_sd = sysfs_get_dirent(kobj->sd, grp->name);
if (dir_sd) {
for (attr = grp->attrs; *attr; ++attr)
sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name);
@@ -311,7 +311,7 @@ int sysfs_add_link_to_group(struct kobject *kobj, const char *group_name,
struct sysfs_dirent *dir_sd;
int error = 0;
- dir_sd = sysfs_get_dirent(kobj->sd, NULL, group_name);
+ dir_sd = sysfs_get_dirent(kobj->sd, group_name);
if (!dir_sd)
return -ENOENT;
@@ -333,7 +333,7 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
{
struct sysfs_dirent *dir_sd;
- dir_sd = sysfs_get_dirent(kobj->sd, NULL, group_name);
+ dir_sd = sysfs_get_dirent(kobj->sd, group_name);
if (dir_sd) {
sysfs_hash_and_remove(dir_sd, NULL, link_name);
sysfs_put(dir_sd);
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 7d981ce..c96b31a 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -191,7 +191,7 @@ int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ,
old_ns = targ->sd->s_ns;
result = -ENOENT;
- sd = sysfs_get_dirent(parent_sd, old_ns, old);
+ sd = sysfs_get_dirent_ns(parent_sd, old, old_ns);
if (!sd)
goto out;
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 7664d1b..6faacaf 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -164,9 +164,6 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
const void *ns,
const unsigned char *name);
-struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
- const void *ns,
- const unsigned char *name);
struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type);
void release_sysfs_dirent(struct sysfs_dirent *sd);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index c792f73..6695040 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -245,9 +245,9 @@ void sysfs_remove_link_from_group(struct kobject *kobj, const char *group_name,
void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
void sysfs_notify_dirent(struct sysfs_dirent *sd);
-struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
- const void *ns,
- const unsigned char *name);
+struct sysfs_dirent *sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd,
+ const unsigned char *name,
+ const void *ns);
struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd);
void sysfs_put(struct sysfs_dirent *sd);
@@ -422,10 +422,9 @@ static inline void sysfs_notify(struct kobject *kobj, const char *dir,
static inline void sysfs_notify_dirent(struct sysfs_dirent *sd)
{
}
-static inline
-struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
- const void *ns,
- const unsigned char *name)
+static inline struct sysfs_dirent *
+sysfs_get_dirent_ns(struct sysfs_dirent *parent_sd, const unsigned char *name,
+ const void *ns)
{
return NULL;
}
@@ -462,4 +461,10 @@ static inline int sysfs_rename_link(struct kobject *kobj, struct kobject *target
return sysfs_rename_link_ns(kobj, target, old_name, new_name, NULL);
}
+static inline struct sysfs_dirent *
+sysfs_get_dirent(struct sysfs_dirent *parent_sd, const unsigned char *name)
+{
+ return sysfs_get_dirent_ns(parent_sd, name, NULL);
+}
+
#endif /* _SYSFS_H_ */
--
1.8.3.1
^ permalink raw reply related
* [PATCH 4/7] sysfs: remove ktype->namespace() invocations in symlink code
From: Tejun Heo @ 2013-09-12 2:29 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, kay, ebiederm, netdev, lizefan, Tejun Heo
In-Reply-To: <1378952949-7900-1-git-send-email-tj@kernel.org>
There's no reason for sysfs to be calling ktype->namespace(). It is
backwards, obfuscates what's going on and unnecessarily tangles two
separate layers.
There are two places where symlink code calls ktype->namespace().
* sysfs_do_create_link_sd() calls it to find out the namespace tag of
the target directory. Unless symlinking races with cross-namespace
renaming, this equals @target_sd->s_ns.
* sysfs_rename_link() uses it to find out the new namespace to rename
to and the new namespace can be different from the existing one.
The function is renamed to sysfs_rename_link_ns() with an explicit
@ns argument and the ktype->namespace() invocation is shifted to the
device layer.
While this patch replaces ktype->namespace() invocation with the
recorded result in @target_sd, this shouldn't result in any behvior
difference.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Kay Sievers <kay@vrfy.org>
---
drivers/base/core.c | 8 +++++---
fs/sysfs/symlink.c | 16 +++++++---------
include/linux/sysfs.h | 16 ++++++++++++----
3 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index c7cfadc..3335000 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1881,6 +1881,7 @@ EXPORT_SYMBOL_GPL(device_destroy);
*/
int device_rename(struct device *dev, const char *new_name)
{
+ struct kobject *kobj = &dev->kobj;
char *old_device_name = NULL;
int error;
@@ -1898,13 +1899,14 @@ int device_rename(struct device *dev, const char *new_name)
}
if (dev->class) {
- error = sysfs_rename_link(&dev->class->p->subsys.kobj,
- &dev->kobj, old_device_name, new_name);
+ error = sysfs_rename_link_ns(&dev->class->p->subsys.kobj,
+ kobj, old_device_name,
+ new_name, kobject_namespace(kobj));
if (error)
goto out;
}
- error = kobject_rename(&dev->kobj, new_name);
+ error = kobject_rename(kobj, new_name);
if (error)
goto out;
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 2dd4507..12d58ad 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -52,7 +52,7 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd,
ns_type = sysfs_ns_type(parent_sd);
if (ns_type)
- sd->s_ns = target->ktype->namespace(target);
+ sd->s_ns = target_sd->s_ns;
sd->s_symlink.target_sd = target_sd;
target_sd = NULL; /* reference is now owned by the symlink */
@@ -181,19 +181,20 @@ void sysfs_remove_link(struct kobject *kobj, const char *name)
EXPORT_SYMBOL_GPL(sysfs_remove_link);
/**
- * sysfs_rename_link - rename symlink in object's directory.
+ * sysfs_rename_link_ns - rename symlink in object's directory.
* @kobj: object we're acting for.
* @targ: object we're pointing to.
* @old: previous name of the symlink.
* @new: new name of the symlink.
+ * @new_ns: new namespace of the symlink.
*
* A helper function for the common rename symlink idiom.
*/
-int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
- const char *old, const char *new)
+int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ,
+ const char *old, const char *new, const void *new_ns)
{
struct sysfs_dirent *parent_sd, *sd = NULL;
- const void *old_ns = NULL, *new_ns = NULL;
+ const void *old_ns = NULL;
int result;
if (!kobj)
@@ -215,16 +216,13 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
if (sd->s_symlink.target_sd->s_dir.kobj != targ)
goto out;
- if (sysfs_ns_type(parent_sd))
- new_ns = targ->ktype->namespace(targ);
-
result = sysfs_rename(sd, parent_sd, new_ns, new);
out:
sysfs_put(sd);
return result;
}
-EXPORT_SYMBOL_GPL(sysfs_rename_link);
+EXPORT_SYMBOL_GPL(sysfs_rename_link_ns);
static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
struct sysfs_dirent *target_sd, char *path)
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 7f56bad..c792f73 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -213,8 +213,9 @@ int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
const char *name);
void sysfs_remove_link(struct kobject *kobj, const char *name);
-int sysfs_rename_link(struct kobject *kobj, struct kobject *target,
- const char *old_name, const char *new_name);
+int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *target,
+ const char *old_name, const char *new_name,
+ const void *new_ns);
void sysfs_delete_link(struct kobject *dir, struct kobject *targ,
const char *name);
@@ -340,8 +341,9 @@ static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
{
}
-static inline int sysfs_rename_link(struct kobject *k, struct kobject *t,
- const char *old_name, const char *new_name)
+static inline int sysfs_rename_link_ns(struct kobject *k, struct kobject *t,
+ const char *old_name,
+ const char *new_name, const void *ns)
{
return 0;
}
@@ -454,4 +456,10 @@ static inline void sysfs_remove_file(struct kobject *kobj,
return sysfs_remove_file_ns(kobj, attr, NULL);
}
+static inline int sysfs_rename_link(struct kobject *kobj, struct kobject *target,
+ const char *old_name, const char *new_name)
+{
+ return sysfs_rename_link_ns(kobj, target, old_name, new_name, NULL);
+}
+
#endif /* _SYSFS_H_ */
--
1.8.3.1
^ permalink raw reply related
* [PATCH 3/7] sysfs: remove ktype->namespace() invocations in directory code
From: Tejun Heo @ 2013-09-12 2:29 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, kay, ebiederm, netdev, lizefan, Tejun Heo
In-Reply-To: <1378952949-7900-1-git-send-email-tj@kernel.org>
For some unrecognizable reason, namespace information is communicated
to sysfs through ktype->namespace() callback when there's *nothing*
which needs the use of a callback. The whole sequence of operations
is completely synchronous and sysfs operations simply end up calling
back into the layer which just invoked it in order to find out the
namespace information, which is completely backwards, obfuscates
what's going on and unnecessarily tangles two separate layers.
This patch doesn't remove ktype->namespace() but shifts its handling
to kobject layer. We probably want to get rid of the callback in the
long term.
This patch adds an explicit param to sysfs_{create|rename|move}_dir()
and renames them to sysfs_{create|rename|move}_dir_ns(), respectively.
ktype->namespace() invocations are moved to the calling sites of the
above functions. A new helper kboject_namespace() is introduced which
directly tests kobj_ns_type_operations->type which should give the
same result as testing sysfs_fs_type(parent_sd) and returns @kobj's
namespace tag as necessary. kobject_namespace() is extern as it will
be used from another file in the following patches.
This patch should be an equivalent conversion without any functional
difference.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Kay Sievers <kay@vrfy.org>
---
fs/sysfs/dir.c | 23 ++++++++---------------
include/linux/kobject.h | 1 +
include/linux/sysfs.h | 20 ++++++++++++--------
lib/kobject.c | 28 ++++++++++++++++++++++++----
4 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 834c64c..878ac3a 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -730,14 +730,14 @@ static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj)
}
/**
- * sysfs_create_dir - create a directory for an object.
- * @kobj: object we're creating directory for.
+ * sysfs_create_dir_ns - create a directory for an object with a namespace tag
+ * @kobj: object we're creating directory for
+ * @ns: the namespace tag to use
*/
-int sysfs_create_dir(struct kobject *kobj)
+int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
{
enum kobj_ns_type type;
struct sysfs_dirent *parent_sd, *sd;
- const void *ns = NULL;
int error = 0;
BUG_ON(!kobj);
@@ -750,8 +750,6 @@ int sysfs_create_dir(struct kobject *kobj)
if (!parent_sd)
return -ENOENT;
- if (sysfs_ns_type(parent_sd))
- ns = kobj->ktype->namespace(kobj);
type = sysfs_read_ns_type(kobj);
error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd);
@@ -909,26 +907,21 @@ int sysfs_rename(struct sysfs_dirent *sd,
return error;
}
-int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
+int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
+ const void *new_ns)
{
struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
- const void *new_ns = NULL;
-
- if (sysfs_ns_type(parent_sd))
- new_ns = kobj->ktype->namespace(kobj);
return sysfs_rename(kobj->sd, parent_sd, new_ns, new_name);
}
-int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
+int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
+ const void *new_ns)
{
struct sysfs_dirent *sd = kobj->sd;
struct sysfs_dirent *new_parent_sd;
- const void *new_ns = NULL;
BUG_ON(!sd->s_parent);
- if (sysfs_ns_type(sd->s_parent))
- new_ns = kobj->ktype->namespace(kobj);
new_parent_sd = new_parent_kobj && new_parent_kobj->sd ?
new_parent_kobj->sd : &sysfs_root;
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index de6dcbcc..e7ba650 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -107,6 +107,7 @@ extern int __must_check kobject_move(struct kobject *, struct kobject *);
extern struct kobject *kobject_get(struct kobject *kobj);
extern void kobject_put(struct kobject *kobj);
+extern const void *kobject_namespace(struct kobject *kobj);
extern char *kobject_get_path(struct kobject *kobj, gfp_t flag);
struct kobj_type {
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 82f7fac..7f56bad 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -182,11 +182,13 @@ struct sysfs_dirent;
int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
void *data, struct module *owner);
-int __must_check sysfs_create_dir(struct kobject *kobj);
+int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns);
void sysfs_remove_dir(struct kobject *kobj);
-int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name);
-int __must_check sysfs_move_dir(struct kobject *kobj,
- struct kobject *new_parent_kobj);
+int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
+ const void *new_ns);
+int __must_check sysfs_move_dir_ns(struct kobject *kobj,
+ struct kobject *new_parent_kobj,
+ const void *new_ns);
int __must_check sysfs_create_file_ns(struct kobject *kobj,
const struct attribute *attr,
@@ -258,7 +260,7 @@ static inline int sysfs_schedule_callback(struct kobject *kobj,
return -ENOSYS;
}
-static inline int sysfs_create_dir(struct kobject *kobj)
+static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
{
return 0;
}
@@ -267,13 +269,15 @@ static inline void sysfs_remove_dir(struct kobject *kobj)
{
}
-static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
+static inline int sysfs_rename_dir_ns(struct kobject *kobj,
+ const char *new_name, const void *new_ns)
{
return 0;
}
-static inline int sysfs_move_dir(struct kobject *kobj,
- struct kobject *new_parent_kobj)
+static inline int sysfs_move_dir_ns(struct kobject *kobj,
+ struct kobject *new_parent_kobj,
+ const void *new_ns)
{
return 0;
}
diff --git a/lib/kobject.c b/lib/kobject.c
index 9621751..85fb3a1 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -18,6 +18,24 @@
#include <linux/stat.h>
#include <linux/slab.h>
+/**
+ * kobject_namespace - return @kobj's namespace tag
+ * @kobj: kobject in question
+ *
+ * Returns namespace tag of @kobj if its parent has namespace ops enabled
+ * and thus @kobj should have a namespace tag associated with it. Returns
+ * %NULL otherwise.
+ */
+const void *kobject_namespace(struct kobject *kobj)
+{
+ const struct kobj_ns_type_operations *ns_ops = kobj_ns_ops(kobj);
+
+ if (!ns_ops || ns_ops->type == KOBJ_NS_TYPE_NONE)
+ return NULL;
+
+ return kobj->ktype->namespace(kobj);
+}
+
/*
* populate_dir - populate directory with attributes.
* @kobj: object we're working on.
@@ -46,8 +64,9 @@ static int populate_dir(struct kobject *kobj)
static int create_dir(struct kobject *kobj)
{
- int error = 0;
- error = sysfs_create_dir(kobj);
+ int error;
+
+ error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
if (!error) {
error = populate_dir(kobj);
if (error)
@@ -428,7 +447,7 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
goto out;
}
- error = sysfs_rename_dir(kobj, new_name);
+ error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
if (error)
goto out;
@@ -472,6 +491,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
if (kobj->kset)
new_parent = kobject_get(&kobj->kset->kobj);
}
+
/* old object path */
devpath = kobject_get_path(kobj, GFP_KERNEL);
if (!devpath) {
@@ -486,7 +506,7 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
envp[0] = devpath_string;
envp[1] = NULL;
- error = sysfs_move_dir(kobj, new_parent);
+ error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
if (error)
goto out;
old_parent = kobj->parent;
--
1.8.3.1
^ permalink raw reply related
* [PATCH 2/7] sysfs: make attr namespace interface less convoluted
From: Tejun Heo @ 2013-09-12 2:29 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, kay, ebiederm, netdev, lizefan, Tejun Heo
In-Reply-To: <1378952949-7900-1-git-send-email-tj@kernel.org>
sysfs ns (namespace) implementation became more convoluted than
necessary while trying to hide ns information from visible interface.
The relatively recent attr ns support is a good example.
* attr ns tag is determined by sysfs_ops->namespace() callback while
dir tag is determined by kobj_type->namespace(). The placement is
arbitrary.
* Instead of performing operations with explicit ns tag, the namespace
callback is routed through sysfs_attr_ns(), sysfs_ops->namespace(),
class_attr_namespace(), class_attr->namespace(). It's not simpler
in any sense. The only thing this convolution does is traversing
the whole stack backwards.
The namespace callbacks are unncessary because the operations involved
are inherently synchronous. The information can be provided in in
straight-forward top-down direction and reversing that direction is
unnecessary and against basic design principles.
This backward interface is unnecessarily convoluted and hinders
properly separating out sysfs from driver model / kobject for proper
layering. This patch updates attr ns support such that
* sysfs_ops->namespace() and class_attr->namespace() are dropped.
* sysfs_{create|remove}_file_ns(), which take explicit @ns param, are
added and sysfs_{create|remove}_file() are now simple wrappers
around the ns aware functions.
* ns handling is dropped from sysfs_chmod_file(). Nobody uses it at
this point. sysfs_chmod_file_ns() can be added later if necessary.
* Explicit @ns is propagated through class_{create|remove}_file_ns()
and netdev_class_{create|remove}_file_ns().
* driver/net/bonding which is currently the only user of attr
namespace is updated to use netdev_class_{create|remove}_file_ns()
with @bh->net as the ns tag instead of using the namespace callback.
This patch should be an equivalent conversion without any functional
difference. It makes the code easier to follow, reduces lines of code
a bit and helps proper separation and layering.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Kay Sievers <kay@vrfy.org>
---
drivers/base/class.c | 29 ++++--------
drivers/net/bonding/bond_sysfs.c | 14 ++----
fs/sysfs/file.c | 95 ++++++++++------------------------------
fs/sysfs/group.c | 7 +--
fs/sysfs/sysfs.h | 5 ++-
include/linux/device.h | 24 +++++++---
include/linux/netdevice.h | 16 ++++++-
include/linux/sysfs.h | 31 +++++++++----
net/core/net-sysfs.c | 14 +++---
9 files changed, 106 insertions(+), 129 deletions(-)
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 8b7818b..f96f704 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -47,18 +47,6 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
return ret;
}
-static const void *class_attr_namespace(struct kobject *kobj,
- const struct attribute *attr)
-{
- struct class_attribute *class_attr = to_class_attr(attr);
- struct subsys_private *cp = to_subsys_private(kobj);
- const void *ns = NULL;
-
- if (class_attr->namespace)
- ns = class_attr->namespace(cp->class, class_attr);
- return ns;
-}
-
static void class_release(struct kobject *kobj)
{
struct subsys_private *cp = to_subsys_private(kobj);
@@ -86,7 +74,6 @@ static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject
static const struct sysfs_ops class_sysfs_ops = {
.show = class_attr_show,
.store = class_attr_store,
- .namespace = class_attr_namespace,
};
static struct kobj_type class_ktype = {
@@ -99,21 +86,23 @@ static struct kobj_type class_ktype = {
static struct kset *class_kset;
-int class_create_file(struct class *cls, const struct class_attribute *attr)
+int class_create_file_ns(struct class *cls, const struct class_attribute *attr,
+ const void *ns)
{
int error;
if (cls)
- error = sysfs_create_file(&cls->p->subsys.kobj,
- &attr->attr);
+ error = sysfs_create_file_ns(&cls->p->subsys.kobj,
+ &attr->attr, ns);
else
error = -EINVAL;
return error;
}
-void class_remove_file(struct class *cls, const struct class_attribute *attr)
+void class_remove_file_ns(struct class *cls, const struct class_attribute *attr,
+ const void *ns)
{
if (cls)
- sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr);
+ sysfs_remove_file_ns(&cls->p->subsys.kobj, &attr->attr, ns);
}
static struct class *class_get(struct class *cls)
@@ -600,8 +589,8 @@ int __init classes_init(void)
return 0;
}
-EXPORT_SYMBOL_GPL(class_create_file);
-EXPORT_SYMBOL_GPL(class_remove_file);
+EXPORT_SYMBOL_GPL(class_create_file_ns);
+EXPORT_SYMBOL_GPL(class_remove_file_ns);
EXPORT_SYMBOL_GPL(class_unregister);
EXPORT_SYMBOL_GPL(class_destroy);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index eeab40b..72ad0a9 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -149,14 +149,6 @@ err_no_cmd:
return -EPERM;
}
-static const void *bonding_namespace(struct class *cls,
- const struct class_attribute *attr)
-{
- const struct bond_net *bn =
- container_of(attr, struct bond_net, class_attr_bonding_masters);
- return bn->net;
-}
-
/* class attribute for bond_masters file. This ends up in /sys/class/net */
static const struct class_attribute class_attr_bonding_masters = {
.attr = {
@@ -165,7 +157,6 @@ static const struct class_attribute class_attr_bonding_masters = {
},
.show = bonding_show_bonds,
.store = bonding_store_bonds,
- .namespace = bonding_namespace,
};
int bond_create_slave_symlinks(struct net_device *master,
@@ -1748,7 +1739,8 @@ int bond_create_sysfs(struct bond_net *bn)
bn->class_attr_bonding_masters = class_attr_bonding_masters;
sysfs_attr_init(&bn->class_attr_bonding_masters.attr);
- ret = netdev_class_create_file(&bn->class_attr_bonding_masters);
+ ret = netdev_class_create_file_ns(&bn->class_attr_bonding_masters,
+ bn->net);
/*
* Permit multiple loads of the module by ignoring failures to
* create the bonding_masters sysfs file. Bonding devices
@@ -1778,7 +1770,7 @@ int bond_create_sysfs(struct bond_net *bn)
*/
void bond_destroy_sysfs(struct bond_net *bn)
{
- netdev_class_remove_file(&bn->class_attr_bonding_masters);
+ netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
}
/*
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 15ef5eb..e784340 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -485,58 +485,15 @@ const struct file_operations sysfs_file_operations = {
.poll = sysfs_poll,
};
-static int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr,
- const void **pns)
-{
- struct sysfs_dirent *dir_sd = kobj->sd;
- const struct sysfs_ops *ops;
- const void *ns = NULL;
- int err;
-
- if (!dir_sd) {
- WARN(1, KERN_ERR "sysfs: kobject %s without dirent\n",
- kobject_name(kobj));
- return -ENOENT;
- }
-
- err = 0;
- if (!sysfs_ns_type(dir_sd))
- goto out;
-
- err = -EINVAL;
- if (!kobj->ktype)
- goto out;
- ops = kobj->ktype->sysfs_ops;
- if (!ops)
- goto out;
- if (!ops->namespace)
- goto out;
-
- err = 0;
- ns = ops->namespace(kobj, attr);
-out:
- if (err) {
- WARN(1, KERN_ERR
- "missing sysfs namespace attribute operation for kobject: %s\n",
- kobject_name(kobj));
- }
- *pns = ns;
- return err;
-}
-
-int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
- const struct attribute *attr, int type, umode_t amode)
+int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
+ const struct attribute *attr, int type,
+ umode_t amode, const void *ns)
{
umode_t mode = (amode & S_IALLUGO) | S_IFREG;
struct sysfs_addrm_cxt acxt;
struct sysfs_dirent *sd;
- const void *ns;
int rc;
- rc = sysfs_attr_ns(dir_sd->s_dir.kobj, attr, &ns);
- if (rc)
- return rc;
-
sd = sysfs_new_dirent(attr->name, mode, type);
if (!sd)
return -ENOMEM;
@@ -559,23 +516,25 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
int type)
{
- return sysfs_add_file_mode(dir_sd, attr, type, attr->mode);
+ return sysfs_add_file_mode_ns(dir_sd, attr, type, attr->mode, NULL);
}
-
/**
- * sysfs_create_file - create an attribute file for an object.
- * @kobj: object we're creating for.
- * @attr: attribute descriptor.
+ * sysfs_create_file_ns - create an attribute file for an object with custom ns
+ * @kobj: object we're creating for
+ * @attr: attribute descriptor
+ * @ns: namespace the new file should belong to
*/
-int sysfs_create_file(struct kobject *kobj, const struct attribute *attr)
+int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
+ const void *ns)
{
BUG_ON(!kobj || !kobj->sd || !attr);
- return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR);
+ return sysfs_add_file_mode_ns(kobj->sd, attr, SYSFS_KOBJ_ATTR,
+ attr->mode, ns);
}
-EXPORT_SYMBOL_GPL(sysfs_create_file);
+EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
{
@@ -630,17 +589,12 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
{
struct sysfs_dirent *sd;
struct iattr newattrs;
- const void *ns;
int rc;
- rc = sysfs_attr_ns(kobj, attr, &ns);
- if (rc)
- return rc;
-
mutex_lock(&sysfs_mutex);
rc = -ENOENT;
- sd = sysfs_find_dirent(kobj->sd, ns, attr->name);
+ sd = sysfs_find_dirent(kobj->sd, NULL, attr->name);
if (!sd)
goto out;
@@ -655,22 +609,21 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
EXPORT_SYMBOL_GPL(sysfs_chmod_file);
/**
- * sysfs_remove_file - remove an object attribute.
- * @kobj: object we're acting for.
- * @attr: attribute descriptor.
+ * sysfs_remove_file_ns - remove an object attribute with a custom ns tag
+ * @kobj: object we're acting for
+ * @attr: attribute descriptor
+ * @ns: namespace tag of the file to remove
*
- * Hash the attribute name and kill the victim.
+ * Hash the attribute name and namespace tag and kill the victim.
*/
-void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr)
+void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
+ const void *ns)
{
- const void *ns;
-
- if (sysfs_attr_ns(kobj, attr, &ns))
- return;
+ struct sysfs_dirent *dir_sd = kobj->sd;
- sysfs_hash_and_remove(kobj->sd, ns, attr->name);
+ sysfs_hash_and_remove(dir_sd, ns, attr->name);
}
-EXPORT_SYMBOL_GPL(sysfs_remove_file);
+EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr)
{
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 5f92cd2..25c78f2 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -56,9 +56,10 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
if (!mode)
continue;
}
- error = sysfs_add_file_mode(dir_sd, *attr,
- SYSFS_KOBJ_ATTR,
- (*attr)->mode | mode);
+ error = sysfs_add_file_mode_ns(dir_sd, *attr,
+ SYSFS_KOBJ_ATTR,
+ (*attr)->mode | mode,
+ NULL);
if (unlikely(error))
break;
}
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index b6deca3..a96da25 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -230,8 +230,9 @@ extern const struct file_operations sysfs_file_operations;
int sysfs_add_file(struct sysfs_dirent *dir_sd,
const struct attribute *attr, int type);
-int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
- const struct attribute *attr, int type, umode_t amode);
+int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
+ const struct attribute *attr, int type,
+ umode_t amode, const void *ns);
/*
* bin.c
*/
diff --git a/include/linux/device.h b/include/linux/device.h
index 2a9d6ed..ce690ea 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -427,8 +427,6 @@ struct class_attribute {
char *buf);
ssize_t (*store)(struct class *class, struct class_attribute *attr,
const char *buf, size_t count);
- const void *(*namespace)(struct class *class,
- const struct class_attribute *attr);
};
#define CLASS_ATTR(_name, _mode, _show, _store) \
@@ -438,10 +436,24 @@ struct class_attribute {
#define CLASS_ATTR_RO(_name) \
struct class_attribute class_attr_##_name = __ATTR_RO(_name)
-extern int __must_check class_create_file(struct class *class,
- const struct class_attribute *attr);
-extern void class_remove_file(struct class *class,
- const struct class_attribute *attr);
+extern int __must_check class_create_file_ns(struct class *class,
+ const struct class_attribute *attr,
+ const void *ns);
+extern void class_remove_file_ns(struct class *class,
+ const struct class_attribute *attr,
+ const void *ns);
+
+static inline int __must_check class_create_file(struct class *class,
+ const struct class_attribute *attr)
+{
+ return class_create_file_ns(class, attr, NULL);
+}
+
+static inline void class_remove_file(struct class *class,
+ const struct class_attribute *attr)
+{
+ return class_remove_file_ns(class, attr, NULL);
+}
/* Simple class attribute that is just a static string */
struct class_attribute_string {
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 041b42a..d551624 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2873,8 +2873,20 @@ extern int __init dev_proc_init(void);
#define dev_proc_init() 0
#endif
-extern int netdev_class_create_file(struct class_attribute *class_attr);
-extern void netdev_class_remove_file(struct class_attribute *class_attr);
+extern int netdev_class_create_file_ns(struct class_attribute *class_attr,
+ const void *ns);
+extern void netdev_class_remove_file_ns(struct class_attribute *class_attr,
+ const void *ns);
+
+static inline int netdev_class_create_file(struct class_attribute *class_attr)
+{
+ return netdev_class_create_file_ns(class_attr, NULL);
+}
+
+static inline void netdev_class_remove_file(struct class_attribute *class_attr)
+{
+ netdev_class_remove_file_ns(class_attr, NULL);
+}
extern struct kobj_ns_type_operations net_ns_type_operations;
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 11baec7..82f7fac 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -173,7 +173,6 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size)
struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *, char *);
ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
- const void *(*namespace)(struct kobject *, const struct attribute *);
};
struct sysfs_dirent;
@@ -189,13 +188,15 @@ int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name);
int __must_check sysfs_move_dir(struct kobject *kobj,
struct kobject *new_parent_kobj);
-int __must_check sysfs_create_file(struct kobject *kobj,
- const struct attribute *attr);
+int __must_check sysfs_create_file_ns(struct kobject *kobj,
+ const struct attribute *attr,
+ const void *ns);
int __must_check sysfs_create_files(struct kobject *kobj,
const struct attribute **attr);
int __must_check sysfs_chmod_file(struct kobject *kobj,
const struct attribute *attr, umode_t mode);
-void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);
+void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
+ const void *ns);
void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr);
int __must_check sysfs_create_bin_file(struct kobject *kobj,
@@ -277,8 +278,9 @@ static inline int sysfs_move_dir(struct kobject *kobj,
return 0;
}
-static inline int sysfs_create_file(struct kobject *kobj,
- const struct attribute *attr)
+static inline int sysfs_create_file_ns(struct kobject *kobj,
+ const struct attribute *attr,
+ const void *ns)
{
return 0;
}
@@ -295,8 +297,9 @@ static inline int sysfs_chmod_file(struct kobject *kobj,
return 0;
}
-static inline void sysfs_remove_file(struct kobject *kobj,
- const struct attribute *attr)
+static inline void sysfs_remove_file_ns(struct kobject *kobj,
+ const struct attribute *attr,
+ const void *ns)
{
}
@@ -435,4 +438,16 @@ static inline int __must_check sysfs_init(void)
#endif /* CONFIG_SYSFS */
+static inline int __must_check sysfs_create_file(struct kobject *kobj,
+ const struct attribute *attr)
+{
+ return sysfs_create_file_ns(kobj, attr, NULL);
+}
+
+static inline void sysfs_remove_file(struct kobject *kobj,
+ const struct attribute *attr)
+{
+ return sysfs_remove_file_ns(kobj, attr, NULL);
+}
+
#endif /* _SYSFS_H_ */
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index d954b56..325dee8 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1344,17 +1344,19 @@ int netdev_register_kobject(struct net_device *net)
return error;
}
-int netdev_class_create_file(struct class_attribute *class_attr)
+int netdev_class_create_file_ns(struct class_attribute *class_attr,
+ const void *ns)
{
- return class_create_file(&net_class, class_attr);
+ return class_create_file_ns(&net_class, class_attr, ns);
}
-EXPORT_SYMBOL(netdev_class_create_file);
+EXPORT_SYMBOL(netdev_class_create_file_ns);
-void netdev_class_remove_file(struct class_attribute *class_attr)
+void netdev_class_remove_file_ns(struct class_attribute *class_attr,
+ const void *ns)
{
- class_remove_file(&net_class, class_attr);
+ class_remove_file_ns(&net_class, class_attr, ns);
}
-EXPORT_SYMBOL(netdev_class_remove_file);
+EXPORT_SYMBOL(netdev_class_remove_file_ns);
int netdev_kobject_init(void)
{
--
1.8.3.1
^ permalink raw reply related
* [PATCH 1/7] sysfs: drop semicolon from to_sysfs_dirent() definition
From: Tejun Heo @ 2013-09-12 2:29 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, kay, ebiederm, netdev, lizefan, Tejun Heo
In-Reply-To: <1378952949-7900-1-git-send-email-tj@kernel.org>
The expansion of to_sysfs_dirent() contains an unncessary trailing
semicolon making it impossible to use in the middle of statements.
Drop it.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
fs/sysfs/dir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 4d83ced..834c64c 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -28,7 +28,7 @@
DEFINE_MUTEX(sysfs_mutex);
DEFINE_SPINLOCK(sysfs_assoc_lock);
-#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb);
+#define to_sysfs_dirent(X) rb_entry((X), struct sysfs_dirent, s_rb)
static DEFINE_SPINLOCK(sysfs_ino_lock);
static DEFINE_IDA(sysfs_ino_ida);
--
1.8.3.1
^ permalink raw reply related
* [PATCHSET] sysfs: disentangle kobject namespace handling from sysfs
From: Tejun Heo @ 2013-09-12 2:29 UTC (permalink / raw)
To: gregkh; +Cc: linux-kernel, kay, ebiederm, netdev, lizefan
Hello,
I'll send out multiple patchsets to separate out sysfs from driver
core and kobject. The eventual goal is making sysfs modular enough so
that cgroup can replace its nightmarish cgroupfs implementation which
repeated and worsened all the past mistakes of sysfs. This patchset
is first of the effort and separates out kobject namespace handling
from sysfs.
I never really understood why namespace support was added the way it
was added. Namespace information is communicated to sysfs via
callbacks and back-queries to upper layer, which is a very unusual and
weird thing to do when all the involved operations are synchronous.
For example, a tagged attribute creation looks like the following.
driver code driver callback
v ^
netdev_class_create_file() |
v class_attr->namespace()
class_create_file() class_attr_namespace()
v |
sysfs_create_file() |
v |
sysfs_attr_ns() -------------> sysfs_ops->namespace()
This is an absurd thing to do. It significantly obfuscates what's
going on and adds unnecessary uncertainties - for example, can
namespace() return value disagree with the recorded s_ns value without
being renamed? If so, how should that be handled? If not, what
guarantees that? Even the basic placements of callbacks don't make
much, if any, sense. Why is per-directory namespace() callback in
kobj_type while per-attr namespace() callback is in sysfs_ops? What
does this even mean?
Maybe there's some grand design scheme governing all this but it isn't
obvious at all and the whole thing looks like a hodgepodge of
short-sighted hacks.
There is absolutely *nothing* which requires this convolution. NS tag
can simply be passed down the stack just like any other type of
information and adding an extra argument or variant of interface to
pass down the extra information is way more straight-forward and
apparently even takes less amount of code, so let's please stop the
insanity.
This patchset contains the following seven patches.
0001-sysfs-drop-semicolon-from-to_sysfs_dirent-definition.patch
0002-sysfs-make-attr-namespace-interface-less-convoluted.patch
0003-sysfs-remove-ktype-namespace-invocations-in-director.patch
0004-sysfs-remove-ktype-namespace-invocations-in-symlink-.patch
0005-sysfs-drop-kobj_ns_type-handling.patch
0006-sysfs-clean-up-sysfs_get_dirent.patch
0007-sysfs-name-comes-before-ns.patch
0001 is a minor prep patch.
0002 removes the attr namespace callback.
0003-0004 push the dir namespace callback invocations from sysfs to
kobjct layer. Eventually, this callback should go too.
0005 simplifies sysfs ns support such that sysfs doesn't have any
specific knowledge of kobj namespaces. It now purely deals with
pointer tags. Combined with the previous changes, this makes sysfs ns
support mostly modular.
0006-0007 are cleanup patches to make param orders conventional and
consistent - optional param after mandatory one; otherwise, things get
extremely confusing with different variants of interfaces which take
or don't take optional params. No idea how/why this was done the
wrong way.
This patchset is based on top of the current master
c2d95729e3094ecdd8c54e856bbe971adbbd7f48 ("Merge branch 'akpm'
(patches from Andrew Morton)") and available in the following git
branch.
git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc.git review-sysfs-separate-out-ns
The series was lightly tested with normal and basic namespace
operations. diffstat follows.
drivers/base/class.c | 29 ++----
drivers/base/core.c | 8 +
drivers/gpio/gpiolib.c | 2
drivers/md/bitmap.c | 4
drivers/md/md.c | 2
drivers/md/md.h | 2
drivers/net/bonding/bond_sysfs.c | 14 ---
fs/sysfs/bin.c | 2
fs/sysfs/dir.c | 163 ++++++++++++++-------------------------
fs/sysfs/file.c | 105 ++++++-------------------
fs/sysfs/group.c | 29 +++---
fs/sysfs/inode.c | 6 -
fs/sysfs/mount.c | 24 +----
fs/sysfs/symlink.c | 49 +++--------
fs/sysfs/sysfs.h | 43 +++-------
include/linux/device.h | 24 ++++-
include/linux/kobject.h | 1
include/linux/netdevice.h | 16 +++
include/linux/sysfs.h | 88 ++++++++++++++-------
lib/kobject.c | 31 ++++++-
net/core/net-sysfs.c | 14 +--
21 files changed, 294 insertions(+), 362 deletions(-)
Thanks.
--
tejun
^ permalink raw reply
* Re: usbnet transmit path problems
From: Ming Lei @ 2013-09-12 1:56 UTC (permalink / raw)
To: David Laight; +Cc: Oliver Neukum, Network Development, linux-usb
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B7329@saturn3.aculab.com>
On Thu, Sep 12, 2013 at 12:05 AM, David Laight <David.Laight@aculab.com> wrote:
>> On Wed, Sep 11, 2013 at 8:56 PM, David Laight <David.Laight@aculab.com> wrote:
>> >> > > 2) If 'length % dev->maxpacket == 0' for a multi-fragment packet then
>> >> > > the extra byte isn't added correctly (the code probably falls off
>> >> > > the end of the scatter-gather list).
>> >> >
>> >> > Indeed. Ming Lei, should usbnet handle this in the sg case or better
>> >> > leave it to the subdriver you introduced this for?
>> >
>> > Is the ZLP issue a problem with the host or with the target?
>>
>> Sorry, what do you mean the ZLP issue here? I understand Oliver
>> thinks one commit from me may break ZLP handling, are you discussing
>> this problem? If not, could you explain it in a bit detail?
>
> I was thinking of the general ZLP problem.
IMO the current approach should be general enough.
>
>> > If it is a host problem then the necessity comes from the host,
>> > but the fix needs to be target dependant.
>> > If it is a common target problem then generic code can apply
>> > a common fix.
>>
>> All usbnet device should have sent one ZLP in case the size of
>> bulk out transfer can be divided by max packet size, but the one
>> byte transfer might be introduced for avoiding some target problem
>> (can't deal with zlp well), as said by David, see below discussion:
>>
>> http://marc.info/?l=linux-usb&m=127067487604112&w=2
>
> AFAICT the code avoids sending a zero length packet (that would
> terminate a USB bulk transfer packet) by increasing the length
> of the bulk packet by (at least) one byte.
No, the code on the link supports URB_ZERO_PACKET which
should be the decent approach for the problem.
>
>> > AFICT there are at least 3 fixes:
>> > 1) Extend the ethernet frame by one byte and hope the receiving
>> > system doesn't object to the padding.
This is what usbnet is doing at default if both FLAG_SEND_ZLP and
FLAG_MULTI_PACKET aren't set.
>> > This is probably the only option if tx_fixup() doesn't
>> > add a header.
>> > 2) Put the ethernet frame length in the header and have the
>> > target discard the added pad byte (ax88179_178a.c).
That is probably because the target need the padding flag, so that
it can skip the one byte padding frame.
>> > 3) Add a second zero-length frame in the same USB data block
>> > (ax88172a.c).
Actually it is a 4byte frame added by the subdriver, instead of adding
one zlp. Since the subdriver adds the termination packet by itself, usbnet
won't handle the case at all.
There is no much difference among the 3 appoaches, all of which take
the padding trick, and the difference is that if padding flag is required, and
if the padding length is one byte or others, and both are device-dependent.
So current approach is still general enough to cover all cases, isn't it?
>>
>> Why do we need the above 3 fixes? The patch in my last email can
>> fix the problem which is introduced recently, can't it?
>
> I meant there are 3 ways of avoiding the ZLP, each driver will
> pick one of them.
All the 3 ways are basically same or very similar, and the difference is
that drivers may need the padding flag or take different length termination
packet.
>
> I've just looked at all the drivers in net/usb.
> It doesn't look like they all handle fragmented skb, shared skb,
> or ZLP properly.
>
> A lot of common code could be removed if usbnet knew the size of the
> header and allocated it before calling tx_fixup().
Patches are always welcome, :-)
> None of this is helping me sort out why netperf udp rr tests with
> burst 19 are losing all the packets at once :-(
If you can share your test case, guys in list may help you to troubleshoot
it, :-)
Thanks,
--
Ming Lei
^ permalink raw reply
* Re: 3.10.0 network trace
From: Josh Boyer @ 2013-09-12 1:51 UTC (permalink / raw)
To: Yuchung Cheng; +Cc: Michael Sterrett, netdev, Neal Cardwell, Nandita Dukkipati
In-Reply-To: <CAK6E8=eRZQnPeVPpzcdzUtLqr0n2kjUQ2_JRE8_WXn3sSV2y9A@mail.gmail.com>
On Wed, Sep 11, 2013 at 12:32 PM, Yuchung Cheng <ycheng@google.com> wrote:
> On Wed, Sep 11, 2013 at 5:49 AM, Josh Boyer <jwboyer@fedoraproject.org> wrote:
>> On Sun, Jul 21, 2013 at 9:36 PM, Michael Sterrett <michael@sterretts.net> wrote:
>>> Since upgraded to 3.10.1 which exhibits the same issue (probably not
>>> surprising).
>>>
>>> sysctl net.ipv4.tcp_frto=0 net.ipv4.tcp_early_retrans=3 seems to take
>>> care of it.
>>
>> We're still getting reports of this with 3.10.10 in Fedora [1]. At
>> least one of the reporters has said those sysctl settings didn't help.
>>
>> Is there anything else that can be gathered to help track this down?
> since frto=0 didn't help, I suspect it's either a bug introduced in
> the tail loss probe patch 9b717a8d (tcp: TLP loss detection) or other
> changes related loss recovery.
>
> could you try disable TLP by
> sysctl net.ipv4.tcp_frto=0 net.ipv4.tcp_early_retrans=1
>
> if it still does not work. disable any form of early retransmit by
> sysctl net.ipv4.tcp_frto=0 net.ipv4.tcp_early_retrans=0
Thanks. I've asked the people in the bug to try those settings.
> if you can test a custom build kernel, please try this debugging patch.
I'll get the patch included in a test build for the tomorrow as well.
josh
^ permalink raw reply
* Re: [PATCH 14/52] net: cxgb4vf: remove unnecessary pci_set_drvdata()
From: Jingoo Han @ 2013-09-12 1:19 UTC (permalink / raw)
To: 'Casey Leedom'
Cc: 'David S. Miller', netdev, 'Jingoo Han'
In-Reply-To: <5230A740.4020503@chelsio.com>
On Thursday, September 12, 2013 2:24 AM, Casey Leedom wrote:
>
> I agree that the redundant pci_set_drvdata(pdev, NULL) in
> cxgb4vf_pci_probe() under the err_release_regions: label is unneeded,
> but don't we need to NULL out the PCI Driver Data under the
> err_free_adapter: label and also in cxgb4vf_pci_remove()? Or is that
> handled automatically in the PCI infrastructure code which calls the
> Device Probe and Remove routines? Mostly I was just being an
> obsessively clean housewife assuming that we'd want to clean up these
> references ...
No, 'pci_set_drvdata(pdev, NULL) under err_free_adapter label' is not
necessary.
As you know, pci_set_drvdata(pdev, NULL) calls dev_set_drvdata() as below:
pci_set_drvdata(pdev, NULL) is dev_set_drvdata(&pdev->dev, NULL).
./include/linux/pci.h
1504:static inline void pci_set_drvdata(struct pci_dev *pdev, void *data)
1505{
1506 dev_set_drvdata(&pdev->dev, data);
1507}
However, when the driver goes to err_free_adapter label,
The following sequence will be done.
kfree(adapter) -> .... -> return -ENOMEM;
In this case,
when probe() returns error value such as '-ENOMEM',
really_probe() of driver core automatically calls 'dev_set_drvdata(dev, NULL)'
as below:
./drivers/base/dd.c
303-probe_failed:
304 devres_release_all(dev);
305 driver_sysfs_remove(dev);
306 dev->driver = NULL;
307 dev_set_drvdata(dev, NULL);
Thus, without 'pci_set_drvdata(pdev, NULL) under err_free_adapter label',
dev_set_drvdata(dev, NULL) can be called.
I already tested this with other drivers such as e1000e LAN card driver.
Best regards,
Jingoo Han
^ permalink raw reply
* Re: [PATCH] ipv6: Do route updating for redirect in ndisc layer
From: Vlad Yasevich @ 2013-09-12 1:16 UTC (permalink / raw)
To: Duan Jiong, davem, netdev, dborkman, vyasevich
In-Reply-To: <20130911231721.GA24195@order.stressinduktion.org>
On 09/11/2013 07:17 PM, Hannes Frederic Sowa wrote:
> [added Cc to Daniel and Vlad because of ipv6/sctp/redirect problem]
>
> On Wed, Sep 11, 2013 at 03:04:35PM +0800, Duan Jiong wrote:
>> 于 2013年09月11日 06:50, Hannes Frederic Sowa 写道:
>>> On Mon, Sep 09, 2013 at 03:09:56PM +0800, Duan Jiong wrote:
>>>> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
>>>> index 5c71501..61fe8e5 100644
>>>> --- a/net/ipv6/tcp_ipv6.c
>>>> +++ b/net/ipv6/tcp_ipv6.c
>>>> @@ -382,14 +382,6 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
>>>>
>>>> np = inet6_sk(sk);
>>>>
>>>> - if (type == NDISC_REDIRECT) {
>>>> - struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
>>>> -
>>>> - if (dst)
>>>> - dst->ops->redirect(dst, sk, skb);
>>>> - goto out;
>>>> - }
>>>> -
>>>
>>> You dropped the "goto out" here in case of an NDISC_REDIRECT, so this sends an
>>> EPROTO further up the socket layer. Was this intended?
>>>
>>
>> I'm sorry, i didn't notice the variable err was assigned to EPROTO.
>> I only thought that message should be sent to the socket layer, because
>> i found that in function sctp_v6_err().
>>
>> In addition, the rfc 4443 said the Redirect Message is not the ICMPv6 Error
>> Message, so i think we shouldn't call those err_handler function, in other
>> words we shouldn't call the icmpv6_notify().
>>
>> How do you think of this?
>
> Hm, thats hard.
>
> First of, when the kernel started publishing these errors it had a
> contract with user-space we cannot break now. This includes all error
> handling functions which call ipv6_icmp_error. So we only have to care
> about INET6_PROTO_FINAL protocols, bbecause they mostly operate in socket
> space (in this case these are the raw and the udp protocol and currently
> sctp). Especially I do think it is important to report the redirects
> to raw sockets. The other non-final protocols only need to be notified
> for mtu reduction currently. Maybe we could stop notifying non-final
> protocols for redirects, but I don't think this will improve things.
>
> Also we cannot know if the router sending the redirect discarded the
> original packet or if it forwarded it just notifying us of a better route,
> so we don't know if an actual error happend. So I would do the same thing
> as IPv4 sockets, set sk_err to zero and queue up the icmp packet on the
> socket's error queue (for udp and raw).
>
> Regarding notifying tcp sockets about the redirect seems wrong. It would
> generate a poll notification and I do think it could even tear down
> the whole connection. I guess sctp should also stop updating sk_err
> on redirects. But let's Cc Daniel and Vlad about this. My guess is that
> sctp could go into some error recovery mode because of this which would
> be wrong.
You are right. SCTP shouldn't be setting sk_err on redirects as it
isn't an error condition. it should be doing exactly what tcp is doing
and leaving the error handler without touching the socket.
Thanks
-vlad
>
> So, for this patch I would leave the logic as is and not change anything
> at the error reporting. Maybe Daniel and Vlad could check if we should
> suppress redirect information for ipv6 in sctp, too? But this should
> go into another patch. Regarding the EPROTO problem in raw and udp,
> let's see if all the problems go away if we update icmpv6_err_convert
> to set *err to 0.
>
> Greetings,
>
> Hannes
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [RFC PATCH] vsnprintf: Remove use of %n and convert existing uses
From: Joe Perches @ 2013-09-12 0:41 UTC (permalink / raw)
To: Al Viro
Cc: Tetsuo Handa, linux-kernel, kosaki.motohiro, keescook, fweisbec,
dan.carpenter, devel, gregkh, tushar.behera, lidza.louina, davem,
kuznet, jmorris, yoshfuji, kaber, courmisch, vyasevich, nhorman,
netdev, linux-sctp
In-Reply-To: <20130912001911.GO13318@ZenIV.linux.org.uk>
On Thu, 2013-09-12 at 01:19 +0100, Al Viro wrote:
> On Wed, Sep 11, 2013 at 05:04:17PM -0700, Joe Perches wrote:
> > On Thu, 2013-09-12 at 08:40 +0900, Tetsuo Handa wrote:
> > > Joe Perches wrote:
> > > > - seq_printf(m, "%s%d%n", con->name, con->index, &len);
> > > > + len = seq_printf(m, "%s%d", con->name, con->index);
> > >
> > > Isn't len always 0 or -1 ?
> >
> > Right. Well you're no fun...
> >
> > These uses would seem broken anyway because the
> > seq_printf isn't itself tested for correctness.
> >
> > Hmm.
> >
> > Also, there's a large amount of code that appears
> > to do calculations with pos or len like:
> >
> > pos += seq_printf(handle, fmt. ...)
>
> ... and most of that code proceeds to ignore pos completely.
> Note that ->show() is *NOT* supposed to return the number of
> characters it has/would like to have produced. Just return
> 0 and be done with that; overflows are dealt with just fine.
> The large amount, BTW, is below 100 lines, AFAICS, in rather
> few files.
Unfortunately, when you count the uses of
return seq_printf(...)
it's rather higher and all the callers need
to be chased down too.
$ grep -rP --include=*.[ch] "^[ \t]*(\S[ \t\S]*=|return[\s\(]*)\s*\bseq_[v]?printf\b" * | wc -l
320
$ grep -rPl --include=*.[ch] "^[ \t]*(\S[ \t\S]*=|return[\s\(]*)\s*\bseq_[v]?printf\b" *|wc -l
81
> Just bury the cargo-culting crap. All those += seq_printf() should
> be simply calling it.
Most likely.
> The *only* reason to look at the return
> value is "if we'd already overflown the buffer, I'd rather skipped
> the costly generation of the rest of the record". In that case
> seq_printf() returning -1 means "skip it, nothing else will fit and
> caller will be repeating with bigger buffer anyway".
Perhaps changing the seq_vprintf return from 0 to len
and testing for -1 would work.
Still would need to change a few lines in netfilter
and probably a few other places.
^ permalink raw reply
* Re: [RFC PATCH] vsnprintf: Remove use of %n and convert existing uses
From: Al Viro @ 2013-09-12 0:19 UTC (permalink / raw)
To: Joe Perches
Cc: Tetsuo Handa, linux-kernel, kosaki.motohiro, keescook, fweisbec,
dan.carpenter, devel, gregkh, tushar.behera, lidza.louina, davem,
kuznet, jmorris, yoshfuji, kaber, courmisch, vyasevich, nhorman,
netdev, linux-sctp
In-Reply-To: <1378944257.4714.45.camel@joe-AO722>
On Wed, Sep 11, 2013 at 05:04:17PM -0700, Joe Perches wrote:
> On Thu, 2013-09-12 at 08:40 +0900, Tetsuo Handa wrote:
> > Joe Perches wrote:
> > > - seq_printf(m, "%s%d%n", con->name, con->index, &len);
> > > + len = seq_printf(m, "%s%d", con->name, con->index);
> >
> > Isn't len always 0 or -1 ?
>
> Right. Well you're no fun...
>
> These uses would seem broken anyway because the
> seq_printf isn't itself tested for correctness.
>
> Hmm.
>
> Also, there's a large amount of code that appears
> to do calculations with pos or len like:
>
> pos += seq_printf(handle, fmt. ...)
... and most of that code proceeds to ignore pos completely.
Note that ->show() is *NOT* supposed to return the number of
characters it has/would like to have produced. Just return
0 and be done with that; overflows are dealt with just fine.
The large amount, BTW, is below 100 lines, AFAICS, in rather
few files.
> There are very few that seem to use it correctly
> like netfilter.
> Suggestions?
Just bury the cargo-culting crap. All those += seq_printf() should
be simply calling it. The *only* reason to look at the return
value is "if we'd already overflown the buffer, I'd rather skipped
the costly generation of the rest of the record". In that case
seq_printf() returning -1 means "skip it, nothing else will fit and
caller will be repeating with bigger buffer anyway".
^ permalink raw reply
* Re: [PATCH 20/52] net: fealnx: remove unnecessary pci_set_drvdata()
From: Jingoo Han @ 2013-09-12 0:11 UTC (permalink / raw)
To: 'Sergei Shtylyov'
Cc: 'David S. Miller', netdev, 'Jingoo Han'
In-Reply-To: <5230B435.2050908@cogentembedded.com>
On Thursday, September 12, 2013 3:20 AM, Jingoo Han wrote:
> On 09/11/2013 11:40 AM, Jingoo Han wrote:
>
> > The driver core clears the driver data to NULL after device_release
> > or on probe failure. Thus, it is not needed to manually clear the
> > device driver data to NULL.
>
> > Signed-off-by: Jingoo Han <jg1.han@samsung.com>
> > ---
> > drivers/net/ethernet/fealnx.c | 4 ++--
> > 1 file changed, 2 insertions(+), 2 deletions(-)
>
> > diff --git a/drivers/net/ethernet/fealnx.c b/drivers/net/ethernet/fealnx.c
> > index c706b7a..99194d1 100644
> > --- a/drivers/net/ethernet/fealnx.c
> > +++ b/drivers/net/ethernet/fealnx.c
> > @@ -699,9 +699,9 @@ static void fealnx_remove_one(struct pci_dev *pdev)
> > pci_iounmap(pdev, np->mem);
> > free_netdev(dev);
> > pci_release_regions(pdev);
> > - pci_set_drvdata(pdev, NULL);
> > - } else
> > + } else {
> > printk(KERN_ERR "fealnx: remove for unknown device\n");
> > + }
>
> No "drove-by" coding style fixes, please.
Hi Sergei,
Sorry, but I just want to know the reason. :-)
Would you let know the reason not to add coding style fixes?
Thank you.
Best regards,
Jingoo Han
^ permalink raw reply
* Re: [RFC PATCH] vsnprintf: Remove use of %n and convert existing uses
From: Joe Perches @ 2013-09-12 0:04 UTC (permalink / raw)
To: Tetsuo Handa
Cc: linux-kernel, kosaki.motohiro, keescook, fweisbec, dan.carpenter,
devel, gregkh, tushar.behera, lidza.louina, davem, kuznet,
jmorris, yoshfuji, kaber, courmisch, vyasevich, nhorman, netdev,
linux-sctp
In-Reply-To: <201309120840.HHE37542.OJMFFHSOQOtVFL@I-love.SAKURA.ne.jp>
On Thu, 2013-09-12 at 08:40 +0900, Tetsuo Handa wrote:
> Joe Perches wrote:
> > - seq_printf(m, "%s%d%n", con->name, con->index, &len);
> > + len = seq_printf(m, "%s%d", con->name, con->index);
>
> Isn't len always 0 or -1 ?
Right. Well you're no fun...
These uses would seem broken anyway because the
seq_printf isn't itself tested for correctness.
Hmm.
Also, there's a large amount of code that appears
to do calculations with pos or len like:
pos += seq_printf(handle, fmt. ...)
There are very few that seem to use it correctly
like netfilter.
$ grep -rP --include=*.[ch] "^[ \t]*\S[ \t\S]*\bseq_[v]?printf\b" *
Suggestions?
> int seq_vprintf(struct seq_file *m, const char *f, va_list args)
> {
> int len;
>
> if (m->count < m->size) {
> len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
> if (m->count + len < m->size) {
> m->count += len;
> return 0;
> }
> }
> seq_set_overflow(m);
> return -1;
> }
> EXPORT_SYMBOL(seq_vprintf);
>
> int seq_printf(struct seq_file *m, const char *f, ...)
> {
> int ret;
> va_list args;
>
> va_start(args, f);
> ret = seq_vprintf(m, f, args);
> va_end(args);
>
> return ret;
> }
> EXPORT_SYMBOL(seq_printf);
^ permalink raw reply
* Re: [RFC PATCH] vsnprintf: Remove use of %n and convert existing uses
From: Joe Perches @ 2013-09-11 23:43 UTC (permalink / raw)
To: Kees Cook
Cc: LKML, KOSAKI Motohiro, Frederic Weisbecker, Dan Carpenter, devel,
Greg Kroah-Hartman, Tushar Behera, Lidza Louina, David S. Miller,
Alexey Kuznetsov, James Morris, Hideaki YOSHIFUJI,
Patrick McHardy, Remi Denis-Courmont, Vlad Yasevich, Neil Horman,
netdev, linux-sctp
In-Reply-To: <CAGXu5jLyCGuSRqEGCSw=VrrOvOr=aAok6ZZTAj_qmDA3CbmLww@mail.gmail.com>
On Wed, 2013-09-11 at 16:29 -0700, Kees Cook wrote:
> On Wed, Sep 11, 2013 at 4:22 PM, Joe Perches <joe@perches.com> wrote:
> > Using vsnprintf or its derivatives with %n can have security
> > vulnerability implications.
> >
> > Prior to commit fef20d9c1380
> > ("vsprintf: unify the format decoding layer for its 3 users"),
> > any use of %n was ignored.
> >
> > Reintroduce this feature and convert the existing uses of %n
> > to use the return length from vsnprintf or its derivatives.
> >
> > Signed-off-by: Joe Perches <joe@perches.com>
> > Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> (proc bits)
> > cc: Kees Cook <keescook@chromium.org>
> > cc: Frederic Weisbecker <fweisbec@gmail.com>
>
> Yes, please. It might also be worth updating
> Documentation/printk-formats.txt to mention that %n has intentionally
> removed and will be ignored.
Fine with me if you want to update that file.
It doesn't currently try to be a complete man page
for vsnprintf though.
vsprintf.c does have kernel-doc documentation and
that already does show that %n is ignored.
^ permalink raw reply
* Re: [RFC PATCH] vsnprintf: Remove use of %n and convert existing uses
From: Tetsuo Handa @ 2013-09-11 23:40 UTC (permalink / raw)
To: joe, linux-kernel
Cc: kosaki.motohiro, keescook, fweisbec, dan.carpenter, devel, gregkh,
tushar.behera, lidza.louina, davem, kuznet, jmorris, yoshfuji,
kaber, courmisch, vyasevich, nhorman, netdev, linux-sctp
In-Reply-To: <1378941761.4714.37.camel@joe-AO722>
Joe Perches wrote:
> - seq_printf(m, "%s%d%n", con->name, con->index, &len);
> + len = seq_printf(m, "%s%d", con->name, con->index);
Isn't len always 0 or -1 ?
int seq_vprintf(struct seq_file *m, const char *f, va_list args)
{
int len;
if (m->count < m->size) {
len = vsnprintf(m->buf + m->count, m->size - m->count, f, args);
if (m->count + len < m->size) {
m->count += len;
return 0;
}
}
seq_set_overflow(m);
return -1;
}
EXPORT_SYMBOL(seq_vprintf);
int seq_printf(struct seq_file *m, const char *f, ...)
{
int ret;
va_list args;
va_start(args, f);
ret = seq_vprintf(m, f, args);
va_end(args);
return ret;
}
EXPORT_SYMBOL(seq_printf);
^ permalink raw reply
* Re: [RFC PATCH] vsnprintf: Remove use of %n and convert existing uses
From: Kees Cook @ 2013-09-11 23:29 UTC (permalink / raw)
To: Joe Perches
Cc: devel, Lidza Louina, Neil Horman, Patrick McHardy,
Hideaki YOSHIFUJI, Frederic Weisbecker, Vlad Yasevich, LKML,
James Morris, Remi Denis-Courmont, linux-sctp, netdev,
KOSAKI Motohiro, Greg Kroah-Hartman, Alexey Kuznetsov,
David S. Miller, Dan Carpenter, Tushar Behera
In-Reply-To: <1378941761.4714.37.camel@joe-AO722>
On Wed, Sep 11, 2013 at 4:22 PM, Joe Perches <joe@perches.com> wrote:
> Using vsnprintf or its derivatives with %n can have security
> vulnerability implications.
>
> Prior to commit fef20d9c1380
> ("vsprintf: unify the format decoding layer for its 3 users"),
> any use of %n was ignored.
>
> Reintroduce this feature and convert the existing uses of %n
> to use the return length from vsnprintf or its derivatives.
>
> Signed-off-by: Joe Perches <joe@perches.com>
> Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> (proc bits)
> cc: Kees Cook <keescook@chromium.org>
> cc: Frederic Weisbecker <fweisbec@gmail.com>
Yes, please. It might also be worth updating
Documentation/printk-formats.txt to mention that %n has intentionally
removed and will be ignored.
Reviewed-by: Kees Cook <keescook@chromium.org>
-Kees
>
> ---
>
> Not particularly well tested...
>
> fs/proc/consoles.c | 2 +-
> fs/proc/nommu.c | 20 ++++++-------
> fs/proc/task_mmu.c | 18 +++++------
> fs/proc/task_nommu.c | 20 ++++++-------
> lib/vsprintf.c | 21 ++++++-------
> net/ipv4/fib_trie.c | 30 ++++++++-----------
> net/ipv4/ping.c | 19 ++++++------
> net/ipv4/tcp_ipv4.c | 84 +++++++++++++++++++++++++---------------------------
> net/ipv4/udp.c | 19 ++++++------
> net/phonet/socket.c | 32 ++++++++++----------
> net/sctp/objcnt.c | 5 ++--
> 11 files changed, 132 insertions(+), 138 deletions(-)
>
> diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
> index b701eaa..42f2bb7 100644
> --- a/fs/proc/consoles.c
> +++ b/fs/proc/consoles.c
> @@ -47,7 +47,7 @@ static int show_console_dev(struct seq_file *m, void *v)
> con_flags[a].name : ' ';
> flags[a] = 0;
>
> - seq_printf(m, "%s%d%n", con->name, con->index, &len);
> + len = seq_printf(m, "%s%d", con->name, con->index);
> len = 21 - len;
> if (len < 1)
> len = 1;
> diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
> index ccfd99b..91cfd19 100644
> --- a/fs/proc/nommu.c
> +++ b/fs/proc/nommu.c
> @@ -50,16 +50,16 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
> ino = inode->i_ino;
> }
>
> - seq_printf(m,
> - "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
> - region->vm_start,
> - region->vm_end,
> - flags & VM_READ ? 'r' : '-',
> - flags & VM_WRITE ? 'w' : '-',
> - flags & VM_EXEC ? 'x' : '-',
> - flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
> - ((loff_t)region->vm_pgoff) << PAGE_SHIFT,
> - MAJOR(dev), MINOR(dev), ino, &len);
> + len = seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
> + region->vm_start,
> + region->vm_end,
> + flags & VM_READ ? 'r' : '-',
> + flags & VM_WRITE ? 'w' : '-',
> + flags & VM_EXEC ? 'x' : '-',
> + flags & VM_MAYSHARE ?
> + flags & VM_SHARED ? 'S' : 's' : 'p',
> + ((loff_t)region->vm_pgoff) << PAGE_SHIFT,
> + MAJOR(dev), MINOR(dev), ino);
>
> if (file) {
> len = 25 + sizeof(void *) * 6 - len;
> diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
> index 107d026..f84ee9f 100644
> --- a/fs/proc/task_mmu.c
> +++ b/fs/proc/task_mmu.c
> @@ -286,15 +286,15 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
> if (stack_guard_page_end(vma, end))
> end -= PAGE_SIZE;
>
> - seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
> - start,
> - end,
> - flags & VM_READ ? 'r' : '-',
> - flags & VM_WRITE ? 'w' : '-',
> - flags & VM_EXEC ? 'x' : '-',
> - flags & VM_MAYSHARE ? 's' : 'p',
> - pgoff,
> - MAJOR(dev), MINOR(dev), ino, &len);
> + len = seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
> + start,
> + end,
> + flags & VM_READ ? 'r' : '-',
> + flags & VM_WRITE ? 'w' : '-',
> + flags & VM_EXEC ? 'x' : '-',
> + flags & VM_MAYSHARE ? 's' : 'p',
> + pgoff,
> + MAJOR(dev), MINOR(dev), ino);
>
> /*
> * Print the dentry name for named mappings, and a
> diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
> index 56123a6..1d7bbe5 100644
> --- a/fs/proc/task_nommu.c
> +++ b/fs/proc/task_nommu.c
> @@ -155,16 +155,16 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
> pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
> }
>
> - seq_printf(m,
> - "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
> - vma->vm_start,
> - vma->vm_end,
> - flags & VM_READ ? 'r' : '-',
> - flags & VM_WRITE ? 'w' : '-',
> - flags & VM_EXEC ? 'x' : '-',
> - flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
> - pgoff,
> - MAJOR(dev), MINOR(dev), ino, &len);
> + len = seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
> + vma->vm_start,
> + vma->vm_end,
> + flags & VM_READ ? 'r' : '-',
> + flags & VM_WRITE ? 'w' : '-',
> + flags & VM_EXEC ? 'x' : '-',
> + flags & VM_MAYSHARE ?
> + flags & VM_SHARED ? 'S' : 's' : 'p',
> + pgoff,
> + MAJOR(dev), MINOR(dev), ino);
>
> if (file) {
> pad_len_spaces(m, len);
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index 26559bd..43c2ea0 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -1683,18 +1683,19 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
> break;
>
> case FORMAT_TYPE_NRCHARS: {
> + /* skip %n 's argument */
> u8 qualifier = spec.qualifier;
> + void *skip_arg;
>
> - if (qualifier == 'l') {
> - long *ip = va_arg(args, long *);
> - *ip = (str - buf);
> - } else if (_tolower(qualifier) == 'z') {
> - size_t *ip = va_arg(args, size_t *);
> - *ip = (str - buf);
> - } else {
> - int *ip = va_arg(args, int *);
> - *ip = (str - buf);
> - }
> + WARN_ONCE(1, "Please remove ignored use of %%n in '%s'\n",
> + old_fmt);
> +
> + if (qualifier == 'l')
> + skip_arg = va_arg(args, long *);
> + else if (_tolower(qualifier) == 'z')
> + skip_arg = va_arg(args, size_t *);
> + else
> + skip_arg = va_arg(args, int *);
> break;
> }
>
> diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
> index 3df6d3e..ddf1e9c 100644
> --- a/net/ipv4/fib_trie.c
> +++ b/net/ipv4/fib_trie.c
> @@ -2537,24 +2537,20 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
> continue;
>
> if (fi)
> - seq_printf(seq,
> - "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
> - "%d\t%08X\t%d\t%u\t%u%n",
> - fi->fib_dev ? fi->fib_dev->name : "*",
> - prefix,
> - fi->fib_nh->nh_gw, flags, 0, 0,
> - fi->fib_priority,
> - mask,
> - (fi->fib_advmss ?
> - fi->fib_advmss + 40 : 0),
> - fi->fib_window,
> - fi->fib_rtt >> 3, &len);
> + len = seq_printf(seq, "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
> + (fi->fib_dev ?
> + fi->fib_dev->name : "*"),
> + prefix,
> + fi->fib_nh->nh_gw, flags,
> + 0, 0, fi->fib_priority, mask,
> + (fi->fib_advmss ?
> + fi->fib_advmss + 40 : 0),
> + fi->fib_window,
> + fi->fib_rtt >> 3);
> else
> - seq_printf(seq,
> - "*\t%08X\t%08X\t%04X\t%d\t%u\t"
> - "%d\t%08X\t%d\t%u\t%u%n",
> - prefix, 0, flags, 0, 0, 0,
> - mask, 0, 0, 0, &len);
> + len = seq_printf(seq, "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
> + prefix, 0, flags, 0, 0, 0,
> + mask, 0, 0, 0);
>
> seq_printf(seq, "%*s\n", 127 - len, "");
> }
> diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
> index d7d9882..ac8d79f 100644
> --- a/net/ipv4/ping.c
> +++ b/net/ipv4/ping.c
> @@ -1081,16 +1081,15 @@ static void ping_v4_format_sock(struct sock *sp, struct seq_file *f,
> __u16 destp = ntohs(inet->inet_dport);
> __u16 srcp = ntohs(inet->inet_sport);
>
> - seq_printf(f, "%5d: %08X:%04X %08X:%04X"
> - " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d%n",
> - bucket, src, srcp, dest, destp, sp->sk_state,
> - sk_wmem_alloc_get(sp),
> - sk_rmem_alloc_get(sp),
> - 0, 0L, 0,
> - from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
> - 0, sock_i_ino(sp),
> - atomic_read(&sp->sk_refcnt), sp,
> - atomic_read(&sp->sk_drops), len);
> + *len = seq_printf(f, "%5d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d",
> + bucket, src, srcp, dest, destp, sp->sk_state,
> + sk_wmem_alloc_get(sp),
> + sk_rmem_alloc_get(sp),
> + 0, 0L, 0,
> + from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
> + 0, sock_i_ino(sp),
> + atomic_read(&sp->sk_refcnt), sp,
> + atomic_read(&sp->sk_drops));
> }
>
> static int ping_v4_seq_show(struct seq_file *seq, void *v)
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index b14266b..1279c16 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -2603,24 +2603,24 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req,
> const struct inet_request_sock *ireq = inet_rsk(req);
> long delta = req->expires - jiffies;
>
> - seq_printf(f, "%4d: %08X:%04X %08X:%04X"
> - " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK%n",
> - i,
> - ireq->loc_addr,
> - ntohs(inet_sk(sk)->inet_sport),
> - ireq->rmt_addr,
> - ntohs(ireq->rmt_port),
> - TCP_SYN_RECV,
> - 0, 0, /* could print option size, but that is af dependent. */
> - 1, /* timers active (only the expire timer) */
> - jiffies_delta_to_clock_t(delta),
> - req->num_timeout,
> - from_kuid_munged(seq_user_ns(f), uid),
> - 0, /* non standard timer */
> - 0, /* open_requests have no inode */
> - atomic_read(&sk->sk_refcnt),
> - req,
> - len);
> + *len = seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
> + i,
> + ireq->loc_addr,
> + ntohs(inet_sk(sk)->inet_sport),
> + ireq->rmt_addr,
> + ntohs(ireq->rmt_port),
> + TCP_SYN_RECV,
> + 0, 0, /* could print option size,
> + * but that is af dependent.
> + */
> + 1, /* timers active (only the expire timer) */
> + jiffies_delta_to_clock_t(delta),
> + req->num_timeout,
> + from_kuid_munged(seq_user_ns(f), uid),
> + 0, /* non standard timer */
> + 0, /* open_requests have no inode */
> + atomic_read(&sk->sk_refcnt),
> + req);
> }
>
> static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
> @@ -2661,26 +2661,25 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
> */
> rx_queue = max_t(int, tp->rcv_nxt - tp->copied_seq, 0);
>
> - seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
> - "%08X %5u %8d %lu %d %pK %lu %lu %u %u %d%n",
> - i, src, srcp, dest, destp, sk->sk_state,
> - tp->write_seq - tp->snd_una,
> - rx_queue,
> - timer_active,
> - jiffies_delta_to_clock_t(timer_expires - jiffies),
> - icsk->icsk_retransmits,
> - from_kuid_munged(seq_user_ns(f), sock_i_uid(sk)),
> - icsk->icsk_probes_out,
> - sock_i_ino(sk),
> - atomic_read(&sk->sk_refcnt), sk,
> - jiffies_to_clock_t(icsk->icsk_rto),
> - jiffies_to_clock_t(icsk->icsk_ack.ato),
> - (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
> - tp->snd_cwnd,
> - sk->sk_state == TCP_LISTEN ?
> - (fastopenq ? fastopenq->max_qlen : 0) :
> - (tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh),
> - len);
> + *len = seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %lu %lu %u %u %d",
> + i, src, srcp, dest, destp, sk->sk_state,
> + tp->write_seq - tp->snd_una,
> + rx_queue,
> + timer_active,
> + jiffies_delta_to_clock_t(timer_expires - jiffies),
> + icsk->icsk_retransmits,
> + from_kuid_munged(seq_user_ns(f), sock_i_uid(sk)),
> + icsk->icsk_probes_out,
> + sock_i_ino(sk),
> + atomic_read(&sk->sk_refcnt), sk,
> + jiffies_to_clock_t(icsk->icsk_rto),
> + jiffies_to_clock_t(icsk->icsk_ack.ato),
> + (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
> + tp->snd_cwnd,
> + sk->sk_state == TCP_LISTEN ?
> + (fastopenq ? fastopenq->max_qlen : 0) :
> + (tcp_in_initial_slowstart(tp) ? -1 :
> + tp->snd_ssthresh));
> }
>
> static void get_timewait4_sock(const struct inet_timewait_sock *tw,
> @@ -2695,11 +2694,10 @@ static void get_timewait4_sock(const struct inet_timewait_sock *tw,
> destp = ntohs(tw->tw_dport);
> srcp = ntohs(tw->tw_sport);
>
> - seq_printf(f, "%4d: %08X:%04X %08X:%04X"
> - " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK%n",
> - i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
> - 3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
> - atomic_read(&tw->tw_refcnt), tw, len);
> + *len = seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK",
> + i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
> + 3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
> + atomic_read(&tw->tw_refcnt), tw);
> }
>
> #define TMPSZ 150
> diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
> index 74d2c95..ddc24a2d 100644
> --- a/net/ipv4/udp.c
> +++ b/net/ipv4/udp.c
> @@ -2158,16 +2158,15 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f,
> __u16 destp = ntohs(inet->inet_dport);
> __u16 srcp = ntohs(inet->inet_sport);
>
> - seq_printf(f, "%5d: %08X:%04X %08X:%04X"
> - " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d%n",
> - bucket, src, srcp, dest, destp, sp->sk_state,
> - sk_wmem_alloc_get(sp),
> - sk_rmem_alloc_get(sp),
> - 0, 0L, 0,
> - from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
> - 0, sock_i_ino(sp),
> - atomic_read(&sp->sk_refcnt), sp,
> - atomic_read(&sp->sk_drops), len);
> + *len = seq_printf(f, "%5d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d",
> + bucket, src, srcp, dest, destp, sp->sk_state,
> + sk_wmem_alloc_get(sp),
> + sk_rmem_alloc_get(sp),
> + 0, 0L, 0,
> + from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
> + 0, sock_i_ino(sp),
> + atomic_read(&sp->sk_refcnt), sp,
> + atomic_read(&sp->sk_drops));
> }
>
> int udp4_seq_show(struct seq_file *seq, void *v)
> diff --git a/net/phonet/socket.c b/net/phonet/socket.c
> index 77e38f7..553f896 100644
> --- a/net/phonet/socket.c
> +++ b/net/phonet/socket.c
> @@ -598,21 +598,20 @@ static int pn_sock_seq_show(struct seq_file *seq, void *v)
> int len;
>
> if (v == SEQ_START_TOKEN)
> - seq_printf(seq, "%s%n", "pt loc rem rs st tx_queue rx_queue "
> - " uid inode ref pointer drops", &len);
> + len = seq_puts(seq, "pt loc rem rs st tx_queue rx_queue uid inode ref pointer drops");
> else {
> struct sock *sk = v;
> struct pn_sock *pn = pn_sk(sk);
>
> - seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu "
> - "%d %pK %d%n",
> - sk->sk_protocol, pn->sobject, pn->dobject,
> - pn->resource, sk->sk_state,
> - sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
> - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
> - sock_i_ino(sk),
> - atomic_read(&sk->sk_refcnt), sk,
> - atomic_read(&sk->sk_drops), &len);
> + len = seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu %d %pK %d",
> + sk->sk_protocol, pn->sobject, pn->dobject,
> + pn->resource, sk->sk_state,
> + sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
> + from_kuid_munged(seq_user_ns(seq),
> + sock_i_uid(sk)),
> + sock_i_ino(sk),
> + atomic_read(&sk->sk_refcnt), sk,
> + atomic_read(&sk->sk_drops));
> }
> seq_printf(seq, "%*s\n", 127 - len, "");
> return 0;
> @@ -788,15 +787,16 @@ static int pn_res_seq_show(struct seq_file *seq, void *v)
> int len;
>
> if (v == SEQ_START_TOKEN)
> - seq_printf(seq, "%s%n", "rs uid inode", &len);
> + len = seq_puts(seq, "rs uid inode");
> else {
> struct sock **psk = v;
> struct sock *sk = *psk;
>
> - seq_printf(seq, "%02X %5u %lu%n",
> - (int) (psk - pnres.sk),
> - from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
> - sock_i_ino(sk), &len);
> + len = seq_printf(seq, "%02X %5u %lu",
> + (int) (psk - pnres.sk),
> + from_kuid_munged(seq_user_ns(seq),
> + sock_i_uid(sk)),
> + sock_i_ino(sk));
> }
> seq_printf(seq, "%*s\n", 63 - len, "");
> return 0;
> diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c
> index 5ea573b..8034325 100644
> --- a/net/sctp/objcnt.c
> +++ b/net/sctp/objcnt.c
> @@ -82,8 +82,9 @@ static int sctp_objcnt_seq_show(struct seq_file *seq, void *v)
> int i, len;
>
> i = (int)*(loff_t *)v;
> - seq_printf(seq, "%s: %d%n", sctp_dbg_objcnt[i].label,
> - atomic_read(sctp_dbg_objcnt[i].counter), &len);
> + len = seq_printf(seq, "%s: %d",
> + sctp_dbg_objcnt[i].label,
> + atomic_read(sctp_dbg_objcnt[i].counter));
> seq_printf(seq, "%*s\n", 127 - len, "");
> return 0;
> }
> --
> 1.8.1.2.459.gbcd45b4.dirty
>
>
>
--
Kees Cook
Chrome OS Security
^ permalink raw reply
* [RFC PATCH] vsnprintf: Remove use of %n and convert existing uses
From: Joe Perches @ 2013-09-11 23:22 UTC (permalink / raw)
To: LKML
Cc: KOSAKI Motohiro, Kees Cook, Frederic Weisbecker, Dan Carpenter,
devel, Greg Kroah-Hartman, Tushar Behera, Lidza Louina,
David S. Miller, Alexey Kuznetsov, James Morris,
Hideaki YOSHIFUJI, Patrick McHardy, Remi Denis-Courmont,
Vlad Yasevich, Neil Horman, netdev, linux-sctp
In-Reply-To: <CAGXu5jLTjrPr=GwOmMcu55Qp9K-_XS75xq9NJ0vBUEwy-i_YMw@mail.gmail.com>
Using vsnprintf or its derivatives with %n can have security
vulnerability implications.
Prior to commit fef20d9c1380
("vsprintf: unify the format decoding layer for its 3 users"),
any use of %n was ignored.
Reintroduce this feature and convert the existing uses of %n
to use the return length from vsnprintf or its derivatives.
Signed-off-by: Joe Perches <joe@perches.com>
Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> (proc bits)
cc: Kees Cook <keescook@chromium.org>
cc: Frederic Weisbecker <fweisbec@gmail.com>
---
Not particularly well tested...
fs/proc/consoles.c | 2 +-
fs/proc/nommu.c | 20 ++++++-------
fs/proc/task_mmu.c | 18 +++++------
fs/proc/task_nommu.c | 20 ++++++-------
lib/vsprintf.c | 21 ++++++-------
net/ipv4/fib_trie.c | 30 ++++++++-----------
net/ipv4/ping.c | 19 ++++++------
net/ipv4/tcp_ipv4.c | 84 +++++++++++++++++++++++++---------------------------
net/ipv4/udp.c | 19 ++++++------
net/phonet/socket.c | 32 ++++++++++----------
net/sctp/objcnt.c | 5 ++--
11 files changed, 132 insertions(+), 138 deletions(-)
diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index b701eaa..42f2bb7 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -47,7 +47,7 @@ static int show_console_dev(struct seq_file *m, void *v)
con_flags[a].name : ' ';
flags[a] = 0;
- seq_printf(m, "%s%d%n", con->name, con->index, &len);
+ len = seq_printf(m, "%s%d", con->name, con->index);
len = 21 - len;
if (len < 1)
len = 1;
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
index ccfd99b..91cfd19 100644
--- a/fs/proc/nommu.c
+++ b/fs/proc/nommu.c
@@ -50,16 +50,16 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
ino = inode->i_ino;
}
- seq_printf(m,
- "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
- region->vm_start,
- region->vm_end,
- flags & VM_READ ? 'r' : '-',
- flags & VM_WRITE ? 'w' : '-',
- flags & VM_EXEC ? 'x' : '-',
- flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
- ((loff_t)region->vm_pgoff) << PAGE_SHIFT,
- MAJOR(dev), MINOR(dev), ino, &len);
+ len = seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
+ region->vm_start,
+ region->vm_end,
+ flags & VM_READ ? 'r' : '-',
+ flags & VM_WRITE ? 'w' : '-',
+ flags & VM_EXEC ? 'x' : '-',
+ flags & VM_MAYSHARE ?
+ flags & VM_SHARED ? 'S' : 's' : 'p',
+ ((loff_t)region->vm_pgoff) << PAGE_SHIFT,
+ MAJOR(dev), MINOR(dev), ino);
if (file) {
len = 25 + sizeof(void *) * 6 - len;
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 107d026..f84ee9f 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -286,15 +286,15 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
if (stack_guard_page_end(vma, end))
end -= PAGE_SIZE;
- seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
- start,
- end,
- flags & VM_READ ? 'r' : '-',
- flags & VM_WRITE ? 'w' : '-',
- flags & VM_EXEC ? 'x' : '-',
- flags & VM_MAYSHARE ? 's' : 'p',
- pgoff,
- MAJOR(dev), MINOR(dev), ino, &len);
+ len = seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
+ start,
+ end,
+ flags & VM_READ ? 'r' : '-',
+ flags & VM_WRITE ? 'w' : '-',
+ flags & VM_EXEC ? 'x' : '-',
+ flags & VM_MAYSHARE ? 's' : 'p',
+ pgoff,
+ MAJOR(dev), MINOR(dev), ino);
/*
* Print the dentry name for named mappings, and a
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index 56123a6..1d7bbe5 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -155,16 +155,16 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
}
- seq_printf(m,
- "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
- vma->vm_start,
- vma->vm_end,
- flags & VM_READ ? 'r' : '-',
- flags & VM_WRITE ? 'w' : '-',
- flags & VM_EXEC ? 'x' : '-',
- flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
- pgoff,
- MAJOR(dev), MINOR(dev), ino, &len);
+ len = seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
+ vma->vm_start,
+ vma->vm_end,
+ flags & VM_READ ? 'r' : '-',
+ flags & VM_WRITE ? 'w' : '-',
+ flags & VM_EXEC ? 'x' : '-',
+ flags & VM_MAYSHARE ?
+ flags & VM_SHARED ? 'S' : 's' : 'p',
+ pgoff,
+ MAJOR(dev), MINOR(dev), ino);
if (file) {
pad_len_spaces(m, len);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 26559bd..43c2ea0 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1683,18 +1683,19 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
break;
case FORMAT_TYPE_NRCHARS: {
+ /* skip %n 's argument */
u8 qualifier = spec.qualifier;
+ void *skip_arg;
- if (qualifier == 'l') {
- long *ip = va_arg(args, long *);
- *ip = (str - buf);
- } else if (_tolower(qualifier) == 'z') {
- size_t *ip = va_arg(args, size_t *);
- *ip = (str - buf);
- } else {
- int *ip = va_arg(args, int *);
- *ip = (str - buf);
- }
+ WARN_ONCE(1, "Please remove ignored use of %%n in '%s'\n",
+ old_fmt);
+
+ if (qualifier == 'l')
+ skip_arg = va_arg(args, long *);
+ else if (_tolower(qualifier) == 'z')
+ skip_arg = va_arg(args, size_t *);
+ else
+ skip_arg = va_arg(args, int *);
break;
}
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 3df6d3e..ddf1e9c 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -2537,24 +2537,20 @@ static int fib_route_seq_show(struct seq_file *seq, void *v)
continue;
if (fi)
- seq_printf(seq,
- "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
- "%d\t%08X\t%d\t%u\t%u%n",
- fi->fib_dev ? fi->fib_dev->name : "*",
- prefix,
- fi->fib_nh->nh_gw, flags, 0, 0,
- fi->fib_priority,
- mask,
- (fi->fib_advmss ?
- fi->fib_advmss + 40 : 0),
- fi->fib_window,
- fi->fib_rtt >> 3, &len);
+ len = seq_printf(seq, "%s\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
+ (fi->fib_dev ?
+ fi->fib_dev->name : "*"),
+ prefix,
+ fi->fib_nh->nh_gw, flags,
+ 0, 0, fi->fib_priority, mask,
+ (fi->fib_advmss ?
+ fi->fib_advmss + 40 : 0),
+ fi->fib_window,
+ fi->fib_rtt >> 3);
else
- seq_printf(seq,
- "*\t%08X\t%08X\t%04X\t%d\t%u\t"
- "%d\t%08X\t%d\t%u\t%u%n",
- prefix, 0, flags, 0, 0, 0,
- mask, 0, 0, 0, &len);
+ len = seq_printf(seq, "*\t%08X\t%08X\t%04X\t%d\t%u\t%d\t%08X\t%d\t%u\t%u",
+ prefix, 0, flags, 0, 0, 0,
+ mask, 0, 0, 0);
seq_printf(seq, "%*s\n", 127 - len, "");
}
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index d7d9882..ac8d79f 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -1081,16 +1081,15 @@ static void ping_v4_format_sock(struct sock *sp, struct seq_file *f,
__u16 destp = ntohs(inet->inet_dport);
__u16 srcp = ntohs(inet->inet_sport);
- seq_printf(f, "%5d: %08X:%04X %08X:%04X"
- " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d%n",
- bucket, src, srcp, dest, destp, sp->sk_state,
- sk_wmem_alloc_get(sp),
- sk_rmem_alloc_get(sp),
- 0, 0L, 0,
- from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
- 0, sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp,
- atomic_read(&sp->sk_drops), len);
+ *len = seq_printf(f, "%5d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d",
+ bucket, src, srcp, dest, destp, sp->sk_state,
+ sk_wmem_alloc_get(sp),
+ sk_rmem_alloc_get(sp),
+ 0, 0L, 0,
+ from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
+ 0, sock_i_ino(sp),
+ atomic_read(&sp->sk_refcnt), sp,
+ atomic_read(&sp->sk_drops));
}
static int ping_v4_seq_show(struct seq_file *seq, void *v)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index b14266b..1279c16 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2603,24 +2603,24 @@ static void get_openreq4(const struct sock *sk, const struct request_sock *req,
const struct inet_request_sock *ireq = inet_rsk(req);
long delta = req->expires - jiffies;
- seq_printf(f, "%4d: %08X:%04X %08X:%04X"
- " %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK%n",
- i,
- ireq->loc_addr,
- ntohs(inet_sk(sk)->inet_sport),
- ireq->rmt_addr,
- ntohs(ireq->rmt_port),
- TCP_SYN_RECV,
- 0, 0, /* could print option size, but that is af dependent. */
- 1, /* timers active (only the expire timer) */
- jiffies_delta_to_clock_t(delta),
- req->num_timeout,
- from_kuid_munged(seq_user_ns(f), uid),
- 0, /* non standard timer */
- 0, /* open_requests have no inode */
- atomic_read(&sk->sk_refcnt),
- req,
- len);
+ *len = seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5u %8d %u %d %pK",
+ i,
+ ireq->loc_addr,
+ ntohs(inet_sk(sk)->inet_sport),
+ ireq->rmt_addr,
+ ntohs(ireq->rmt_port),
+ TCP_SYN_RECV,
+ 0, 0, /* could print option size,
+ * but that is af dependent.
+ */
+ 1, /* timers active (only the expire timer) */
+ jiffies_delta_to_clock_t(delta),
+ req->num_timeout,
+ from_kuid_munged(seq_user_ns(f), uid),
+ 0, /* non standard timer */
+ 0, /* open_requests have no inode */
+ atomic_read(&sk->sk_refcnt),
+ req);
}
static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
@@ -2661,26 +2661,25 @@ static void get_tcp4_sock(struct sock *sk, struct seq_file *f, int i, int *len)
*/
rx_queue = max_t(int, tp->rcv_nxt - tp->copied_seq, 0);
- seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX "
- "%08X %5u %8d %lu %d %pK %lu %lu %u %u %d%n",
- i, src, srcp, dest, destp, sk->sk_state,
- tp->write_seq - tp->snd_una,
- rx_queue,
- timer_active,
- jiffies_delta_to_clock_t(timer_expires - jiffies),
- icsk->icsk_retransmits,
- from_kuid_munged(seq_user_ns(f), sock_i_uid(sk)),
- icsk->icsk_probes_out,
- sock_i_ino(sk),
- atomic_read(&sk->sk_refcnt), sk,
- jiffies_to_clock_t(icsk->icsk_rto),
- jiffies_to_clock_t(icsk->icsk_ack.ato),
- (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
- tp->snd_cwnd,
- sk->sk_state == TCP_LISTEN ?
- (fastopenq ? fastopenq->max_qlen : 0) :
- (tcp_in_initial_slowstart(tp) ? -1 : tp->snd_ssthresh),
- len);
+ *len = seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %lu %lu %u %u %d",
+ i, src, srcp, dest, destp, sk->sk_state,
+ tp->write_seq - tp->snd_una,
+ rx_queue,
+ timer_active,
+ jiffies_delta_to_clock_t(timer_expires - jiffies),
+ icsk->icsk_retransmits,
+ from_kuid_munged(seq_user_ns(f), sock_i_uid(sk)),
+ icsk->icsk_probes_out,
+ sock_i_ino(sk),
+ atomic_read(&sk->sk_refcnt), sk,
+ jiffies_to_clock_t(icsk->icsk_rto),
+ jiffies_to_clock_t(icsk->icsk_ack.ato),
+ (icsk->icsk_ack.quick << 1) | icsk->icsk_ack.pingpong,
+ tp->snd_cwnd,
+ sk->sk_state == TCP_LISTEN ?
+ (fastopenq ? fastopenq->max_qlen : 0) :
+ (tcp_in_initial_slowstart(tp) ? -1 :
+ tp->snd_ssthresh));
}
static void get_timewait4_sock(const struct inet_timewait_sock *tw,
@@ -2695,11 +2694,10 @@ static void get_timewait4_sock(const struct inet_timewait_sock *tw,
destp = ntohs(tw->tw_dport);
srcp = ntohs(tw->tw_sport);
- seq_printf(f, "%4d: %08X:%04X %08X:%04X"
- " %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK%n",
- i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
- 3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
- atomic_read(&tw->tw_refcnt), tw, len);
+ *len = seq_printf(f, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %pK",
+ i, src, srcp, dest, destp, tw->tw_substate, 0, 0,
+ 3, jiffies_delta_to_clock_t(delta), 0, 0, 0, 0,
+ atomic_read(&tw->tw_refcnt), tw);
}
#define TMPSZ 150
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 74d2c95..ddc24a2d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2158,16 +2158,15 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f,
__u16 destp = ntohs(inet->inet_dport);
__u16 srcp = ntohs(inet->inet_sport);
- seq_printf(f, "%5d: %08X:%04X %08X:%04X"
- " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d%n",
- bucket, src, srcp, dest, destp, sp->sk_state,
- sk_wmem_alloc_get(sp),
- sk_rmem_alloc_get(sp),
- 0, 0L, 0,
- from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
- 0, sock_i_ino(sp),
- atomic_read(&sp->sk_refcnt), sp,
- atomic_read(&sp->sk_drops), len);
+ *len = seq_printf(f, "%5d: %08X:%04X %08X:%04X %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %d",
+ bucket, src, srcp, dest, destp, sp->sk_state,
+ sk_wmem_alloc_get(sp),
+ sk_rmem_alloc_get(sp),
+ 0, 0L, 0,
+ from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
+ 0, sock_i_ino(sp),
+ atomic_read(&sp->sk_refcnt), sp,
+ atomic_read(&sp->sk_drops));
}
int udp4_seq_show(struct seq_file *seq, void *v)
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 77e38f7..553f896 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -598,21 +598,20 @@ static int pn_sock_seq_show(struct seq_file *seq, void *v)
int len;
if (v == SEQ_START_TOKEN)
- seq_printf(seq, "%s%n", "pt loc rem rs st tx_queue rx_queue "
- " uid inode ref pointer drops", &len);
+ len = seq_puts(seq, "pt loc rem rs st tx_queue rx_queue uid inode ref pointer drops");
else {
struct sock *sk = v;
struct pn_sock *pn = pn_sk(sk);
- seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu "
- "%d %pK %d%n",
- sk->sk_protocol, pn->sobject, pn->dobject,
- pn->resource, sk->sk_state,
- sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
- from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
- sock_i_ino(sk),
- atomic_read(&sk->sk_refcnt), sk,
- atomic_read(&sk->sk_drops), &len);
+ len = seq_printf(seq, "%2d %04X:%04X:%02X %02X %08X:%08X %5d %lu %d %pK %d",
+ sk->sk_protocol, pn->sobject, pn->dobject,
+ pn->resource, sk->sk_state,
+ sk_wmem_alloc_get(sk), sk_rmem_alloc_get(sk),
+ from_kuid_munged(seq_user_ns(seq),
+ sock_i_uid(sk)),
+ sock_i_ino(sk),
+ atomic_read(&sk->sk_refcnt), sk,
+ atomic_read(&sk->sk_drops));
}
seq_printf(seq, "%*s\n", 127 - len, "");
return 0;
@@ -788,15 +787,16 @@ static int pn_res_seq_show(struct seq_file *seq, void *v)
int len;
if (v == SEQ_START_TOKEN)
- seq_printf(seq, "%s%n", "rs uid inode", &len);
+ len = seq_puts(seq, "rs uid inode");
else {
struct sock **psk = v;
struct sock *sk = *psk;
- seq_printf(seq, "%02X %5u %lu%n",
- (int) (psk - pnres.sk),
- from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
- sock_i_ino(sk), &len);
+ len = seq_printf(seq, "%02X %5u %lu",
+ (int) (psk - pnres.sk),
+ from_kuid_munged(seq_user_ns(seq),
+ sock_i_uid(sk)),
+ sock_i_ino(sk));
}
seq_printf(seq, "%*s\n", 63 - len, "");
return 0;
diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c
index 5ea573b..8034325 100644
--- a/net/sctp/objcnt.c
+++ b/net/sctp/objcnt.c
@@ -82,8 +82,9 @@ static int sctp_objcnt_seq_show(struct seq_file *seq, void *v)
int i, len;
i = (int)*(loff_t *)v;
- seq_printf(seq, "%s: %d%n", sctp_dbg_objcnt[i].label,
- atomic_read(sctp_dbg_objcnt[i].counter), &len);
+ len = seq_printf(seq, "%s: %d",
+ sctp_dbg_objcnt[i].label,
+ atomic_read(sctp_dbg_objcnt[i].counter));
seq_printf(seq, "%*s\n", 127 - len, "");
return 0;
}
--
1.8.1.2.459.gbcd45b4.dirty
^ permalink raw reply related
* Re: [PATCH] ipv6: Do route updating for redirect in ndisc layer
From: Hannes Frederic Sowa @ 2013-09-11 23:17 UTC (permalink / raw)
To: Duan Jiong; +Cc: davem, netdev, dborkman, vyasevich
In-Reply-To: <52301603.7030906@cn.fujitsu.com>
[added Cc to Daniel and Vlad because of ipv6/sctp/redirect problem]
On Wed, Sep 11, 2013 at 03:04:35PM +0800, Duan Jiong wrote:
> 于 2013年09月11日 06:50, Hannes Frederic Sowa 写道:
> > On Mon, Sep 09, 2013 at 03:09:56PM +0800, Duan Jiong wrote:
> >> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
> >> index 5c71501..61fe8e5 100644
> >> --- a/net/ipv6/tcp_ipv6.c
> >> +++ b/net/ipv6/tcp_ipv6.c
> >> @@ -382,14 +382,6 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
> >>
> >> np = inet6_sk(sk);
> >>
> >> - if (type == NDISC_REDIRECT) {
> >> - struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
> >> -
> >> - if (dst)
> >> - dst->ops->redirect(dst, sk, skb);
> >> - goto out;
> >> - }
> >> -
> >
> > You dropped the "goto out" here in case of an NDISC_REDIRECT, so this sends an
> > EPROTO further up the socket layer. Was this intended?
> >
>
> I'm sorry, i didn't notice the variable err was assigned to EPROTO.
> I only thought that message should be sent to the socket layer, because
> i found that in function sctp_v6_err().
>
> In addition, the rfc 4443 said the Redirect Message is not the ICMPv6 Error
> Message, so i think we shouldn't call those err_handler function, in other
> words we shouldn't call the icmpv6_notify().
>
> How do you think of this?
Hm, thats hard.
First of, when the kernel started publishing these errors it had a
contract with user-space we cannot break now. This includes all error
handling functions which call ipv6_icmp_error. So we only have to care
about INET6_PROTO_FINAL protocols, bbecause they mostly operate in socket
space (in this case these are the raw and the udp protocol and currently
sctp). Especially I do think it is important to report the redirects
to raw sockets. The other non-final protocols only need to be notified
for mtu reduction currently. Maybe we could stop notifying non-final
protocols for redirects, but I don't think this will improve things.
Also we cannot know if the router sending the redirect discarded the
original packet or if it forwarded it just notifying us of a better route,
so we don't know if an actual error happend. So I would do the same thing
as IPv4 sockets, set sk_err to zero and queue up the icmp packet on the
socket's error queue (for udp and raw).
Regarding notifying tcp sockets about the redirect seems wrong. It would
generate a poll notification and I do think it could even tear down
the whole connection. I guess sctp should also stop updating sk_err
on redirects. But let's Cc Daniel and Vlad about this. My guess is that
sctp could go into some error recovery mode because of this which would
be wrong.
So, for this patch I would leave the logic as is and not change anything
at the error reporting. Maybe Daniel and Vlad could check if we should
suppress redirect information for ipv6 in sctp, too? But this should
go into another patch. Regarding the EPROTO problem in raw and udp,
let's see if all the problems go away if we update icmpv6_err_convert
to set *err to 0.
Greetings,
Hannes
^ permalink raw reply
* Re: [PATCH net 1/1] r8169: enforce RX_MULTI_EN for the 8168f.
From: Francois Romieu @ 2013-09-11 23:15 UTC (permalink / raw)
To: David Miller; +Cc: dborkman, netdev, david, fredo, hayeswang
In-Reply-To: <20130911.161606.1575635427616463157.davem@davemloft.net>
David Miller <davem@davemloft.net> :
[...]
> Francois, if you reply to this thread with your signoff, all will
> be well and I will apply this.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
I slowly built an AMD IOMMU + 8168{e/f} problem report pattern but
the picture got blurred:
- Hayes has not heard of anything like this
- the oracle suggests it could be an "AMD IOMMU + whatever" problem
- "iommu=pt" seems quite effective (hardly surprizing :o/ )
I still have a pile of iommu mailing-list messages to search through.
Let aside the AMD-Vi error log message, I haven't done a thorough analysis.
It's lame.
--
Ueimor
^ permalink raw reply
* Re: [PATCH 01/52] net: typhoon: remove unnecessary pci_set_drvdata()
From: David Dillow @ 2013-09-11 22:18 UTC (permalink / raw)
To: Jingoo Han; +Cc: 'David S. Miller', netdev
In-Reply-To: <004b01ceaebf$7e7e0e20$7b7a2a60$%han@samsung.com>
On Wed, 2013-09-11 at 16:21 +0900, Jingoo Han wrote:
> The driver core clears the driver data to NULL after device_release
> or on probe failure. Thus, it is not needed to manually clear the
> device driver data to NULL.
>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
For what it is worth,
Acked-by: David Dillow <dave@thedillows.org>
^ permalink raw reply
* Re: [net v7 0/8][pull request] Intel Wired LAN Driver Updates
From: Jeff Kirsher @ 2013-09-11 22:08 UTC (permalink / raw)
To: David Miller; +Cc: e1000-devel, netdev, jesse.brandeburg, gospo, sassmann
In-Reply-To: <20130911.170807.48801927112532333.davem@davemloft.net>
[-- Attachment #1.1: Type: text/plain, Size: 446 bytes --]
On Wed, 2013-09-11 at 17:08 -0400, David Miller wrote:
> From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> Date: Wed, 11 Sep 2013 02:50:48 -0700
>
> > git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net master
>
> Ok, I've pulled this.
>
> Please send fixups based upon the trivial issues a few folks have
> pointed out.
>
> Thanks.
Noted, we are already working on the fixups based on the feedback.
Thanks,
Jeff
[-- Attachment #1.2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 407 bytes --]
------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. Consolidate legacy IT systems to a single system of record for IT
2. Standardize and globalize service processes across IT
3. Implement zero-touch automation to replace manual, redundant tasks
http://pubads.g.doubleclick.net/gampad/clk?id=51271111&iu=/4140/ostg.clktrk
[-- Attachment #3: Type: text/plain, Size: 257 bytes --]
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* From Mrs Monat Adama.
From: monat @ 2013-09-11 21:42 UTC (permalink / raw)
Dear Friend,
Greetings to you and your family.
My name is Mrs Monate Adama, the current Chief Auditor of a formidable bank here in Ouagadougou, Burkina Faso, West Africa. I have a transaction worth of 12.5 Million U.S dollars for transferring into your care for our mutual benefits, so i need your assistance with 100% cooperation to realise this task.
Further details about the fund, its source and the administrative procedure to transfer this fund into your receiving bank account shall be made known to you immediately as I have your positive response.
Thanks and Regards,
Mrs Monate Adama.
^ permalink raw reply
* [GIT] Networking
From: David Miller @ 2013-09-11 21:25 UTC (permalink / raw)
To: torvalds; +Cc: akpm, netdev, linux-kernel
1) Brown paper bag fix in HTB scheduler, class options set incorrectly due
to a typoe. Fix from Vimalkumar.
2) It's possible for the ipv6 FIB garbage collector to run before all
the necessary datastructure are setup during init, defer the notifier
registry to avoid this problem. Fix from Michal Kubecek.
3) New i40e ethernet driver from the Intel folks.
4) Add new qmi wwan device IDs, from Bjørn Mork.
5) Doorbell lock in bnx2x driver is not initialized properly in some
configurations, fix from Ariel Elior.
6) Revert an ipv6 packet option padding change that broke standardized
ipv6 implementation test suites. From Jiri Pirko.
7) Fix synchronization of ARP information in bonding layer, from Nikolay
Aleksandrov.
8) Fix missing error return resulting in illegal memory accesses in
openvswitch, from Daniel Borkmann.
9) SCTP doesn't signal poll events properly due to mistaken operator
precedence, fix also from Daniel Borkmann.
10) __netdev_pick_tx() passes wrong index to sk_tx_queue_set() which
essentially disables caching of TX queue in sockets :-/ Fix from
Eric Dumazet.
Please pull, thanks a lot!
The following changes since commit 300893b08f3bc7057a7a5f84074090ba66c8b5ca:
Merge tag 'xfs-for-linus-v3.12-rc1' of git://oss.sgi.com/xfs/xfs (2013-09-09 11:19:09 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git master
for you to fetch changes up to f3ad857e3da1abaea780dc892b592cd86c541c52:
net_sched: htb: fix a typo in htb_change_class() (2013-09-11 17:16:22 -0400)
----------------------------------------------------------------
Ariel Elior (1):
bnx2x: Fix configuration of doorbell block
Bjørn Mork (1):
net: qmi_wwan: add new Qualcomm devices
Chris Metcalf (1):
net: tilegx driver: avoid compiler warning
Daniel Borkmann (4):
net: ovs: flow: fix potential illegal memory access in __parse_flow_nlattrs
net: fib: fib6_add: fix potential NULL pointer dereference
net: sctp: fix bug in sctp_poll for SOCK_SELECT_ERR_QUEUE
net: sctp: fix smatch warning in sctp_send_asconf_del_ip
David S. Miller (2):
Merge branch 'bonding_arp'
Merge branch 'master' of git://git.kernel.org/.../jkirsher/net
Eric Dumazet (1):
net: fix multiqueue selection
Herbert Xu (1):
macvlan: Move skb_clone check closer to call
Jesse Brandeburg (8):
i40e: main driver core
i40e: transmit, receive, and NAPI
i40e: driver ethtool core
i40e: driver core headers
i40e: implement virtual device interface
i40e: init code and hardware support
i40e: debugfs interface
i40e: include i40e in kernel proper
Jingoo Han (2):
irda: donauboe: Remove casting the return value which is a void pointer
irda: vlsi_ir: Remove casting the return value which is a void pointer
Jiri Pirko (1):
ipv6/exthdrs: accept tlv which includes only padding
Jitendra Kalsaria (1):
qlcnic: Fix warning reported by kbuild test robot.
Michael Opdenacker (2):
net: korina: remove deprecated IRQF_DISABLED
bcm63xx_enet: remove deprecated IRQF_DISABLED
Michal Kubeček (1):
ipv6: don't call fib6_run_gc() until routing is ready
Michal Schmidt (1):
bnx2x: avoid atomic allocations during initialization
Stefan Tomanek (1):
fib6_rules: fix indentation
Vimalkumar (1):
net_sched: htb: fix a typo in htb_change_class()
nikolay@redhat.com (2):
bonding: fix store_arp_validate race with mode change
bonding: fix bond_arp_rcv setting and arp validate desync state
Documentation/networking/00-INDEX | 2 +
Documentation/networking/i40e.txt | 115 ++
MAINTAINERS | 3 +-
drivers/net/bonding/bond_main.c | 4 +-
drivers/net/bonding/bond_sysfs.c | 31 +-
drivers/net/bonding/bonding.h | 1 +
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 8 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 38 +-
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 1 +
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 3 -
drivers/net/ethernet/intel/Kconfig | 18 +
drivers/net/ethernet/intel/Makefile | 1 +
drivers/net/ethernet/intel/i40e/Makefile | 44 +
drivers/net/ethernet/intel/i40e/i40e.h | 558 ++++++
drivers/net/ethernet/intel/i40e/i40e_adminq.c | 983 ++++++++++
drivers/net/ethernet/intel/i40e/i40e_adminq.h | 112 ++
drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 2076 +++++++++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_alloc.h | 59 +
drivers/net/ethernet/intel/i40e/i40e_common.c | 2041 ++++++++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 2076 +++++++++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_diag.c | 131 ++
drivers/net/ethernet/intel/i40e/i40e_diag.h | 52 +
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 1449 +++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_hmc.c | 366 ++++
drivers/net/ethernet/intel/i40e/i40e_hmc.h | 245 +++
drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c | 1006 ++++++++++
drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h | 169 ++
drivers/net/ethernet/intel/i40e/i40e_main.c | 7375 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_nvm.c | 391 ++++
drivers/net/ethernet/intel/i40e/i40e_osdep.h | 82 +
drivers/net/ethernet/intel/i40e/i40e_prototype.h | 239 +++
drivers/net/ethernet/intel/i40e/i40e_register.h | 4688 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_status.h | 101 +
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 1817 ++++++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_txrx.h | 259 +++
drivers/net/ethernet/intel/i40e/i40e_type.h | 1154 ++++++++++++
drivers/net/ethernet/intel/i40e/i40e_virtchnl.h | 368 ++++
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 2335 +++++++++++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h | 120 ++
drivers/net/ethernet/korina.c | 8 +-
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 2 +-
drivers/net/ethernet/tile/tilegx.c | 6 +-
drivers/net/irda/donauboe.c | 6 +-
drivers/net/irda/vlsi_ir.c | 2 +-
drivers/net/macvlan.c | 10 +-
drivers/net/usb/qmi_wwan.c | 130 +-
include/net/ndisc.h | 2 +
net/core/flow_dissector.c | 2 +-
net/ipv6/af_inet6.c | 6 +
net/ipv6/exthdrs.c | 6 -
net/ipv6/fib6_rules.c | 4 +-
net/ipv6/ip6_fib.c | 2 +-
net/ipv6/ndisc.c | 18 +-
net/openvswitch/flow.c | 1 +
net/sched/sch_htb.c | 2 +-
net/sctp/socket.c | 5 +-
56 files changed, 30666 insertions(+), 67 deletions(-)
create mode 100644 Documentation/networking/i40e.txt
create mode 100644 drivers/net/ethernet/intel/i40e/Makefile
create mode 100644 drivers/net/ethernet/intel/i40e/i40e.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_adminq.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_adminq.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_alloc.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_common.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_debugfs.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_diag.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_diag.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_ethtool.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_hmc.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_hmc.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_main.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_nvm.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_osdep.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_prototype.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_register.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_status.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_txrx.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_txrx.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_type.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_virtchnl.h
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
create mode 100644 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox