[PATCH] r/o bind mounts: unlink: monitor i_nlink
authorDave Hansen <haveblue@us.ibm.com>
Sun, 1 Oct 2006 06:29:03 +0000 (23:29 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 1 Oct 2006 07:39:30 +0000 (00:39 -0700)
When a filesystem decrements i_nlink to zero, it means that a write must be
performed in order to drop the inode from the filesystem.

We're shortly going to have keep filesystems from being remounted r/o between
the time that this i_nlink decrement and that write occurs.

So, add a little helper function to do the decrements.  We'll tie into it in a
bit to note when i_nlink hits zero.

Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
28 files changed:
drivers/usb/core/inode.c
fs/autofs/root.c
fs/autofs4/root.c
fs/bfs/dir.c
fs/cifs/inode.c
fs/coda/dir.c
fs/ext2/namei.c
fs/ext3/namei.c
fs/hfs/dir.c
fs/hfsplus/dir.c
fs/hpfs/namei.c
fs/jffs/inode-v23.c
fs/jffs2/dir.c
fs/jfs/namei.c
fs/libfs.c
fs/minix/namei.c
fs/msdos/namei.c
fs/nfs/dir.c
fs/ocfs2/namei.c
fs/qnx4/namei.c
fs/reiserfs/namei.c
fs/sysv/namei.c
fs/udf/namei.c
fs/ufs/namei.c
fs/vfat/namei.c
include/linux/fs.h
ipc/mqueue.c
mm/shmem.c

index df3d152f0493dbb5dfcd3e76195f370791a78876..88002e45a6b4a3b8a6b175ef2808208ad6a2c7ea 100644 (file)
@@ -332,7 +332,7 @@ static int usbfs_unlink (struct inode *dir, struct dentry *dentry)
 {
        struct inode *inode = dentry->d_inode;
        mutex_lock(&inode->i_mutex);
-       dentry->d_inode->i_nlink--;
+       drop_nlink(dentry->d_inode);
        dput(dentry);
        mutex_unlock(&inode->i_mutex);
        d_delete(dentry);
@@ -347,10 +347,11 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
        mutex_lock(&inode->i_mutex);
        dentry_unhash(dentry);
        if (usbfs_empty(dentry)) {
-               dentry->d_inode->i_nlink -= 2;
+               drop_nlink(dentry->d_inode);
+               drop_nlink(dentry->d_inode);
                dput(dentry);
                inode->i_flags |= S_DEAD;
-               dir->i_nlink--;
+               drop_nlink(dir);
                error = 0;
        }
        mutex_unlock(&inode->i_mutex);
index 9cac08d6a873111086c8ab75529976589e12dfce..54ad7073192717602cd69e7dc6208b2811410550 100644 (file)
@@ -414,7 +414,7 @@ static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
 
        dentry->d_time = (unsigned long)(struct autofs_dir_ent *)NULL;
        autofs_hash_delete(ent);
-       dir->i_nlink--;
+       drop_nlink(dir);
        d_drop(dentry);
        unlock_kernel();
 
index 563ef9d7da9ffa858ad754217861f4e2292b30ea..348bec0982b068fcdc45cb468ad5af3c00412af6 100644 (file)
@@ -676,7 +676,7 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
        dentry->d_inode->i_nlink = 0;
 
        if (dir->i_nlink)
-               dir->i_nlink--;
+               drop_nlink(dir);
 
        return 0;
 }
index dcf04cb132831c116cac8fe0de090a7106527a47..ce05d1643dd17096b5c1b59758be0dc511d7ed42 100644 (file)
@@ -117,8 +117,7 @@ static int bfs_create(struct inode * dir, struct dentry * dentry, int mode,
 
        err = bfs_add_entry(dir, dentry->d_name.name, dentry->d_name.len, inode->i_ino);
        if (err) {
-               inode->i_nlink--;
-               mark_inode_dirty(inode);
+               inode_dec_link_count(inode);
                iput(inode);
                unlock_kernel();
                return err;
@@ -196,9 +195,8 @@ static int bfs_unlink(struct inode * dir, struct dentry * dentry)
        mark_buffer_dirty(bh);
        dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
        mark_inode_dirty(dir);
-       inode->i_nlink--;
        inode->i_ctime = dir->i_ctime;
-       mark_inode_dirty(inode);
+       inode_dec_link_count(inode);
        error = 0;
 
 out_brelse:
@@ -249,9 +247,8 @@ static int bfs_rename(struct inode * old_dir, struct dentry * old_dentry,
        old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
        mark_inode_dirty(old_dir);
        if (new_inode) {
-               new_inode->i_nlink--;
                new_inode->i_ctime = CURRENT_TIME_SEC;
-               mark_inode_dirty(new_inode);
+               inode_dec_link_count(new_inode);
        }
        mark_buffer_dirty(old_bh);
        error = 0;
index 05f874c7441bbd388087dd0be9a1197628144373..74441a17e1864dd9e3c2c42e54ca0f54b8fe63ce 100644 (file)
@@ -590,7 +590,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
 
        if (!rc) {
                if (direntry->d_inode)
-                       direntry->d_inode->i_nlink--;
+                       drop_nlink(direntry->d_inode);
        } else if (rc == -ENOENT) {
                d_drop(direntry);
        } else if (rc == -ETXTBSY) {
@@ -609,7 +609,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        CIFSSMBClose(xid, pTcon, netfid);
                        if (direntry->d_inode)
-                               direntry->d_inode->i_nlink--;
+                               drop_nlink(direntry->d_inode);
                }
        } else if (rc == -EACCES) {
                /* try only if r/o attribute set in local lookup data? */
@@ -663,7 +663,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                        if (!rc) {
                                if (direntry->d_inode)
-                                       direntry->d_inode->i_nlink--;
+                                       drop_nlink(direntry->d_inode);
                        } else if (rc == -ETXTBSY) {
                                int oplock = FALSE;
                                __u16 netfid;
@@ -684,7 +684,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
                                                    CIFS_MOUNT_MAP_SPECIAL_CHR);
                                        CIFSSMBClose(xid, pTcon, netfid);
                                        if (direntry->d_inode)
-                                               direntry->d_inode->i_nlink--;
+                                               drop_nlink(direntry->d_inode);
                                }
                        /* BB if rc = -ETXTBUSY goto the rename logic BB */
                        }
@@ -816,7 +816,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
 
        if (!rc) {
-               inode->i_nlink--;
+               drop_nlink(inode);
                i_size_write(direntry->d_inode,0);
                direntry->d_inode->i_nlink = 0;
        }
index 8651ea6a23b727c1c27b24b0d9a3b9d03c062fa0..0a2fd8bb7579bd60dcc153e7634da38c9a01ff0c 100644 (file)
@@ -367,7 +367,7 @@ int coda_unlink(struct inode *dir, struct dentry *de)
         }
 
        coda_dir_changed(dir, 0);
-       de->d_inode->i_nlink--;
+       drop_nlink(de->d_inode);
        unlock_kernel();
 
         return 0;
@@ -394,7 +394,7 @@ int coda_rmdir(struct inode *dir, struct dentry *de)
         }
 
        coda_dir_changed(dir, -1);
-       de->d_inode->i_nlink--;
+       drop_nlink(de->d_inode);
        d_delete(de);
        unlock_kernel();
 
index 4ca8249853219cbee8529031e8602052cda46db2..e1af5b4cf80c100c26ce08a559bbdab12de8753b 100644 (file)
@@ -326,7 +326,7 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
                ext2_set_link(new_dir, new_de, new_page, old_inode);
                new_inode->i_ctime = CURRENT_TIME_SEC;
                if (dir_de)
-                       new_inode->i_nlink--;
+                       drop_nlink(new_inode);
                inode_dec_link_count(new_inode);
        } else {
                if (dir_de) {
index 235e77b52ea59b2610c2ed5cf4af464f4cd12359..14c55adfae83eddbdc0abc78223782394ee7707b 100644 (file)
@@ -1621,7 +1621,7 @@ static inline void ext3_inc_count(handle_t *handle, struct inode *inode)
 
 static inline void ext3_dec_count(handle_t *handle, struct inode *inode)
 {
-       inode->i_nlink--;
+       drop_nlink(inode);
 }
 
 static int ext3_add_nondir(handle_t *handle,
@@ -1743,7 +1743,7 @@ retry:
        inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize;
        dir_block = ext3_bread (handle, inode, 0, 1, &err);
        if (!dir_block) {
-               inode->i_nlink--; /* is this nlink == 0? */
+               drop_nlink(inode); /* is this nlink == 0? */
                ext3_mark_inode_dirty(handle, inode);
                iput (inode);
                goto out_stop;
@@ -2053,7 +2053,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry)
        ext3_orphan_add(handle, inode);
        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
        ext3_mark_inode_dirty(handle, inode);
-       dir->i_nlink--;
+       drop_nlink(dir);
        ext3_update_dx_flag(dir);
        ext3_mark_inode_dirty(handle, dir);
 
@@ -2104,7 +2104,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry)
        dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
        ext3_update_dx_flag(dir);
        ext3_mark_inode_dirty(handle, dir);
-       inode->i_nlink--;
+       drop_nlink(inode);
        if (!inode->i_nlink)
                ext3_orphan_add(handle, inode);
        inode->i_ctime = dir->i_ctime;
@@ -2326,7 +2326,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
        }
 
        if (new_inode) {
-               new_inode->i_nlink--;
+               drop_nlink(new_inode);
                new_inode->i_ctime = CURRENT_TIME_SEC;
        }
        old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
@@ -2337,9 +2337,9 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry,
                PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
                BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata");
                ext3_journal_dirty_metadata(handle, dir_bh);
-               old_dir->i_nlink--;
+               drop_nlink(old_dir);
                if (new_inode) {
-                       new_inode->i_nlink--;
+                       drop_nlink(new_inode);
                } else {
                        new_dir->i_nlink++;
                        ext3_update_dx_flag(new_dir);
index 7cd8cc03aea7790159aa7ce5263e73655dabfd8d..cfef6ad529a7289d35f8f79590118ba43255a24d 100644 (file)
@@ -246,7 +246,7 @@ static int hfs_unlink(struct inode *dir, struct dentry *dentry)
        if (res)
                return res;
 
-       inode->i_nlink--;
+       drop_nlink(inode);
        hfs_delete_inode(inode);
        inode->i_ctime = CURRENT_TIME_SEC;
        mark_inode_dirty(inode);
index 1f9ece0de326227af5a15c238aca2f7b78a61aa0..9ceb0dfaa1cc0e8c14004dade785cc7860ca0111 100644 (file)
@@ -338,7 +338,7 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
                return res;
 
        if (inode->i_nlink > 0)
-               inode->i_nlink--;
+               drop_nlink(inode);
        hfsplus_delete_inode(inode);
        if (inode->i_ino != cnid && !inode->i_nlink) {
                if (!atomic_read(&HFSPLUS_I(inode).opencnt)) {
index 59e7dc182a0c760ff78631cf162313ff6b2f97d4..4078b0becc5e71f87a78c98f28e0c9cc8e70b03a 100644 (file)
@@ -434,7 +434,7 @@ again:
                unlock_kernel();
                return -ENOSPC;
        default:
-               inode->i_nlink--;
+               drop_nlink(inode);
                err = 0;
        }
        goto out;
@@ -494,7 +494,7 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
                err = -ENOSPC;
                break;
        default:
-               dir->i_nlink--;
+               drop_nlink(dir);
                inode->i_nlink = 0;
                err = 0;
        }
@@ -636,7 +636,7 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        hpfs_i(i)->i_parent_dir = new_dir->i_ino;
        if (S_ISDIR(i->i_mode)) {
                new_dir->i_nlink++;
-               old_dir->i_nlink--;
+               drop_nlink(old_dir);
        }
        if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
                fnode->up = new_dir->i_ino;
index 068ef0de8de2b63400da3a81be3e423cfc8d93ce..3f7899ea4cba9389742e6cb85d441ce9ff8c2535 100644 (file)
@@ -1052,9 +1052,8 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type)
 
        dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
        mark_inode_dirty(dir);
-       inode->i_nlink--;
        inode->i_ctime = dir->i_ctime;
-       mark_inode_dirty(inode);
+       inode_dec_link_count(inode);
 
        d_delete(dentry);       /* This also frees the inode */
 
index edd8371fc6a5b0f6f3c4dc1e220fe245642c5871..a5e9f2205b33b1e0980bb319558cb62fc795ee04 100644 (file)
@@ -615,7 +615,7 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
        }
        ret = jffs2_unlink(dir_i, dentry);
        if (!ret)
-               dir_i->i_nlink--;
+               drop_nlink(dir_i);
        return ret;
 }
 
@@ -823,7 +823,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
 
        if (victim_f) {
                /* There was a victim. Kill it off nicely */
-               new_dentry->d_inode->i_nlink--;
+               drop_nlink(new_dentry->d_inode);
                /* Don't oops if the victim was a dirent pointing to an
                   inode which didn't exist. */
                if (victim_f->inocache) {
@@ -862,7 +862,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
        }
 
        if (S_ISDIR(old_dentry->d_inode->i_mode))
-               old_dir_i->i_nlink--;
+               drop_nlink(old_dir_i);
 
        new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
 
index 295268ad231b5ec1f26c78cb43489d434122c907..088b85976ac0252fa69426f9c1cc89dbe0014a7d 100644 (file)
@@ -393,9 +393,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
        /* update parent directory's link count corresponding
         * to ".." entry of the target directory deleted
         */
-       dip->i_nlink--;
        dip->i_ctime = dip->i_mtime = CURRENT_TIME;
-       mark_inode_dirty(dip);
+       inode_dec_link_count(dip);
 
        /*
         * OS/2 could have created EA and/or ACL
@@ -515,8 +514,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
        mark_inode_dirty(dip);
 
        /* update target's inode */
-       ip->i_nlink--;
-       mark_inode_dirty(ip);
+       inode_dec_link_count(ip);
 
        /*
         *      commit zero link count object
@@ -835,7 +833,7 @@ static int jfs_link(struct dentry *old_dentry,
        rc = txCommit(tid, 2, &iplist[0], 0);
 
        if (rc) {
-               ip->i_nlink--;
+               ip->i_nlink--; /* never instantiated */
                iput(ip);
        } else
                d_instantiate(dentry, ip);
@@ -1155,9 +1153,9 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                              old_ip->i_ino, JFS_RENAME);
                if (rc)
                        goto out4;
-               new_ip->i_nlink--;
+               drop_nlink(new_ip);
                if (S_ISDIR(new_ip->i_mode)) {
-                       new_ip->i_nlink--;
+                       drop_nlink(new_ip);
                        if (new_ip->i_nlink) {
                                mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
                                if (old_dir != new_dir)
@@ -1223,7 +1221,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                goto out4;
        }
        if (S_ISDIR(old_ip->i_mode)) {
-               old_dir->i_nlink--;
+               drop_nlink(old_dir);
                if (old_dir != new_dir) {
                        /*
                         * Change inode number of parent for moved directory
index 3793aaa145776971a19fbbbb9b61934634f80731..9204feba75acebd5338ac706de510d38bf085578 100644 (file)
@@ -275,7 +275,7 @@ int simple_unlink(struct inode *dir, struct dentry *dentry)
        struct inode *inode = dentry->d_inode;
 
        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       inode->i_nlink--;
+       drop_nlink(inode);
        dput(dentry);
        return 0;
 }
@@ -285,9 +285,9 @@ int simple_rmdir(struct inode *dir, struct dentry *dentry)
        if (!simple_empty(dentry))
                return -ENOTEMPTY;
 
-       dentry->d_inode->i_nlink--;
+       drop_nlink(dentry->d_inode);
        simple_unlink(dir, dentry);
-       dir->i_nlink--;
+       drop_nlink(dir);
        return 0;
 }
 
@@ -303,9 +303,9 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
        if (new_dentry->d_inode) {
                simple_unlink(new_dir, new_dentry);
                if (they_are_dirs)
-                       old_dir->i_nlink--;
+                       drop_nlink(old_dir);
        } else if (they_are_dirs) {
-               old_dir->i_nlink--;
+               drop_nlink(old_dir);
                new_dir->i_nlink++;
        }
 
index 5b6a4540a05b61cf496d2f5b3bcbd2c3e9958fa0..299bb66e3bde55a880435c5dee0c315cfbdced0d 100644 (file)
@@ -249,7 +249,7 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
                minix_set_link(new_de, new_page, old_inode);
                new_inode->i_ctime = CURRENT_TIME_SEC;
                if (dir_de)
-                       new_inode->i_nlink--;
+                       drop_nlink(new_inode);
                inode_dec_link_count(new_inode);
        } else {
                if (dir_de) {
index d220165d49180fc53c6b66401e439ac2b9d36113..635613f2f65ac626cbd5118708027a3f36b55700 100644 (file)
@@ -343,7 +343,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry)
        err = fat_remove_entries(dir, &sinfo);  /* and releases bh */
        if (err)
                goto out;
-       dir->i_nlink--;
+       drop_nlink(dir);
 
        inode->i_nlink = 0;
        inode->i_ctime = CURRENT_TIME_SEC;
@@ -549,7 +549,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
                        if (err)
                                goto error_dotdot;
                }
-               old_dir->i_nlink--;
+               drop_nlink(old_dir);
                if (!new_inode)
                        new_dir->i_nlink++;
        }
@@ -566,10 +566,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
                mark_inode_dirty(old_dir);
 
        if (new_inode) {
+               drop_nlink(new_inode);
                if (is_dir)
-                       new_inode->i_nlink -= 2;
-               else
-                       new_inode->i_nlink--;
+                       drop_nlink(new_inode);
                new_inode->i_ctime = ts;
        }
 out:
index 7432f1a43f3d6bc66c3aee43366a3111a46b8ad8..26eecb86f9b085b145c169faad6288e68a8a4417 100644 (file)
@@ -843,7 +843,7 @@ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode)
        nfs_inode_return_delegation(inode);
        if (dentry->d_flags & DCACHE_NFSFS_RENAMED) {
                lock_kernel();
-               inode->i_nlink--;
+               drop_nlink(inode);
                nfs_complete_unlink(dentry);
                unlock_kernel();
        }
@@ -1401,7 +1401,7 @@ static int nfs_safe_remove(struct dentry *dentry)
                error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
                /* The VFS may want to delete this inode */
                if (error == 0)
-                       inode->i_nlink--;
+                       drop_nlink(inode);
                nfs_mark_for_revalidate(inode);
                nfs_end_data_update(inode);
        } else
@@ -1639,7 +1639,7 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        goto out;
                }
        } else
-               new_inode->i_nlink--;
+               drop_nlink(new_inode);
 
 go_ahead:
        /*
index 849c3b4bb94a12d1e856df92e3c47d8e08dd3b43..40f83f53053a8eac58a027c68892aa1ed42d8392 100644 (file)
@@ -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;
        }
index c3d83f67154a61c2fe39421d7809a04d4769577b..ad5afa4ea8f3fa975318151c2118ad754941d468 100644 (file)
@@ -189,8 +189,7 @@ int qnx4_rmdir(struct inode *dir, struct dentry *dentry)
        inode->i_nlink = 0;
        mark_inode_dirty(inode);
        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
-       dir->i_nlink--;
-       mark_inode_dirty(dir);
+       inode_dec_link_count(dir);
        retval = 0;
 
       end_rmdir:
@@ -234,9 +233,8 @@ int qnx4_unlink(struct inode *dir, struct dentry *dentry)
        mark_buffer_dirty(bh);
        dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
        mark_inode_dirty(dir);
-       inode->i_nlink--;
        inode->i_ctime = dir->i_ctime;
-       mark_inode_dirty(inode);
+       inode_dec_link_count(inode);
        retval = 0;
 
 end_unlink:
index c61710e49c6244e9559cb0f1b0fb92e24442d59f..c76d427e027b3d8246b0a6ebd8d4bce74fd958bf 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/quotaops.h>
 
 #define INC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) { i->i_nlink++; if (i->i_nlink >= REISERFS_LINK_MAX) i->i_nlink=1; }
-#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) i->i_nlink--;
+#define DEC_DIR_INODE_NLINK(i) if (i->i_nlink != 1) drop_nlink(i);
 
 // directory item contains array of entry headers. This performs
 // binary search through that array
@@ -994,7 +994,7 @@ static int reiserfs_unlink(struct inode *dir, struct dentry *dentry)
                inode->i_nlink = 1;
        }
 
-       inode->i_nlink--;
+       drop_nlink(inode);
 
        /*
         * we schedule before doing the add_save_link call, save the link
@@ -1475,7 +1475,7 @@ static int reiserfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                if (S_ISDIR(new_dentry_inode->i_mode)) {
                        new_dentry_inode->i_nlink = 0;
                } else {
-                       new_dentry_inode->i_nlink--;
+                       drop_nlink(new_dentry_inode);
                }
                new_dentry_inode->i_ctime = ctime;
                savelink = new_dentry_inode->i_nlink;
index b8a73f716fbe35c5a0683017db96fc3c2d1136cd..f7c08db8e34c80225000cd10b7722e5d8ef82eb6 100644 (file)
@@ -250,7 +250,7 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
                sysv_set_link(new_de, new_page, old_inode);
                new_inode->i_ctime = CURRENT_TIME_SEC;
                if (dir_de)
-                       new_inode->i_nlink--;
+                       drop_nlink(new_inode);
                inode_dec_link_count(new_inode);
        } else {
                if (dir_de) {
index ab9a7629d23e82c094e8b7db9606a57af007e294..d14d25534aa8df29074718d8e1cd30f3b168cea6 100644 (file)
@@ -878,8 +878,7 @@ static int udf_rmdir(struct inode * dir, struct dentry * dentry)
                        inode->i_nlink);
        inode->i_nlink = 0;
        inode->i_size = 0;
-       mark_inode_dirty(inode);
-       dir->i_nlink --;
+       inode_dec_link_count(inode);
        inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
        mark_inode_dirty(dir);
 
@@ -923,8 +922,7 @@ static int udf_unlink(struct inode * dir, struct dentry * dentry)
                goto end_unlink;
        dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
        mark_inode_dirty(dir);
-       inode->i_nlink--;
-       mark_inode_dirty(inode);
+       inode_dec_link_count(inode);
        inode->i_ctime = dir->i_ctime;
        retval = 0;
 
@@ -1101,8 +1099,7 @@ out:
        return err;
 
 out_no_entry:
-       inode->i_nlink--;
-       mark_inode_dirty(inode);
+       inode_dec_link_count(inode);
        iput(inode);
        goto out;
 }
@@ -1261,9 +1258,8 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
 
        if (new_inode)
        {
-               new_inode->i_nlink--;
                new_inode->i_ctime = current_fs_time(new_inode->i_sb);
-               mark_inode_dirty(new_inode);
+               inode_dec_link_count(new_inode);
        }
        old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb);
        mark_inode_dirty(old_dir);
@@ -1279,12 +1275,10 @@ static int udf_rename (struct inode * old_dir, struct dentry * old_dentry,
                }
                else
                        mark_buffer_dirty_inode(dir_bh, old_inode);
-               old_dir->i_nlink --;
-               mark_inode_dirty(old_dir);
+               inode_dec_link_count(old_dir);
                if (new_inode)
                {
-                       new_inode->i_nlink --;
-                       mark_inode_dirty(new_inode);
+                       inode_dec_link_count(new_inode);
                }
                else
                {
index d344b411e2617eca708d104a7b8dc5266e26ab7b..e84c0ecf07304f0f8222e3c438f4e1b8bb5bed34 100644 (file)
@@ -308,7 +308,7 @@ static int ufs_rename(struct inode *old_dir, struct dentry *old_dentry,
                ufs_set_link(new_dir, new_de, new_page, old_inode);
                new_inode->i_ctime = CURRENT_TIME_SEC;
                if (dir_de)
-                       new_inode->i_nlink--;
+                       drop_nlink(new_inode);
                inode_dec_link_count(new_inode);
        } else {
                if (dir_de) {
index 9a8f48bae95626b739b34867713fc2d7d367f649..090d74ffa0615aa09a651dab6bfa6733784965cf 100644 (file)
@@ -782,7 +782,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
        err = fat_remove_entries(dir, &sinfo);  /* and releases bh */
        if (err)
                goto out;
-       dir->i_nlink--;
+       drop_nlink(dir);
 
        inode->i_nlink = 0;
        inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
@@ -930,7 +930,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
                        if (err)
                                goto error_dotdot;
                }
-               old_dir->i_nlink--;
+               drop_nlink(old_dir);
                if (!new_inode)
                        new_dir->i_nlink++;
        }
@@ -947,10 +947,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
                mark_inode_dirty(old_dir);
 
        if (new_inode) {
+               drop_nlink(new_inode);
                if (is_dir)
-                       new_inode->i_nlink -= 2;
-               else
-                       new_inode->i_nlink--;
+                       drop_nlink(new_inode);
                new_inode->i_ctime = ts;
        }
 out:
index 4bb70871873f3392c3e1d53b73366a4ce4bded34..26d3c61116c04e843fbb0d8517f818289c9d953f 100644 (file)
@@ -1225,9 +1225,14 @@ static inline void inode_inc_link_count(struct inode *inode)
        mark_inode_dirty(inode);
 }
 
-static inline void inode_dec_link_count(struct inode *inode)
+static inline void drop_nlink(struct inode *inode)
 {
        inode->i_nlink--;
+}
+
+static inline void inode_dec_link_count(struct inode *inode)
+{
+       drop_nlink(inode);
        mark_inode_dirty(inode);
 }
 
index 840f8a6fb85ff1e98ee37774df42ea748465eff6..10aa8eeeb112a745b84ef123f9f1641dcf819f5c 100644 (file)
@@ -307,7 +307,7 @@ static int mqueue_unlink(struct inode *dir, struct dentry *dentry)
 
        dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
        dir->i_size -= DIRENT_SIZE;
-       inode->i_nlink--;
+       drop_nlink(inode);
        dput(dentry);
        return 0;
 }
index b96de69f236b22225c4dcb9221d807808a7c8945..908dd947b1ea8ceb109fdd45cb6b8eb94c8d621e 100644 (file)
@@ -1772,7 +1772,7 @@ static int shmem_unlink(struct inode *dir, struct dentry *dentry)
 
        dir->i_size -= BOGO_DIRENT_SIZE;
        inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       inode->i_nlink--;
+       drop_nlink(inode);
        dput(dentry);   /* Undo the count from "create" - this does all the work */
        return 0;
 }
@@ -1782,8 +1782,8 @@ static int shmem_rmdir(struct inode *dir, struct dentry *dentry)
        if (!simple_empty(dentry))
                return -ENOTEMPTY;
 
-       dentry->d_inode->i_nlink--;
-       dir->i_nlink--;
+       drop_nlink(dentry->d_inode);
+       drop_nlink(dir);
        return shmem_unlink(dir, dentry);
 }
 
@@ -1804,9 +1804,9 @@ static int shmem_rename(struct inode *old_dir, struct dentry *old_dentry, struct
        if (new_dentry->d_inode) {
                (void) shmem_unlink(new_dir, new_dentry);
                if (they_are_dirs)
-                       old_dir->i_nlink--;
+                       drop_nlink(old_dir);
        } else if (they_are_dirs) {
-               old_dir->i_nlink--;
+               drop_nlink(old_dir);
                new_dir->i_nlink++;
        }