Move down the become_root()/unbecome_root() calls into the VFS modules
authorVolker Lendecke <vl@samba.org>
Mon, 18 May 2009 11:30:16 +0000 (13:30 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 18 May 2009 11:38:56 +0000 (13:38 +0200)
The aio_fork module does not need this, as it does not communicate via signals
but with pipes. Watching a strace log with those become_root() calls in aio.c
is absolutely awful, and it does affect performance.

source3/modules/vfs_default.c
source3/smbd/aio.c

index 6c1946a99d042be80ef7db2f872226bb7cf0e7d2..aa207056b3bdfd9d2e1643e6597c9703ea27a554 100644 (file)
@@ -1423,12 +1423,32 @@ static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_stru
 
 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
 {
-       return sys_aio_read(aiocb);
+       int ret;
+       /*
+        * aio_read must be done as root, because in the glibc aio
+        * implementation the helper thread needs to be able to send a signal
+        * to the main thread, even when it has done a seteuid() to a
+        * different user.
+        */
+       become_root();
+       ret = sys_aio_read(aiocb);
+       unbecome_root();
+       return ret;
 }
 
 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
 {
-       return sys_aio_write(aiocb);
+       int ret;
+       /*
+        * aio_write must be done as root, because in the glibc aio
+        * implementation the helper thread needs to be able to send a signal
+        * to the main thread, even when it has done a seteuid() to a
+        * different user.
+        */
+       become_root();
+       ret = sys_aio_write(aiocb);
+       unbecome_root();
+       return ret;
 }
 
 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
index 77616be48c669ab4a7ab58fda11dae2bdd8cc1bc..a5eea0a32e703709a9ab0f66fab1b7683e6bb1e0 100644 (file)
@@ -179,10 +179,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
        a->aio_sigevent.sigev_signo  = RT_SIGNAL_AIO;
        a->aio_sigevent.sigev_value.sival_int = req->mid;
 
-       become_root();
        ret = SMB_VFS_AIO_READ(fsp, a);
-       unbecome_root();
-
        if (ret == -1) {
                DEBUG(0,("schedule_aio_read_and_X: aio_read failed. "
                         "Error %s\n", strerror(errno) ));
@@ -277,10 +274,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
        a->aio_sigevent.sigev_signo  = RT_SIGNAL_AIO;
        a->aio_sigevent.sigev_value.sival_int = req->mid;
 
-       become_root();
        ret = SMB_VFS_AIO_WRITE(fsp, a);
-       unbecome_root();
-
        if (ret == -1) {
                DEBUG(3,("schedule_aio_wrote_and_X: aio_write failed. "
                         "Error %s\n", strerror(errno) ));