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

« back to all changes in this revision

Viewing changes to fs/aufs/plink.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: plink.c,v 1.6 2007/05/27 23:05:15 sfjro Exp $ */
 
19
/* $Id: plink.c,v 1.16 2007/10/29 04:41:10 sfjro Exp $ */
20
20
 
21
21
#include "aufs.h"
22
22
 
32
32
        struct list_head *plink_list;
33
33
        struct pseudo_link *plink;
34
34
 
35
 
        TraceEnter();
 
35
        AuTraceEnter();
36
36
        SiMustAnyLock(sb);
37
 
        AuDebugOn(!au_flag_test(sb, AuFlag_PLINK));
38
 
 
39
37
        sbinfo = stosi(sb);
 
38
        AuDebugOn(!AuFlag(sbinfo, f_plink));
 
39
 
40
40
        plink_list = &sbinfo->si_plink;
41
41
        spin_lock(&sbinfo->si_plink_lock);
42
42
        list_for_each_entry(plink, plink_list, list)
43
 
                Dbg("%lu\n", plink->inode->i_ino);
 
43
                AuDbg("%lu\n", plink->inode->i_ino);
44
44
        spin_unlock(&sbinfo->si_plink_lock);
45
45
}
46
46
#endif
47
47
 
48
 
int au_is_plinked(struct super_block *sb, struct inode *inode)
 
48
int au_test_plink(struct super_block *sb, struct inode *inode)
49
49
{
50
50
        int found;
51
51
        struct aufs_sbinfo *sbinfo;
54
54
 
55
55
        LKTRTrace("i%lu\n", inode->i_ino);
56
56
        SiMustAnyLock(sb);
57
 
        AuDebugOn(!au_flag_test(sb, AuFlag_PLINK));
 
57
        sbinfo = stosi(sb);
 
58
        AuDebugOn(!AuFlag(sbinfo, f_plink));
58
59
 
59
60
        found = 0;
60
 
        sbinfo = stosi(sb);
61
61
        plink_list = &sbinfo->si_plink;
62
62
        spin_lock(&sbinfo->si_plink_lock);
63
63
        list_for_each_entry(plink, plink_list, list)
69
69
        return found;
70
70
}
71
71
 
72
 
// 20 is max digits length of ulong 64
 
72
/* 20 is max digits length of ulong 64 */
73
73
#define PLINK_NAME_LEN  ((20 + 1) * 2)
74
74
 
75
75
static int plink_name(char *name, int len, struct inode *inode,
87
87
        return rlen;
88
88
}
89
89
 
90
 
struct dentry *lkup_plink(struct super_block *sb, aufs_bindex_t bindex,
91
 
                          struct inode *inode)
 
90
struct dentry *au_lkup_plink(struct super_block *sb, aufs_bindex_t bindex,
 
91
                             struct inode *inode)
92
92
{
93
93
        struct dentry *h_dentry, *h_parent;
94
94
        struct aufs_branch *br;
95
95
        struct inode *h_dir;
96
96
        char tgtname[PLINK_NAME_LEN];
97
97
        int len;
98
 
        struct lkup_args lkup;
 
98
        struct aufs_ndx ndx = {
 
99
                .nd     = NULL,
 
100
                //.br   = NULL
 
101
        };
99
102
 
100
103
        LKTRTrace("b%d, i%lu\n", bindex, inode->i_ino);
101
104
        br = stobr(sb, bindex);
106
109
 
107
110
        len = plink_name(tgtname, sizeof(tgtname), inode, bindex);
108
111
 
109
 
        // always superio.
110
 
        lkup.nfsmnt = au_do_nfsmnt(br->br_mnt);
111
 
        lkup.dlgt = need_dlgt(sb);
112
 
        hi_lock_whplink(h_dir);
113
 
        h_dentry = sio_lkup_one(tgtname, h_parent, len, &lkup);
114
 
        i_unlock(h_dir);
 
112
        /* always superio. */
 
113
        ndx.nfsmnt = au_do_nfsmnt(br->br_mnt);
 
114
        ndx.dlgt = au_need_dlgt(sb);
 
115
        vfsub_i_lock_nested(h_dir, AuLsc_I_CHILD2);
 
116
        h_dentry = au_sio_lkup_one(tgtname, h_parent, len, &ndx);
 
117
        vfsub_i_unlock(h_dir);
115
118
        return h_dentry;
116
119
}
117
120
 
122
125
        int err;
123
126
        struct dentry *h_tgt;
124
127
        struct inode *h_dir;
125
 
        struct lkup_args lkup = {
 
128
        struct vfsub_args vargs;
 
129
        struct aufs_ndx ndx = {
126
130
                .nfsmnt = nfsmnt,
127
 
                .dlgt   = need_dlgt(sb)
 
131
                .dlgt   = au_need_dlgt(sb),
 
132
                .nd     = NULL,
 
133
                //.br   = NULL
128
134
        };
129
135
 
130
 
        h_tgt = lkup_one(tgt, h_parent, len, &lkup);
 
136
        h_tgt = au_lkup_one(tgt, h_parent, len, &ndx);
131
137
        err = PTR_ERR(h_tgt);
132
138
        if (IS_ERR(h_tgt))
133
139
                goto out;
134
140
 
135
141
        err = 0;
 
142
        vfsub_args_init(&vargs, NULL, ndx.dlgt, 0);
136
143
        h_dir = h_parent->d_inode;
137
144
        if (unlikely(h_tgt->d_inode && h_tgt->d_inode != h_dentry->d_inode))
138
 
                err = vfsub_unlink(h_dir, h_tgt, lkup.dlgt);
 
145
                err = vfsub_unlink(h_dir, h_tgt, &vargs);
139
146
        if (!err && !h_tgt->d_inode) {
140
 
                err = vfsub_link(h_dentry, h_dir, h_tgt, lkup.dlgt);
 
147
                err = vfsub_link(h_dentry, h_dir, h_tgt, ndx.dlgt);
141
148
                //inode->i_nlink++;
142
149
        }
143
150
        dput(h_tgt);
144
151
 
145
152
 out:
146
 
        TraceErr(err);
 
153
        AuTraceErr(err);
147
154
        return err;
148
155
}
149
156
 
173
180
        struct inode *h_dir;
174
181
        char tgtname[PLINK_NAME_LEN];
175
182
 
176
 
        LKTRTrace("%.*s\n", DLNPair(h_dentry));
 
183
        LKTRTrace("%.*s\n", AuDLNPair(h_dentry));
177
184
        br = stobr(inode->i_sb, bindex);
178
185
        h_parent = br->br_plink;
179
186
        AuDebugOn(!h_parent);
182
189
 
183
190
        len = plink_name(tgtname, sizeof(tgtname), inode, bindex);
184
191
 
185
 
        // always superio.
186
 
        hi_lock_whplink(h_dir);
187
 
        if (!is_au_wkq(current)) {
 
192
        /* always superio. */
 
193
        vfsub_i_lock_nested(h_dir, AuLsc_I_CHILD2);
 
194
        if (!au_test_wkq(current)) {
188
195
                struct do_whplink_args args = {
189
196
                        .errp           = &err,
190
197
                        .tgt            = tgtname,
200
207
        } else
201
208
                err = do_whplink(tgtname, len, h_parent, h_dentry,
202
209
                                 au_do_nfsmnt(br->br_mnt), sb);
203
 
        i_unlock(h_dir);
 
210
        vfsub_i_unlock(h_dir);
204
211
 
205
 
        TraceErr(err);
 
212
        AuTraceErr(err);
206
213
        return err;
207
214
}
208
215
 
209
 
void append_plink(struct super_block *sb, struct inode *inode,
210
 
                  struct dentry *h_dentry, aufs_bindex_t bindex)
 
216
void au_append_plink(struct super_block *sb, struct inode *inode,
 
217
                     struct dentry *h_dentry, aufs_bindex_t bindex)
211
218
{
212
219
        struct aufs_sbinfo *sbinfo;
213
220
        struct list_head *plink_list;
216
223
 
217
224
        LKTRTrace("i%lu\n", inode->i_ino);
218
225
        SiMustAnyLock(sb);
219
 
        AuDebugOn(!au_flag_test(sb, AuFlag_PLINK));
 
226
        sbinfo = stosi(sb);
 
227
        AuDebugOn(!AuFlag(sbinfo, f_plink));
220
228
 
221
229
        cnt = 0;
222
230
        found = 0;
223
 
        sbinfo = stosi(sb);
224
231
        plink_list = &sbinfo->si_plink;
225
232
        spin_lock(&sbinfo->si_plink_lock);
226
233
        list_for_each_entry(plink, plink_list, list) {
247
254
                err = whplink(h_dentry, inode, bindex, sb);
248
255
 
249
256
        if (unlikely(cnt > 100))
250
 
                Warn1("unexpectedly many pseudo links, %d\n", cnt);
 
257
                AuWarn1("unexpectedly many pseudo links, %d\n", cnt);
251
258
        if (unlikely(err))
252
 
                Warn("err %d, damaged pseudo link. ignored.\n", err);
 
259
                AuWarn("err %d, damaged pseudo link. ignored.\n", err);
253
260
}
254
261
 
255
262
static void do_put_plink(struct pseudo_link *plink, int do_del)
256
263
{
257
 
        TraceEnter();
 
264
        AuTraceEnter();
258
265
 
259
266
        iput(plink->inode);
260
267
        if (do_del)
268
275
        struct list_head *plink_list;
269
276
        struct pseudo_link *plink, *tmp;
270
277
 
271
 
        TraceEnter();
 
278
        AuTraceEnter();
272
279
        SiMustWriteLock(sb);
273
 
        AuDebugOn(!au_flag_test(sb, AuFlag_PLINK));
274
 
 
275
280
        sbinfo = stosi(sb);
 
281
        AuDebugOn(!AuFlag(sbinfo, f_plink));
 
282
 
276
283
        plink_list = &sbinfo->si_plink;
277
284
        //spin_lock(&sbinfo->si_plink_lock);
278
285
        list_for_each_entry_safe(plink, tmp, plink_list, list)
281
288
        //spin_unlock(&sbinfo->si_plink_lock);
282
289
}
283
290
 
284
 
void half_refresh_plink(struct super_block *sb, aufs_bindex_t br_id)
 
291
void au_half_refresh_plink(struct super_block *sb, aufs_bindex_t br_id)
285
292
{
286
293
        struct aufs_sbinfo *sbinfo;
287
294
        struct list_head *plink_list;
290
297
        aufs_bindex_t bstart, bend, bindex;
291
298
        int do_put;
292
299
 
293
 
        TraceEnter();
 
300
        AuTraceEnter();
294
301
        SiMustWriteLock(sb);
295
 
        AuDebugOn(!au_flag_test(sb, AuFlag_PLINK));
296
 
 
297
302
        sbinfo = stosi(sb);
 
303
        AuDebugOn(!AuFlag(sbinfo, f_plink));
 
304
 
298
305
        plink_list = &sbinfo->si_plink;
299
306
        //spin_lock(&sbinfo->si_plink_lock);
300
307
        list_for_each_entry_safe(plink, tmp, plink_list, list) {