aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/inode.c35
-rw-r--r--fs/gfs2/ops_inode.c23
2 files changed, 50 insertions, 8 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 94c3a7db1116..5a02606b68c0 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -248,6 +248,32 @@ fail_iput:
248 goto fail; 248 goto fail;
249} 249}
250 250
251/**
252 * gfs2_set_nlink - Set the inode's link count based on on-disk info
253 * @inode: The inode in question
254 * @nlink: The link count
255 *
256 * If the link count has hit zero, it must never be raised, whatever the
257 * on-disk inode might say. When new struct inodes are created the link
258 * count is set to 1, so that we can safely use this test even when reading
259 * in on disk information for the first time.
260 */
261
262static void gfs2_set_nlink(struct inode *inode, u32 nlink)
263{
264 /*
265 * We will need to review setting the nlink count here in the
266 * light of the forthcoming ro bind mount work. This is a reminder
267 * to do that.
268 */
269 if ((inode->i_nlink != nlink) && (inode->i_nlink != 0)) {
270 if (nlink == 0)
271 clear_nlink(inode);
272 else
273 inode->i_nlink = nlink;
274 }
275}
276
251static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) 277static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
252{ 278{
253 const struct gfs2_dinode *str = buf; 279 const struct gfs2_dinode *str = buf;
@@ -269,12 +295,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
269 295
270 ip->i_inode.i_uid = be32_to_cpu(str->di_uid); 296 ip->i_inode.i_uid = be32_to_cpu(str->di_uid);
271 ip->i_inode.i_gid = be32_to_cpu(str->di_gid); 297 ip->i_inode.i_gid = be32_to_cpu(str->di_gid);
272 /* 298 gfs2_set_nlink(&ip->i_inode, be32_to_cpu(str->di_nlink));
273 * We will need to review setting the nlink count here in the
274 * light of the forthcoming ro bind mount work. This is a reminder
275 * to do that.
276 */
277 ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink);
278 i_size_write(&ip->i_inode, be64_to_cpu(str->di_size)); 299 i_size_write(&ip->i_inode, be64_to_cpu(str->di_size));
279 gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); 300 gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks));
280 atime.tv_sec = be64_to_cpu(str->di_atime); 301 atime.tv_sec = be64_to_cpu(str->di_atime);
@@ -484,7 +505,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name,
484 505
485 /* Don't create entries in an unlinked directory */ 506 /* Don't create entries in an unlinked directory */
486 if (!dip->i_inode.i_nlink) 507 if (!dip->i_inode.i_nlink)
487 return -EPERM; 508 return -ENOENT;
488 509
489 error = gfs2_dir_check(&dip->i_inode, name, NULL); 510 error = gfs2_dir_check(&dip->i_inode, name, NULL);
490 switch (error) { 511 switch (error) {
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 09e436a50723..1005f9eb456e 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -162,6 +162,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
162 if (error) 162 if (error)
163 goto out_child; 163 goto out_child;
164 164
165 error = -ENOENT;
166 if (inode->i_nlink == 0)
167 goto out_gunlock;
168
165 error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC, 0); 169 error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC, 0);
166 if (error) 170 if (error)
167 goto out_gunlock; 171 goto out_gunlock;
@@ -335,6 +339,10 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
335 if (error) 339 if (error)
336 goto out_child; 340 goto out_child;
337 341
342 error = -ENOENT;
343 if (ip->i_inode.i_nlink == 0)
344 goto out_rgrp;
345
338 error = gfs2_glock_nq(ghs + 2); /* rgrp */ 346 error = gfs2_glock_nq(ghs + 2); /* rgrp */
339 if (error) 347 if (error)
340 goto out_rgrp; 348 goto out_rgrp;
@@ -589,6 +597,10 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
589 if (error) 597 if (error)
590 goto out_child; 598 goto out_child;
591 599
600 error = -ENOENT;
601 if (ip->i_inode.i_nlink == 0)
602 goto out_rgrp;
603
592 error = gfs2_glock_nq(ghs + 2); /* rgrp */ 604 error = gfs2_glock_nq(ghs + 2); /* rgrp */
593 if (error) 605 if (error)
594 goto out_rgrp; 606 goto out_rgrp;
@@ -792,6 +804,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
792 goto out_gunlock; 804 goto out_gunlock;
793 } 805 }
794 806
807 error = -ENOENT;
808 if (ip->i_inode.i_nlink == 0)
809 goto out_gunlock;
810
795 /* Check out the old directory */ 811 /* Check out the old directory */
796 812
797 error = gfs2_unlink_ok(odip, &odentry->d_name, ip); 813 error = gfs2_unlink_ok(odip, &odentry->d_name, ip);
@@ -805,6 +821,11 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
805 if (error) 821 if (error)
806 goto out_gunlock; 822 goto out_gunlock;
807 823
824 if (nip->i_inode.i_nlink == 0) {
825 error = -EAGAIN;
826 goto out_gunlock;
827 }
828
808 if (S_ISDIR(nip->i_inode.i_mode)) { 829 if (S_ISDIR(nip->i_inode.i_mode)) {
809 if (nip->i_entries < 2) { 830 if (nip->i_entries < 2) {
810 if (gfs2_consist_inode(nip)) 831 if (gfs2_consist_inode(nip))
@@ -835,7 +856,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
835 856
836 if (odip != ndip) { 857 if (odip != ndip) {
837 if (!ndip->i_inode.i_nlink) { 858 if (!ndip->i_inode.i_nlink) {
838 error = -EINVAL; 859 error = -ENOENT;
839 goto out_gunlock; 860 goto out_gunlock;
840 } 861 }
841 if (ndip->i_entries == (u32)-1) { 862 if (ndip->i_entries == (u32)-1) {