本文整理汇总了C++中write_lock函数的典型用法代码示例。如果您正苦于以下问题:C++ write_lock函数的具体用法?C++ write_lock怎么用?C++ write_lock使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了write_lock函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: expand_fd_array
int expand_fd_array(struct files_struct *files, int nr)
{
struct file **new_fds;
int error, nfds;
error = -EMFILE;
if (files->max_fds >= NR_OPEN || nr >= NR_OPEN)
goto out;
nfds = files->max_fds;
write_unlock(&files->file_lock);
/*
* Expand to the max in easy steps, and keep expanding it until
* we have enough for the requested fd array size.
*/
do {
#if NR_OPEN_DEFAULT < 256
if (nfds < 256)
nfds = 256;
else
#endif
if (nfds < (PAGE_SIZE / sizeof(struct file *)))
nfds = PAGE_SIZE / sizeof(struct file *);
else {
nfds = nfds * 2;
if (nfds > NR_OPEN)
nfds = NR_OPEN;
}
} while (nfds <= nr);
error = -ENOMEM;
new_fds = alloc_fd_array(nfds);
write_lock(&files->file_lock);
if (!new_fds)
goto out;
/* Copy the existing array and install the new pointer */
if (nfds > files->max_fds) {
struct file **old_fds;
int i;
old_fds = xchg(&files->fd, new_fds);
i = xchg(&files->max_fds, nfds);
/* Don't copy/clear the array if we are creating a new
fd array for fork() */
if (i) {
memcpy(new_fds, old_fds, i * sizeof(struct file *));
/* clear the remainder of the array */
memset(&new_fds[i], 0,
(nfds-i) * sizeof(struct file *));
write_unlock(&files->file_lock);
free_fd_array(old_fds, i);
write_lock(&files->file_lock);
}
} else {
/* Somebody expanded the array while we slept ... */
write_unlock(&files->file_lock);
free_fd_array(new_fds, nfds);
write_lock(&files->file_lock);
}
error = 0;
out:
return error;
}
示例2: write_lock
void SortedVectorMapRow<V>::ApplyInc(int32_t column_id, const void *update) {
std::unique_lock<SharedMutex> write_lock(rw_mutex_);
ApplyIncUnsafe(column_id, update);
}
示例3: ip6_frag_queue
//.........这里部分代码省略.........
}
}
if (end == offset)
goto err;
/* Point into the IP datagram 'data' part. */
if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data))
goto err;
if (pskb_trim_rcsum(skb, end - offset))
goto err;
/* Find out which fragments are in front and at the back of us
* in the chain of fragments so far. We must know where to put
* this fragment, right?
*/
prev = fq->q.fragments_tail;
if (!prev || FRAG6_CB(prev)->offset < offset) {
next = NULL;
goto found;
}
prev = NULL;
for(next = fq->q.fragments; next != NULL; next = next->next) {
if (FRAG6_CB(next)->offset >= offset)
break; /* bingo! */
prev = next;
}
found:
/* RFC5722, Section 4, amended by Errata ID : 3089
* When reassembling an IPv6 datagram, if
* one or more its constituent fragments is determined to be an
* overlapping fragment, the entire datagram (and any constituent
* fragments) MUST be silently discarded.
*/
/* Check for overlap with preceding fragment. */
if (prev &&
(FRAG6_CB(prev)->offset + prev->len) > offset)
goto discard_fq;
/* Look for overlap with succeeding segment. */
if (next && FRAG6_CB(next)->offset < end)
goto discard_fq;
FRAG6_CB(skb)->offset = offset;
/* Insert this fragment in the chain of fragments. */
skb->next = next;
if (!next)
fq->q.fragments_tail = skb;
if (prev)
prev->next = skb;
else
fq->q.fragments = skb;
dev = skb->dev;
if (dev) {
fq->iif = dev->ifindex;
skb->dev = NULL;
}
fq->q.stamp = skb->tstamp;
fq->q.meat += skb->len;
atomic_add(skb->truesize, &fq->q.net->mem);
/* The first fragment.
* nhoffset is obtained from the first fragment, of course.
*/
if (offset == 0) {
fq->nhoffset = nhoff;
fq->q.last_in |= INET_FRAG_FIRST_IN;
}
if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
fq->q.meat == fq->q.len) {
int res;
unsigned long orefdst = skb->_skb_refdst;
skb->_skb_refdst = 0UL;
res = ip6_frag_reasm(fq, prev, dev);
skb->_skb_refdst = orefdst;
return res;
}
skb_dst_drop(skb);
write_lock(&ip6_frags.lock);
list_move_tail(&fq->q.lru_list, &fq->q.net->lru_list);
write_unlock(&ip6_frags.lock);
return -1;
discard_fq:
fq_kill(fq);
err:
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_REASMFAILS);
kfree_skb(skb);
return -1;
}
示例4: ip_frag_queue
//.........这里部分代码省略.........
* any overlaps are eliminated.
*/
if (prev) {
int i = (FRAG_CB(prev)->offset + prev->len) - offset;
if (i > 0) {
offset += i;
err = -EINVAL;
if (end <= offset)
goto err;
err = -ENOMEM;
if (!pskb_pull(skb, i))
goto err;
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->ip_summed = CHECKSUM_NONE;
}
}
err = -ENOMEM;
while (next && FRAG_CB(next)->offset < end) {
int i = end - FRAG_CB(next)->offset; /* overlap is 'i' bytes */
if (i < next->len) {
/* Eat head of the next overlapped fragment
* and leave the loop. The next ones cannot overlap.
*/
if (!pskb_pull(next, i))
goto err;
FRAG_CB(next)->offset += i;
qp->q.meat -= i;
if (next->ip_summed != CHECKSUM_UNNECESSARY)
next->ip_summed = CHECKSUM_NONE;
break;
} else {
struct sk_buff *free_it = next;
/* Old fragment is completely overridden with
* new one drop it.
*/
next = next->next;
if (prev)
prev->next = next;
else
qp->q.fragments = next;
qp->q.meat -= free_it->len;
frag_kfree_skb(qp->q.net, free_it);
}
}
FRAG_CB(skb)->offset = offset;
/* Insert this fragment in the chain of fragments. */
skb->next = next;
if (!next)
qp->q.fragments_tail = skb;
if (prev)
prev->next = skb;
else
qp->q.fragments = skb;
dev = skb->dev;
if (dev) {
qp->iif = dev->ifindex;
skb->dev = NULL;
}
qp->q.stamp = skb->tstamp;
qp->q.meat += skb->len;
qp->ecn |= ecn;
atomic_add(skb->truesize, &qp->q.net->mem);
if (offset == 0)
qp->q.last_in |= INET_FRAG_FIRST_IN;
if (ip_hdr(skb)->frag_off & htons(IP_DF) &&
skb->len + ihl > qp->q.max_size)
qp->q.max_size = skb->len + ihl;
if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
qp->q.meat == qp->q.len) {
unsigned long orefdst = skb->_skb_refdst;
skb->_skb_refdst = 0UL;
err = ip_frag_reasm(qp, prev, dev);
skb->_skb_refdst = orefdst;
return err;
}
skb_dst_drop(skb);
write_lock(&ip4_frags.lock);
list_move_tail(&qp->q.lru_list, &qp->q.net->lru_list);
write_unlock(&ip4_frags.lock);
return -EINPROGRESS;
err:
kfree_skb(skb);
return err;
}
示例5: my_write
static ssize_t my_write(struct file *fp, const char __user *buf, size_t len, loff_t *off) {
write_lock(&rwlock);
data = data==1 ? 0 : 1; //NORACE!
write_unlock(&rwlock);
return 0;
}
示例6: fld_index_create
/**
* insert range in fld store.
*
* \param range range to be inserted
* \param th transaction for this operation as it could compound
* transaction.
*
* \retval 0 success
* \retval -ve error
*
* The whole fld index insertion is protected by seq->lss_mutex (see
* seq_server_alloc_super), i.e. only one thread will access fldb each
* time, so we do not need worry the fld file and cache will being
* changed between declare and create.
* Because the fld entry can only be increamental, so we will only check
* whether it can be merged from the left.
*
* Caller must hold fld->lsf_lock
**/
int fld_index_create(const struct lu_env *env, struct lu_server_fld *fld,
const struct lu_seq_range *new_range, struct thandle *th)
{
struct lu_seq_range *range;
struct lu_seq_range *tmp;
struct fld_thread_info *info;
int rc = 0;
int deleted = 0;
struct fld_cache_entry *flde;
ENTRY;
info = lu_context_key_get(&env->le_ctx, &fld_thread_key);
LASSERT(mutex_is_locked(&fld->lsf_lock));
range = &info->fti_lrange;
memset(range, 0, sizeof(*range));
tmp = &info->fti_irange;
rc = fld_index_lookup(env, fld, new_range->lsr_start, range);
if (rc != -ENOENT) {
rc = rc == 0 ? -EEXIST : rc;
GOTO(out, rc);
}
if (new_range->lsr_start == range->lsr_end && range->lsr_end != 0 &&
lu_seq_range_compare_loc(new_range, range) == 0) {
range_cpu_to_be(tmp, range);
rc = dt_delete(env, fld->lsf_obj,
(struct dt_key *)&tmp->lsr_start, th);
if (rc != 0)
GOTO(out, rc);
*tmp = *new_range;
tmp->lsr_start = range->lsr_start;
deleted = 1;
} else {
*tmp = *new_range;
}
range_cpu_to_be(tmp, tmp);
rc = dt_insert(env, fld->lsf_obj, (struct dt_rec *)tmp,
(struct dt_key *)&tmp->lsr_start, th, 1);
if (rc != 0) {
CERROR("%s: insert range "DRANGE" failed: rc = %d\n",
fld->lsf_name, PRANGE(new_range), rc);
GOTO(out, rc);
}
flde = fld_cache_entry_create(new_range);
if (IS_ERR(flde))
GOTO(out, rc = PTR_ERR(flde));
write_lock(&fld->lsf_cache->fci_lock);
if (deleted)
fld_cache_delete_nolock(fld->lsf_cache, new_range);
rc = fld_cache_insert_nolock(fld->lsf_cache, flde);
write_unlock(&fld->lsf_cache->fci_lock);
if (rc)
OBD_FREE_PTR(flde);
out:
RETURN(rc);
}
示例7: powernet_snmp_ups_check_state
int powernet_snmp_ups_check_state(UPSINFO *ups)
{
struct snmp_ups_internal_data *Sid =
(struct snmp_ups_internal_data *)ups->driver_internal_data;
fd_set fds;
int numfds, rc, block;
struct timeval tmo, exit, now;
int sleep_time;
/* Check for commlost under lock since UPS status might be changed */
write_lock(ups);
rc = powernet_check_comm_lost(ups);
write_unlock(ups);
if (rc == 0)
return 0;
sleep_time = ups->wait_time;
/* If we're not doing SNMP traps, just sleep and exit */
if (!Sid->trap_session) {
sleep(sleep_time);
return 1;
}
/* Figure out when we need to exit by */
gettimeofday(&exit, NULL);
exit.tv_sec += sleep_time;
while(1)
{
/* Figure out how long until we have to exit */
gettimeofday(&now, NULL);
if (now.tv_sec > exit.tv_sec ||
(now.tv_sec == exit.tv_sec &&
now.tv_usec >= exit.tv_usec)) {
/* Done already? How time flies... */
return 0;
}
tmo.tv_sec = exit.tv_sec - now.tv_sec;
tmo.tv_usec = exit.tv_usec - now.tv_usec;
if (tmo.tv_usec < 0) {
tmo.tv_sec--; /* Normalize */
tmo.tv_usec += 1000000;
}
/* Get select parameters from SNMP library */
FD_ZERO(&fds);
block = 0;
numfds = 0;
snmp_select_info(&numfds, &fds, &tmo, &block);
/* Wait for something to happen */
rc = select(numfds, &fds, NULL, NULL, &tmo);
switch (rc) {
case 0: /* Timeout */
/* Tell SNMP library about the timeout */
snmp_timeout();
break;
case -1: /* Error */
if (errno == EINTR || errno == EAGAIN)
continue; /* assume SIGCHLD */
Dmsg1(200, "select error: ERR=%s\n", strerror(errno));
return 0;
default: /* Data available */
/* Reset trap flag and run callback processing */
Sid->trap_received = false;
snmp_read(&fds);
/* If callback processing set the flag, we got a trap */
if (Sid->trap_received)
return 1;
break;
}
}
}
示例8: fq_unlink
static __inline__ void fq_unlink(struct nf_ct_frag6_queue *fq)
{
write_lock(&nf_ct_frag6_lock);
__fq_unlink(fq);
write_unlock(&nf_ct_frag6_lock);
}
示例9: read_unlock
void RWMutex::upgrade_read_to_write_lock()
{
read_unlock();
write_lock();
}
示例10: neigh_expire_timer_check
static void neigh_expire_timer_check(unsigned long dummy)
{
int i;
unsigned long flags;
save_flags(flags);
cli();
write_lock(&clip_tbl.lock);
for (i = 0; i <= NEIGH_HASHMASK; i++)
{
struct neighbour **np;
for (np = &clip_tbl.hash_buckets[i]; *np;)
{
struct neighbour *n = *np;
struct atmarp_entry *entry = NEIGH2ENTRY(n);
struct clip_vcc *clip_vcc;
int need_resolving = 1;
if (time_before(jiffies + CLIP_ENTRY_EXPIRE / 4, entry->expires))
need_resolving = 0;
for (clip_vcc = entry->vccs; clip_vcc; clip_vcc = clip_vcc->next)
{
if (clip_vcc->idle_timeout && time_after(jiffies,
clip_vcc->last_use + clip_vcc->idle_timeout))
{
DPRINTK("releasing vcc %p->%p of entry %p\n",
clip_vcc, clip_vcc->vcc, entry);
atm_async_release_vcc(clip_vcc->vcc, -ETIMEDOUT);
}
else if (need_resolving && !clip_vcc->resolve_timeout)
clip_start_resolving(clip_vcc);
}
if (!need_resolving || time_before(jiffies, entry->expires))
{
np = &n->next;
continue;
}
if (atomic_read(&n->refcnt) > 1)
{
struct sk_buff *skb;
DPRINTK("destruction postponed with ref %d\n",
atomic_read(&n->refcnt));
while ((skb = skb_dequeue(&n->arp_queue)))
dev_kfree_skb(skb);
np = &n->next;
continue;
}
*np = n->next;
DPRINTK("expired neigh %p\n",n);
n->dead = 1;
neigh_release(n);
}
}
mod_timer(&neigh_expire_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
write_unlock(&clip_tbl.lock);
restore_flags(flags);
}
示例11: rxrpc_bind
/*
* bind a local address to an RxRPC socket
*/
static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
{
struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr;
struct rxrpc_local *local;
struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
u16 service_id;
int ret;
_enter("%p,%p,%d", rx, saddr, len);
ret = rxrpc_validate_address(rx, srx, len);
if (ret < 0)
goto error;
service_id = srx->srx_service;
lock_sock(&rx->sk);
switch (rx->sk.sk_state) {
case RXRPC_UNBOUND:
rx->srx = *srx;
local = rxrpc_lookup_local(sock_net(&rx->sk), &rx->srx);
if (IS_ERR(local)) {
ret = PTR_ERR(local);
goto error_unlock;
}
if (service_id) {
write_lock(&local->services_lock);
if (rcu_access_pointer(local->service))
goto service_in_use;
rx->local = local;
rcu_assign_pointer(local->service, rx);
write_unlock(&local->services_lock);
rx->sk.sk_state = RXRPC_SERVER_BOUND;
} else {
rx->local = local;
rx->sk.sk_state = RXRPC_CLIENT_BOUND;
}
break;
case RXRPC_SERVER_BOUND:
ret = -EINVAL;
if (service_id == 0)
goto error_unlock;
ret = -EADDRINUSE;
if (service_id == rx->srx.srx_service)
goto error_unlock;
ret = -EINVAL;
srx->srx_service = rx->srx.srx_service;
if (memcmp(srx, &rx->srx, sizeof(*srx)) != 0)
goto error_unlock;
rx->second_service = service_id;
rx->sk.sk_state = RXRPC_SERVER_BOUND2;
break;
default:
ret = -EINVAL;
goto error_unlock;
}
release_sock(&rx->sk);
_leave(" = 0");
return 0;
service_in_use:
write_unlock(&local->services_lock);
rxrpc_put_local(local);
ret = -EADDRINUSE;
error_unlock:
release_sock(&rx->sk);
error:
_leave(" = %d", ret);
return ret;
}
示例12: get_unused_fd
/*
* Find an empty file descriptor entry, and mark it busy.
*/
int get_unused_fd(void)
{
struct files_struct * files = current->files;
int fd, error;
error = -EMFILE;
write_lock(&files->file_lock);
repeat:
fd = find_next_zero_bit(files->open_fds,
files->max_fdset,
files->next_fd);
/*
* N.B. For clone tasks sharing a files structure, this test
* will limit the total number of files that can be opened.
*/
if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
goto out;
/* Do we need to expand the fdset array? */
if (fd >= files->max_fdset)
{
error = expand_fdset(files, fd);
if (!error)
{
error = -EMFILE;
goto repeat;
}
goto out;
}
/*
* Check whether we need to expand the fd array.
*/
if (fd >= files->max_fds)
{
error = expand_fd_array(files, fd);
if (!error)
{
error = -EMFILE;
goto repeat;
}
goto out;
}
FD_SET(fd, files->open_fds);
FD_CLR(fd, files->close_on_exec);
files->next_fd = fd + 1;
#if 1
/* Sanity check */
if (files->fd[fd] != NULL)
{
printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
files->fd[fd] = NULL;
}
#endif
error = fd;
out:
write_unlock(&files->file_lock);
return error;
}
示例13: osd_attr_set
//.........这里部分代码省略.........
/* do both accounting updates outside oo_attr_lock below */
if ((valid & LA_UID) && (la->la_uid != obj->oo_attr.la_uid)) {
/* Update user accounting. Failure isn't fatal, but we still
* log an error message */
rc = -zap_increment_int(osd->od_os, osd->od_iusr_oid,
la->la_uid, 1, oh->ot_tx);
if (rc)
CERROR("%s: failed to update accounting ZAP for user "
"%d (%d)\n", osd->od_svname, la->la_uid, rc);
rc = -zap_increment_int(osd->od_os, osd->od_iusr_oid,
obj->oo_attr.la_uid, -1, oh->ot_tx);
if (rc)
CERROR("%s: failed to update accounting ZAP for user "
"%d (%d)\n", osd->od_svname,
obj->oo_attr.la_uid, rc);
}
if ((valid & LA_GID) && (la->la_gid != obj->oo_attr.la_gid)) {
/* Update group accounting. Failure isn't fatal, but we still
* log an error message */
rc = -zap_increment_int(osd->od_os, osd->od_igrp_oid,
la->la_gid, 1, oh->ot_tx);
if (rc)
CERROR("%s: failed to update accounting ZAP for user "
"%d (%d)\n", osd->od_svname, la->la_gid, rc);
rc = -zap_increment_int(osd->od_os, osd->od_igrp_oid,
obj->oo_attr.la_gid, -1, oh->ot_tx);
if (rc)
CERROR("%s: failed to update accounting ZAP for user "
"%d (%d)\n", osd->od_svname,
obj->oo_attr.la_gid, rc);
}
write_lock(&obj->oo_attr_lock);
cnt = 0;
if (valid & LA_ATIME) {
osa->atime[0] = obj->oo_attr.la_atime = la->la_atime;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_ATIME(osd), NULL,
osa->atime, 16);
}
if (valid & LA_MTIME) {
osa->mtime[0] = obj->oo_attr.la_mtime = la->la_mtime;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MTIME(osd), NULL,
osa->mtime, 16);
}
if (valid & LA_CTIME) {
osa->ctime[0] = obj->oo_attr.la_ctime = la->la_ctime;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_CTIME(osd), NULL,
osa->ctime, 16);
}
if (valid & LA_MODE) {
/* mode is stored along with type, so read it first */
obj->oo_attr.la_mode = (obj->oo_attr.la_mode & S_IFMT) |
(la->la_mode & ~S_IFMT);
osa->mode = obj->oo_attr.la_mode;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_MODE(osd), NULL,
&osa->mode, 8);
}
if (valid & LA_SIZE) {
osa->size = obj->oo_attr.la_size = la->la_size;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_SIZE(osd), NULL,
&osa->size, 8);
}
if (valid & LA_NLINK) {
osa->nlink = obj->oo_attr.la_nlink = la->la_nlink;
SA_ADD_BULK_ATTR(bulk, cnt, SA_ZPL_LINKS(osd), NULL,
示例14: miscd_dodaemon
static int miscd_dodaemon(char *argv1, char *daemon)
{
struct sigaction act;
char *commandline;
char commbuf[10];
char ch;
if (!check_file_writable(PASSFILE))
{
fprintf(stderr, "Error! File %s is not writable.\n", PASSFILE);
exit(-1);
}
if (!check_file_writable(BOARDS))
{
fprintf(stderr, "Error! File %s is not writable.\n", BOARDS);
exit(-1);
}
truncate(BOARDS, MAXBOARD * sizeof(struct boardheader));
if (load_ucache() != 0) {
printf("ft,load ucache error!");
exit(-1);
}
/* init tmpfs */
sprintf(genbuf1,"%s/home",TMPFSROOT);
mkdir(genbuf1,0700);
sprintf(genbuf1,"%s/boards",TMPFSROOT);
mkdir(genbuf1,0700);
for (ch='A';ch<='Z';ch++) {
sprintf(genbuf1,"%s/home/%c",TMPFSROOT,ch);
mkdir(genbuf1,0700);
}
resolve_boards();
resolve_utmp();
resolve_guest_table();
if (argv1 != NULL) {
switch (fork()) {
case -1:
printf("faint, i can't fork.\n");
exit(0);
break;
case 0:
break;
default:
exit(0);
break;
}
commandline = argv1;
} else {
commandline = commbuf;
}
setsid();
#if defined(FREEBSD) || defined(MACOSX)
setpgid(0, 0);
#else
// by zixia setpgrp(0, 0);
setpgrp();
#endif
#ifdef AIX
act.sa_handler = NULL;
act.sa_flags = SA_RESTART | SA_NOCLDWAIT;
sigaction(SIGCHLD, &act, NULL);
#else
act.sa_handler = reaper;
act.sa_flags = SA_RESTART;
sigaction(SIGCHLD, &act, NULL);
#endif
if (((daemon == NULL) || (!strcmp(daemon, "timed"))) && ((argv1 == NULL) || fork())) {
strcpy(commandline, "timed");
timed();
exit(0);
}
if (((daemon == NULL) || (!strcmp(daemon, "killd"))) && ((argv1 == NULL) || fork())) {
strcpy(commandline, "killd");
char line[20];
const char *path = "var/killd.pid";
int pidfd = open(path, O_RDWR | O_CREAT, 0660);
if (write_lock(pidfd, 0, SEEK_SET, 0) < 0) {
bbslog("3error", "killd had already been started!");
exit(-1);
}
snprintf(line, sizeof(line), "%ld\n", (long)getpid());
ftruncate(pidfd, 0);
write(pidfd, line, strlen(line));
while (1) {
time_t ft;
ft = getnextday4am();
do {
sleep(ft - time(0));
} while (ft > time(0));
if (argv1 == NULL) {
dokilluser();
//doupdategiveupuser();
//.........这里部分代码省略.........
示例15: nf_ct_frag6_queue
//.........这里部分代码省略.........
* in the chain of fragments so far. We must know where to put
* this fragment, right?
*/
prev = NULL;
for (next = fq->fragments; next != NULL; next = next->next) {
if (NFCT_FRAG6_CB(next)->offset >= offset)
break; /* bingo! */
prev = next;
}
/* We found where to put this one. Check for overlap with
* preceding fragment, and, if needed, align things so that
* any overlaps are eliminated.
*/
if (prev) {
int i = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset;
if (i > 0) {
offset += i;
if (end <= offset) {
DEBUGP("overlap\n");
goto err;
}
if (!pskb_pull(skb, i)) {
DEBUGP("Can't pull\n");
goto err;
}
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
skb->ip_summed = CHECKSUM_NONE;
}
}
/* Look for overlap with succeeding segments.
* If we can merge fragments, do it.
*/
while (next && NFCT_FRAG6_CB(next)->offset < end) {
/* overlap is 'i' bytes */
int i = end - NFCT_FRAG6_CB(next)->offset;
if (i < next->len) {
/* Eat head of the next overlapped fragment
* and leave the loop. The next ones cannot overlap.
*/
DEBUGP("Eat head of the overlapped parts.: %d", i);
if (!pskb_pull(next, i))
goto err;
/* next fragment */
NFCT_FRAG6_CB(next)->offset += i;
fq->meat -= i;
if (next->ip_summed != CHECKSUM_UNNECESSARY)
next->ip_summed = CHECKSUM_NONE;
break;
} else {
struct sk_buff *free_it = next;
/* Old fragmnet is completely overridden with
* new one drop it.
*/
next = next->next;
if (prev)
prev->next = next;
else
fq->fragments = next;
fq->meat -= free_it->len;
frag_kfree_skb(free_it, NULL);
}
}
NFCT_FRAG6_CB(skb)->offset = offset;
/* Insert this fragment in the chain of fragments. */
skb->next = next;
if (prev)
prev->next = skb;
else
fq->fragments = skb;
skb->dev = NULL;
skb_get_timestamp(skb, &fq->stamp);
fq->meat += skb->len;
atomic_add(skb->truesize, &nf_ct_frag6_mem);
/* The first fragment.
* nhoffset is obtained from the first fragment, of course.
*/
if (offset == 0) {
fq->nhoffset = nhoff;
fq->last_in |= FIRST_IN;
}
write_lock(&nf_ct_frag6_lock);
list_move_tail(&fq->lru_list, &nf_ct_frag6_lru_list);
write_unlock(&nf_ct_frag6_lock);
return 0;
err:
return -1;
}