diff options
Diffstat (limited to 'fs/gfs2/ops_inode.c')
-rw-r--r-- | fs/gfs2/ops_inode.c | 72 |
1 files changed, 35 insertions, 37 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 7633a8584b0d..e8ab9d254b76 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -58,7 +58,6 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
58 | struct gfs2_holder ghs[2]; | 58 | struct gfs2_holder ghs[2]; |
59 | struct inode *inode; | 59 | struct inode *inode; |
60 | int new = 1; | 60 | int new = 1; |
61 | int error; | ||
62 | 61 | ||
63 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 62 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
64 | 63 | ||
@@ -78,14 +77,16 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
78 | return PTR_ERR(inode); | 77 | return PTR_ERR(inode); |
79 | } | 78 | } |
80 | 79 | ||
81 | error = gfs2_lookupi(dir, &dentry->d_name, 0, &inode); | 80 | inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd); |
82 | if (!error) { | 81 | if (inode) { |
83 | new = 0; | 82 | if (!IS_ERR(inode)) { |
84 | gfs2_holder_uninit(ghs); | 83 | new = 0; |
85 | break; | 84 | gfs2_holder_uninit(ghs); |
86 | } else if (error != -ENOENT) { | 85 | break; |
87 | gfs2_holder_uninit(ghs); | 86 | } else { |
88 | return error; | 87 | gfs2_holder_uninit(ghs); |
88 | return PTR_ERR(inode); | ||
89 | } | ||
89 | } | 90 | } |
90 | } | 91 | } |
91 | 92 | ||
@@ -110,17 +111,13 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
110 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, | 111 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, |
111 | struct nameidata *nd) | 112 | struct nameidata *nd) |
112 | { | 113 | { |
113 | struct gfs2_inode *dip = dir->u.generic_ip; | ||
114 | struct gfs2_sbd *sdp = dip->i_sbd; | ||
115 | struct inode *inode = NULL; | 114 | struct inode *inode = NULL; |
116 | int error; | ||
117 | 115 | ||
118 | if (!sdp->sd_args.ar_localcaching) | 116 | dentry->d_op = &gfs2_dops; |
119 | dentry->d_op = &gfs2_dops; | ||
120 | 117 | ||
121 | error = gfs2_lookupi(dir, &dentry->d_name, 0, &inode); | 118 | inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd); |
122 | if (error && error != -ENOENT) | 119 | if (inode && IS_ERR(inode)) |
123 | return ERR_PTR(error); | 120 | return ERR_PTR(PTR_ERR(inode)); |
124 | 121 | ||
125 | if (inode) | 122 | if (inode) |
126 | return d_splice_alias(inode, dentry); | 123 | return d_splice_alias(inode, dentry); |
@@ -166,7 +163,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
166 | if (error) | 163 | if (error) |
167 | goto out_gunlock; | 164 | goto out_gunlock; |
168 | 165 | ||
169 | error = gfs2_dir_search(dip, &dentry->d_name, NULL, NULL); | 166 | error = gfs2_dir_search(dir, &dentry->d_name, NULL, NULL); |
170 | switch (error) { | 167 | switch (error) { |
171 | case -ENOENT: | 168 | case -ENOENT: |
172 | break; | 169 | break; |
@@ -192,10 +189,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
192 | if (ip->i_di.di_nlink == (uint32_t)-1) | 189 | if (ip->i_di.di_nlink == (uint32_t)-1) |
193 | goto out_gunlock; | 190 | goto out_gunlock; |
194 | 191 | ||
195 | error = gfs2_diradd_alloc_required(dip, &dentry->d_name, | 192 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); |
196 | &alloc_required); | 193 | if (error < 0) |
197 | if (error) | ||
198 | goto out_gunlock; | 194 | goto out_gunlock; |
195 | error = 0; | ||
199 | 196 | ||
200 | if (alloc_required) { | 197 | if (alloc_required) { |
201 | struct gfs2_alloc *al = gfs2_alloc_get(dip); | 198 | struct gfs2_alloc *al = gfs2_alloc_get(dip); |
@@ -228,7 +225,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
228 | goto out_ipres; | 225 | goto out_ipres; |
229 | } | 226 | } |
230 | 227 | ||
231 | error = gfs2_dir_add(dip, &dentry->d_name, &ip->i_num, | 228 | error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, |
232 | IF2DT(ip->i_di.di_mode)); | 229 | IF2DT(ip->i_di.di_mode)); |
233 | if (error) | 230 | if (error) |
234 | goto out_end_trans; | 231 | goto out_end_trans; |
@@ -419,24 +416,24 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
419 | 416 | ||
420 | if (!gfs2_assert_withdraw(sdp, !error)) { | 417 | if (!gfs2_assert_withdraw(sdp, !error)) { |
421 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; | 418 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; |
422 | struct gfs2_dirent *dent; | 419 | struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); |
423 | 420 | struct qstr str = { .name = ".", .len = 1 }; | |
424 | gfs2_dirent_alloc(ip, dibh, 1, &dent); | 421 | str.hash = gfs2_disk_hash(str.name, str.len); |
425 | 422 | ||
423 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
424 | gfs2_qstr2dirent(&str, GFS2_DIRENT_SIZE(str.len), dent); | ||
426 | dent->de_inum = di->di_num; /* already GFS2 endian */ | 425 | dent->de_inum = di->di_num; /* already GFS2 endian */ |
427 | dent->de_hash = gfs2_disk_hash(".", 1); | ||
428 | dent->de_hash = cpu_to_be32(dent->de_hash); | ||
429 | dent->de_type = DT_DIR; | 426 | dent->de_type = DT_DIR; |
430 | memcpy((char *) (dent + 1), ".", 1); | ||
431 | di->di_entries = cpu_to_be32(1); | 427 | di->di_entries = cpu_to_be32(1); |
432 | 428 | ||
433 | gfs2_dirent_alloc(ip, dibh, 2, &dent); | 429 | str.name = ".."; |
430 | str.len = 2; | ||
431 | str.hash = gfs2_disk_hash(str.name, str.len); | ||
432 | dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); | ||
433 | gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); | ||
434 | 434 | ||
435 | gfs2_inum_out(&dip->i_num, (char *) &dent->de_inum); | 435 | gfs2_inum_out(&dip->i_num, (char *) &dent->de_inum); |
436 | dent->de_hash = gfs2_disk_hash("..", 2); | ||
437 | dent->de_hash = cpu_to_be32(dent->de_hash); | ||
438 | dent->de_type = DT_DIR; | 436 | dent->de_type = DT_DIR; |
439 | memcpy((char *) (dent + 1), "..", 2); | ||
440 | 437 | ||
441 | gfs2_dinode_out(&ip->i_di, (char *)di); | 438 | gfs2_dinode_out(&ip->i_di, (char *)di); |
442 | 439 | ||
@@ -687,7 +684,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
687 | if (error) | 684 | if (error) |
688 | goto out_gunlock; | 685 | goto out_gunlock; |
689 | 686 | ||
690 | error = gfs2_dir_search(ndip, &ndentry->d_name, NULL, NULL); | 687 | error = gfs2_dir_search(ndir, &ndentry->d_name, NULL, NULL); |
691 | switch (error) { | 688 | switch (error) { |
692 | case -ENOENT: | 689 | case -ENOENT: |
693 | error = 0; | 690 | error = 0; |
@@ -723,10 +720,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
723 | goto out_gunlock; | 720 | goto out_gunlock; |
724 | } | 721 | } |
725 | 722 | ||
726 | error = gfs2_diradd_alloc_required(ndip, &ndentry->d_name, | 723 | alloc_required = error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); |
727 | &alloc_required); | 724 | if (error < 0) |
728 | if (error) | ||
729 | goto out_gunlock; | 725 | goto out_gunlock; |
726 | error = 0; | ||
730 | 727 | ||
731 | if (alloc_required) { | 728 | if (alloc_required) { |
732 | struct gfs2_alloc *al = gfs2_alloc_get(ndip); | 729 | struct gfs2_alloc *al = gfs2_alloc_get(ndip); |
@@ -777,6 +774,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
777 | struct qstr name; | 774 | struct qstr name; |
778 | name.len = 2; | 775 | name.len = 2; |
779 | name.name = ".."; | 776 | name.name = ".."; |
777 | name.hash = gfs2_disk_hash(name.name, name.len); | ||
780 | 778 | ||
781 | error = gfs2_change_nlink(ndip, +1); | 779 | error = gfs2_change_nlink(ndip, +1); |
782 | if (error) | 780 | if (error) |
@@ -803,7 +801,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
803 | if (error) | 801 | if (error) |
804 | goto out_end_trans; | 802 | goto out_end_trans; |
805 | 803 | ||
806 | error = gfs2_dir_add(ndip, &ndentry->d_name, &ip->i_num, | 804 | error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, |
807 | IF2DT(ip->i_di.di_mode)); | 805 | IF2DT(ip->i_di.di_mode)); |
808 | if (error) | 806 | if (error) |
809 | goto out_end_trans; | 807 | goto out_end_trans; |