Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/fs/afs/dir.c
15111 views
1
/* dir.c: AFS filesystem directory handling
2
*
3
* Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version
9
* 2 of the License, or (at your option) any later version.
10
*/
11
12
#include <linux/kernel.h>
13
#include <linux/module.h>
14
#include <linux/init.h>
15
#include <linux/fs.h>
16
#include <linux/namei.h>
17
#include <linux/pagemap.h>
18
#include <linux/ctype.h>
19
#include <linux/sched.h>
20
#include "internal.h"
21
22
static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
23
struct nameidata *nd);
24
static int afs_dir_open(struct inode *inode, struct file *file);
25
static int afs_readdir(struct file *file, void *dirent, filldir_t filldir);
26
static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
27
static int afs_d_delete(const struct dentry *dentry);
28
static void afs_d_release(struct dentry *dentry);
29
static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
30
loff_t fpos, u64 ino, unsigned dtype);
31
static int afs_create(struct inode *dir, struct dentry *dentry, int mode,
32
struct nameidata *nd);
33
static int afs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
34
static int afs_rmdir(struct inode *dir, struct dentry *dentry);
35
static int afs_unlink(struct inode *dir, struct dentry *dentry);
36
static int afs_link(struct dentry *from, struct inode *dir,
37
struct dentry *dentry);
38
static int afs_symlink(struct inode *dir, struct dentry *dentry,
39
const char *content);
40
static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
41
struct inode *new_dir, struct dentry *new_dentry);
42
43
const struct file_operations afs_dir_file_operations = {
44
.open = afs_dir_open,
45
.release = afs_release,
46
.readdir = afs_readdir,
47
.lock = afs_lock,
48
.llseek = generic_file_llseek,
49
};
50
51
const struct inode_operations afs_dir_inode_operations = {
52
.create = afs_create,
53
.lookup = afs_lookup,
54
.link = afs_link,
55
.unlink = afs_unlink,
56
.symlink = afs_symlink,
57
.mkdir = afs_mkdir,
58
.rmdir = afs_rmdir,
59
.rename = afs_rename,
60
.permission = afs_permission,
61
.getattr = afs_getattr,
62
.setattr = afs_setattr,
63
};
64
65
const struct dentry_operations afs_fs_dentry_operations = {
66
.d_revalidate = afs_d_revalidate,
67
.d_delete = afs_d_delete,
68
.d_release = afs_d_release,
69
.d_automount = afs_d_automount,
70
};
71
72
#define AFS_DIR_HASHTBL_SIZE 128
73
#define AFS_DIR_DIRENT_SIZE 32
74
#define AFS_DIRENT_PER_BLOCK 64
75
76
union afs_dirent {
77
struct {
78
uint8_t valid;
79
uint8_t unused[1];
80
__be16 hash_next;
81
__be32 vnode;
82
__be32 unique;
83
uint8_t name[16];
84
uint8_t overflow[4]; /* if any char of the name (inc
85
* NUL) reaches here, consume
86
* the next dirent too */
87
} u;
88
uint8_t extended_name[32];
89
};
90
91
/* AFS directory page header (one at the beginning of every 2048-byte chunk) */
92
struct afs_dir_pagehdr {
93
__be16 npages;
94
__be16 magic;
95
#define AFS_DIR_MAGIC htons(1234)
96
uint8_t nentries;
97
uint8_t bitmap[8];
98
uint8_t pad[19];
99
};
100
101
/* directory block layout */
102
union afs_dir_block {
103
104
struct afs_dir_pagehdr pagehdr;
105
106
struct {
107
struct afs_dir_pagehdr pagehdr;
108
uint8_t alloc_ctrs[128];
109
/* dir hash table */
110
uint16_t hashtable[AFS_DIR_HASHTBL_SIZE];
111
} hdr;
112
113
union afs_dirent dirents[AFS_DIRENT_PER_BLOCK];
114
};
115
116
/* layout on a linux VM page */
117
struct afs_dir_page {
118
union afs_dir_block blocks[PAGE_SIZE / sizeof(union afs_dir_block)];
119
};
120
121
struct afs_lookup_cookie {
122
struct afs_fid fid;
123
const char *name;
124
size_t nlen;
125
int found;
126
};
127
128
/*
129
* check that a directory page is valid
130
*/
131
static inline void afs_dir_check_page(struct inode *dir, struct page *page)
132
{
133
struct afs_dir_page *dbuf;
134
loff_t latter;
135
int tmp, qty;
136
137
#if 0
138
/* check the page count */
139
qty = desc.size / sizeof(dbuf->blocks[0]);
140
if (qty == 0)
141
goto error;
142
143
if (page->index == 0 && qty != ntohs(dbuf->blocks[0].pagehdr.npages)) {
144
printk("kAFS: %s(%lu): wrong number of dir blocks %d!=%hu\n",
145
__func__, dir->i_ino, qty,
146
ntohs(dbuf->blocks[0].pagehdr.npages));
147
goto error;
148
}
149
#endif
150
151
/* determine how many magic numbers there should be in this page */
152
latter = dir->i_size - page_offset(page);
153
if (latter >= PAGE_SIZE)
154
qty = PAGE_SIZE;
155
else
156
qty = latter;
157
qty /= sizeof(union afs_dir_block);
158
159
/* check them */
160
dbuf = page_address(page);
161
for (tmp = 0; tmp < qty; tmp++) {
162
if (dbuf->blocks[tmp].pagehdr.magic != AFS_DIR_MAGIC) {
163
printk("kAFS: %s(%lu): bad magic %d/%d is %04hx\n",
164
__func__, dir->i_ino, tmp, qty,
165
ntohs(dbuf->blocks[tmp].pagehdr.magic));
166
goto error;
167
}
168
}
169
170
SetPageChecked(page);
171
return;
172
173
error:
174
SetPageChecked(page);
175
SetPageError(page);
176
}
177
178
/*
179
* discard a page cached in the pagecache
180
*/
181
static inline void afs_dir_put_page(struct page *page)
182
{
183
kunmap(page);
184
page_cache_release(page);
185
}
186
187
/*
188
* get a page into the pagecache
189
*/
190
static struct page *afs_dir_get_page(struct inode *dir, unsigned long index,
191
struct key *key)
192
{
193
struct page *page;
194
_enter("{%lu},%lu", dir->i_ino, index);
195
196
page = read_cache_page(dir->i_mapping, index, afs_page_filler, key);
197
if (!IS_ERR(page)) {
198
kmap(page);
199
if (!PageChecked(page))
200
afs_dir_check_page(dir, page);
201
if (PageError(page))
202
goto fail;
203
}
204
return page;
205
206
fail:
207
afs_dir_put_page(page);
208
_leave(" = -EIO");
209
return ERR_PTR(-EIO);
210
}
211
212
/*
213
* open an AFS directory file
214
*/
215
static int afs_dir_open(struct inode *inode, struct file *file)
216
{
217
_enter("{%lu}", inode->i_ino);
218
219
BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
220
BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
221
222
if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(inode)->flags))
223
return -ENOENT;
224
225
return afs_open(inode, file);
226
}
227
228
/*
229
* deal with one block in an AFS directory
230
*/
231
static int afs_dir_iterate_block(unsigned *fpos,
232
union afs_dir_block *block,
233
unsigned blkoff,
234
void *cookie,
235
filldir_t filldir)
236
{
237
union afs_dirent *dire;
238
unsigned offset, next, curr;
239
size_t nlen;
240
int tmp, ret;
241
242
_enter("%u,%x,%p,,",*fpos,blkoff,block);
243
244
curr = (*fpos - blkoff) / sizeof(union afs_dirent);
245
246
/* walk through the block, an entry at a time */
247
for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries;
248
offset < AFS_DIRENT_PER_BLOCK;
249
offset = next
250
) {
251
next = offset + 1;
252
253
/* skip entries marked unused in the bitmap */
254
if (!(block->pagehdr.bitmap[offset / 8] &
255
(1 << (offset % 8)))) {
256
_debug("ENT[%Zu.%u]: unused",
257
blkoff / sizeof(union afs_dir_block), offset);
258
if (offset >= curr)
259
*fpos = blkoff +
260
next * sizeof(union afs_dirent);
261
continue;
262
}
263
264
/* got a valid entry */
265
dire = &block->dirents[offset];
266
nlen = strnlen(dire->u.name,
267
sizeof(*block) -
268
offset * sizeof(union afs_dirent));
269
270
_debug("ENT[%Zu.%u]: %s %Zu \"%s\"",
271
blkoff / sizeof(union afs_dir_block), offset,
272
(offset < curr ? "skip" : "fill"),
273
nlen, dire->u.name);
274
275
/* work out where the next possible entry is */
276
for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_dirent)) {
277
if (next >= AFS_DIRENT_PER_BLOCK) {
278
_debug("ENT[%Zu.%u]:"
279
" %u travelled beyond end dir block"
280
" (len %u/%Zu)",
281
blkoff / sizeof(union afs_dir_block),
282
offset, next, tmp, nlen);
283
return -EIO;
284
}
285
if (!(block->pagehdr.bitmap[next / 8] &
286
(1 << (next % 8)))) {
287
_debug("ENT[%Zu.%u]:"
288
" %u unmarked extension (len %u/%Zu)",
289
blkoff / sizeof(union afs_dir_block),
290
offset, next, tmp, nlen);
291
return -EIO;
292
}
293
294
_debug("ENT[%Zu.%u]: ext %u/%Zu",
295
blkoff / sizeof(union afs_dir_block),
296
next, tmp, nlen);
297
next++;
298
}
299
300
/* skip if starts before the current position */
301
if (offset < curr)
302
continue;
303
304
/* found the next entry */
305
ret = filldir(cookie,
306
dire->u.name,
307
nlen,
308
blkoff + offset * sizeof(union afs_dirent),
309
ntohl(dire->u.vnode),
310
filldir == afs_lookup_filldir ?
311
ntohl(dire->u.unique) : DT_UNKNOWN);
312
if (ret < 0) {
313
_leave(" = 0 [full]");
314
return 0;
315
}
316
317
*fpos = blkoff + next * sizeof(union afs_dirent);
318
}
319
320
_leave(" = 1 [more]");
321
return 1;
322
}
323
324
/*
325
* iterate through the data blob that lists the contents of an AFS directory
326
*/
327
static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
328
filldir_t filldir, struct key *key)
329
{
330
union afs_dir_block *dblock;
331
struct afs_dir_page *dbuf;
332
struct page *page;
333
unsigned blkoff, limit;
334
int ret;
335
336
_enter("{%lu},%u,,", dir->i_ino, *fpos);
337
338
if (test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dir)->flags)) {
339
_leave(" = -ESTALE");
340
return -ESTALE;
341
}
342
343
/* round the file position up to the next entry boundary */
344
*fpos += sizeof(union afs_dirent) - 1;
345
*fpos &= ~(sizeof(union afs_dirent) - 1);
346
347
/* walk through the blocks in sequence */
348
ret = 0;
349
while (*fpos < dir->i_size) {
350
blkoff = *fpos & ~(sizeof(union afs_dir_block) - 1);
351
352
/* fetch the appropriate page from the directory */
353
page = afs_dir_get_page(dir, blkoff / PAGE_SIZE, key);
354
if (IS_ERR(page)) {
355
ret = PTR_ERR(page);
356
break;
357
}
358
359
limit = blkoff & ~(PAGE_SIZE - 1);
360
361
dbuf = page_address(page);
362
363
/* deal with the individual blocks stashed on this page */
364
do {
365
dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) /
366
sizeof(union afs_dir_block)];
367
ret = afs_dir_iterate_block(fpos, dblock, blkoff,
368
cookie, filldir);
369
if (ret != 1) {
370
afs_dir_put_page(page);
371
goto out;
372
}
373
374
blkoff += sizeof(union afs_dir_block);
375
376
} while (*fpos < dir->i_size && blkoff < limit);
377
378
afs_dir_put_page(page);
379
ret = 0;
380
}
381
382
out:
383
_leave(" = %d", ret);
384
return ret;
385
}
386
387
/*
388
* read an AFS directory
389
*/
390
static int afs_readdir(struct file *file, void *cookie, filldir_t filldir)
391
{
392
unsigned fpos;
393
int ret;
394
395
_enter("{%Ld,{%lu}}",
396
file->f_pos, file->f_path.dentry->d_inode->i_ino);
397
398
ASSERT(file->private_data != NULL);
399
400
fpos = file->f_pos;
401
ret = afs_dir_iterate(file->f_path.dentry->d_inode, &fpos,
402
cookie, filldir, file->private_data);
403
file->f_pos = fpos;
404
405
_leave(" = %d", ret);
406
return ret;
407
}
408
409
/*
410
* search the directory for a name
411
* - if afs_dir_iterate_block() spots this function, it'll pass the FID
412
* uniquifier through dtype
413
*/
414
static int afs_lookup_filldir(void *_cookie, const char *name, int nlen,
415
loff_t fpos, u64 ino, unsigned dtype)
416
{
417
struct afs_lookup_cookie *cookie = _cookie;
418
419
_enter("{%s,%Zu},%s,%u,,%llu,%u",
420
cookie->name, cookie->nlen, name, nlen,
421
(unsigned long long) ino, dtype);
422
423
/* insanity checks first */
424
BUILD_BUG_ON(sizeof(union afs_dir_block) != 2048);
425
BUILD_BUG_ON(sizeof(union afs_dirent) != 32);
426
427
if (cookie->nlen != nlen || memcmp(cookie->name, name, nlen) != 0) {
428
_leave(" = 0 [no]");
429
return 0;
430
}
431
432
cookie->fid.vnode = ino;
433
cookie->fid.unique = dtype;
434
cookie->found = 1;
435
436
_leave(" = -1 [found]");
437
return -1;
438
}
439
440
/*
441
* do a lookup in a directory
442
* - just returns the FID the dentry name maps to if found
443
*/
444
static int afs_do_lookup(struct inode *dir, struct dentry *dentry,
445
struct afs_fid *fid, struct key *key)
446
{
447
struct afs_lookup_cookie cookie;
448
struct afs_super_info *as;
449
unsigned fpos;
450
int ret;
451
452
_enter("{%lu},%p{%s},", dir->i_ino, dentry, dentry->d_name.name);
453
454
as = dir->i_sb->s_fs_info;
455
456
/* search the directory */
457
cookie.name = dentry->d_name.name;
458
cookie.nlen = dentry->d_name.len;
459
cookie.fid.vid = as->volume->vid;
460
cookie.found = 0;
461
462
fpos = 0;
463
ret = afs_dir_iterate(dir, &fpos, &cookie, afs_lookup_filldir,
464
key);
465
if (ret < 0) {
466
_leave(" = %d [iter]", ret);
467
return ret;
468
}
469
470
ret = -ENOENT;
471
if (!cookie.found) {
472
_leave(" = -ENOENT [not found]");
473
return -ENOENT;
474
}
475
476
*fid = cookie.fid;
477
_leave(" = 0 { vn=%u u=%u }", fid->vnode, fid->unique);
478
return 0;
479
}
480
481
/*
482
* Try to auto mount the mountpoint with pseudo directory, if the autocell
483
* operation is setted.
484
*/
485
static struct inode *afs_try_auto_mntpt(
486
int ret, struct dentry *dentry, struct inode *dir, struct key *key,
487
struct afs_fid *fid)
488
{
489
const char *devname = dentry->d_name.name;
490
struct afs_vnode *vnode = AFS_FS_I(dir);
491
struct inode *inode;
492
493
_enter("%d, %p{%s}, {%x:%u}, %p",
494
ret, dentry, devname, vnode->fid.vid, vnode->fid.vnode, key);
495
496
if (ret != -ENOENT ||
497
!test_bit(AFS_VNODE_AUTOCELL, &vnode->flags))
498
goto out;
499
500
inode = afs_iget_autocell(dir, devname, strlen(devname), key);
501
if (IS_ERR(inode)) {
502
ret = PTR_ERR(inode);
503
goto out;
504
}
505
506
*fid = AFS_FS_I(inode)->fid;
507
_leave("= %p", inode);
508
return inode;
509
510
out:
511
_leave("= %d", ret);
512
return ERR_PTR(ret);
513
}
514
515
/*
516
* look up an entry in a directory
517
*/
518
static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
519
struct nameidata *nd)
520
{
521
struct afs_vnode *vnode;
522
struct afs_fid fid;
523
struct inode *inode;
524
struct key *key;
525
int ret;
526
527
vnode = AFS_FS_I(dir);
528
529
_enter("{%x:%u},%p{%s},",
530
vnode->fid.vid, vnode->fid.vnode, dentry, dentry->d_name.name);
531
532
ASSERTCMP(dentry->d_inode, ==, NULL);
533
534
if (dentry->d_name.len >= AFSNAMEMAX) {
535
_leave(" = -ENAMETOOLONG");
536
return ERR_PTR(-ENAMETOOLONG);
537
}
538
539
if (test_bit(AFS_VNODE_DELETED, &vnode->flags)) {
540
_leave(" = -ESTALE");
541
return ERR_PTR(-ESTALE);
542
}
543
544
key = afs_request_key(vnode->volume->cell);
545
if (IS_ERR(key)) {
546
_leave(" = %ld [key]", PTR_ERR(key));
547
return ERR_CAST(key);
548
}
549
550
ret = afs_validate(vnode, key);
551
if (ret < 0) {
552
key_put(key);
553
_leave(" = %d [val]", ret);
554
return ERR_PTR(ret);
555
}
556
557
ret = afs_do_lookup(dir, dentry, &fid, key);
558
if (ret < 0) {
559
inode = afs_try_auto_mntpt(ret, dentry, dir, key, &fid);
560
if (!IS_ERR(inode)) {
561
key_put(key);
562
goto success;
563
}
564
565
ret = PTR_ERR(inode);
566
key_put(key);
567
if (ret == -ENOENT) {
568
d_add(dentry, NULL);
569
_leave(" = NULL [negative]");
570
return NULL;
571
}
572
_leave(" = %d [do]", ret);
573
return ERR_PTR(ret);
574
}
575
dentry->d_fsdata = (void *)(unsigned long) vnode->status.data_version;
576
577
/* instantiate the dentry */
578
inode = afs_iget(dir->i_sb, key, &fid, NULL, NULL);
579
key_put(key);
580
if (IS_ERR(inode)) {
581
_leave(" = %ld", PTR_ERR(inode));
582
return ERR_CAST(inode);
583
}
584
585
success:
586
d_add(dentry, inode);
587
_leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%u }",
588
fid.vnode,
589
fid.unique,
590
dentry->d_inode->i_ino,
591
dentry->d_inode->i_generation);
592
593
return NULL;
594
}
595
596
/*
597
* check that a dentry lookup hit has found a valid entry
598
* - NOTE! the hit can be a negative hit too, so we can't assume we have an
599
* inode
600
*/
601
static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
602
{
603
struct afs_vnode *vnode, *dir;
604
struct afs_fid uninitialized_var(fid);
605
struct dentry *parent;
606
struct key *key;
607
void *dir_version;
608
int ret;
609
610
if (nd->flags & LOOKUP_RCU)
611
return -ECHILD;
612
613
vnode = AFS_FS_I(dentry->d_inode);
614
615
if (dentry->d_inode)
616
_enter("{v={%x:%u} n=%s fl=%lx},",
617
vnode->fid.vid, vnode->fid.vnode, dentry->d_name.name,
618
vnode->flags);
619
else
620
_enter("{neg n=%s}", dentry->d_name.name);
621
622
key = afs_request_key(AFS_FS_S(dentry->d_sb)->volume->cell);
623
if (IS_ERR(key))
624
key = NULL;
625
626
/* lock down the parent dentry so we can peer at it */
627
parent = dget_parent(dentry);
628
if (!parent->d_inode)
629
goto out_bad;
630
631
dir = AFS_FS_I(parent->d_inode);
632
633
/* validate the parent directory */
634
if (test_bit(AFS_VNODE_MODIFIED, &dir->flags))
635
afs_validate(dir, key);
636
637
if (test_bit(AFS_VNODE_DELETED, &dir->flags)) {
638
_debug("%s: parent dir deleted", dentry->d_name.name);
639
goto out_bad;
640
}
641
642
dir_version = (void *) (unsigned long) dir->status.data_version;
643
if (dentry->d_fsdata == dir_version)
644
goto out_valid; /* the dir contents are unchanged */
645
646
_debug("dir modified");
647
648
/* search the directory for this vnode */
649
ret = afs_do_lookup(&dir->vfs_inode, dentry, &fid, key);
650
switch (ret) {
651
case 0:
652
/* the filename maps to something */
653
if (!dentry->d_inode)
654
goto out_bad;
655
if (is_bad_inode(dentry->d_inode)) {
656
printk("kAFS: afs_d_revalidate: %s/%s has bad inode\n",
657
parent->d_name.name, dentry->d_name.name);
658
goto out_bad;
659
}
660
661
/* if the vnode ID has changed, then the dirent points to a
662
* different file */
663
if (fid.vnode != vnode->fid.vnode) {
664
_debug("%s: dirent changed [%u != %u]",
665
dentry->d_name.name, fid.vnode,
666
vnode->fid.vnode);
667
goto not_found;
668
}
669
670
/* if the vnode ID uniqifier has changed, then the file has
671
* been deleted and replaced, and the original vnode ID has
672
* been reused */
673
if (fid.unique != vnode->fid.unique) {
674
_debug("%s: file deleted (uq %u -> %u I:%u)",
675
dentry->d_name.name, fid.unique,
676
vnode->fid.unique,
677
dentry->d_inode->i_generation);
678
spin_lock(&vnode->lock);
679
set_bit(AFS_VNODE_DELETED, &vnode->flags);
680
spin_unlock(&vnode->lock);
681
goto not_found;
682
}
683
goto out_valid;
684
685
case -ENOENT:
686
/* the filename is unknown */
687
_debug("%s: dirent not found", dentry->d_name.name);
688
if (dentry->d_inode)
689
goto not_found;
690
goto out_valid;
691
692
default:
693
_debug("failed to iterate dir %s: %d",
694
parent->d_name.name, ret);
695
goto out_bad;
696
}
697
698
out_valid:
699
dentry->d_fsdata = dir_version;
700
out_skip:
701
dput(parent);
702
key_put(key);
703
_leave(" = 1 [valid]");
704
return 1;
705
706
/* the dirent, if it exists, now points to a different vnode */
707
not_found:
708
spin_lock(&dentry->d_lock);
709
dentry->d_flags |= DCACHE_NFSFS_RENAMED;
710
spin_unlock(&dentry->d_lock);
711
712
out_bad:
713
if (dentry->d_inode) {
714
/* don't unhash if we have submounts */
715
if (have_submounts(dentry))
716
goto out_skip;
717
}
718
719
_debug("dropping dentry %s/%s",
720
parent->d_name.name, dentry->d_name.name);
721
shrink_dcache_parent(dentry);
722
d_drop(dentry);
723
dput(parent);
724
key_put(key);
725
726
_leave(" = 0 [bad]");
727
return 0;
728
}
729
730
/*
731
* allow the VFS to enquire as to whether a dentry should be unhashed (mustn't
732
* sleep)
733
* - called from dput() when d_count is going to 0.
734
* - return 1 to request dentry be unhashed, 0 otherwise
735
*/
736
static int afs_d_delete(const struct dentry *dentry)
737
{
738
_enter("%s", dentry->d_name.name);
739
740
if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
741
goto zap;
742
743
if (dentry->d_inode &&
744
(test_bit(AFS_VNODE_DELETED, &AFS_FS_I(dentry->d_inode)->flags) ||
745
test_bit(AFS_VNODE_PSEUDODIR, &AFS_FS_I(dentry->d_inode)->flags)))
746
goto zap;
747
748
_leave(" = 0 [keep]");
749
return 0;
750
751
zap:
752
_leave(" = 1 [zap]");
753
return 1;
754
}
755
756
/*
757
* handle dentry release
758
*/
759
static void afs_d_release(struct dentry *dentry)
760
{
761
_enter("%s", dentry->d_name.name);
762
}
763
764
/*
765
* create a directory on an AFS filesystem
766
*/
767
static int afs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
768
{
769
struct afs_file_status status;
770
struct afs_callback cb;
771
struct afs_server *server;
772
struct afs_vnode *dvnode, *vnode;
773
struct afs_fid fid;
774
struct inode *inode;
775
struct key *key;
776
int ret;
777
778
dvnode = AFS_FS_I(dir);
779
780
_enter("{%x:%u},{%s},%o",
781
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode);
782
783
ret = -ENAMETOOLONG;
784
if (dentry->d_name.len >= AFSNAMEMAX)
785
goto error;
786
787
key = afs_request_key(dvnode->volume->cell);
788
if (IS_ERR(key)) {
789
ret = PTR_ERR(key);
790
goto error;
791
}
792
793
mode |= S_IFDIR;
794
ret = afs_vnode_create(dvnode, key, dentry->d_name.name,
795
mode, &fid, &status, &cb, &server);
796
if (ret < 0)
797
goto mkdir_error;
798
799
inode = afs_iget(dir->i_sb, key, &fid, &status, &cb);
800
if (IS_ERR(inode)) {
801
/* ENOMEM at a really inconvenient time - just abandon the new
802
* directory on the server */
803
ret = PTR_ERR(inode);
804
goto iget_error;
805
}
806
807
/* apply the status report we've got for the new vnode */
808
vnode = AFS_FS_I(inode);
809
spin_lock(&vnode->lock);
810
vnode->update_cnt++;
811
spin_unlock(&vnode->lock);
812
afs_vnode_finalise_status_update(vnode, server);
813
afs_put_server(server);
814
815
d_instantiate(dentry, inode);
816
if (d_unhashed(dentry)) {
817
_debug("not hashed");
818
d_rehash(dentry);
819
}
820
key_put(key);
821
_leave(" = 0");
822
return 0;
823
824
iget_error:
825
afs_put_server(server);
826
mkdir_error:
827
key_put(key);
828
error:
829
d_drop(dentry);
830
_leave(" = %d", ret);
831
return ret;
832
}
833
834
/*
835
* remove a directory from an AFS filesystem
836
*/
837
static int afs_rmdir(struct inode *dir, struct dentry *dentry)
838
{
839
struct afs_vnode *dvnode, *vnode;
840
struct key *key;
841
int ret;
842
843
dvnode = AFS_FS_I(dir);
844
845
_enter("{%x:%u},{%s}",
846
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
847
848
ret = -ENAMETOOLONG;
849
if (dentry->d_name.len >= AFSNAMEMAX)
850
goto error;
851
852
key = afs_request_key(dvnode->volume->cell);
853
if (IS_ERR(key)) {
854
ret = PTR_ERR(key);
855
goto error;
856
}
857
858
ret = afs_vnode_remove(dvnode, key, dentry->d_name.name, true);
859
if (ret < 0)
860
goto rmdir_error;
861
862
if (dentry->d_inode) {
863
vnode = AFS_FS_I(dentry->d_inode);
864
clear_nlink(&vnode->vfs_inode);
865
set_bit(AFS_VNODE_DELETED, &vnode->flags);
866
afs_discard_callback_on_delete(vnode);
867
}
868
869
key_put(key);
870
_leave(" = 0");
871
return 0;
872
873
rmdir_error:
874
key_put(key);
875
error:
876
_leave(" = %d", ret);
877
return ret;
878
}
879
880
/*
881
* remove a file from an AFS filesystem
882
*/
883
static int afs_unlink(struct inode *dir, struct dentry *dentry)
884
{
885
struct afs_vnode *dvnode, *vnode;
886
struct key *key;
887
int ret;
888
889
dvnode = AFS_FS_I(dir);
890
891
_enter("{%x:%u},{%s}",
892
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name);
893
894
ret = -ENAMETOOLONG;
895
if (dentry->d_name.len >= AFSNAMEMAX)
896
goto error;
897
898
key = afs_request_key(dvnode->volume->cell);
899
if (IS_ERR(key)) {
900
ret = PTR_ERR(key);
901
goto error;
902
}
903
904
if (dentry->d_inode) {
905
vnode = AFS_FS_I(dentry->d_inode);
906
907
/* make sure we have a callback promise on the victim */
908
ret = afs_validate(vnode, key);
909
if (ret < 0)
910
goto error;
911
}
912
913
ret = afs_vnode_remove(dvnode, key, dentry->d_name.name, false);
914
if (ret < 0)
915
goto remove_error;
916
917
if (dentry->d_inode) {
918
/* if the file wasn't deleted due to excess hard links, the
919
* fileserver will break the callback promise on the file - if
920
* it had one - before it returns to us, and if it was deleted,
921
* it won't
922
*
923
* however, if we didn't have a callback promise outstanding,
924
* or it was outstanding on a different server, then it won't
925
* break it either...
926
*/
927
vnode = AFS_FS_I(dentry->d_inode);
928
if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
929
_debug("AFS_VNODE_DELETED");
930
if (test_bit(AFS_VNODE_CB_BROKEN, &vnode->flags))
931
_debug("AFS_VNODE_CB_BROKEN");
932
set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags);
933
ret = afs_validate(vnode, key);
934
_debug("nlink %d [val %d]", vnode->vfs_inode.i_nlink, ret);
935
}
936
937
key_put(key);
938
_leave(" = 0");
939
return 0;
940
941
remove_error:
942
key_put(key);
943
error:
944
_leave(" = %d", ret);
945
return ret;
946
}
947
948
/*
949
* create a regular file on an AFS filesystem
950
*/
951
static int afs_create(struct inode *dir, struct dentry *dentry, int mode,
952
struct nameidata *nd)
953
{
954
struct afs_file_status status;
955
struct afs_callback cb;
956
struct afs_server *server;
957
struct afs_vnode *dvnode, *vnode;
958
struct afs_fid fid;
959
struct inode *inode;
960
struct key *key;
961
int ret;
962
963
dvnode = AFS_FS_I(dir);
964
965
_enter("{%x:%u},{%s},%o,",
966
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name, mode);
967
968
ret = -ENAMETOOLONG;
969
if (dentry->d_name.len >= AFSNAMEMAX)
970
goto error;
971
972
key = afs_request_key(dvnode->volume->cell);
973
if (IS_ERR(key)) {
974
ret = PTR_ERR(key);
975
goto error;
976
}
977
978
mode |= S_IFREG;
979
ret = afs_vnode_create(dvnode, key, dentry->d_name.name,
980
mode, &fid, &status, &cb, &server);
981
if (ret < 0)
982
goto create_error;
983
984
inode = afs_iget(dir->i_sb, key, &fid, &status, &cb);
985
if (IS_ERR(inode)) {
986
/* ENOMEM at a really inconvenient time - just abandon the new
987
* directory on the server */
988
ret = PTR_ERR(inode);
989
goto iget_error;
990
}
991
992
/* apply the status report we've got for the new vnode */
993
vnode = AFS_FS_I(inode);
994
spin_lock(&vnode->lock);
995
vnode->update_cnt++;
996
spin_unlock(&vnode->lock);
997
afs_vnode_finalise_status_update(vnode, server);
998
afs_put_server(server);
999
1000
d_instantiate(dentry, inode);
1001
if (d_unhashed(dentry)) {
1002
_debug("not hashed");
1003
d_rehash(dentry);
1004
}
1005
key_put(key);
1006
_leave(" = 0");
1007
return 0;
1008
1009
iget_error:
1010
afs_put_server(server);
1011
create_error:
1012
key_put(key);
1013
error:
1014
d_drop(dentry);
1015
_leave(" = %d", ret);
1016
return ret;
1017
}
1018
1019
/*
1020
* create a hard link between files in an AFS filesystem
1021
*/
1022
static int afs_link(struct dentry *from, struct inode *dir,
1023
struct dentry *dentry)
1024
{
1025
struct afs_vnode *dvnode, *vnode;
1026
struct key *key;
1027
int ret;
1028
1029
vnode = AFS_FS_I(from->d_inode);
1030
dvnode = AFS_FS_I(dir);
1031
1032
_enter("{%x:%u},{%x:%u},{%s}",
1033
vnode->fid.vid, vnode->fid.vnode,
1034
dvnode->fid.vid, dvnode->fid.vnode,
1035
dentry->d_name.name);
1036
1037
ret = -ENAMETOOLONG;
1038
if (dentry->d_name.len >= AFSNAMEMAX)
1039
goto error;
1040
1041
key = afs_request_key(dvnode->volume->cell);
1042
if (IS_ERR(key)) {
1043
ret = PTR_ERR(key);
1044
goto error;
1045
}
1046
1047
ret = afs_vnode_link(dvnode, vnode, key, dentry->d_name.name);
1048
if (ret < 0)
1049
goto link_error;
1050
1051
ihold(&vnode->vfs_inode);
1052
d_instantiate(dentry, &vnode->vfs_inode);
1053
key_put(key);
1054
_leave(" = 0");
1055
return 0;
1056
1057
link_error:
1058
key_put(key);
1059
error:
1060
d_drop(dentry);
1061
_leave(" = %d", ret);
1062
return ret;
1063
}
1064
1065
/*
1066
* create a symlink in an AFS filesystem
1067
*/
1068
static int afs_symlink(struct inode *dir, struct dentry *dentry,
1069
const char *content)
1070
{
1071
struct afs_file_status status;
1072
struct afs_server *server;
1073
struct afs_vnode *dvnode, *vnode;
1074
struct afs_fid fid;
1075
struct inode *inode;
1076
struct key *key;
1077
int ret;
1078
1079
dvnode = AFS_FS_I(dir);
1080
1081
_enter("{%x:%u},{%s},%s",
1082
dvnode->fid.vid, dvnode->fid.vnode, dentry->d_name.name,
1083
content);
1084
1085
ret = -ENAMETOOLONG;
1086
if (dentry->d_name.len >= AFSNAMEMAX)
1087
goto error;
1088
1089
ret = -EINVAL;
1090
if (strlen(content) >= AFSPATHMAX)
1091
goto error;
1092
1093
key = afs_request_key(dvnode->volume->cell);
1094
if (IS_ERR(key)) {
1095
ret = PTR_ERR(key);
1096
goto error;
1097
}
1098
1099
ret = afs_vnode_symlink(dvnode, key, dentry->d_name.name, content,
1100
&fid, &status, &server);
1101
if (ret < 0)
1102
goto create_error;
1103
1104
inode = afs_iget(dir->i_sb, key, &fid, &status, NULL);
1105
if (IS_ERR(inode)) {
1106
/* ENOMEM at a really inconvenient time - just abandon the new
1107
* directory on the server */
1108
ret = PTR_ERR(inode);
1109
goto iget_error;
1110
}
1111
1112
/* apply the status report we've got for the new vnode */
1113
vnode = AFS_FS_I(inode);
1114
spin_lock(&vnode->lock);
1115
vnode->update_cnt++;
1116
spin_unlock(&vnode->lock);
1117
afs_vnode_finalise_status_update(vnode, server);
1118
afs_put_server(server);
1119
1120
d_instantiate(dentry, inode);
1121
if (d_unhashed(dentry)) {
1122
_debug("not hashed");
1123
d_rehash(dentry);
1124
}
1125
key_put(key);
1126
_leave(" = 0");
1127
return 0;
1128
1129
iget_error:
1130
afs_put_server(server);
1131
create_error:
1132
key_put(key);
1133
error:
1134
d_drop(dentry);
1135
_leave(" = %d", ret);
1136
return ret;
1137
}
1138
1139
/*
1140
* rename a file in an AFS filesystem and/or move it between directories
1141
*/
1142
static int afs_rename(struct inode *old_dir, struct dentry *old_dentry,
1143
struct inode *new_dir, struct dentry *new_dentry)
1144
{
1145
struct afs_vnode *orig_dvnode, *new_dvnode, *vnode;
1146
struct key *key;
1147
int ret;
1148
1149
vnode = AFS_FS_I(old_dentry->d_inode);
1150
orig_dvnode = AFS_FS_I(old_dir);
1151
new_dvnode = AFS_FS_I(new_dir);
1152
1153
_enter("{%x:%u},{%x:%u},{%x:%u},{%s}",
1154
orig_dvnode->fid.vid, orig_dvnode->fid.vnode,
1155
vnode->fid.vid, vnode->fid.vnode,
1156
new_dvnode->fid.vid, new_dvnode->fid.vnode,
1157
new_dentry->d_name.name);
1158
1159
ret = -ENAMETOOLONG;
1160
if (new_dentry->d_name.len >= AFSNAMEMAX)
1161
goto error;
1162
1163
key = afs_request_key(orig_dvnode->volume->cell);
1164
if (IS_ERR(key)) {
1165
ret = PTR_ERR(key);
1166
goto error;
1167
}
1168
1169
ret = afs_vnode_rename(orig_dvnode, new_dvnode, key,
1170
old_dentry->d_name.name,
1171
new_dentry->d_name.name);
1172
if (ret < 0)
1173
goto rename_error;
1174
key_put(key);
1175
_leave(" = 0");
1176
return 0;
1177
1178
rename_error:
1179
key_put(key);
1180
error:
1181
d_drop(new_dentry);
1182
_leave(" = %d", ret);
1183
return ret;
1184
}
1185
1186