38
37
LKTRTrace("fsuid %d\n", current->fsuid);
39
38
*a->errp = security_inode_permission(a->h_inode, a->mask, a->fake_nd);
40
#endif /* CONFIG_AUFS_DLGT */
43
static int hidden_permission(struct inode *hidden_inode, int mask,
44
struct nameidata *fake_nd, int brperm, int dlgt)
42
static int h_permission(struct inode *h_inode, int mask,
43
struct nameidata *fake_nd, int brperm, int dlgt)
47
46
const int write_mask = (mask & (MAY_WRITE | MAY_APPEND));
49
48
LKTRTrace("ino %lu, mask 0x%x, brperm 0x%x\n",
50
hidden_inode->i_ino, mask, brperm);
49
h_inode->i_ino, mask, brperm);
53
if (unlikely(write_mask && IS_IMMUTABLE(hidden_inode)))
52
if (unlikely((write_mask && IS_IMMUTABLE(h_inode))
53
|| ((mask & MAY_EXEC) && S_ISREG(h_inode->i_mode)
54
&& fake_nd && fake_nd->mnt
55
&& (fake_nd->mnt->mnt_flags & MNT_NOEXEC))
56
59
/* skip hidden fs test in the case of write to ro branch */
57
60
submask = mask & ~MAY_APPEND;
58
61
if (unlikely((write_mask && !br_writable(brperm))
59
|| !hidden_inode->i_op
60
|| !hidden_inode->i_op->permission)) {
63
|| !h_inode->i_op->permission)) {
61
64
//LKTRLabel(generic_permission);
62
err = generic_permission(hidden_inode, submask, NULL);
65
err = generic_permission(h_inode, submask, NULL);
64
67
//LKTRLabel(h_inode->permission);
65
err = hidden_inode->i_op->permission(hidden_inode, submask,
68
err = h_inode->i_op->permission(h_inode, submask, fake_nd);
72
74
#ifndef CONFIG_AUFS_DLGT
73
err = security_inode_permission(hidden_inode, mask, fake_nd);
75
err = security_inode_permission(h_inode, mask, fake_nd);
76
err = security_inode_permission(hidden_inode, mask,
78
err = security_inode_permission(h_inode, mask,
80
82
struct security_inode_permission_args args = {
82
.h_inode = hidden_inode,
146
148
si_read_unlock(sb);
149
aufs_read_unlock(nd->dentry, AUFS_I_RLOCK);
151
aufs_read_unlock(nd->dentry, AuLock_IR);
156
#endif /* CONFIG_AUFS_FAKE_DM */
157
159
static int aufs_permission(struct inode *inode, int mask, struct nameidata *nd)
159
161
int err, locked, dlgt;
160
162
aufs_bindex_t bindex, bend;
161
struct inode *hidden_inode;
163
struct inode *h_inode;
162
164
struct super_block *sb;
163
165
struct nameidata fake_nd, *p;
164
166
const int write_mask = (mask & (MAY_WRITE | MAY_APPEND));
165
167
const int nondir = !S_ISDIR(inode->i_mode);
167
169
LKTRTrace("ino %lu, mask 0x%x, nondir %d, write_mask %d, "
169
171
inode->i_ino, mask, nondir, write_mask,
170
nd, nd ? nd->dentry : NULL, nd ? nd->mnt : NULL);
172
!!nd, nd ? !!nd->dentry : 0, nd ? !!nd->mnt : 0);
172
174
sb = inode->i_sb;
173
175
locked = silly_lock(inode, nd);
174
dlgt = need_dlgt(sb);
176
dlgt = au_need_dlgt(sb);
178
180
if (/* unlikely */(nondir || write_mask)) {
179
hidden_inode = au_h_iptr(inode);
180
AuDebugOn(!hidden_inode
181
|| ((hidden_inode->i_mode & S_IFMT)
181
h_inode = au_h_iptr(inode);
183
|| ((h_inode->i_mode & S_IFMT)
182
184
!= (inode->i_mode & S_IFMT)));
184
186
bindex = ibstart(inode);
185
p = fake_dm(&fake_nd, nd, sb, bindex);
187
p = au_fake_dm(&fake_nd, nd, sb, bindex);
186
188
/* actual test will be delegated to LSM */
188
190
AuDebugOn(PTR_ERR(p) != -ENOENT);
190
err = hidden_permission(hidden_inode, mask, p,
191
sbr_perm(sb, bindex), dlgt);
192
err = h_permission(h_inode, mask, p,
193
sbr_perm(sb, bindex), dlgt);
194
au_fake_dm_release(p);
194
196
if (write_mask && !err) {
195
err = find_rw_br(sb, bindex);
197
/* test whether the upper writable branch exists */
199
for (; bindex >= 0; bindex--)
200
if (!br_rdonly(stobr(sb, bindex))) {
204
210
bend = ibend(inode);
205
211
for (bindex = ibstart(inode); !err && bindex <= bend; bindex++) {
206
hidden_inode = au_h_iptr_i(inode, bindex);
212
h_inode = au_h_iptr_i(inode, bindex);
209
AuDebugOn(!S_ISDIR(hidden_inode->i_mode));
215
AuDebugOn(!S_ISDIR(h_inode->i_mode));
211
p = fake_dm(&fake_nd, nd, sb, bindex);
217
p = au_fake_dm(&fake_nd, nd, sb, bindex);
212
218
/* actual test will be delegated to LSM */
214
220
AuDebugOn(PTR_ERR(p) != -ENOENT);
216
err = hidden_permission(hidden_inode, mask, p,
217
sbr_perm(sb, bindex), dlgt);
222
err = h_permission(h_inode, mask, p,
223
sbr_perm(sb, bindex), dlgt);
224
au_fake_dm_release(p);
223
229
silly_unlock(locked, inode, nd);
233
239
struct dentry *ret, *parent;
234
240
int err, npositive;
235
241
struct inode *inode;
242
struct nameidata tmp_nd, *ndp;
243
//todo: no more lower nameidata, only here. re-use it.
237
LKTRTrace("dir %lu, %.*s\n", dir->i_ino, DLNPair(dentry));
245
LKTRTrace("dir %lu, %.*s, nd{0x%x}\n",
246
dir->i_ino, AuDLNPair(dentry), nd ? nd->flags : 0);
238
247
AuDebugOn(IS_ROOT(dentry));
242
parent = dget_parent(dentry);
243
aufs_read_lock(parent, !AUFS_I_RLOCK);
251
parent = dentry->d_parent; /* dir inode is locked */
252
aufs_read_lock(parent, !AuLock_FLUSH);
244
253
err = au_alloc_dinfo(dentry);
245
254
//if (LktrCond) err = -1;
246
255
ret = ERR_PTR(err);
247
256
if (unlikely(err))
250
err = npositive = lkup_dentry(dentry, dbstart(parent), /*type*/0);
259
ndp = au_dup_nd(stosi(dir->i_sb), &tmp_nd, nd);
260
npositive = au_lkup_dentry(dentry, dbstart(parent), /*type*/0, ndp);
252
264
ret = ERR_PTR(err);
253
265
if (unlikely(err < 0))
267
279
d_add(dentry, inode);
281
//AuDbgDentry(dentry);
283
&& (nd->flags & LOOKUP_OPEN)
284
&& nd->intent.open.file
285
&& nd->intent.open.file->f_dentry);
286
au_store_fmode_exec(nd, inode);
272
290
di_write_unlock(dentry);
274
aufs_read_unlock(parent, !AUFS_I_RLOCK);
292
aufs_read_unlock(parent, !AuLock_IR);
280
297
/* ---------------------------------------------------------------------- */
283
301
* decide the branch and the parent dir where we will create a new entry.
284
302
* returns new bindex or an error.
285
303
* copyup the parent dir if needed.
287
int wr_dir(struct dentry *dentry, int add_entry, struct dentry *src_dentry,
288
aufs_bindex_t force_btgt, int do_lock_srcdir)
305
int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry,
306
struct au_wr_dir_args *args)
291
309
aufs_bindex_t bcpup, bstart, src_bstart;
292
struct dentry *hidden_parent;
293
310
struct super_block *sb;
294
struct dentry *parent, *src_parent = NULL;
311
struct dentry *parent, *src_parent = NULL, *h_parent;
295
312
struct inode *dir, *src_dir = NULL;
313
struct aufs_sbinfo *sbinfo;
297
LKTRTrace("%.*s, add %d, src %p, force %d, lock_srcdir %d\n",
298
DLNPair(dentry), add_entry, src_dentry, force_btgt,
315
LKTRTrace("%.*s, src %p, {%d, %d, %d, %d}\n",
316
AuDLNPair(dentry), src_dentry, args->force_btgt,
317
args->add_entry, args->do_lock_srcdir, args->isdir);
318
//AuDbgDentry(dentry);
301
320
sb = dentry->d_sb;
302
322
parent = dget_parent(dentry);
303
bcpup = bstart = dbstart(dentry);
304
if (force_btgt < 0) {
323
bstart = dbstart(dentry);
325
if (args->force_btgt < 0) {
305
326
if (src_dentry) {
306
327
src_bstart = dbstart(src_dentry);
307
328
if (src_bstart < bstart)
308
329
bcpup = src_bstart;
330
} else if (args->add_entry) {
331
err = AuWbrCreate(sbinfo, dentry, args->isdir);
310
if (test_ro(sb, bcpup, dentry->d_inode)) {
312
di_read_lock_parent(parent, !AUFS_I_RLOCK);
313
bcpup = err = find_rw_parent_br(dentry, bcpup);
314
//bcpup = err = find_rw_br(sb, bcpup);
316
di_read_unlock(parent, !AUFS_I_RLOCK);
335
if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) {
337
err = AuWbrCopyup(sbinfo, dentry);
339
di_read_lock_parent(parent, !AuLock_IR);
340
err = AuWbrCopyup(sbinfo, dentry);
341
di_read_unlock(parent, !AuLock_IR);
318
345
if (unlikely(err < 0))
322
AuDebugOn(bstart <= force_btgt
323
|| test_ro(sb, force_btgt, dentry->d_inode));
349
bcpup = args->force_btgt;
350
AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode));
326
352
LKTRTrace("bstart %d, bcpup %d\n", bstart, bcpup);
354
au_update_dbrange(dentry, /*do_put_zero*/1);
329
357
if (bcpup == bstart)
330
358
goto out; /* success */
332
360
/* copyup the new parent into the branch we process */
333
hidden_parent = dget_parent(au_h_dptr(dentry));
334
361
if (src_dentry) {
335
362
src_parent = dget_parent(src_dentry);
336
363
src_dir = src_parent->d_inode;
364
if (args->do_lock_srcdir)
338
365
di_write_lock_parent2(src_parent);
341
368
dir = parent->d_inode;
369
if (args->add_entry) {
343
370
au_update_dbstart(dentry);
345
372
DiMustWriteLock(parent);
348
375
di_write_lock_parent(parent);
351
if (!au_h_dptr_i(parent, bcpup))
352
err = cpup_dirs(dentry, bcpup, src_parent);
378
if (!au_h_dptr_i(parent, bcpup)) {
380
err = au_cpdown_dirs(dentry, bcpup, src_parent);
382
err = au_cpup_dirs(dentry, bcpup, src_parent);
354
if (!err && add_entry) {
356
hidden_parent = dget(au_h_dptr_i(parent, bcpup));
357
AuDebugOn(!hidden_parent || !hidden_parent->d_inode);
358
hi_lock_parent(hidden_parent->d_inode);
359
err = lkup_neg(dentry, bcpup);
385
if (!err && args->add_entry) {
386
h_parent = au_h_dptr_i(parent, bcpup);
387
AuDebugOn(!h_parent || !h_parent->d_inode);
388
vfsub_i_lock_nested(h_parent->d_inode, AuLsc_I_PARENT);
389
err = au_lkup_neg(dentry, bcpup);
361
i_unlock(hidden_parent->d_inode);
391
vfsub_i_unlock(h_parent->d_inode);
392
if (bstart < bcpup && dbstart(dentry) < 0) {
393
set_dbstart(dentry, 0);
394
au_update_dbrange(dentry, /*do_put_zero*/0);
398
if (!args->add_entry)
366
399
di_write_unlock(parent);
400
if (args->do_lock_srcdir)
368
401
di_write_unlock(src_parent);
369
402
dput(src_parent);
381
415
static int aufs_setattr(struct dentry *dentry, struct iattr *ia)
384
418
aufs_bindex_t bstart, bcpup;
385
struct inode *hidden_inode, *inode, *dir, *h_dir, *gh_dir, *gdir;
386
struct dentry *hidden_dentry, *parent;
419
struct inode *h_inode, *inode, *dir, *h_dir, *gdir;
420
struct dentry *h_dentry, *parent, *hi_wh, *gparent;
387
421
unsigned int udba;
422
struct aufs_hin_ignore ign;
423
struct vfsub_args vargs;
424
struct super_block *sb;
426
struct au_cpup_flags cflags;
427
struct au_wr_dir_args wr_dir_args = {
431
.isdir = S_ISDIR(dentry->d_inode->i_mode)
389
LKTRTrace("%.*s, ia_valid 0x%x\n", DLNPair(dentry), ia->ia_valid);
434
LKTRTrace("%.*s, ia_valid 0x%x\n", AuDLNPair(dentry), ia->ia_valid);
390
435
inode = dentry->d_inode;
391
436
IMustLock(inode);
393
aufs_read_lock(dentry, AUFS_D_WLOCK);
438
aufs_read_lock(dentry, AuLock_DW);
394
439
bstart = dbstart(dentry);
395
bcpup = err = wr_dir(dentry, /*add*/0, /*src_dentry*/NULL,
396
/*force_btgt*/-1, /*do_lock_srcdir*/0);
440
err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args);
398
443
if (unlikely(err < 0))
401
446
/* crazy udba locks */
402
udba = au_flag_test(dentry->d_sb, AuFlag_UDBA_INOTIFY);
448
udba = au_flag_test_udba_inotify(sb);
404
gdir = gh_dir = dir = h_dir = NULL;
405
if ((udba || bstart != bcpup) && !IS_ROOT(dentry)) {
406
parent = dentry->d_parent; // dget_parent()
451
if (!IS_ROOT(dentry)) {
452
parent = dget_parent(dentry);
407
453
dir = parent->d_inode;
408
di_read_lock_parent(parent, AUFS_I_RLOCK);
409
h_dir = au_h_iptr_i(dir, bcpup);
412
if (unlikely(udba && !IS_ROOT(parent))) {
413
gdir = parent->d_parent->d_inode; // dget_parent()
414
ii_read_lock_parent2(gdir);
415
gh_dir = au_h_iptr_i(gdir, bcpup);
416
hgdir_lock(gh_dir, gdir, bcpup);
418
hdir_lock(h_dir, dir, bcpup);
421
isdir = S_ISDIR(inode->i_mode);
422
hidden_dentry = au_h_dptr(dentry);
423
hidden_inode = hidden_dentry->d_inode;
424
AuDebugOn(!hidden_inode);
426
#define HiLock(bindex) do {\
428
hi_lock_child(hidden_inode); \
430
hdir2_lock(hidden_inode, inode, bindex); \
454
di_read_lock_parent(parent, AuLock_IR);
458
if (unlikely(udba && parent && !IS_ROOT(parent))) {
459
gparent = dget_parent(parent);
460
gdir = gparent->d_inode;
461
ii_read_lock_parent2(gdir);
464
h_dentry = au_h_dptr(dentry);
465
h_inode = h_dentry->d_inode;
468
#define HiLock(bindex) \
470
if (!wr_dir_args.isdir) \
471
vfsub_i_lock_nested(h_inode, AuLsc_I_CHILD); \
473
hdir2_lock(h_inode, inode, bindex); \
432
#define HiUnlock(bindex) do {\
434
i_unlock(hidden_inode); \
436
hdir_unlock(hidden_inode, inode, bindex); \
475
#define HiUnlock(bindex) \
477
if (!wr_dir_args.isdir) \
478
vfsub_i_unlock(h_inode); \
480
hdir_unlock(h_inode, inode, bindex); \
439
483
if (bstart != bcpup) {
444
488
size = ia->ia_size;
445
489
ia->ia_valid &= ~ATTR_SIZE;
492
h_dir = au_h_iptr_i(dir, bcpup);
493
hdir_lock(h_dir, dir, bcpup);
448
err = sio_cpup_simple(dentry, bcpup, size,
449
au_flags_cpup(CPUP_DTIME, parent));
495
if (!d_unhashed(dentry)) {
497
err = au_sio_cpup_simple(dentry, bcpup, size, &cflags);
499
hi_wh = au_hi_wh(inode, bcpup);
501
err = au_sio_cpup_wh(dentry, bcpup, size,
504
hi_wh = au_hi_wh(inode, bcpup);
451
509
HiUnlock(bstart);
510
hdir_unlock(h_dir, dir, bcpup);
452
511
if (unlikely(err || !ia->ia_valid))
455
hidden_dentry = au_h_dptr(dentry);
456
hidden_inode = hidden_dentry->d_inode;
457
AuDebugOn(!hidden_inode);
515
h_dentry = au_h_dptr(dentry);
517
h_dentry = hi_wh; /* do not dget here */
518
h_inode = h_dentry->d_inode;
522
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
523
if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
524
ia->ia_valid &= ~ATTR_MODE;
527
vfsub_args_init(&vargs, &ign, au_need_dlgt(sb), 0);
528
if (unlikely(udba && dir)) {
529
events = vfsub_events_notify_change(ia);
531
vfsub_ign_hinode(&vargs, events, itohi(dir, bcpup));
461
err = vfsub_notify_change(hidden_dentry, ia, need_dlgt(dentry->d_sb));
534
err = vfsub_notify_change(h_dentry, ia, &vargs);
464
au_cpup_attr_changable(inode);
537
au_cpup_attr_changeable(inode);
471
hdir_unlock(h_dir, dir, bcpup);
472
di_read_unlock(parent, AUFS_I_RLOCK);
544
di_read_unlock(parent, AuLock_IR);
474
547
if (unlikely(gdir)) {
475
hdir_unlock(gh_dir, gdir, bcpup);
476
548
ii_read_unlock(gdir);
479
aufs_read_unlock(dentry, AUFS_D_WLOCK);
552
aufs_read_unlock(dentry, AuLock_DW);
557
/* currently, for fuse only */
558
#ifdef CONFIG_AUFS_WORKAROUND_FUSE
559
static int aufs_getattr(struct vfsmount *mnt, struct dentry *dentry,
563
struct inode *inode, *h_inode;
564
struct dentry *h_dentry;
566
LKTRTrace("%.*s\n", AuDLNPair(dentry));
569
aufs_read_lock(dentry, AuLock_IR);
570
inode = dentry->d_inode;
571
h_inode = au_h_iptr(inode);
572
if (unlikely(au_test_fuse(h_inode->i_sb))) {
573
h_dentry = d_find_alias(h_inode);
574
/* simply gave up updating fuse inode */
577
if (!au_update_fuse_h_inode(NULL, h_dentry))
578
au_cpup_attr_all(inode);
582
generic_fillattr(inode, st);
584
aufs_read_unlock(dentry, AuLock_IR);
587
#endif /* CONFIG_AUFS_WORKAROUND_FUSE */
484
589
/* ---------------------------------------------------------------------- */
486
static int hidden_readlink(struct dentry *dentry, int bindex,
487
char __user * buf, int bufsiz)
591
static int h_readlink(struct dentry *dentry, int bindex, char __user *buf,
489
594
struct super_block *sb;
490
struct dentry *hidden_dentry;
492
hidden_dentry = au_h_dptr_i(dentry, bindex);
493
if (unlikely(!hidden_dentry->d_inode->i_op
494
|| !hidden_dentry->d_inode->i_op->readlink))
595
struct dentry *h_dentry;
597
LKTRTrace("%.*s, b%d, %d\n", AuDLNPair(dentry), bindex, bufsiz);
599
h_dentry = au_h_dptr_i(dentry, bindex);
600
if (unlikely(!h_dentry->d_inode->i_op
601
|| !h_dentry->d_inode->i_op->readlink))
497
604
sb = dentry->d_sb;
498
if (!test_ro(sb, bindex, dentry->d_inode)) {
499
touch_atime(sbr_mnt(sb, bindex), hidden_dentry);
500
dentry->d_inode->i_atime = hidden_dentry->d_inode->i_atime;
605
if (!au_test_ro(sb, bindex, dentry->d_inode)) {
606
touch_atime(sbr_mnt(sb, bindex), h_dentry);
607
au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/
608
dentry->d_inode->i_atime = h_dentry->d_inode->i_atime;
502
return hidden_dentry->d_inode->i_op->readlink
503
(hidden_dentry, buf, bufsiz);
610
return h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz);
506
static int aufs_readlink(struct dentry *dentry, char __user * buf, int bufsiz)
613
static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
510
LKTRTrace("%.*s, %d\n", DLNPair(dentry), bufsiz);
617
LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), bufsiz);
512
aufs_read_lock(dentry, AUFS_I_RLOCK);
513
err = hidden_readlink(dentry, dbstart(dentry), buf, bufsiz);
619
aufs_read_lock(dentry, AuLock_IR);
620
err = h_readlink(dentry, dbstart(dentry), buf, bufsiz);
515
aufs_read_unlock(dentry, AUFS_I_RLOCK);
622
aufs_read_unlock(dentry, AuLock_IR);
552
658
path_release(nd);
554
660
return ERR_PTR(err);
557
663
static void aufs_put_link(struct dentry *dentry, struct nameidata *nd,
560
LKTRTrace("%.*s\n", DLNPair(dentry));
666
LKTRTrace("%.*s\n", AuDLNPair(dentry));
561
667
__putname(nd_get_link(nd));
564
670
/* ---------------------------------------------------------------------- */
566
struct inode_operations {
567
int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
568
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
569
int (*link) (struct dentry *,struct inode *,struct dentry *);
570
int (*unlink) (struct inode *,struct dentry *);
571
int (*symlink) (struct inode *,struct dentry *,const char *);
572
int (*mkdir) (struct inode *,struct dentry *,int);
573
int (*rmdir) (struct inode *,struct dentry *);
574
int (*mknod) (struct inode *,struct dentry *,int,dev_t);
575
int (*rename) (struct inode *, struct dentry *,
576
struct inode *, struct dentry *);
577
int (*readlink) (struct dentry *, char __user *,int);
578
void * (*follow_link) (struct dentry *, struct nameidata *);
579
void (*put_link) (struct dentry *, struct nameidata *, void *);
580
void (*truncate) (struct inode *);
581
int (*permission) (struct inode *, int, struct nameidata *);
582
int (*setattr) (struct dentry *, struct iattr *);
583
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
584
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
585
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
586
ssize_t (*listxattr) (struct dentry *, char *, size_t);
587
int (*removexattr) (struct dentry *, const char *);
588
void (*truncate_range)(struct inode *, loff_t, loff_t);
672
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
673
static void aufs_truncate_range(struct inode *inode, loff_t start, loff_t end)
679
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
680
static long aufs_fallocate(struct inode *inode, int mode, loff_t offset,
688
/* ---------------------------------------------------------------------- */
592
690
struct inode_operations aufs_symlink_iop = {
593
691
.permission = aufs_permission,
594
692
.setattr = aufs_setattr,
693
#ifdef CONFIG_AUFS_WORKAROUND_FUSE
694
.getattr = aufs_getattr,
596
697
.readlink = aufs_readlink,
597
698
.follow_link = aufs_follow_link,
612
713
.permission = aufs_permission,
613
714
.setattr = aufs_setattr,
715
#ifdef CONFIG_AUFS_WORKAROUND_FUSE
716
.getattr = aufs_getattr,
616
720
.setxattr = aufs_setxattr,
617
721
.getxattr = aufs_getxattr,
618
722
.listxattr = aufs_listxattr,
619
.removexattr = aufs_removexattr
723
.removexattr = aufs_removexattr,
726
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
727
.fallocate = aufs_fallocate
623
731
struct inode_operations aufs_iop = {
624
732
.permission = aufs_permission,
625
733
.setattr = aufs_setattr,
734
#ifdef CONFIG_AUFS_WORKAROUND_FUSE
735
.getattr = aufs_getattr,
628
739
.setxattr = aufs_setxattr,
629
740
.getxattr = aufs_getxattr,
630
741
.listxattr = aufs_listxattr,
631
.removexattr = aufs_removexattr
742
.removexattr = aufs_removexattr,
745
//void (*truncate) (struct inode *);
746
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
747
.truncate_range = aufs_truncate_range,
750
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
751
.fallocate = aufs_fallocate