16
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
/* $Id: dentry.c,v 1.72 2008/03/31 07:42:05 sfjro Exp $ */
20
* lookup and dentry operations
22
* $Id: dentry.c,v 1.74 2008/04/13 23:39:09 sfjro Exp $
21
25
//#include <linux/fs.h>
22
26
//#include <linux/namei.h>
26
/* subset of nameidata */
28
struct dentry *dentry;
33
struct open_intent open;
37
static void au_ndsub_restore(struct nameidata *nd, struct au_ndsub *save)
39
nd->dentry = save->dentry;
41
nd->flags = save->flags;
42
nd->intent = save->intent;
46
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) \
47
&& !defined(AuNoNfsBranch)
48
static int au_fake_intent(/* struct au_ndsub *save, */struct nameidata *nd,
53
LKTRTrace("perm %d\n", perm);
57
save->dentry = nd->dentry;
59
save->flags = nd->flags;
60
save->intent = nd->intent;
63
nd->intent.open.file = NULL;
64
if (nd->flags & LOOKUP_OPEN) {
66
nd->intent.open.file = get_empty_filp();
67
if (unlikely(!nd->intent.open.file)) {
68
//nd->intent.open.file = save->intent.open.file;
73
if (!br_writable(perm)) {
74
nd->intent.open.flags = au_file_roflags
75
(nd->intent.open.flags) | FMODE_READ;
76
nd->flags &= ~LOOKUP_CREATE;
85
static int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry,
86
aufs_bindex_t bindex, struct file *file)
90
LKTRTrace("nd %p, %.*s, b%d, f %d\n",
91
nd, AuDLNPair(dentry), bindex, !!file);
94
if ((nd->flags & LOOKUP_OPEN)
95
&& nd->intent.open.file
96
&& !IS_ERR(nd->intent.open.file)) {
97
if (nd->intent.open.file->f_dentry) {
98
//AuDbgFile(nd->intent.open.file);
99
err = au_set_h_intent(dentry, bindex, file,
100
nd->intent.open.file);
102
nd->intent.open.file = NULL;
104
if (unlikely(nd->intent.open.file))
105
put_filp(nd->intent.open.file);
111
#ifdef CONFIG_AUFS_DLGT
112
struct au_lookup_hash_args {
113
struct dentry **errp;
116
struct nameidata *nd;
119
static void au_call_lookup_hash(void *args)
121
struct au_lookup_hash_args *a = args;
122
*a->errp = vfsub__lookup_hash(a->name, a->base, a->nd);
124
#endif /* CONFIG_AUFS_DLGT */
126
static struct dentry *au_lkup_hash(const char *name, struct dentry *parent,
127
int len, struct aufs_ndx *ndx)
129
struct dentry *dentry;
134
struct nameidata tmp_nd, *ndo;
137
dentry = ERR_PTR(-EACCES);
144
hash = init_name_hash();
147
if (unlikely(c == '/' || c == '\0'))
149
hash = partial_name_hash(c, hash);
151
this.hash = end_name_hash(hash);
156
err = au_fake_intent(&tmp_nd, ndx->br->br_perm);
157
dentry = ERR_PTR(err);
161
memset(&tmp_nd, 0, sizeof(tmp_nd));
163
tmp_nd.dentry = dget(parent);
164
tmp_nd.mnt = mntget(ndx->nfsmnt);
165
#ifndef CONFIG_AUFS_DLGT
167
dentry = vfsub__lookup_hash(&this, parent, &tmp_nd);
169
dirperm1 = au_ftest_ndx(ndx->flags, DIRPERM1);
170
if (!dirperm1 && !au_ftest_ndx(ndx->flags, DLGT))
171
dentry = vfsub__lookup_hash(&this, parent, &tmp_nd);
174
struct au_lookup_hash_args args = {
180
wkq_err = au_wkq_wait(au_call_lookup_hash, &args,
182
if (unlikely(wkq_err))
183
dentry = ERR_PTR(wkq_err);
185
#endif /* CONFIG_AUFS_DLGT */
186
if (0 && !IS_ERR(dentry))
188
if (!IS_ERR(dentry)) {
189
/* why negative dentry for a new dir was unhashed? */
190
if (unlikely(d_unhashed(dentry)))
192
if (tmp_nd.intent.open.file
193
&& tmp_nd.intent.open.file->f_dentry) {
194
//AuDbgFile(tmp_nd.intent.open.file);
195
ndx->nd_file = tmp_nd.intent.open.file;
196
tmp_nd.intent.open.file = NULL;
200
path_release(&tmp_nd);
203
if (tmp_nd.intent.open.file)
204
put_filp(tmp_nd.intent.open.file);
206
AuTraceErrPtr(dentry);
210
static int au_fake_intent(struct nameidata *nd, int perm)
215
static int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry,
216
aufs_bindex_t bindex, struct file *file)
221
#if !defined(AuNoNfsBranch) || defined(CONFIG_AUFS_DLGT)
222
static struct dentry *au_lkup_hash(const char *name, struct dentry *parent,
223
int len, struct aufs_ndx *ndx)
225
return ERR_PTR(-ENOSYS);
228
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && !AuNoNfsBranch */
230
29
/* ---------------------------------------------------------------------- */
232
#if !defined(AuNoNfsBranch) || defined(CONFIG_AUFS_DLGT)
234
#ifdef CONFIG_AUFS_DLGT
235
struct au_lookup_one_len_args {
236
struct dentry **errp;
238
struct dentry *parent;
242
static void au_call_lookup_one_len(void *args)
244
struct au_lookup_one_len_args *a = args;
245
*a->errp = vfsub_lookup_one_len(a->name, a->parent, a->len);
247
#endif /* CONFIG_AUFS_DLGT */
31
#if defined(CONFIG_AUFS_BR_NFS) || defined(CONFIG_AUFS_DLGT)
249
32
/* cf. lookup_one_len() in linux/fs/namei.c */
250
33
struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len,
251
struct aufs_ndx *ndx)
253
36
struct dentry *dentry;
256
39
AuDLNPair(parent), len, name, !!ndx->nfsmnt, ndx->flags);
258
41
ndx->nd_file = NULL;
260
#ifndef CONFIG_AUFS_DLGT
261
dentry = vfsub_lookup_one_len(name, parent, len);
263
int dirperm1 = au_ftest_ndx(ndx->flags, DIRPERM1);
264
if (!dirperm1 && !au_ftest_ndx(ndx->flags, DLGT))
265
dentry = vfsub_lookup_one_len(name, parent, len);
268
struct au_lookup_one_len_args args = {
274
wkq_err = au_wkq_wait(au_call_lookup_one_len, &args,
276
if (unlikely(wkq_err))
277
dentry = ERR_PTR(wkq_err);
279
#endif /* CONFIG_AUFS_DLGT */
43
dentry = au_lkup_one_dlgt(name, parent, len, ndx->flags);
282
45
dentry = au_lkup_hash(name, parent, len, ndx);
284
47
AuTraceErrPtr(dentry);
287
#endif /* !defined(AuNoNfsBranch) || defined(CONFIG_AUFS_DLGT) */
289
#ifdef CONFIG_AUFS_ROBR
290
static int au_test_robr_wh(struct qstr *name, struct dentry *h_parent,
291
struct qstr *wh_name, int try_sio,
292
struct aufs_ndx *ndx)
294
if (strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))
295
return au_test_wh(h_parent, wh_name, try_sio, ndx);
299
static int au_test_robr_shwh(struct super_block *sb, const struct qstr *name)
306
static int au_test_robr_wh(struct qstr *name, struct dentry *h_parent,
307
struct qstr *wh_name, int try_sio,
308
struct aufs_ndx *ndx)
310
return au_test_wh(h_parent, wh_name, try_sio, ndx);
313
static int au_test_robr_shwh(struct super_block *sb, const struct qstr *name)
315
if (unlikely(!au_flag_test_shwh(sb)
316
&& !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)))
321
#endif /* CONFIG_AUFS_ROBR */
50
#endif /* CONFIG_AUFS_BR_NFS || CONFIG_AUFS_DLGT */
323
52
struct au_lkup_one_args {
324
53
struct dentry **errp;
326
55
struct dentry *parent;
328
struct aufs_ndx *ndx;
331
60
static void au_call_lkup_one(void *args)
423
158
|| (args->type && args->type != (h_inode->i_mode & S_IFMT)))
426
if (dbend(dentry) <= bindex)
427
set_dbend(dentry, bindex);
428
if (dbstart(dentry) < 0 || bindex < dbstart(dentry))
429
set_dbstart(dentry, bindex);
430
set_h_dptr(dentry, bindex, h_dentry);
161
if (au_dbend(dentry) <= bindex)
162
au_set_dbend(dentry, bindex);
163
if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry))
164
au_set_dbstart(dentry, bindex);
165
au_set_h_dptr(dentry, bindex, h_dentry);
432
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) \
433
&& !defined(AuNoNfsBranch)
434
if (unlikely(ndx.nd_file)) {
436
AuDebugOn(!args->nd);
437
err = au_set_h_intent(dentry, bindex,
438
args->nd->intent.open.file, ndx.nd_file);
441
set_h_dptr(dentry, bindex, NULL);
442
//todo: update bstart and bend
443
h_dentry = ERR_PTR(err);
167
err = au_br_nfs_h_intent(ndx.nd_file, dentry, bindex, args->nd);
169
h_dentry = ERR_PTR(err);
449
173
inode = dentry->d_inode;
450
174
if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able
501
226
if (unlikely(err))
504
err = au_alloc_whname(name->name, name->len, &whname);
505
//if (LktrCond) {au_free_whname(&whname); err = -1;}
229
err = au_wh_name_alloc(name->name, name->len, &whname);
230
//if (LktrCond) {au_wh_name_free(&whname); err = -1;}
506
231
if (unlikely(err))
509
234
sb = dentry->d_sb;
235
mnt_flags = au_mntflags(sb);
510
236
inode = dentry->d_inode;
511
237
isdir = (inode && S_ISDIR(inode->i_mode));
513
if (unlikely(au_need_dlgt(sb)))
239
if (unlikely(au_opt_test_dlgt(mnt_flags)))
514
240
au_fset_lkup(args.flags, DLGT);
515
if (unlikely(au_need_dirperm1(sb)))
241
if (unlikely(au_opt_test_dirperm1(mnt_flags)))
516
242
au_fset_lkup(args.flags, DIRPERM1);
518
244
au_fset_lkup(args.flags, ALLOW_NEG);
520
btail = dbtaildir(parent);
246
btail = au_dbtaildir(parent);
521
247
for (bindex = bstart; bindex <= btail; bindex++) {
522
248
struct dentry *h_parent, *h_dentry;
523
249
struct inode *h_inode, *h_dir;