bits 函数和map.c文件

int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
{
    int start = skb_headlen(skb);
    struct sk_buff *frag_iter;
    int i, copy;

if (offset > (int)skb->len - len)
        goto fault;

/* Copy header. */
    if ((copy = start - offset) > 0) {
        if (copy > len)
            copy = len;
        skb_copy_from_linear_data_offset(skb, offset, to, copy);
        if ((len -= copy) == 0)
            return 0;
        offset += copy;
        to     += copy;
    }

for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
        int end;

WARN_ON(start > offset + len);

end = start + skb_shinfo(skb)->frags[i].size;
        if ((copy = end - offset) > 0) {
            u8 *vaddr;

if (copy > len)
                copy = len;

vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]);
            memcpy(to,
                   vaddr + skb_shinfo(skb)->frags[i].page_offset+
                   offset - start, copy);
            kunmap_skb_frag(vaddr);

if ((len -= copy) == 0)
                return 0;
            offset += copy;
            to     += copy;
        }
        start = end;
    }

skb_walk_frags(skb, frag_iter) {
        int end;

WARN_ON(start > offset + len);

end = start + frag_iter->len;
        if ((copy = end - offset) > 0) {
            if (copy > len)
                copy = len;
            if (skb_copy_bits(frag_iter, offset - start, to, copy))
                goto fault;
            if ((len -= copy) == 0)
                return 0;
            offset += copy;
            to     += copy;
        }
        start = end;
    }
    if (!len)
        return 0;

fault:
    return -EFAULT;
}
EXPORT_SYMBOL(skb_copy_bits);

/*
 *  linux/drivers/base/map.c
 *
 * (C) Copyright Al Viro 2002,2003
 * Released under GPL v2.
 *
 * NOTE: data structure needs to be changed.  It works, but for large dev_t
 * it will be too slow.  It is isolated, though, so these changes will be
 * local to that file.
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/kdev_t.h>
#include <linux/kobject.h>
#include <linux/kobj_map.h>

struct kobj_map {
 struct probe {
  struct probe *next;
  dev_t dev;
  unsigned long range;
  struct module *owner;
  kobj_probe_t *get;
  int (*lock)(dev_t, void *);
  void *data;
 } *probes[255];
 struct mutex *lock;
};

int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
      struct module *module, kobj_probe_t *probe,
      int (*lock)(dev_t, void *), void *data)
{
 unsigned n = MAJOR(dev + range - 1) - MAJOR(dev) + 1;
 unsigned index = MAJOR(dev);
 unsigned i;
 struct probe *p;

if (n > 255)
  n = 255;

p = kmalloc(sizeof(struct probe) * n, GFP_KERNEL);

if (p == NULL)
  return -ENOMEM;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwxwyw.html