kaio
[Top] [All Lists]

File descriptor in siginfo.

To: kaio@xxxxxxxxxxx
Subject: File descriptor in siginfo.
From: Piotr GOLONKA <Piotr.Golonka@xxxxxxx>
Date: Tue, 7 Aug 2001 17:13:34 +0200
Sender: owner-kaio@xxxxxxxxxxx
Hi.
I just slightly modified /usr/src/linux/mm/filemap.c 
in order to have file descriptor passed in
siginfo structure when using SIGEV_SIGNAL as notification method.
As I remember, someone asked for this feature some time in the past.
Maybe someone find it useful...
Sorry, I wont send another patch to the patch, to the patch , etc.: 
here's my version of three modified routines from filemap.c:
Main modifiation is adding the third argument to send_signal()
which allows setting siginfo's si_fd field:
In lio_complete() I put zero as this argument (anyone has better idea?),
and in kaio_io_complete I get filedescriptor from the original
(passed by user) kaiocb->kaio_uaiocb->aio_fildes

-------------------------------------------------------------------------------
static void
send_signal(sigevent_t *sigev, struct task_struct *task, int fd)
{
        if (sigev->sigev_notify == SIGEV_SIGNAL) {
                struct siginfo sinfo;
 
                memset(&sinfo, 0, sizeof(sinfo));
                sinfo.si_signo = sigev->sigev_signo;
                sinfo.si_code = SI_ASYNCIO;
                sinfo.si_value = sigev->sigev_value;
                sinfo.si_fd=fd;
 
                send_sig_info(sigev->sigev_signo, &sinfo, task);
        }
}

static int
lio_complete(liocb_t *liocb, int n, int wakeup)
{
        spin_lock(&liocb->lio_lock);
        liocb->lio_done += n;
        if (liocb->lio_nent == liocb->lio_done) {
                spin_unlock(&liocb->lio_lock);
                if (wakeup) {
                        lock_kernel();
                        wake_up(&liocb->lio_wait);
                        unlock_kernel();
                }
                send_signal(&liocb->lio_sigevent, liocb->lio_task,0);
                if (liocb->lio_mode == LIO_NOWAIT)
                        kfree(liocb);
                return 1;
        }
        if (!wakeup)
                lock_kernel();
        spin_unlock(&liocb->lio_lock);
        return 0;
}

static int
kaio_io_complete(kaiocb_t *kaiocb, int nbytes, int ret, int gc)
{
        aiocb_t *uaiocb = kaiocb->kaio_uaiocb;
        liocb_t *liocb = kaiocb->kaio_liocb;
        int     i;
 
        if (kaiocb->kaio_pages) {
 
                for (i = 0; i < kaiocb->kaio_npages; i++)
                        page_cache_release(kaiocb->kaio_pages[i]);
                if (kaiocb->kaio_pages != &kaiocb->kaio_page_inline)
                        kfree(kaiocb->kaio_pages);
        }
 
#ifdef KAIO_STATS
        if (copy_to_user(&uaiocb->aio_times, &kaiocb->kaio_times,
                        sizeof(unsigned long) * AIO_TIMES))
        {
                ret = -EFAULT;
        } else
#endif
        if (put_user(nbytes, &uaiocb->aio_return))
                ret = -EFAULT;
        /* aio_error does not go through syscall so -ret */
        else if (put_user(-ret, &uaiocb->aio_error))
                ret = -EFAULT;
        else {
                send_signal(&kaiocb->kaio_sigevent, kaiocb->kaio_task,
                            kaiocb->kaio_uaiocb->aio_fildes);
                //kaiocb->kaio_filp->_fileno);
                spin_lock(&kaio_hash_lock);
                if (kaiocb->kaio_suspend_wait) {
                        lock_kernel();
                        kaiocb->kaio_error = -ret;
                        wake_up(kaiocb->kaio_suspend_wait);
                        unlock_kernel();
                } else {
                        kaiocb->kaio_error = -ret;
                        /* gc |= (liocb && liocb->lio_mode == LIO_WAIT); */
                        gc = 1;
                        if (gc)
                                kaio_remove_hash(kaiocb);
                }
                spin_unlock(&kaio_hash_lock);
                if (liocb)
                        lio_complete(liocb, 1, 1);
        }
        if (gc) {
                fput(kaiocb->kaio_filp);
                kfree(kaiocb);
        }
        return ret;
}

--------------------------------------------
Ah, BTW: I use kernel 2.4.2, with
kaio-kern-1.3.1-2.4.2 patch
and a "patch to the patch" sent by
Christopher Smith <x@xxxxxxxx>
to this list on : Sun, 08 Apr 2001 06:32:25 -0700
I'm trying to get it work with TCP sockets and it seems
to be OK for SIGEV_SIGNAL notification method.
Would be nice if SIGEV_THREAD is implemented as well.

        regards:
        Piotr Golonka
        CERN, European Laboratory for High Energy Physics,
        ATLAS Experiment
        e-mail:Piotr.Golonka@xxxxxxx

PS: This is my first hacking inside LINUX kernel, please be forbearing
for a beginner.

<Prev in Thread] Current Thread [Next in Thread>
  • File descriptor in siginfo., Piotr GOLONKA <=