diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2007-05-15 10:37:50 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-07-09 03:22:24 -0400 |
commit | dbb7cae2a36170cd17ffbe286ec0c91a998740ff (patch) | |
tree | 1f4da65b07ac31648fe9b72f2742075486a86008 /fs/gfs2/inode.c | |
parent | 41d7db0ab437bc84f8a6e77cccc626ce937605ac (diff) |
[GFS2] Clean up inode number handling
This patch cleans up the inode number handling code. The main difference
is that instead of looking up the inodes using a struct gfs2_inum_host
we now use just the no_addr member of this structure. The tests relating
to no_formal_ino can then be done by the calling code. This has
advantages in that we want to do different things in different code
paths if the no_formal_ino doesn't match. In the NFS patch we want to
return -ESTALE, but in the ->lookup() path, its a bug in the fs if the
no_formal_ino doesn't match and thus we can withdraw in this case.
In order to later fix bz #201012, we need to be able to look up an inode
without knowing no_formal_ino, as the only information that is known to
us is the on-disk location of the inode in question.
This patch will also help us to fix bz #236099 at a later date by
cleaning up a lot of the code in that area.
There are no user visible changes as a result of this patch and there
are no changes to the on-disk format either.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 80 |
1 files changed, 31 insertions, 49 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index df0b8b3018b9..58f5a67e1c35 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -41,9 +41,9 @@ | |||
41 | static int iget_test(struct inode *inode, void *opaque) | 41 | static int iget_test(struct inode *inode, void *opaque) |
42 | { | 42 | { |
43 | struct gfs2_inode *ip = GFS2_I(inode); | 43 | struct gfs2_inode *ip = GFS2_I(inode); |
44 | struct gfs2_inum_host *inum = opaque; | 44 | u64 *no_addr = opaque; |
45 | 45 | ||
46 | if (ip->i_num.no_addr == inum->no_addr && | 46 | if (ip->i_no_addr == *no_addr && |
47 | inode->i_private != NULL) | 47 | inode->i_private != NULL) |
48 | return 1; | 48 | return 1; |
49 | 49 | ||
@@ -53,37 +53,37 @@ static int iget_test(struct inode *inode, void *opaque) | |||
53 | static int iget_set(struct inode *inode, void *opaque) | 53 | static int iget_set(struct inode *inode, void *opaque) |
54 | { | 54 | { |
55 | struct gfs2_inode *ip = GFS2_I(inode); | 55 | struct gfs2_inode *ip = GFS2_I(inode); |
56 | struct gfs2_inum_host *inum = opaque; | 56 | u64 *no_addr = opaque; |
57 | 57 | ||
58 | ip->i_num = *inum; | 58 | inode->i_ino = (unsigned long)*no_addr; |
59 | inode->i_ino = inum->no_addr; | 59 | ip->i_no_addr = *no_addr; |
60 | return 0; | 60 | return 0; |
61 | } | 61 | } |
62 | 62 | ||
63 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) | 63 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) |
64 | { | 64 | { |
65 | return ilookup5(sb, (unsigned long)inum->no_addr, | 65 | unsigned long hash = (unsigned long)no_addr; |
66 | iget_test, inum); | 66 | return ilookup5(sb, hash, iget_test, &no_addr); |
67 | } | 67 | } |
68 | 68 | ||
69 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) | 69 | static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) |
70 | { | 70 | { |
71 | return iget5_locked(sb, (unsigned long)inum->no_addr, | 71 | unsigned long hash = (unsigned long)no_addr; |
72 | iget_test, iget_set, inum); | 72 | return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); |
73 | } | 73 | } |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * gfs2_inode_lookup - Lookup an inode | 76 | * gfs2_inode_lookup - Lookup an inode |
77 | * @sb: The super block | 77 | * @sb: The super block |
78 | * @inum: The inode number | 78 | * @no_addr: The inode number |
79 | * @type: The type of the inode | 79 | * @type: The type of the inode |
80 | * | 80 | * |
81 | * Returns: A VFS inode, or an error | 81 | * Returns: A VFS inode, or an error |
82 | */ | 82 | */ |
83 | 83 | ||
84 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) | 84 | struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned int type) |
85 | { | 85 | { |
86 | struct inode *inode = gfs2_iget(sb, inum); | 86 | struct inode *inode = gfs2_iget(sb, no_addr); |
87 | struct gfs2_inode *ip = GFS2_I(inode); | 87 | struct gfs2_inode *ip = GFS2_I(inode); |
88 | struct gfs2_glock *io_gl; | 88 | struct gfs2_glock *io_gl; |
89 | int error; | 89 | int error; |
@@ -110,12 +110,12 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *i | |||
110 | inode->i_op = &gfs2_dev_iops; | 110 | inode->i_op = &gfs2_dev_iops; |
111 | } | 111 | } |
112 | 112 | ||
113 | error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | 113 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
114 | if (unlikely(error)) | 114 | if (unlikely(error)) |
115 | goto fail; | 115 | goto fail; |
116 | ip->i_gl->gl_object = ip; | 116 | ip->i_gl->gl_object = ip; |
117 | 117 | ||
118 | error = gfs2_glock_get(sdp, inum->no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | 118 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); |
119 | if (unlikely(error)) | 119 | if (unlikely(error)) |
120 | goto fail_put; | 120 | goto fail_put; |
121 | 121 | ||
@@ -144,14 +144,12 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
144 | struct gfs2_dinode_host *di = &ip->i_di; | 144 | struct gfs2_dinode_host *di = &ip->i_di; |
145 | const struct gfs2_dinode *str = buf; | 145 | const struct gfs2_dinode *str = buf; |
146 | 146 | ||
147 | if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) { | 147 | if (ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)) { |
148 | if (gfs2_consist_inode(ip)) | 148 | if (gfs2_consist_inode(ip)) |
149 | gfs2_dinode_print(ip); | 149 | gfs2_dinode_print(ip); |
150 | return -EIO; | 150 | return -EIO; |
151 | } | 151 | } |
152 | if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino)) | 152 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); |
153 | return -ESTALE; | ||
154 | |||
155 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | 153 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); |
156 | ip->i_inode.i_rdev = 0; | 154 | ip->i_inode.i_rdev = 0; |
157 | switch (ip->i_inode.i_mode & S_IFMT) { | 155 | switch (ip->i_inode.i_mode & S_IFMT) { |
@@ -247,7 +245,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
247 | if (error) | 245 | if (error) |
248 | goto out_qs; | 246 | goto out_qs; |
249 | 247 | ||
250 | rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr); | 248 | rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr); |
251 | if (!rgd) { | 249 | if (!rgd) { |
252 | gfs2_consist_inode(ip); | 250 | gfs2_consist_inode(ip); |
253 | error = -EIO; | 251 | error = -EIO; |
@@ -366,8 +364,6 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
366 | struct super_block *sb = dir->i_sb; | 364 | struct super_block *sb = dir->i_sb; |
367 | struct gfs2_inode *dip = GFS2_I(dir); | 365 | struct gfs2_inode *dip = GFS2_I(dir); |
368 | struct gfs2_holder d_gh; | 366 | struct gfs2_holder d_gh; |
369 | struct gfs2_inum_host inum; | ||
370 | unsigned int type; | ||
371 | int error; | 367 | int error; |
372 | struct inode *inode = NULL; | 368 | struct inode *inode = NULL; |
373 | int unlock = 0; | 369 | int unlock = 0; |
@@ -395,12 +391,9 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
395 | goto out; | 391 | goto out; |
396 | } | 392 | } |
397 | 393 | ||
398 | error = gfs2_dir_search(dir, name, &inum, &type); | 394 | inode = gfs2_dir_search(dir, name); |
399 | if (error) | 395 | if (IS_ERR(inode)) |
400 | goto out; | 396 | error = PTR_ERR(inode); |
401 | |||
402 | inode = gfs2_inode_lookup(sb, &inum, type); | ||
403 | |||
404 | out: | 397 | out: |
405 | if (unlock) | 398 | if (unlock) |
406 | gfs2_glock_dq_uninit(&d_gh); | 399 | gfs2_glock_dq_uninit(&d_gh); |
@@ -548,7 +541,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
548 | if (!dip->i_inode.i_nlink) | 541 | if (!dip->i_inode.i_nlink) |
549 | return -EPERM; | 542 | return -EPERM; |
550 | 543 | ||
551 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); | 544 | error = gfs2_dir_check(&dip->i_inode, name, NULL); |
552 | switch (error) { | 545 | switch (error) { |
553 | case -ENOENT: | 546 | case -ENOENT: |
554 | error = 0; | 547 | error = 0; |
@@ -588,8 +581,7 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, | |||
588 | *gid = current->fsgid; | 581 | *gid = current->fsgid; |
589 | } | 582 | } |
590 | 583 | ||
591 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, | 584 | static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) |
592 | u64 *generation) | ||
593 | { | 585 | { |
594 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 586 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
595 | int error; | 587 | int error; |
@@ -605,7 +597,7 @@ static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, | |||
605 | if (error) | 597 | if (error) |
606 | goto out_ipreserv; | 598 | goto out_ipreserv; |
607 | 599 | ||
608 | inum->no_addr = gfs2_alloc_di(dip, generation); | 600 | *no_addr = gfs2_alloc_di(dip, generation); |
609 | 601 | ||
610 | gfs2_trans_end(sdp); | 602 | gfs2_trans_end(sdp); |
611 | 603 | ||
@@ -760,7 +752,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
760 | goto fail_quota_locks; | 752 | goto fail_quota_locks; |
761 | } | 753 | } |
762 | 754 | ||
763 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode)); | 755 | error = gfs2_dir_add(&dip->i_inode, name, ip, IF2DT(ip->i_inode.i_mode)); |
764 | if (error) | 756 | if (error) |
765 | goto fail_end_trans; | 757 | goto fail_end_trans; |
766 | 758 | ||
@@ -844,7 +836,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
844 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; | 836 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; |
845 | struct inode *dir = &dip->i_inode; | 837 | struct inode *dir = &dip->i_inode; |
846 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 838 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
847 | struct gfs2_inum_host inum; | 839 | struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; |
848 | int error; | 840 | int error; |
849 | u64 generation; | 841 | u64 generation; |
850 | 842 | ||
@@ -864,7 +856,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
864 | if (error) | 856 | if (error) |
865 | goto fail_gunlock; | 857 | goto fail_gunlock; |
866 | 858 | ||
867 | error = alloc_dinode(dip, &inum, &generation); | 859 | error = alloc_dinode(dip, &inum.no_addr, &generation); |
868 | if (error) | 860 | if (error) |
869 | goto fail_gunlock; | 861 | goto fail_gunlock; |
870 | 862 | ||
@@ -877,7 +869,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
877 | if (error) | 869 | if (error) |
878 | goto fail_gunlock2; | 870 | goto fail_gunlock2; |
879 | 871 | ||
880 | inode = gfs2_inode_lookup(dir->i_sb, &inum, IF2DT(mode)); | 872 | inode = gfs2_inode_lookup(dir->i_sb, inum.no_addr, IF2DT(mode)); |
881 | if (IS_ERR(inode)) | 873 | if (IS_ERR(inode)) |
882 | goto fail_gunlock2; | 874 | goto fail_gunlock2; |
883 | 875 | ||
@@ -976,10 +968,8 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
976 | */ | 968 | */ |
977 | 969 | ||
978 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 970 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
979 | struct gfs2_inode *ip) | 971 | const struct gfs2_inode *ip) |
980 | { | 972 | { |
981 | struct gfs2_inum_host inum; | ||
982 | unsigned int type; | ||
983 | int error; | 973 | int error; |
984 | 974 | ||
985 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | 975 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) |
@@ -997,18 +987,10 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
997 | if (error) | 987 | if (error) |
998 | return error; | 988 | return error; |
999 | 989 | ||
1000 | error = gfs2_dir_search(&dip->i_inode, name, &inum, &type); | 990 | error = gfs2_dir_check(&dip->i_inode, name, ip); |
1001 | if (error) | 991 | if (error) |
1002 | return error; | 992 | return error; |
1003 | 993 | ||
1004 | if (!gfs2_inum_equal(&inum, &ip->i_num)) | ||
1005 | return -ENOENT; | ||
1006 | |||
1007 | if (IF2DT(ip->i_inode.i_mode) != type) { | ||
1008 | gfs2_consist_inode(dip); | ||
1009 | return -EIO; | ||
1010 | } | ||
1011 | |||
1012 | return 0; | 994 | return 0; |
1013 | } | 995 | } |
1014 | 996 | ||