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

« back to all changes in this revision

Viewing changes to fs/aufs/misc.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: misc.c,v 1.33 2007/06/04 02:17:35 sfjro Exp $ */
 
19
/* $Id: misc.c,v 1.47 2007/11/12 01:40:06 sfjro Exp $ */
20
20
 
21
21
//#include <linux/fs.h>
22
22
//#include <linux/namei.h>
28
28
{
29
29
        void *q;
30
30
 
31
 
        LKTRTrace("p %p, nused %d, sz %d, ksize %d\n",
32
 
                  p, nused, new_sz, ksize(p));
 
31
        LKTRTrace("p %p, nused %d, sz %d\n", p, nused, new_sz);
33
32
        AuDebugOn(new_sz <= 0);
34
33
        if (new_sz <= nused)
35
34
                return p;
 
35
 
 
36
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
 
37
        q = krealloc(p, new_sz, gfp);
 
38
        if (q)
 
39
                memset(q + nused, 0, new_sz - nused);
 
40
        return q;
 
41
#else
 
42
        LKTRTrace("ksize %d\n", ksize(p));
36
43
        if (new_sz <= ksize(p)) {
37
44
                memset(p + nused, 0, new_sz - nused);
38
45
                return p;
47
54
        //smp_mb();
48
55
        kfree(p);
49
56
        return q;
 
57
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) */
50
58
}
51
59
 
52
60
/* ---------------------------------------------------------------------- */
53
61
 
 
62
struct nameidata *au_dup_nd(struct aufs_sbinfo *sbinfo, struct nameidata *dst,
 
63
                            struct nameidata *src)
 
64
{
 
65
        LKTRTrace("src %p\n", src);
 
66
 
 
67
        if (src) {
 
68
                *dst = *src;
 
69
                dst->flags &= ~LOOKUP_PARENT;
 
70
                if (unlikely(AuFlag(sbinfo, f_wbr_create) != AuWbrCreate_TDP)) {
 
71
                        dst->flags &= ~LOOKUP_CREATE;
 
72
                        dst->intent.open.flags &= ~O_CREAT;
 
73
                }
 
74
        } else
 
75
                dst = NULL;
 
76
 
 
77
        return dst;
 
78
}
 
79
 
54
80
// todo: make it inline
55
 
struct nameidata *fake_dm(struct nameidata *fake_nd, struct nameidata *nd,
56
 
                          struct super_block *sb, aufs_bindex_t bindex)
 
81
struct nameidata *au_fake_dm(struct nameidata *fake_nd, struct nameidata *nd,
 
82
                             struct super_block *sb, aufs_bindex_t bindex)
57
83
{
58
84
        LKTRTrace("nd %p, b%d\n", nd, bindex);
59
85
 
77
103
                fake_nd = ERR_PTR(-ENOENT);
78
104
#endif
79
105
 
80
 
        TraceErrPtr(fake_nd);
 
106
        AuTraceErrPtr(fake_nd);
81
107
        return fake_nd;
82
108
}
83
109
 
84
 
void fake_dm_release(struct nameidata *fake_nd)
 
110
void au_fake_dm_release(struct nameidata *fake_nd)
85
111
{
86
112
#ifndef CONFIG_AUFS_FAKE_DM
87
113
        if (fake_nd) {
91
117
#endif
92
118
}
93
119
 
 
120
int au_h_create(struct inode *h_dir, struct dentry *h_dentry, int mode,
 
121
                int dlgt, struct nameidata *nd, struct vfsmount *nfsmnt)
 
122
{
 
123
        int err;
 
124
 
 
125
        LKTRTrace("hi%lu, %.*s, 0%o, nd %d, nfsmnt %d\n",
 
126
                  h_dir->i_ino, AuDLNPair(h_dentry), mode, !!nd, !!nfsmnt);
 
127
 
 
128
        err = -ENOSYS;
 
129
        if (!nfsmnt)
 
130
                err = vfsub_create(h_dir, h_dentry, mode, /*nd*/NULL, dlgt);
 
131
        else {
 
132
#ifndef CONFIG_AUFS_FAKE_DM
 
133
                struct nameidata fake_nd;
 
134
 
 
135
                if (nd)
 
136
                        fake_nd = *nd;
 
137
                else
 
138
                        memset(&fake_nd, 0, sizeof(fake_nd));
 
139
                fake_nd.dentry = dget(h_dentry);
 
140
                fake_nd.mnt = mntget(nfsmnt);
 
141
                fake_nd.flags = LOOKUP_CREATE;
 
142
                fake_nd.intent.open.flags = O_CREAT | FMODE_READ;
 
143
                fake_nd.intent.open.create_mode = mode;
 
144
 
 
145
                err = vfsub_create(h_dir, h_dentry, mode, &fake_nd, dlgt);
 
146
                path_release(&fake_nd);
 
147
#endif
 
148
        }
 
149
 
 
150
        AuTraceErr(err);
 
151
        return err;
 
152
}
 
153
 
94
154
/* ---------------------------------------------------------------------- */
95
155
 
96
156
int au_copy_file(struct file *dst, struct file *src, loff_t len,
97
 
                 struct super_block *sb, int *sparse)
 
157
                 struct super_block *sb)
98
158
{
99
 
        int err, all_zero, dlgt;
 
159
        int err, all_zero;
100
160
        unsigned long blksize;
101
161
        char *buf;
 
162
        struct vfsub_args vargs;
102
163
        /* reduce stack space */
103
164
        struct iattr *ia;
104
165
 
105
166
        LKTRTrace("%.*s, %.*s\n",
106
 
                  DLNPair(dst->f_dentry), DLNPair(src->f_dentry));
 
167
                  AuDLNPair(dst->f_dentry), AuDLNPair(src->f_dentry));
107
168
        AuDebugOn(!(dst->f_mode & FMODE_WRITE));
108
169
#ifdef CONFIG_AUFS_DEBUG
109
170
        {
119
180
        if (!blksize || PAGE_SIZE < blksize)
120
181
                blksize = PAGE_SIZE;
121
182
        LKTRTrace("blksize %lu\n", blksize);
122
 
        buf = kmalloc(blksize, GFP_KERNEL);
 
183
        buf = kmalloc(blksize, GFP_TEMPORARY);
123
184
        //buf = NULL;
124
185
        if (unlikely(!buf))
125
186
                goto out;
126
 
        ia = kmalloc(sizeof(*ia), GFP_KERNEL);
 
187
        ia = kmalloc(sizeof(*ia), GFP_TEMPORARY);
127
188
        if (unlikely(!ia))
128
189
                goto out_buf;
129
190
 
130
 
        dlgt = need_dlgt(sb);
131
 
        err = all_zero = 0;
132
 
        dst->f_pos = src->f_pos = 0;
 
191
#ifdef CONFIG_AUFS_DEBUG
 
192
        if (len > (1 << 22))
 
193
                AuWarn("copying a large file %Ld\n", (long long)len);
 
194
#endif
 
195
        vfsub_args_init(&vargs, NULL, au_need_dlgt(sb), 0);
 
196
        err = 0;
 
197
        all_zero = 0;
 
198
        src->f_pos = 0;
 
199
        dst->f_pos = 0;
133
200
        while (len) {
134
201
                size_t sz, rbytes, wbytes, i;
135
202
                char *p;
141
208
 
142
209
                /* support LSM and notify */
143
210
                rbytes = 0;
144
 
                while (!rbytes || err == -EAGAIN || err == -EINTR)
145
 
                        err = rbytes = vfsub_read_k(src, buf, sz, &src->f_pos,
146
 
                                                    dlgt);
 
211
                // signal_pending
 
212
                while (!rbytes || err == -EAGAIN || err == -EINTR) {
 
213
                        rbytes = vfsub_read_k(src, buf, sz, &src->f_pos,
 
214
                                              vargs.dlgt);
 
215
                        err = rbytes;
 
216
                }
147
217
                if (unlikely(err < 0))
148
218
                        break;
149
219
 
160
230
                        while (wbytes) {
161
231
                                size_t b;
162
232
                                /* support LSM and notify */
163
 
                                err = b = vfsub_write_k(dst, p, wbytes,
164
 
                                                        &dst->f_pos, dlgt);
 
233
                                b = vfsub_write_k(dst, p, wbytes, &dst->f_pos,
 
234
                                                  &vargs);
 
235
                                err = b;
 
236
                                // signal_pending
165
237
                                if (unlikely(err == -EAGAIN || err == -EINTR))
166
238
                                        continue;
167
239
                                if (unlikely(err < 0))
172
244
                } else {
173
245
                        loff_t res;
174
246
                        LKTRLabel(hole);
175
 
                        *sparse = 1;
176
 
                        err = res = vfsub_llseek(dst, rbytes, SEEK_CUR);
 
247
                        res = vfsub_llseek(dst, rbytes, SEEK_CUR);
 
248
                        err = res;
177
249
                        if (unlikely(res < 0))
178
250
                                break;
179
251
                }
188
260
 
189
261
                LKTRLabel(last hole);
190
262
                do {
191
 
                        err = vfsub_write_k(dst, "\0", 1, &dst->f_pos, dlgt);
 
263
                        // signal_pending
 
264
                        err = vfsub_write_k(dst, "\0", 1, &dst->f_pos, &vargs);
192
265
                } while (err == -EAGAIN || err == -EINTR);
193
266
                if (err == 1) {
194
267
                        ia->ia_size = dst->f_pos;
195
268
                        ia->ia_valid = ATTR_SIZE | ATTR_FILE;
196
269
                        ia->ia_file = dst;
197
 
                        hi_lock_child2(h_i);
198
 
                        err = vfsub_notify_change(h_d, ia, dlgt);
199
 
                        i_unlock(h_i);
 
270
                        vfsub_i_lock_nested(h_i, AuLsc_I_CHILD2);
 
271
                        err = vfsub_notify_change(h_d, ia, &vargs);
 
272
                        vfsub_i_unlock(h_i);
200
273
                }
201
274
        }
202
275
 
204
277
 out_buf:
205
278
        kfree(buf);
206
279
 out:
207
 
        TraceErr(err);
 
280
        AuTraceErr(err);
208
281
        return err;
209
282
}
210
283
 
211
284
/* ---------------------------------------------------------------------- */
212
285
 
213
 
int test_ro(struct super_block *sb, aufs_bindex_t bindex, struct inode *inode)
 
286
int au_test_ro(struct super_block *sb, aufs_bindex_t bindex,
 
287
               struct inode *inode)
214
288
{
215
289
        int err;
216
290
 
217
291
        err = br_rdonly(stobr(sb, bindex));
218
 
        if (!err && inode) {
 
292
 
 
293
        /* pseudo-link after flushed may out of bounds */
 
294
        if (!err
 
295
            && inode
 
296
            && ibstart(inode) <= bindex
 
297
            && bindex <= ibend(inode)) {
 
298
                /*
 
299
                 * permission check is unnecessary since later vfsub routine
 
300
                 * does
 
301
                 */
219
302
                struct inode *hi = au_h_iptr_i(inode, bindex);
220
303
                if (hi)
221
304
                        err = IS_IMMUTABLE(hi) ? -EROFS : 0;
222
305
        }
 
306
 
 
307
        AuTraceErr(err);
223
308
        return err;
224
309
}
225
310
 
227
312
{
228
313
        if (!current->fsuid)
229
314
                return 0;
230
 
        if (unlikely(au_is_nfs(hidden_inode->i_sb)
 
315
        if (unlikely(au_test_nfs(hidden_inode->i_sb)
231
316
                     && (mask & MAY_WRITE)
232
317
                     && S_ISDIR(hidden_inode->i_mode)))
233
318
                mask |= MAY_READ; /* force permission check */
 
319
        //todo: fake nameidata
234
320
        return vfsub_permission(hidden_inode, mask, NULL, dlgt);
235
321
}