Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / fs / aufs / dynop.c
1 /*
2  * Copyright (C) 2010-2013 Junjiro R. Okajima
3  *
4  * This program, aufs 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, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 /*
20  * dynamically customizable operations for regular files
21  */
22
23 #include "aufs.h"
24
25 #define DyPrSym(key)    AuDbgSym(key->dk_op.dy_hop)
26
27 /*
28  * How large will these lists be?
29  * Usually just a few elements, 20-30 at most for each, I guess.
30  */
31 static struct au_splhead dynop[AuDyLast];
32
33 static struct au_dykey *dy_gfind_get(struct au_splhead *spl, const void *h_op)
34 {
35         struct au_dykey *key, *tmp;
36         struct list_head *head;
37
38         key = NULL;
39         head = &spl->head;
40         rcu_read_lock();
41         list_for_each_entry_rcu(tmp, head, dk_list)
42                 if (tmp->dk_op.dy_hop == h_op) {
43                         key = tmp;
44                         kref_get(&key->dk_kref);
45                         break;
46                 }
47         rcu_read_unlock();
48
49         return key;
50 }
51
52 static struct au_dykey *dy_bradd(struct au_branch *br, struct au_dykey *key)
53 {
54         struct au_dykey **k, *found;
55         const void *h_op = key->dk_op.dy_hop;
56         int i;
57
58         found = NULL;
59         k = br->br_dykey;
60         for (i = 0; i < AuBrDynOp; i++)
61                 if (k[i]) {
62                         if (k[i]->dk_op.dy_hop == h_op) {
63                                 found = k[i];
64                                 break;
65                         }
66                 } else
67                         break;
68         if (!found) {
69                 spin_lock(&br->br_dykey_lock);
70                 for (; i < AuBrDynOp; i++)
71                         if (k[i]) {
72                                 if (k[i]->dk_op.dy_hop == h_op) {
73                                         found = k[i];
74                                         break;
75                                 }
76                         } else {
77                                 k[i] = key;
78                                 break;
79                         }
80                 spin_unlock(&br->br_dykey_lock);
81                 BUG_ON(i == AuBrDynOp); /* expand the array */
82         }
83
84         return found;
85 }
86
87 /* kref_get() if @key is already added */
88 static struct au_dykey *dy_gadd(struct au_splhead *spl, struct au_dykey *key)
89 {
90         struct au_dykey *tmp, *found;
91         struct list_head *head;
92         const void *h_op = key->dk_op.dy_hop;
93
94         found = NULL;
95         head = &spl->head;
96         spin_lock(&spl->spin);
97         list_for_each_entry(tmp, head, dk_list)
98                 if (tmp->dk_op.dy_hop == h_op) {
99                         kref_get(&tmp->dk_kref);
100                         found = tmp;
101                         break;
102                 }
103         if (!found)
104                 list_add_rcu(&key->dk_list, head);
105         spin_unlock(&spl->spin);
106
107         if (!found)
108                 DyPrSym(key);
109         return found;
110 }
111
112 static void dy_free_rcu(struct rcu_head *rcu)
113 {
114         struct au_dykey *key;
115
116         key = container_of(rcu, struct au_dykey, dk_rcu);
117         DyPrSym(key);
118         kfree(key);
119 }
120
121 static void dy_free(struct kref *kref)
122 {
123         struct au_dykey *key;
124         struct au_splhead *spl;
125
126         key = container_of(kref, struct au_dykey, dk_kref);
127         spl = dynop + key->dk_op.dy_type;
128         au_spl_del_rcu(&key->dk_list, spl);
129         call_rcu(&key->dk_rcu, dy_free_rcu);
130 }
131
132 void au_dy_put(struct au_dykey *key)
133 {
134         kref_put(&key->dk_kref, dy_free);
135 }
136
137 /* ---------------------------------------------------------------------- */
138
139 #define DyDbgSize(cnt, op)      AuDebugOn(cnt != sizeof(op)/sizeof(void *))
140
141 #ifdef CONFIG_AUFS_DEBUG
142 #define DyDbgDeclare(cnt)       unsigned int cnt = 0
143 #define DyDbgInc(cnt)           do { cnt++; } while (0)
144 #else
145 #define DyDbgDeclare(cnt)       do {} while (0)
146 #define DyDbgInc(cnt)           do {} while (0)
147 #endif
148
149 #define DySet(func, dst, src, h_op, h_sb) do {                          \
150         DyDbgInc(cnt);                                                  \
151         if (h_op->func) {                                               \
152                 if (src.func)                                           \
153                         dst.func = src.func;                            \
154                 else                                                    \
155                         AuDbg("%s %s\n", au_sbtype(h_sb), #func);       \
156         }                                                               \
157 } while (0)
158
159 #define DySetForce(func, dst, src) do {         \
160         AuDebugOn(!src.func);                   \
161         DyDbgInc(cnt);                          \
162         dst.func = src.func;                    \
163 } while (0)
164
165 #define DySetAop(func) \
166         DySet(func, dyaop->da_op, aufs_aop, h_aop, h_sb)
167 #define DySetAopForce(func) \
168         DySetForce(func, dyaop->da_op, aufs_aop)
169
170 static void dy_aop(struct au_dykey *key, const void *h_op,
171                    struct super_block *h_sb __maybe_unused)
172 {
173         struct au_dyaop *dyaop = (void *)key;
174         const struct address_space_operations *h_aop = h_op;
175         DyDbgDeclare(cnt);
176
177         AuDbg("%s\n", au_sbtype(h_sb));
178
179         DySetAop(writepage);
180         DySetAopForce(readpage);        /* force */
181         DySetAop(writepages);
182         DySetAop(set_page_dirty);
183         DySetAop(readpages);
184         DySetAop(write_begin);
185         DySetAop(write_end);
186         DySetAop(bmap);
187         DySetAop(invalidatepage);
188         DySetAop(releasepage);
189         DySetAop(freepage);
190         /* these two will be changed according to an aufs mount option */
191         DySetAop(direct_IO);
192         DySetAop(get_xip_mem);
193         DySetAop(migratepage);
194         DySetAop(launder_page);
195         DySetAop(is_partially_uptodate);
196         DySetAop(error_remove_page);
197
198         DyDbgSize(cnt, *h_aop);
199         dyaop->da_get_xip_mem = h_aop->get_xip_mem;
200 }
201
202 /* ---------------------------------------------------------------------- */
203
204 static void dy_bug(struct kref *kref)
205 {
206         BUG();
207 }
208
209 static struct au_dykey *dy_get(struct au_dynop *op, struct au_branch *br)
210 {
211         struct au_dykey *key, *old;
212         struct au_splhead *spl;
213         struct op {
214                 unsigned int sz;
215                 void (*set)(struct au_dykey *key, const void *h_op,
216                             struct super_block *h_sb __maybe_unused);
217         };
218         static const struct op a[] = {
219                 [AuDy_AOP] = {
220                         .sz     = sizeof(struct au_dyaop),
221                         .set    = dy_aop
222                 }
223         };
224         const struct op *p;
225
226         spl = dynop + op->dy_type;
227         key = dy_gfind_get(spl, op->dy_hop);
228         if (key)
229                 goto out_add; /* success */
230
231         p = a + op->dy_type;
232         key = kzalloc(p->sz, GFP_NOFS);
233         if (unlikely(!key)) {
234                 key = ERR_PTR(-ENOMEM);
235                 goto out;
236         }
237
238         key->dk_op.dy_hop = op->dy_hop;
239         kref_init(&key->dk_kref);
240         p->set(key, op->dy_hop, au_br_sb(br));
241         old = dy_gadd(spl, key);
242         if (old) {
243                 kfree(key);
244                 key = old;
245         }
246
247 out_add:
248         old = dy_bradd(br, key);
249         if (old)
250                 /* its ref-count should never be zero here */
251                 kref_put(&key->dk_kref, dy_bug);
252 out:
253         return key;
254 }
255
256 /* ---------------------------------------------------------------------- */
257 /*
258  * Aufs prohibits O_DIRECT by defaut even if the branch supports it.
259  * This behaviour is neccessary to return an error from open(O_DIRECT) instead
260  * of the succeeding I/O. The dio mount option enables O_DIRECT and makes
261  * open(O_DIRECT) always succeed, but the succeeding I/O may return an error.
262  * See the aufs manual in detail.
263  *
264  * To keep this behaviour, aufs has to set NULL to ->get_xip_mem too, and the
265  * performance of fadvise() and madvise() may be affected.
266  */
267 static void dy_adx(struct au_dyaop *dyaop, int do_dx)
268 {
269         if (!do_dx) {
270                 dyaop->da_op.direct_IO = NULL;
271                 dyaop->da_op.get_xip_mem = NULL;
272         } else {
273                 dyaop->da_op.direct_IO = aufs_aop.direct_IO;
274                 dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem;
275                 if (!dyaop->da_get_xip_mem)
276                         dyaop->da_op.get_xip_mem = NULL;
277         }
278 }
279
280 static struct au_dyaop *dy_aget(struct au_branch *br,
281                                 const struct address_space_operations *h_aop,
282                                 int do_dx)
283 {
284         struct au_dyaop *dyaop;
285         struct au_dynop op;
286
287         op.dy_type = AuDy_AOP;
288         op.dy_haop = h_aop;
289         dyaop = (void *)dy_get(&op, br);
290         if (IS_ERR(dyaop))
291                 goto out;
292         dy_adx(dyaop, do_dx);
293
294 out:
295         return dyaop;
296 }
297
298 int au_dy_iaop(struct inode *inode, aufs_bindex_t bindex,
299                 struct inode *h_inode)
300 {
301         int err, do_dx;
302         struct super_block *sb;
303         struct au_branch *br;
304         struct au_dyaop *dyaop;
305
306         AuDebugOn(!S_ISREG(h_inode->i_mode));
307         IiMustWriteLock(inode);
308
309         sb = inode->i_sb;
310         br = au_sbr(sb, bindex);
311         do_dx = !!au_opt_test(au_mntflags(sb), DIO);
312         dyaop = dy_aget(br, h_inode->i_mapping->a_ops, do_dx);
313         err = PTR_ERR(dyaop);
314         if (IS_ERR(dyaop))
315                 /* unnecessary to call dy_fput() */
316                 goto out;
317
318         err = 0;
319         inode->i_mapping->a_ops = &dyaop->da_op;
320
321 out:
322         return err;
323 }
324
325 /*
326  * Is it safe to replace a_ops during the inode/file is in operation?
327  * Yes, I hope so.
328  */
329 int au_dy_irefresh(struct inode *inode)
330 {
331         int err;
332         aufs_bindex_t bstart;
333         struct inode *h_inode;
334
335         err = 0;
336         if (S_ISREG(inode->i_mode)) {
337                 bstart = au_ibstart(inode);
338                 h_inode = au_h_iptr(inode, bstart);
339                 err = au_dy_iaop(inode, bstart, h_inode);
340         }
341         return err;
342 }
343
344 void au_dy_arefresh(int do_dx)
345 {
346         struct au_splhead *spl;
347         struct list_head *head;
348         struct au_dykey *key;
349
350         spl = dynop + AuDy_AOP;
351         head = &spl->head;
352         spin_lock(&spl->spin);
353         list_for_each_entry(key, head, dk_list)
354                 dy_adx((void *)key, do_dx);
355         spin_unlock(&spl->spin);
356 }
357
358 /* ---------------------------------------------------------------------- */
359
360 void __init au_dy_init(void)
361 {
362         int i;
363
364         /* make sure that 'struct au_dykey *' can be any type */
365         BUILD_BUG_ON(offsetof(struct au_dyaop, da_key));
366
367         for (i = 0; i < AuDyLast; i++)
368                 au_spl_init(dynop + i);
369 }
370
371 void au_dy_fin(void)
372 {
373         int i;
374
375         for (i = 0; i < AuDyLast; i++)
376                 WARN_ON(!list_empty(&dynop[i].head));
377 }