~ubuntu-branches/ubuntu/quantal/aufs/quantal

« back to all changes in this revision

Viewing changes to fs/aufs/vfsub.c

  • Committer: Bazaar Package Importer
  • Author(s): Julian Andres Klode
  • Date: 2008-04-01 18:26:37 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080401182637-ujuqq47eiggw4y5w
Tags: 0+20080401-1
* New upstream snapshot
  - Remove bashisms in script (Closes: #471288)
* debian/conf.mk, linux-patch-aufs.kpatches.sysfs_get_dentry:
  - Remove support for this patch, no longer used
* debian/conf.mk:
  - Add hacks for arm to armel (Closes: #473767)
* debian/control:
  - Add Dm-Upload-Allowed
* debian/copyright:
  - Use http://wiki.debian.org/Proposals/CopyrightFormat
* debian/linux-patch-aufs.kpatches.{splice,put_filp}:
  - Add support for Kernel 2.6.24 (and 2.6.25)
* debian/patches:
  - 01_vserver_apparmor: Update patch
  - 06_rt: Add patch for realtime kernel
  - 07_splice_hack: Add hack to support splice operations (Closes: #473430)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2007 Junjiro Okajima
 
2
 * Copyright (C) 2007, 2008 Junjiro Okajima
3
3
 *
4
4
 * This program, aufs is free software; you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
16
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
17
 */
18
18
 
19
 
/* $Id: vfsub.c,v 1.26 2008/01/28 05:01:42 sfjro Exp $ */
 
19
/* $Id: vfsub.c,v 1.32 2008/03/16 23:44:47 sfjro Exp $ */
20
20
// I'm going to slightly mad
21
21
 
22
22
#include "aufs.h"
81
81
 
82
82
/* ---------------------------------------------------------------------- */
83
83
 
84
 
#if 0
85
84
int do_vfsub_create(struct inode *dir, struct dentry *dentry, int mode,
86
85
                    struct nameidata *nd)
87
86
{
88
87
        int err;
89
 
        struct dentry *parent;
90
88
        struct vfsmount *mnt;
91
89
 
92
90
        LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
 
91
        IMustLock(dir);
93
92
 
94
 
        err = -EIO;
95
 
        parent = dget_parent(dentry);
96
 
        if (parent->d_inode == dir) {
97
 
                IMustLock(dir);
98
 
                err = vfs_create(dir, dentry, mode, nd);
99
 
        }
 
93
        err = vfs_create(dir, dentry, mode, nd);
100
94
        if (!err) {
101
95
                mnt = NULL;
102
96
                if (nd)
103
97
                        mnt = nd->mnt;
104
 
                au_update_fuse_h_inode(mnt, parent); /*ignore*/
 
98
                /* dir inode is locked */
 
99
                au_update_fuse_h_inode(mnt, dentry->d_parent); /*ignore*/
105
100
                au_update_fuse_h_inode(mnt, dentry); /*ignore*/
106
101
        }
107
 
        dput(parent);
108
 
        AuTraceErr(err);
109
102
        return err;
110
103
}
111
104
 
113
106
                     const char *symname, int mode)
114
107
{
115
108
        int err;
116
 
        struct dentry *parent;
117
109
 
118
110
        LKTRTrace("i%lu, %.*s, %s, 0x%x\n",
119
111
                  dir->i_ino, AuDLNPair(dentry), symname, mode);
 
112
        IMustLock(dir);
120
113
 
121
 
        err = -EIO;
122
 
        parent = dget_parent(dentry);
123
 
        if (parent->d_inode == dir) {
124
 
                IMustLock(dir);
125
 
                err = vfs_symlink(dir, dentry, symname, mode);
126
 
        }
 
114
        err = vfs_symlink(dir, dentry, symname, mode);
127
115
        if (!err) {
128
 
                au_update_fuse_h_inode(NULL, parent); /*ignore*/
 
116
                /* dir inode is locked */
 
117
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
129
118
                au_update_fuse_h_inode(NULL, dentry); /*ignore*/
130
119
        }
131
 
        dput(parent);
132
 
        AuTraceErr(err);
133
120
        return err;
134
121
}
135
122
 
137
124
                   dev_t dev)
138
125
{
139
126
        int err;
140
 
        struct dentry *parent;
141
 
 
142
 
        LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
143
 
 
144
 
        err = -EIO;
145
 
        parent = dget_parent(dentry);
146
 
        if (parent->d_inode == dir) {
147
 
                IMustLock(dir);
148
 
                err = vfs_mknod(dir, dentry, mode, dev);
149
 
        }
150
 
        if (!err) {
151
 
                au_update_fuse_h_inode(NULL, parent); /*ignore*/
152
 
                au_update_fuse_h_inode(NULL, dentry); /*ignore*/
153
 
        }
154
 
        dput(parent);
155
 
        AuTraceErr(err);
156
 
        return err;
157
 
}
158
 
 
159
 
int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode)
160
 
{
161
 
        int err;
162
 
        struct dentry *parent;
163
 
 
164
 
        LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
165
 
 
166
 
        err = -EIO;
167
 
        parent = dget_parent(dentry);
168
 
        if (parent->d_inode == dir) {
169
 
                IMustLock(dir);
170
 
                err = vfs_mkdir(dir, dentry, mode);
171
 
        }
172
 
        if (!err) {
173
 
                au_update_fuse_h_inode(NULL, parent); /*ignore*/
174
 
                au_update_fuse_h_inode(NULL, dentry); /*ignore*/
175
 
        }
176
 
        dput(parent);
177
 
        AuTraceErr(err);
 
127
 
 
128
        LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
 
129
        IMustLock(dir);
 
130
 
 
131
        err = vfs_mknod(dir, dentry, mode, dev);
 
132
        if (!err) {
 
133
                /* dir inode is locked */
 
134
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
 
135
                au_update_fuse_h_inode(NULL, dentry); /*ignore*/
 
136
        }
178
137
        return err;
179
138
}
180
139
 
182
141
                  struct dentry *dentry)
183
142
{
184
143
        int err;
185
 
        struct dentry *parent;
186
144
 
187
145
        LKTRTrace("%.*s, i%lu, %.*s\n",
188
146
                  AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry));
 
147
        IMustLock(dir);
189
148
 
190
 
        err = -EIO;
191
 
        parent = dget_parent(dentry);
192
 
        if (parent->d_inode == dir) {
193
 
                IMustLock(dir);
194
 
                lockdep_off();
195
 
                err = vfs_link(src_dentry, dir, dentry);
196
 
                lockdep_on();
197
 
        }
 
149
        lockdep_off();
 
150
        err = vfs_link(src_dentry, dir, dentry);
 
151
        lockdep_on();
198
152
        if (!err) {
199
153
                LKTRTrace("src_i %p, dst_i %p\n",
200
154
                          src_dentry->d_inode, dentry->d_inode);
201
155
                /* fuse has different memory inode for the same inumber */
202
156
                au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/
203
 
                au_update_fuse_h_inode(NULL, parent); /*ignore*/
 
157
                /* dir inode is locked */
 
158
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
204
159
                au_update_fuse_h_inode(NULL, dentry); /*ignore*/
205
160
        }
206
 
        dput(parent);
207
 
        AuTraceErr(err);
208
161
        return err;
209
162
}
210
163
 
212
165
                    struct inode *dir, struct dentry *dentry)
213
166
{
214
167
        int err;
215
 
        struct dentry *parent, *src_parent;
216
168
 
217
169
        LKTRTrace("i%lu, %.*s, i%lu, %.*s\n",
218
170
                  src_dir->i_ino, AuDLNPair(src_dentry),
219
171
                  dir->i_ino, AuDLNPair(dentry));
 
172
        IMustLock(dir);
 
173
        IMustLock(src_dir);
220
174
 
221
 
        err = -ENOENT;
222
 
        parent = NULL;
223
 
        src_parent = dget_parent(src_dentry);
224
 
        if (src_parent->d_inode == src_dir) {
225
 
                err = -EIO;
226
 
                parent = dget_parent(dentry);
227
 
                if (parent->d_inode == dir)
228
 
                        err = 0;
229
 
        }
230
 
        if (!err) {
231
 
                IMustLock(dir);
232
 
                IMustLock(src_dir);
233
 
                lockdep_off();
234
 
                err = vfs_rename(src_dir, src_dentry, dir, dentry);
235
 
                lockdep_on();
236
 
                AuTraceErr(err);
237
 
        }
238
 
        if (!err) {
239
 
                au_update_fuse_h_inode(NULL, parent); /*ignore*/
240
 
                au_update_fuse_h_inode(NULL, src_parent); /*ignore*/
 
175
        lockdep_off();
 
176
        err = vfs_rename(src_dir, src_dentry, dir, dentry);
 
177
        lockdep_on();
 
178
        if (!err) {
 
179
                /* dir inode is locked */
 
180
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
 
181
                au_update_fuse_h_inode(NULL, src_dentry->d_parent); /*ignore*/
241
182
                au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/
242
183
        }
243
 
        dput(parent);
244
 
        dput(src_parent);
245
 
        AuTraceErr(err);
 
184
        return err;
 
185
}
 
186
 
 
187
int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
188
{
 
189
        int err;
 
190
 
 
191
        LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
 
192
        IMustLock(dir);
 
193
 
 
194
        err = vfs_mkdir(dir, dentry, mode);
 
195
        if (!err) {
 
196
                /* dir inode is locked */
 
197
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
 
198
                au_update_fuse_h_inode(NULL, dentry); /*ignore*/
 
199
        }
246
200
        return err;
247
201
}
248
202
 
249
203
int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry)
250
204
{
251
205
        int err;
252
 
        struct dentry *parent;
253
206
 
254
207
        LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
 
208
        IMustLock(dir);
255
209
 
256
 
        err = -ENOENT;
257
 
        parent = dget_parent(dentry);
258
 
        if (parent->d_inode == dir) {
259
 
                IMustLock(dir);
260
 
                lockdep_off();
261
 
                err = vfs_rmdir(dir, dentry);
262
 
                lockdep_on();
263
 
        }
 
210
        lockdep_off();
 
211
        err = vfs_rmdir(dir, dentry);
 
212
        lockdep_on();
 
213
        /* dir inode is locked */
264
214
        if (!err)
265
 
                au_update_fuse_h_inode(NULL, parent); /*ignore*/
266
 
        dput(parent);
267
 
        AuTraceErr(err);
 
215
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
268
216
        return err;
269
217
}
270
218
 
271
219
int do_vfsub_unlink(struct inode *dir, struct dentry *dentry)
272
220
{
273
221
        int err;
274
 
        struct dentry *parent;
275
222
 
276
223
        LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
277
 
 
278
 
        err = -ENOENT;
279
 
        parent = dget_parent(dentry);
280
 
        if (parent->d_inode == dir) {
281
 
                IMustLock(dir);
282
 
                /* vfs_unlink() locks inode */
 
224
        IMustLock(dir);
 
225
 
 
226
        /* vfs_unlink() locks inode */
 
227
        lockdep_off();
 
228
        err = vfs_unlink(dir, dentry);
 
229
        lockdep_on();
 
230
        /* dir inode is locked */
 
231
        if (!err)
 
232
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
 
233
        return err;
 
234
}
 
235
 
 
236
/* ---------------------------------------------------------------------- */
 
237
 
 
238
ssize_t do_vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
 
239
                        loff_t *ppos)
 
240
{
 
241
        ssize_t err;
 
242
 
 
243
        LKTRTrace("%.*s, cnt %lu, pos %Ld\n",
 
244
                  AuDLNPair(file->f_dentry), (unsigned long)count, *ppos);
 
245
 
 
246
        if (0 /*!au_test_nfs(file->f_vfsmnt->mnt_sb)*/)
 
247
                err = vfs_read(file, ubuf, count, ppos);
 
248
        else {
283
249
                lockdep_off();
284
 
                err = vfs_unlink(dir, dentry);
 
250
                err = vfs_read(file, ubuf, count, ppos);
285
251
                lockdep_on();
286
252
        }
287
 
        if (!err)
288
 
                au_update_fuse_h_inode(NULL, parent); /*ignore*/
289
 
        dput(parent);
290
 
        AuTraceErr(err);
 
253
        if (err >= 0)
 
254
                au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry);
 
255
        /*ignore*/
 
256
        return err;
 
257
}
 
258
 
 
259
// kernel_read() ??
 
260
ssize_t do_vfsub_read_k(struct file *file, void *kbuf, size_t count,
 
261
                        loff_t *ppos)
 
262
{
 
263
        ssize_t err;
 
264
        mm_segment_t oldfs;
 
265
 
 
266
        oldfs = get_fs();
 
267
        set_fs(KERNEL_DS);
 
268
        err = do_vfsub_read_u(file, (char __user *)kbuf, count, ppos);
 
269
        set_fs(oldfs);
 
270
        return err;
 
271
}
 
272
 
 
273
ssize_t do_vfsub_write_u(struct file *file, const char __user *ubuf,
 
274
                         size_t count, loff_t *ppos)
 
275
{
 
276
        ssize_t err;
 
277
 
 
278
        LKTRTrace("%.*s, cnt %lu, pos %Ld\n",
 
279
                  AuDLNPair(file->f_dentry), (unsigned long)count, *ppos);
 
280
 
 
281
        lockdep_off();
 
282
        err = vfs_write(file, ubuf, count, ppos);
 
283
        lockdep_on();
 
284
        if (err >= 0)
 
285
                au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry);
 
286
        /*ignore*/
 
287
        return err;
 
288
}
 
289
 
 
290
ssize_t do_vfsub_write_k(struct file *file, void *kbuf, size_t count,
 
291
                         loff_t *ppos)
 
292
{
 
293
        ssize_t err;
 
294
        mm_segment_t oldfs;
 
295
 
 
296
        oldfs = get_fs();
 
297
        set_fs(KERNEL_DS);
 
298
        err = do_vfsub_write_u(file, (const char __user *)kbuf, count, ppos);
 
299
        set_fs(oldfs);
 
300
        return err;
 
301
}
 
302
 
 
303
int do_vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
 
304
{
 
305
        int err;
 
306
 
 
307
        LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry));
 
308
 
 
309
        lockdep_off();
 
310
        err = vfs_readdir(file, filldir, arg);
 
311
        lockdep_on();
 
312
        if (err >= 0)
 
313
                au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry);
 
314
        /*ignore*/
 
315
        return err;
 
316
}
 
317
 
 
318
#ifdef CONFIG_AUFS_SPLICE_PATCH
 
319
long do_vfsub_splice_to(struct file *in, loff_t *ppos,
 
320
                        struct pipe_inode_info *pipe, size_t len,
 
321
                        unsigned int flags)
 
322
{
 
323
        long err;
 
324
 
 
325
        LKTRTrace("%.*s, pos %Ld, len %lu, 0x%x\n",
 
326
                  AuDLNPair(in->f_dentry), *ppos, (unsigned long)len, flags);
 
327
 
 
328
        lockdep_off();
 
329
        err = do_splice_to(in, ppos, pipe, len, flags);
 
330
        lockdep_on();
 
331
        if (err >= 0)
 
332
                au_update_fuse_h_inode(in->f_vfsmnt, in->f_dentry); /*ignore*/
 
333
        return err;
 
334
}
 
335
 
 
336
long do_vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
 
337
                          loff_t *ppos, size_t len, unsigned int flags)
 
338
{
 
339
        long err;
 
340
 
 
341
        LKTRTrace("%.*s, pos %Ld, len %lu, 0x%x\n",
 
342
                  AuDLNPair(out->f_dentry), *ppos, (unsigned long)len, flags);
 
343
 
 
344
        lockdep_off();
 
345
        err = do_splice_from(pipe, out, ppos, len, flags);
 
346
        lockdep_on();
 
347
        if (err >= 0)
 
348
                au_update_fuse_h_inode(out->f_vfsmnt, out->f_dentry); /*ignore*/
291
349
        return err;
292
350
}
293
351
#endif
524
582
{
525
583
        int err;
526
584
 
527
 
        if (!vargs->dlgt) {
 
585
        if (!vfsub_ftest(vargs->flags, DLGT)) {
528
586
                vfsub_ignore(vargs);
529
587
                err = do_vfsub_rename(src_dir, src_dentry, dir, dentry);
530
588
                if (unlikely(err))
567
625
{
568
626
        int err;
569
627
 
570
 
        if (!vargs->dlgt) {
 
628
        if (!vfsub_ftest(vargs->flags, DLGT)) {
571
629
                vfsub_ignore(vargs);
572
630
                err = do_vfsub_rmdir(dir, dentry);
573
631
                if (unlikely(err))
655
713
                                goto out_free;
656
714
                        count -= err;
657
715
                        /* do not read too much because of file i/o pointer */
658
 
                        if (unlikely(count < args.count))
 
716
                        if (count < args.count)
659
717
                                args.count = count;
660
718
                        ubuf += err;
661
719
                        read += err;
722
780
{
723
781
        ssize_t err;
724
782
 
725
 
        if (!vargs->dlgt) {
 
783
        if (!vfsub_ftest(vargs->flags, DLGT)) {
726
784
                vfsub_ignore(vargs);
727
785
                err = do_vfsub_write_u(file, ubuf, count, ppos);
728
786
                if (unlikely(err < 0))
790
848
{
791
849
        ssize_t err;
792
850
 
793
 
        if (!vargs->dlgt) {
 
851
        if (!vfsub_ftest(vargs->flags, DLGT)) {
794
852
                vfsub_ignore(vargs);
795
853
                err = do_vfsub_write_k(file, kbuf, count, ppos);
796
854
                if (unlikely(err < 0))
844
902
        }
845
903
}
846
904
 
 
905
/* ---------------------------------------------------------------------- */
 
906
 
847
907
struct splice_to_args {
848
908
        long *errp;
849
909
        struct file *in;
910
970
{
911
971
        long err;
912
972
 
913
 
        if (!vargs->dlgt) {
 
973
        if (!vfsub_ftest(vargs->flags, DLGT)) {
914
974
                vfsub_ignore(vargs);
915
975
                err = do_vfsub_splice_from(pipe, out, ppos, len, flags);
916
976
                if (unlikely(err < 0))
992
1052
 
993
1053
        LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
994
1054
 
995
 
        do_sio = au_test_perm(dir, MAY_EXEC | MAY_WRITE, dlgt);
 
1055
        do_sio = au_test_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt);
996
1056
        if (!do_sio)
997
1057
                err = vfsub_mkdir(dir, dentry, mode, dlgt);
998
1058
        else {
1033
1093
        LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry));
1034
1094
 
1035
1095
        vfsub_args_init(&vargs, /*ign*/NULL, dlgt, /*force_unlink*/0);
1036
 
        do_sio = au_test_perm(dir, MAY_EXEC | MAY_WRITE, dlgt);
 
1096
        do_sio = au_test_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt);
1037
1097
        if (!do_sio)
1038
1098
                err = vfsub_rmdir(dir, dentry, &vargs);
1039
1099
        else {
1099
1159
#ifndef CONFIG_AUFS_DLGT
1100
1160
        call_notify_change(&args);
1101
1161
#else
1102
 
        if (!vargs->dlgt)
 
1162
        if (!vfsub_ftest(vargs->flags, DLGT))
1103
1163
                call_notify_change(&args);
1104
1164
        else {
1105
1165
                int wkq_err;
1175
1235
                .vargs  = vargs
1176
1236
        };
1177
1237
 
1178
 
        if (!vargs->dlgt && !vargs->force_unlink)
 
1238
        if (!vfsub_ftest(vargs->flags, DLGT)
 
1239
            && !vfsub_ftest(vargs->flags, FORCE_UNLINK))
1179
1240
                call_unlink(&args);
1180
1241
        else {
1181
1242
                int wkq_err;
1182
 
                wkq_err = au_wkq_wait(call_unlink, &args, vargs->dlgt);
 
1243
                wkq_err = au_wkq_wait(call_unlink, &args,
 
1244
                                      vfsub_ftest(vargs->flags, DLGT));
1183
1245
                if (unlikely(wkq_err))
1184
1246
                        err = wkq_err;
1185
1247
        }