atomic_sub(ctx->max_reqs, &aio_nr); ctx->max_reqs = 0;	/* prevent __put_ioctx from sub'ing aio_nr */ 
static struct kioctx *ioctx_alloc(unsigned nr_events){	struct mm_struct *mm;	struct kioctx *ctx;	/* Prevent overflows */	if ((nr_events > (0x10000000U / sizeof(struct io_event))) ||	    (nr_events > (0x10000000U / sizeof(struct kiocb)))) {		pr_debug("ENOMEM: nr_events too high\n");		return ERR_PTR(-EINVAL);	}	if (nr_events > aio_max_nr)		return ERR_PTR(-EAGAIN);	ctx = kmem_cache_alloc(kioctx_cachep, GFP_KERNEL);	if (!ctx)		return ERR_PTR(-ENOMEM);	memset(ctx, 0, sizeof(*ctx));	ctx->max_reqs = nr_events;	mm = ctx->mm = current->mm;	atomic_inc(&mm->mm_count);	atomic_set(&ctx->users, 1);	spin_lock_init(&ctx->ctx_lock);	spin_lock_init(&ctx->ring_info.ring_lock);	init_waitqueue_head(&ctx->wait);	INIT_LIST_HEAD(&ctx->active_reqs);	INIT_LIST_HEAD(&ctx->run_list);	INIT_WORK(&ctx->wq, aio_kick_handler, ctx);	if (aio_setup_ring(ctx) < 0)		goto out_freectx;	/* limit the number of system wide aios */	atomic_add(ctx->max_reqs, &aio_nr);	/* undone by __put_ioctx */	if (unlikely(atomic_read(&aio_nr) > aio_max_nr))		goto out_cleanup;	/* now link into global list.  kludge.  FIXME */	write_lock(&mm->ioctx_list_lock);	ctx->next = mm->ioctx_list;	mm->ioctx_list = ctx;	write_unlock(&mm->ioctx_list_lock);	dprintk("aio: allocated ioctx %p[%ld]: mm=%p mask=0x%x\n",		ctx, ctx->user_id, current->mm, ctx->ring_info.nr);	return ctx;out_cleanup:	atomic_sub(ctx->max_reqs, &aio_nr);	ctx->max_reqs = 0;	/* prevent __put_ioctx from sub'ing aio_nr */	__put_ioctx(ctx);	return ERR_PTR(-EAGAIN);out_freectx:	mmdrop(mm);	kmem_cache_free(kioctx_cachep, ctx);	ctx = ERR_PTR(-ENOMEM);	dprintk("aio: error allocating ioctx %p\n", ctx);	return ctx;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/d55b5fdaf40846221d543937b786956e27837fda/aio.c/clean/fs/aio.c