[PATCHES] multi-channel: implement network interface info ioctl

Uri Simchoni uri at samba.org
Tue Jan 26 06:22:54 UTC 2016



On 01/26/2016 08:00 AM, Volker Lendecke wrote:
> On Mon, Jan 25, 2016 at 10:52:00AM -0800, Jeremy Allison wrote:
>> It's an explicit error return listed in the man pages, and
>> some network file systems can return it.
>>
>> See here:
>>
>> https://lwn.net/Articles/576478/
>>
>> for an interesting discussion.
> Dunno if it's in that discussion, but I believe somewhere I
> read that Linux deallocates the fd first and only after that
> does the cleanup, which then can fail for some reason. I'd
> call that broken, but between the EINTR and the retry the fd
> might have been opened by another thread. This would be
> really, really bad. Can that be true?
>
> Volker
>
Yep. Here's an excerpt from some randomly-chosen kernel (3.2.54). It 
clearly shows that the FD is released (call to __put_unused_fd(), set 
the file pointer in the table to NULL). Since Linus has a "Don't break 
userspace" mantra, we can be pretty sure that this behavior is 
consistent across all versions.

/*
  * Careful here! We test whether the file pointer is NULL before
  * releasing the fd. This ensures that one clone task can't release
  * an fd while another clone is opening it.
  */
SYSCALL_DEFINE1(close, unsigned int, fd)
{
         struct file * filp;
         struct files_struct *files = current->files;
         struct fdtable *fdt;
         int retval;

         spin_lock(&files->file_lock);
         fdt = files_fdtable(files);
         if (fd >= fdt->max_fds)
                 goto out_unlock;
         filp = fdt->fd[fd];
         if (!filp)
                 goto out_unlock;
         rcu_assign_pointer(fdt->fd[fd], NULL);
         FD_CLR(fd, fdt->close_on_exec);
         __put_unused_fd(files, fd);
         spin_unlock(&files->file_lock);
         retval = filp_close(filp, files);

         /* can't restart close syscall because file table entry was 
cleared */
         if (unlikely(retval == -ERESTARTSYS ||
                      retval == -ERESTARTNOINTR ||
                      retval == -ERESTARTNOHAND ||
                      retval == -ERESTART_RESTARTBLOCK))
                 retval = -EINTR;

         return retval;

out_unlock:
         spin_unlock(&files->file_lock);
         return -EBADF;
}




More information about the samba-technical mailing list