]>
Commit | Line | Data |
---|---|---|
e14748e8 SF |
1 | |
2 | # Copyright (C) 2015-2016 Junjiro R. Okajima | |
3 | # | |
4 | # This program is free software; you can redistribute it and/or modify | |
5 | # it under the terms of the GNU General Public License as published by | |
6 | # the Free Software Foundation; either version 2 of the License, or | |
7 | # (at your option) any later version. | |
8 | # | |
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. | |
13 | # | |
14 | # You should have received a copy of the GNU General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | Support for a branch who has its ->atomic_open() | |
18 | ---------------------------------------------------------------------- | |
19 | The filesystems who implement its ->atomic_open() are not majority. For | |
20 | example NFSv4 does, and aufs should call NFSv4 ->atomic_open, | |
21 | particularly for open(O_CREAT|O_EXCL, 0400) case. Other than | |
22 | ->atomic_open(), NFSv4 returns an error for this open(2). While I am not | |
23 | sure whether all filesystems who have ->atomic_open() behave like this, | |
24 | but NFSv4 surely returns the error. | |
25 | ||
26 | In order to support ->atomic_open() for aufs, there are a few | |
27 | approaches. | |
28 | ||
29 | A. Introduce aufs_atomic_open() | |
30 | - calls one of VFS:do_last(), lookup_open() or atomic_open() for | |
31 | branch fs. | |
32 | B. Introduce aufs_atomic_open() calling create, open and chmod. this is | |
33 | an aufs user Pip Cet's approach | |
34 | - calls aufs_create(), VFS finish_open() and notify_change(). | |
35 | - pass fake-mode to finish_open(), and then correct the mode by | |
36 | notify_change(). | |
37 | C. Extend aufs_open() to call branch fs's ->atomic_open() | |
38 | - no aufs_atomic_open(). | |
39 | - aufs_lookup() registers the TID to an aufs internal object. | |
40 | - aufs_create() does nothing when the matching TID is registered, but | |
41 | registers the mode. | |
42 | - aufs_open() calls branch fs's ->atomic_open() when the matching | |
43 | TID is registered. | |
44 | D. Extend aufs_open() to re-try branch fs's ->open() with superuser's | |
45 | credential | |
46 | - no aufs_atomic_open(). | |
47 | - aufs_create() registers the TID to an internal object. this info | |
48 | represents "this process created this file just now." | |
49 | - when aufs gets EACCES from branch fs's ->open(), then confirm the | |
50 | registered TID and re-try open() with superuser's credential. | |
51 | ||
52 | Pros and cons for each approach. | |
53 | ||
54 | A. | |
55 | - straightforward but highly depends upon VFS internal. | |
56 | - the atomic behavaiour is kept. | |
57 | - some of parameters such as nameidata are hard to reproduce for | |
58 | branch fs. | |
59 | - large overhead. | |
60 | B. | |
61 | - easy to implement. | |
62 | - the atomic behavaiour is lost. | |
63 | C. | |
64 | - the atomic behavaiour is kept. | |
65 | - dirty and tricky. | |
66 | - VFS checks whether the file is created correctly after calling | |
67 | ->create(), which means this approach doesn't work. | |
68 | D. | |
69 | - easy to implement. | |
70 | - the atomic behavaiour is lost. | |
71 | - to open a file with superuser's credential and give it to a user | |
72 | process is a bad idea, since the file object keeps the credential | |
73 | in it. It may affect LSM or something. This approach doesn't work | |
74 | either. | |
75 | ||
76 | The approach A is ideal, but it hard to implement. So here is a | |
77 | variation of A, which is to be implemented. | |
78 | ||
79 | A-1. Introduce aufs_atomic_open() | |
80 | - calls branch fs ->atomic_open() if exists. otherwise calls | |
81 | vfs_create() and finish_open(). | |
82 | - the demerit is that the several checks after branch fs | |
83 | ->atomic_open() are lost. in the ordinary case, the checks are | |
84 | done by VFS:do_last(), lookup_open() and atomic_open(). some can | |
85 | be implemented in aufs, but not all I am afraid. |