2
* Copyright (C) 2005-2008 Junjiro Okajima
4
* This program, aufs is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
* directory operations
22
* $Id: dir.c,v 1.3 2008/04/28 03:04:12 sfjro Exp $
25
#include <linux/fs_stack.h>
28
static int reopen_dir(struct file *file)
31
struct dentry *dentry, *h_dentry;
32
aufs_bindex_t bindex, btail, bstart;
35
dentry = file->f_dentry;
36
LKTRTrace("%.*s\n", AuDLNPair(dentry));
37
AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode));
39
/* open all hidden dirs */
40
bstart = au_dbstart(dentry);
42
for (bindex = au_fbstart(file); bindex < bstart; bindex++)
43
au_set_h_fptr(file, bindex, NULL);
45
au_set_fbstart(file, bstart);
46
btail = au_dbtaildir(dentry);
48
for (bindex = au_fbend(file); btail < bindex; bindex--)
49
au_set_h_fptr(file, bindex, NULL);
51
au_set_fbend(file, btail);
52
for (bindex = bstart; bindex <= btail; bindex++) {
53
h_dentry = au_h_dptr(dentry, bindex);
56
h_file = au_h_fptr(file, bindex);
58
AuDebugOn(h_file->f_dentry != h_dentry);
62
h_file = au_h_open(dentry, bindex, file->f_flags, file);
64
//if (LktrCond) {fput(h_file);
65
//au_br_put(au_sbr(dentry->d_sb, bindex));h_file=ERR_PTR(-1);}
66
err = PTR_ERR(h_file);
68
goto out; // close all?
69
//cpup_file_flags(h_file, file);
70
au_set_h_fptr(file, bindex, h_file);
72
au_update_figen(file);
73
//file->f_ra = h_file->f_ra; //??
81
static int do_open_dir(struct file *file, int flags)
84
aufs_bindex_t bindex, btail;
85
struct dentry *dentry, *h_dentry;
88
dentry = file->f_dentry;
89
LKTRTrace("%.*s, 0x%x\n", AuDLNPair(dentry), flags);
90
AuDebugOn(!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode));
93
au_set_fvdir_cache(file, NULL);
94
file->f_version = dentry->d_inode->i_version;
95
bindex = au_dbstart(dentry);
96
au_set_fbstart(file, bindex);
97
btail = au_dbtaildir(dentry);
98
au_set_fbend(file, btail);
99
for (; !err && bindex <= btail; bindex++) {
100
h_dentry = au_h_dptr(dentry, bindex);
104
h_file = au_h_open(dentry, bindex, flags, file);
105
//if (LktrCond) {fput(h_file);
106
//au_br_put(au_sbr(dentry->d_sb, bindex));h_file=ERR_PTR(-1);}
107
if (!IS_ERR(h_file)) {
108
au_set_h_fptr(file, bindex, h_file);
111
err = PTR_ERR(h_file);
113
au_update_figen(file);
114
//file->f_ra = h_file->f_ra; //??
116
return 0; /* success */
119
for (bindex = au_fbstart(file); !err && bindex <= btail; bindex++)
120
au_set_h_fptr(file, bindex, NULL);
121
au_set_fbstart(file, -1);
122
au_set_fbend(file, -1);
126
static int aufs_open_dir(struct inode *inode, struct file *file)
128
return au_do_open(inode, file, do_open_dir);
131
static int aufs_release_dir(struct inode *inode, struct file *file)
133
struct au_vdir *vdir_cache;
134
struct super_block *sb;
136
LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry));
138
sb = file->f_dentry->d_sb;
139
si_read_lock(sb, !AuLock_FLUSH);
141
vdir_cache = au_fvdir_cache(file);
143
au_vdir_free(vdir_cache);
144
fi_write_unlock(file);
150
static int fsync_dir(struct dentry *dentry, int datasync)
154
struct super_block *sb;
155
aufs_bindex_t bend, bindex;
157
LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), datasync);
158
DiMustAnyLock(dentry);
161
inode = dentry->d_inode;
163
IiMustAnyLock(inode);
166
bend = au_dbend(dentry);
167
for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) {
168
struct dentry *h_dentry;
169
struct inode *h_inode;
170
struct file_operations *fop;
172
if (au_test_ro(sb, bindex, inode))
174
h_dentry = au_h_dptr(dentry, bindex);
177
h_inode = h_dentry->d_inode;
181
/* cf. fs/nsfd/vfs.c and fs/nfsd/nfs4recover.c */
182
//au_hdir_lock(h_inode, inode, bindex);
183
mutex_lock(&h_inode->i_mutex);
184
fop = (void *)h_inode->i_fop;
185
err = filemap_fdatawrite(h_inode->i_mapping);
186
if (!err && fop && fop->fsync)
187
err = fop->fsync(NULL, h_dentry, datasync);
189
err = filemap_fdatawrite(h_inode->i_mapping);
191
au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/
192
//au_hdir_unlock(h_inode, inode, bindex);
193
mutex_unlock(&h_inode->i_mutex);
203
static int aufs_fsync_dir(struct file *file, struct dentry *dentry,
209
struct super_block *sb;
210
aufs_bindex_t bend, bindex;
212
LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), datasync);
213
inode = dentry->d_inode;
218
si_read_lock(sb, !AuLock_FLUSH);
220
err = au_reval_and_lock_finfo(file, reopen_dir, /*wlock*/1,
226
di_read_lock_child(dentry, !AuLock_IW);
228
ii_write_lock_child(inode);
230
bend = au_fbend(file);
231
for (bindex = au_fbstart(file); !err && bindex <= bend;
233
h_file = au_h_fptr(file, bindex);
234
if (!h_file || au_test_ro(sb, bindex, inode))
238
if (h_file->f_op && h_file->f_op->fsync) {
239
// todo: try do_fsync() in fs/sync.c
241
AuDebugOn(h_file->f_dentry->d_inode
242
!= au_h_iptr(inode, bindex));
243
au_hdir_lock(h_file->f_dentry->d_inode, inode,
246
mutex_lock(&h_file->f_mapping->host->i_mutex);
248
err = h_file->f_op->fsync
249
(h_file, h_file->f_dentry, datasync);
252
au_update_fuse_h_inode
257
au_hdir_unlock(h_file->f_dentry->d_inode, inode,
260
mutex_unlock(&h_file->f_mapping->host->i_mutex);
265
err = fsync_dir(dentry, datasync);
266
au_cpup_attr_timesizes(inode);
267
ii_write_unlock(inode);
269
fi_write_unlock(file);
271
di_read_unlock(dentry, !AuLock_IW);
279
/* ---------------------------------------------------------------------- */
281
static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir)
284
struct dentry *dentry;
286
struct super_block *sb;
288
dentry = file->f_dentry;
289
LKTRTrace("%.*s, pos %Ld\n", AuDLNPair(dentry), file->f_pos);
290
inode = dentry->d_inode;
293
au_nfsd_lockdep_off();
295
si_read_lock(sb, AuLock_FLUSH);
296
err = au_reval_and_lock_finfo(file, reopen_dir, /*wlock*/1,
301
ii_write_lock_child(inode);
302
err = au_vdir_init(file);
304
ii_write_unlock(inode);
307
//DbgVdir(au_fvdir_cache(file));// goto out_unlock;
309
/* nfsd filldir calls lookup_one_len(). */
310
ii_downgrade_lock(inode);
311
err = au_vdir_fill_de(file, dirent, filldir);
312
//DbgVdir(au_fvdir_cache(file));// goto out_unlock;
314
fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode)));
315
ii_read_unlock(inode);
318
fi_write_unlock(file);
321
au_nfsd_lockdep_on();
330
/* ---------------------------------------------------------------------- */
332
#define AuTestEmpty_WHONLY 1
333
#define AuTestEmpty_DLGT (1 << 1)
334
#define AuTestEmpty_DIRPERM1 (1 << 2)
335
#define AuTestEmpty_CALLED (1 << 3)
336
#define AuTestEmpty_SHWH (1 << 4)
337
#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name)
338
#define au_fset_testempty(flags, name) { (flags) |= AuTestEmpty_##name; }
339
#define au_fclr_testempty(flags, name) { (flags) &= ~AuTestEmpty_##name; }
340
#ifndef CONFIG_AUFS_DLGT
341
#undef AuTestEmpty_DLGT
342
#define AuTestEmpty_DLGT 0
343
#undef AuTestEmpty_DIRPERM1
344
#define AuTestEmpty_DIRPERM1 0
346
#ifndef CONFIG_AUFS_SHWH
347
#undef AuTestEmpty_SHWH
348
#define AuTestEmpty_SHWH 0
351
struct test_empty_arg {
352
struct au_nhash *whlist;
355
aufs_bindex_t bindex;
358
static int test_empty_cb(void *__arg, const char *__name, int namelen,
359
loff_t offset, u64 ino, unsigned int d_type)
361
struct test_empty_arg *arg = __arg;
362
char *name = (void *)__name;
364
LKTRTrace("%.*s\n", namelen, name);
367
au_fset_testempty(arg->flags, CALLED);
370
&& (namelen == 1 || (name[1] == '.' && namelen == 2)))
371
return 0; /* success */
373
if (namelen <= AUFS_WH_PFX_LEN
374
|| memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) {
375
if (au_ftest_testempty(arg->flags, WHONLY)
376
&& !au_nhash_test_known_wh(arg->whlist, name, namelen))
377
arg->err = -ENOTEMPTY;
381
name += AUFS_WH_PFX_LEN;
382
namelen -= AUFS_WH_PFX_LEN;
383
if (!au_nhash_test_known_wh(arg->whlist, name, namelen))
384
arg->err = au_nhash_append_wh
385
(arg->whlist, name, namelen, ino, d_type, arg->bindex,
386
au_ftest_testempty(arg->flags, SHWH));
390
AuTraceErr(arg->err);
394
static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
399
LKTRTrace("%.*s, {%p, 0x%x, %d}\n",
400
AuDLNPair(dentry), arg->whlist, arg->flags, arg->bindex);
402
h_file = au_h_open(dentry, arg->bindex,
403
O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE,
405
err = PTR_ERR(h_file);
409
if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), UDBA_INOTIFY)
410
&& !h_file->f_dentry->d_inode->i_nlink))
413
dlgt = au_ftest_testempty(arg->flags, DLGT);
417
au_fclr_testempty(arg->flags, CALLED);
419
err = vfsub_readdir(h_file, test_empty_cb, arg, dlgt);
422
} while (!err && au_ftest_testempty(arg->flags, CALLED));
426
au_sbr_put(dentry->d_sb, arg->bindex);
432
struct do_test_empty_args {
434
struct dentry *dentry;
435
struct test_empty_arg *arg;
438
static void call_do_test_empty(void *args)
440
struct do_test_empty_args *a = args;
441
*a->errp = do_test_empty(a->dentry, a->arg);
444
static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg)
447
struct dentry *h_dentry;
448
struct inode *h_inode;
450
LKTRTrace("%.*s\n", AuDLNPair(dentry));
451
h_dentry = au_h_dptr(dentry, arg->bindex);
452
AuDebugOn(!h_dentry);
453
h_inode = h_dentry->d_inode;
454
AuDebugOn(!h_inode || !S_ISDIR(h_inode->i_mode));
456
mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD);
457
err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ,
458
au_opt_test_dlgt(au_mntflags(dentry->d_sb)));
459
mutex_unlock(&h_inode->i_mutex);
461
err = do_test_empty(dentry, arg);
463
struct do_test_empty_args args = {
468
unsigned int flags = arg->flags;
469
au_fclr_testempty(arg->flags, DLGT);
470
au_fclr_testempty(arg->flags, DIRPERM1);
471
wkq_err = au_wkq_wait(call_do_test_empty, &args, /*dlgt*/0);
472
if (unlikely(wkq_err))
481
int au_test_empty_lower(struct dentry *dentry)
485
struct test_empty_arg arg;
486
struct au_nhash *whlist;
487
aufs_bindex_t bindex, bstart, btail;
488
unsigned int mnt_flags;
490
LKTRTrace("%.*s\n", AuDLNPair(dentry));
491
inode = dentry->d_inode;
492
AuDebugOn(!inode || !S_ISDIR(inode->i_mode));
494
whlist = au_nhash_new(GFP_TEMPORARY);
495
err = PTR_ERR(whlist);
499
bstart = au_dbstart(dentry);
500
mnt_flags = au_mntflags(dentry->d_sb);
503
if (unlikely(au_opt_test_dlgt(mnt_flags)))
504
au_fset_testempty(arg.flags, DLGT);
505
if (unlikely(au_opt_test(mnt_flags, SHWH)))
506
au_fset_testempty(arg.flags, SHWH);
508
err = do_test_empty(dentry, &arg);
512
au_fset_testempty(arg.flags, WHONLY);
513
if (unlikely(au_opt_test_dirperm1(mnt_flags)))
514
au_fset_testempty(arg.flags, DIRPERM1);
515
btail = au_dbtaildir(dentry);
516
for (bindex = bstart + 1; !err && bindex <= btail; bindex++) {
517
struct dentry *h_dentry;
518
h_dentry = au_h_dptr(dentry, bindex);
519
if (h_dentry && h_dentry->d_inode) {
520
AuDebugOn(!S_ISDIR(h_dentry->d_inode->i_mode));
522
err = do_test_empty(dentry, &arg);
527
au_nhash_del(whlist);
533
int au_test_empty(struct dentry *dentry, struct au_nhash *whlist)
537
struct test_empty_arg arg;
538
aufs_bindex_t bindex, btail;
540
LKTRTrace("%.*s\n", AuDLNPair(dentry));
541
inode = dentry->d_inode;
542
AuDebugOn(!inode || !S_ISDIR(inode->i_mode));
546
arg.flags = AuTestEmpty_WHONLY;
547
if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), SHWH)))
548
au_fset_testempty(arg.flags, SHWH);
549
btail = au_dbtaildir(dentry);
550
for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) {
551
struct dentry *h_dentry;
552
h_dentry = au_h_dptr(dentry, bindex);
553
if (h_dentry && h_dentry->d_inode) {
554
AuDebugOn(!S_ISDIR(h_dentry->d_inode->i_mode));
556
err = sio_test_empty(dentry, &arg);
564
/* ---------------------------------------------------------------------- */
566
struct file_operations aufs_dir_fop = {
567
.read = generic_read_dir,
568
.readdir = aufs_readdir,
569
.open = aufs_open_dir,
570
.release = aufs_release_dir,
572
.fsync = aufs_fsync_dir,