~ubuntu-branches/ubuntu/vivid/aufs/vivid

« back to all changes in this revision

Viewing changes to fs/aufs/wkq.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2007-12-15 23:32:51 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20071215233251-2vgs2lmg8mai5d9e
Tags: 0+20071211-1ubuntu1
* Merge from debian unstable (LP: #175705), remaining changes:
  - Fix for Ubuntu Kernels (updated)
* patches/01_vserver.dpatch: Removed
* patches/06_ubuntu.dpatch: Added (update of ubuntu patch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
17
 */
18
18
 
19
 
/* $Id: wkq.c,v 1.17 2007/06/04 02:17:35 sfjro Exp $ */
 
19
/* $Id: wkq.c,v 1.25 2007/10/22 02:14:17 sfjro Exp $ */
20
20
 
21
21
#include <linux/module.h>
22
22
#include "aufs.h"
25
25
 
26
26
struct au_cred {
27
27
#ifdef CONFIG_AUFS_DLGT
 
28
        int umask;
28
29
        uid_t fsuid;
29
30
        gid_t fsgid;
30
31
        kernel_cap_t cap_effective, cap_inheritable, cap_permitted;
55
56
#ifdef CONFIG_AUFS_DLGT
56
57
static void cred_store(struct au_cred *cred)
57
58
{
 
59
        cred->umask = current->fs->umask;
58
60
        cred->fsuid = current->fsuid;
59
61
        cred->fsgid = current->fsgid;
60
62
        cred->cap_effective = current->cap_effective;
64
66
 
65
67
static void cred_revert(struct au_cred *cred)
66
68
{
67
 
        AuDebugOn(!is_au_wkq(current));
 
69
        AuDebugOn(!au_test_wkq(current));
 
70
        current->fs->umask = cred->umask;
68
71
        current->fsuid = cred->fsuid;
69
72
        current->fsgid = cred->fsgid;
70
73
        current->cap_effective = cred->cap_effective;
97
100
 
98
101
static int enqueue(struct au_wkq *wkq, struct au_wkinfo *wkinfo)
99
102
{
100
 
        TraceEnter();
 
103
        AuTraceEnter();
101
104
        wkinfo->busyp = &wkq->busy;
102
105
        update_busy(wkq, wkinfo);
103
106
        if (wkinfo->wait)
111
114
        unsigned int idle, n;
112
115
        int i, idle_idx;
113
116
 
114
 
        TraceEnter();
 
117
        AuTraceEnter();
115
118
 
116
119
        while (1) {
117
120
                if (wkinfo->wait) {
126
129
                                        idle_idx = i;
127
130
                                        idle = n;
128
131
                                }
129
 
                                atomic_dec(&au_wkq[i].busy);
 
132
                                atomic_dec_return(&au_wkq[i].busy);
130
133
                        }
131
134
                } else
132
135
                        idle_idx = aufs_nwkq;
133
136
 
134
 
                atomic_inc(&au_wkq[idle_idx].busy);
 
137
                atomic_inc_return(&au_wkq[idle_idx].busy);
135
138
                if (!enqueue(au_wkq + idle_idx, wkinfo))
136
139
                        return; /* success */
137
140
 
138
141
                /* impossible? */
139
 
                Warn1("failed to queue_work()\n");
 
142
                AuWarn1("failed to queue_work()\n");
140
143
                yield();
141
144
        }
142
145
}
161
164
#else
162
165
        wkinfo->func(wkinfo->args);
163
166
#endif
164
 
        atomic_dec(wkinfo->busyp);
 
167
        atomic_dec_return(wkinfo->busyp);
165
168
        if (wkinfo->wait)
166
169
                complete(wkinfo->comp);
167
170
        else {
168
171
                sbinfo = stosi(wkinfo->sb);
169
 
#if 0
 
172
#if 0 // rfu
170
173
                if (atomic_dec_and_test(&sbinfo->si_wkq_nowait))
171
174
                        wake_up_all(&sbinfo->si_wkq_nowait_wq);
172
175
#endif
177
180
}
178
181
 
179
182
int au_wkq_run(au_wkq_func_t func, void *args, struct super_block *sb,
180
 
               int dlgt, int do_wait)
 
183
               struct au_wkq_flags *flags)
181
184
{
182
185
        int err;
183
186
        //int queued;
187
190
        struct au_wkinfo _wkinfo = {
188
191
                //.sb   = sb,
189
192
                .wait   = 1,
190
 
                .dlgt   = !!dlgt,
 
193
                .dlgt   = flags->dlgt,
191
194
                .func   = func,
192
195
                .args   = args,
193
196
                .comp   = &comp
194
197
        }, *wkinfo = &_wkinfo;
195
198
 
196
 
        LKTRTrace("dlgt %d, do_wait %d\n", dlgt, do_wait);
197
 
        AuDebugOn(is_au_wkq(current));
 
199
        LKTRTrace("dlgt %d, do_wait %d\n", flags->dlgt, flags->wait);
 
200
        AuDebugOn(au_test_wkq(current));
198
201
 
199
202
        err = 0;
200
203
        sbinfo = NULL;
201
 
        if (unlikely(!do_wait)) {
 
204
        if (unlikely(!flags->wait)) {
202
205
                AuDebugOn(!sb);
203
206
                /*
204
207
                 * wkq_func() must free this wkinfo.
205
208
                 * it highly depends upon the implementation of workqueue.
206
209
                 */
207
210
                err = -ENOMEM;
208
 
                wkinfo = kmalloc(sizeof(*wkinfo), GFP_KERNEL);
 
211
                wkinfo = kmalloc(sizeof(*wkinfo), GFP_TEMPORARY);
209
212
                if (unlikely(!wkinfo))
210
213
                        goto out;
211
214
                err = 0;
212
215
                wkinfo->sb = sb;
213
216
                wkinfo->wait = 0;
214
 
                wkinfo->dlgt = !!dlgt;
 
217
                wkinfo->dlgt = flags->dlgt;
215
218
                wkinfo->func = func;
216
219
                wkinfo->args = args;
217
220
                wkinfo->comp = NULL;
219
222
                __module_get(THIS_MODULE);
220
223
                sbinfo = stosi(sb);
221
224
                au_mntget(sb);
222
 
                //atomic_inc(&sbinfo->si_wkq_nowait);
223
225
        }
224
226
 
225
227
        AuInitWkq(&wkinfo->wk, wkq_func);
226
228
#ifdef CONFIG_AUFS_DLGT
227
 
        if (dlgt)
 
229
        if (flags->dlgt)
228
230
                cred_store(&wkinfo->cred);
229
231
#endif
230
232
 
231
233
        do_wkq(wkinfo);
232
 
#if 0
 
234
#if 0 // remove
233
235
        /* never fail */
234
236
        queued = 0;
235
237
        wkq = sbinfo->si_wkq;
236
238
        while (1) {
237
 
                if (do_wait)
 
239
                if (flags->wait)
238
240
                        queued = queue_work(wkq, &wkinfo->wk);
239
241
                else
240
242
                        queued = schedule_work(&wkinfo->wk);
247
249
        }
248
250
#endif
249
251
 
250
 
        if (do_wait)
 
252
        if (flags->wait)
251
253
                /* no timeout, no interrupt */
252
254
                wait_for_completion(wkinfo->comp);
253
255
 out:
254
 
        TraceErr(err);
 
256
        AuTraceErr(err);
255
257
        return err;
256
258
}
257
259
 
 
260
/* ---------------------------------------------------------------------- */
 
261
 
258
262
void au_wkq_fin(void)
259
263
{
260
264
        int i;
261
265
 
262
 
        TraceEnter();
 
266
        AuTraceEnter();
263
267
 
264
268
        for (i = 0; i < aufs_nwkq; i++)
265
269
                if (au_wkq[i].q && !IS_ERR(au_wkq[i].q))
299
303
        atomic_set(&nowaitq->busy, 0);
300
304
        nowaitq->max_busy = 0;
301
305
        nowaitq->q = NULL;
 
306
        //smp_mb(); /* atomic_set */
302
307
 
303
308
#if 0 // test accouting
304
309
        if (!err) {
305
 
                static void f(void *args) {
 
310
                static void f(void *args)
 
311
                {
306
312
                        DbgSleep(1);
307
313
                }
308
314
                int i;
318
324
#endif
319
325
 
320
326
 out:
321
 
        TraceErr(err);
 
327
        AuTraceErr(err);
322
328
        return err;
323
329
}