aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/inode.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-05-15 10:37:50 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-07-09 03:22:24 -0400
commitdbb7cae2a36170cd17ffbe286ec0c91a998740ff (patch)
tree1f4da65b07ac31648fe9b72f2742075486a86008 /fs/gfs2/inode.c
parent41d7db0ab437bc84f8a6e77cccc626ce937605ac (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.c80
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 @@
41static int iget_test(struct inode *inode, void *opaque) 41static 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)
53static int iget_set(struct inode *inode, void *opaque) 53static 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
63struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) 63struct 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
69static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) 69static 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
84struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) 84struct 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
404out: 397out:
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
591static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, 584static 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
978int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, 970int 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