4

For example , I have two processes A and B that try to open a special file (/dev/example) . The driver has an open method that initializes a structure (struct c) and passes it to filp->private_data . When afterwards process B opens the same special file , what happens If I understand correct is that we will have two instances of struct file (two filp pointers that point to the same struct file). Is the open method going to initialize struct C again and pass it to filp->private_data and what will happen to the one process A initialized ?

chrk
  • 4,037
  • 2
  • 39
  • 47
mark4rd
  • 255
  • 5
  • 12
  • What function are you using to open it? – Patrick Collins Aug 25 '14 at 13:51
  • with `open()` . Would different functions have different results? – mark4rd Aug 25 '14 at 13:56
  • I don't think so, it appears that `open` is a wrapper around a system call, I was mostly wondering what documentation to look for. – Patrick Collins Aug 25 '14 at 14:08
  • 1
    I suppose that would depend quite a bit on how the driver is actually implemented. In some cases, it would make sense to initialize a single struct and return that to every caller to `open()`. In others, it would make sense to generate a unique struct for every user. There's no way to tell which is appropriate in this case without more information on the driver (probably including code)... – twalberg Aug 25 '14 at 14:22
  • Thanks for the reply. As far as I know , no one returns any struct to any caller. Each file has a specific struct file that represents it and it is passed to any function that operates on the file . The question is general and not about a specific driver . – mark4rd Aug 25 '14 at 14:38
  • If using `O_APPEND` with `fopen()` both processes could write to the file at the same file I believe... – shkschneider Aug 25 '14 at 15:39

1 Answers1

1

When afterwards process B opens the same special file , what happens If I understand correct is that we will have two instances of struct file (two filp pointers that point to the same struct file).

This is wrong. Every open(2) is matched with one struct file. Quoting from LDD3/Chapter3 :

The file structure represents an open file. (It is not specific to device drivers; every open file in the system has an associated struct file in kernel space.) It is created by the kernel on open and is passed to any function that operates on the file, until the last close. After all instances of the file are closed, the kernel releases the data structure.

For two processes to share the same struct file, they have to have acquired their respective file descriptor via the same open(2) system call. This would mean that they either have a parent-child relationship (parent issues open(2), then fork(2)s the child, so that the returned file descriptor will be inherited from the parent to the child), or they could be pthreads that access the same file descriptor.

In your case, assuming that processes A and B do not have a parent-child relationship, they issue a separate open(2) system call each. Therefore, they are associated with a different struct file each. As a result, each of them is expected to allocate, initialize and store (in its filp->private_data) a distinct struct C.

What they do always share (and possibly confused you) is the struct inode, which refers to the special file.


EDIT: As noted in the comments (by @twalberg), this is indeed highly-dependent on the driver. In general, filp->private_data is part of Linux kernel's driver API to allow separate state per open(2). However, depending on the driver, sometimes it might indeed be sensible to associate multiple different struct files to the same stored state instead.

chrk
  • 4,037
  • 2
  • 39
  • 47
  • 1
    "For two processes to share the same `struct file`, they have to have a parent-child relationship" — or they used FD passing over a UNIX domain socket. See: http://stackoverflow.com/q/909064/149341 –  Aug 25 '14 at 15:54