]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/ocfs2/namei.c
[PATCH] sys_pselect7 vs compat_sys_pselect7 uaccess error handling
[linux-2.6-omap-h63xx.git] / fs / ocfs2 / namei.c
index 849c3b4bb94a12d1e856df92e3c47d8e08dd3b43..a57b751d4f40e3fad3cf7bc1df95b09816f8307c 100644 (file)
@@ -429,7 +429,7 @@ static int ocfs2_mknod(struct inode *dir,
                        mlog_errno(status);
                        goto leave;
                }
-               dir->i_nlink++;
+               inc_nlink(dir);
        }
 
        status = ocfs2_add_entry(handle, dentry, inode,
@@ -730,7 +730,7 @@ static int ocfs2_link(struct dentry *old_dentry,
                goto bail;
        }
 
-       inode->i_nlink++;
+       inc_nlink(inode);
        inode->i_ctime = CURRENT_TIME;
        fe->i_links_count = cpu_to_le16(inode->i_nlink);
        fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
@@ -739,7 +739,7 @@ static int ocfs2_link(struct dentry *old_dentry,
        err = ocfs2_journal_dirty(handle, fe_bh);
        if (err < 0) {
                le16_add_cpu(&fe->i_links_count, -1);
-               inode->i_nlink--;
+               drop_nlink(inode);
                mlog_errno(err);
                goto bail;
        }
@@ -749,7 +749,7 @@ static int ocfs2_link(struct dentry *old_dentry,
                              parent_fe_bh, de_bh);
        if (err) {
                le16_add_cpu(&fe->i_links_count, -1);
-               inode->i_nlink--;
+               drop_nlink(inode);
                mlog_errno(err);
                goto bail;
        }
@@ -795,11 +795,23 @@ static int ocfs2_remote_dentry_delete(struct dentry *dentry)
        return ret;
 }
 
+static inline int inode_is_unlinkable(struct inode *inode)
+{
+       if (S_ISDIR(inode->i_mode)) {
+               if (inode->i_nlink == 2)
+                       return 1;
+               return 0;
+       }
+
+       if (inode->i_nlink == 1)
+               return 1;
+       return 0;
+}
+
 static int ocfs2_unlink(struct inode *dir,
                        struct dentry *dentry)
 {
        int status;
-       unsigned int saved_nlink = 0;
        struct inode *inode = dentry->d_inode;
        struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
        u64 blkno;
@@ -874,16 +886,6 @@ static int ocfs2_unlink(struct inode *dir,
                }
        }
 
-       /* There are still a few steps left until we can consider the
-        * unlink to have succeeded. Save off nlink here before
-        * modification so we can set it back in case we hit an issue
-        * before commit. */
-       saved_nlink = inode->i_nlink;
-       if (S_ISDIR(inode->i_mode))
-               inode->i_nlink = 0;
-       else
-               inode->i_nlink--;
-
        status = ocfs2_remote_dentry_delete(dentry);
        if (status < 0) {
                /* This vote should succeed under all normal
@@ -892,7 +894,7 @@ static int ocfs2_unlink(struct inode *dir,
                goto leave;
        }
 
-       if (!inode->i_nlink) {
+       if (inode_is_unlinkable(inode)) {
                status = ocfs2_prepare_orphan_dir(osb, handle, inode,
                                                  orphan_name,
                                                  &orphan_entry_bh);
@@ -919,7 +921,7 @@ static int ocfs2_unlink(struct inode *dir,
 
        fe = (struct ocfs2_dinode *) fe_bh->b_data;
 
-       if (!inode->i_nlink) {
+       if (inode_is_unlinkable(inode)) {
                status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
                                          orphan_entry_bh);
                if (status < 0) {
@@ -935,10 +937,10 @@ static int ocfs2_unlink(struct inode *dir,
                goto leave;
        }
 
-       /* We can set nlink on the dinode now. clear the saved version
-        * so that it doesn't get set later. */
+       if (S_ISDIR(inode->i_mode))
+               drop_nlink(inode);
+       drop_nlink(inode);
        fe->i_links_count = cpu_to_le16(inode->i_nlink);
-       saved_nlink = 0;
 
        status = ocfs2_journal_dirty(handle, fe_bh);
        if (status < 0) {
@@ -947,19 +949,16 @@ static int ocfs2_unlink(struct inode *dir,
        }
 
        if (S_ISDIR(inode->i_mode)) {
-               dir->i_nlink--;
+               drop_nlink(dir);
                status = ocfs2_mark_inode_dirty(handle, dir,
                                                parent_node_bh);
                if (status < 0) {
                        mlog_errno(status);
-                       dir->i_nlink++;
+                       inc_nlink(dir);
                }
        }
 
 leave:
-       if (status < 0 && saved_nlink)
-               inode->i_nlink = saved_nlink;
-
        if (handle)
                ocfs2_commit_trans(handle);
 
@@ -1086,14 +1085,6 @@ static int ocfs2_rename(struct inode *old_dir,
                        BUG();
        }
 
-       if (atomic_read(&old_dentry->d_count) > 2) {
-               shrink_dcache_parent(old_dentry);
-               if (atomic_read(&old_dentry->d_count) > 2) {
-                       status = -EBUSY;
-                       goto bail;
-               }
-       }
-
        /* Assume a directory heirarchy thusly:
         * a/b/c
         * a/d
@@ -1382,7 +1373,7 @@ static int ocfs2_rename(struct inode *old_dir,
                if (new_inode) {
                        new_inode->i_nlink--;
                } else {
-                       new_dir->i_nlink++;
+                       inc_nlink(new_dir);
                        mark_inode_dirty(new_dir);
                }
        }