aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/inode.c37
-rw-r--r--fs/gfs2/ondisk.c3
-rw-r--r--fs/gfs2/ops_inode.c12
3 files changed, 31 insertions, 21 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 0de9b22f454b..711203984823 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -51,7 +51,6 @@ void gfs2_inode_attr_in(struct gfs2_inode *ip)
51 struct gfs2_dinode_host *di = &ip->i_di; 51 struct gfs2_dinode_host *di = &ip->i_di;
52 52
53 inode->i_ino = ip->i_num.no_addr; 53 inode->i_ino = ip->i_num.no_addr;
54 inode->i_nlink = di->di_nlink;
55 i_size_write(inode, di->di_size); 54 i_size_write(inode, di->di_size);
56 inode->i_atime.tv_sec = di->di_atime; 55 inode->i_atime.tv_sec = di->di_atime;
57 inode->i_mtime.tv_sec = di->di_mtime; 56 inode->i_mtime.tv_sec = di->di_mtime;
@@ -214,7 +213,12 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
214 213
215 ip->i_inode.i_uid = be32_to_cpu(str->di_uid); 214 ip->i_inode.i_uid = be32_to_cpu(str->di_uid);
216 ip->i_inode.i_gid = be32_to_cpu(str->di_gid); 215 ip->i_inode.i_gid = be32_to_cpu(str->di_gid);
217 di->di_nlink = be32_to_cpu(str->di_nlink); 216 /*
217 * We will need to review setting the nlink count here in the
218 * light of the forthcoming ro bind mount work. This is a reminder
219 * to do that.
220 */
221 ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink);
218 di->di_size = be64_to_cpu(str->di_size); 222 di->di_size = be64_to_cpu(str->di_size);
219 di->di_blocks = be64_to_cpu(str->di_blocks); 223 di->di_blocks = be64_to_cpu(str->di_blocks);
220 di->di_atime = be64_to_cpu(str->di_atime); 224 di->di_atime = be64_to_cpu(str->di_atime);
@@ -336,12 +340,12 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
336 u32 nlink; 340 u32 nlink;
337 int error; 341 int error;
338 342
339 BUG_ON(ip->i_di.di_nlink != ip->i_inode.i_nlink); 343 BUG_ON(diff != 1 && diff != -1);
340 nlink = ip->i_di.di_nlink + diff; 344 nlink = ip->i_inode.i_nlink + diff;
341 345
342 /* If we are reducing the nlink count, but the new value ends up being 346 /* If we are reducing the nlink count, but the new value ends up being
343 bigger than the old one, we must have underflowed. */ 347 bigger than the old one, we must have underflowed. */
344 if (diff < 0 && nlink > ip->i_di.di_nlink) { 348 if (diff < 0 && nlink > ip->i_inode.i_nlink) {
345 if (gfs2_consist_inode(ip)) 349 if (gfs2_consist_inode(ip))
346 gfs2_dinode_print(ip); 350 gfs2_dinode_print(ip);
347 return -EIO; 351 return -EIO;
@@ -351,16 +355,19 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
351 if (error) 355 if (error)
352 return error; 356 return error;
353 357
354 ip->i_di.di_nlink = nlink; 358 if (diff > 0)
359 inc_nlink(&ip->i_inode);
360 else
361 drop_nlink(&ip->i_inode);
362
355 ip->i_di.di_ctime = get_seconds(); 363 ip->i_di.di_ctime = get_seconds();
356 ip->i_inode.i_nlink = nlink;
357 364
358 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 365 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
359 gfs2_dinode_out(ip, dibh->b_data); 366 gfs2_dinode_out(ip, dibh->b_data);
360 brelse(dibh); 367 brelse(dibh);
361 mark_inode_dirty(&ip->i_inode); 368 mark_inode_dirty(&ip->i_inode);
362 369
363 if (ip->i_di.di_nlink == 0) { 370 if (ip->i_inode.i_nlink == 0) {
364 struct gfs2_rgrpd *rgd; 371 struct gfs2_rgrpd *rgd;
365 struct gfs2_holder ri_gh, rg_gh; 372 struct gfs2_holder ri_gh, rg_gh;
366 373
@@ -375,7 +382,6 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
375 if (error) 382 if (error)
376 goto out_norgrp; 383 goto out_norgrp;
377 384
378 clear_nlink(&ip->i_inode);
379 gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ 385 gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */
380 gfs2_glock_dq_uninit(&rg_gh); 386 gfs2_glock_dq_uninit(&rg_gh);
381out_norgrp: 387out_norgrp:
@@ -586,7 +592,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name,
586 return error; 592 return error;
587 593
588 /* Don't create entries in an unlinked directory */ 594 /* Don't create entries in an unlinked directory */
589 if (!dip->i_di.di_nlink) 595 if (!dip->i_inode.i_nlink)
590 return -EPERM; 596 return -EPERM;
591 597
592 error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); 598 error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL);
@@ -602,7 +608,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name,
602 608
603 if (dip->i_di.di_entries == (u32)-1) 609 if (dip->i_di.di_entries == (u32)-1)
604 return -EFBIG; 610 return -EFBIG;
605 if (S_ISDIR(mode) && dip->i_di.di_nlink == (u32)-1) 611 if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1)
606 return -EMLINK; 612 return -EMLINK;
607 613
608 return 0; 614 return 0;
@@ -808,7 +814,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
808 error = gfs2_meta_inode_buffer(ip, &dibh); 814 error = gfs2_meta_inode_buffer(ip, &dibh);
809 if (error) 815 if (error)
810 goto fail_end_trans; 816 goto fail_end_trans;
811 ip->i_di.di_nlink = 1; 817 ip->i_inode.i_nlink = 1;
812 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 818 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
813 gfs2_dinode_out(ip, dibh->b_data); 819 gfs2_dinode_out(ip, dibh->b_data);
814 brelse(dibh); 820 brelse(dibh);
@@ -1016,7 +1022,12 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
1016 if (error) 1022 if (error)
1017 return error; 1023 return error;
1018 1024
1019 error = gfs2_change_nlink(ip, -2); 1025 /* It looks odd, but it really should be done twice */
1026 error = gfs2_change_nlink(ip, -1);
1027 if (error)
1028 return error;
1029
1030 error = gfs2_change_nlink(ip, -1);
1020 if (error) 1031 if (error)
1021 return error; 1032 return error;
1022 1033
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c
index e224f6a22641..b4e354b18815 100644
--- a/fs/gfs2/ondisk.c
+++ b/fs/gfs2/ondisk.c
@@ -164,7 +164,7 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
164 str->di_mode = cpu_to_be32(ip->i_inode.i_mode); 164 str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
165 str->di_uid = cpu_to_be32(ip->i_inode.i_uid); 165 str->di_uid = cpu_to_be32(ip->i_inode.i_uid);
166 str->di_gid = cpu_to_be32(ip->i_inode.i_gid); 166 str->di_gid = cpu_to_be32(ip->i_inode.i_gid);
167 str->di_nlink = cpu_to_be32(di->di_nlink); 167 str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink);
168 str->di_size = cpu_to_be64(di->di_size); 168 str->di_size = cpu_to_be64(di->di_size);
169 str->di_blocks = cpu_to_be64(di->di_blocks); 169 str->di_blocks = cpu_to_be64(di->di_blocks);
170 str->di_atime = cpu_to_be64(di->di_atime); 170 str->di_atime = cpu_to_be64(di->di_atime);
@@ -191,7 +191,6 @@ void gfs2_dinode_print(const struct gfs2_inode *ip)
191 191
192 gfs2_inum_print(&ip->i_num); 192 gfs2_inum_print(&ip->i_num);
193 193
194 pv(di, di_nlink, "%u");
195 printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); 194 printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size);
196 printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); 195 printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks);
197 printk(KERN_INFO " di_atime = %lld\n", (long long)di->di_atime); 196 printk(KERN_INFO " di_atime = %lld\n", (long long)di->di_atime);
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index efbcec3311bb..06176dee1550 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -169,7 +169,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
169 } 169 }
170 170
171 error = -EINVAL; 171 error = -EINVAL;
172 if (!dip->i_di.di_nlink) 172 if (!dip->i_inode.i_nlink)
173 goto out_gunlock; 173 goto out_gunlock;
174 error = -EFBIG; 174 error = -EFBIG;
175 if (dip->i_di.di_entries == (u32)-1) 175 if (dip->i_di.di_entries == (u32)-1)
@@ -178,10 +178,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
178 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 178 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
179 goto out_gunlock; 179 goto out_gunlock;
180 error = -EINVAL; 180 error = -EINVAL;
181 if (!ip->i_di.di_nlink) 181 if (!ip->i_inode.i_nlink)
182 goto out_gunlock; 182 goto out_gunlock;
183 error = -EMLINK; 183 error = -EMLINK;
184 if (ip->i_di.di_nlink == (u32)-1) 184 if (ip->i_inode.i_nlink == (u32)-1)
185 goto out_gunlock; 185 goto out_gunlock;
186 186
187 alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); 187 alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name);
@@ -386,7 +386,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
386 386
387 ip = ghs[1].gh_gl->gl_object; 387 ip = ghs[1].gh_gl->gl_object;
388 388
389 ip->i_di.di_nlink = 2; 389 ip->i_inode.i_nlink = 2;
390 ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); 390 ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode);
391 ip->i_di.di_flags |= GFS2_DIF_JDATA; 391 ip->i_di.di_flags |= GFS2_DIF_JDATA;
392 ip->i_di.di_payload_format = GFS2_FORMAT_DE; 392 ip->i_di.di_payload_format = GFS2_FORMAT_DE;
@@ -636,7 +636,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
636 }; 636 };
637 637
638 if (odip != ndip) { 638 if (odip != ndip) {
639 if (!ndip->i_di.di_nlink) { 639 if (!ndip->i_inode.i_nlink) {
640 error = -EINVAL; 640 error = -EINVAL;
641 goto out_gunlock; 641 goto out_gunlock;
642 } 642 }
@@ -645,7 +645,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
645 goto out_gunlock; 645 goto out_gunlock;
646 } 646 }
647 if (S_ISDIR(ip->i_inode.i_mode) && 647 if (S_ISDIR(ip->i_inode.i_mode) &&
648 ndip->i_di.di_nlink == (u32)-1) { 648 ndip->i_inode.i_nlink == (u32)-1) {
649 error = -EMLINK; 649 error = -EMLINK;
650 goto out_gunlock; 650 goto out_gunlock;
651 } 651 }