Loading fs/ocfs2/cluster/tcp_internal.h +4 −1 Original line number Diff line number Diff line Loading @@ -44,11 +44,14 @@ * locking semantics of the file system using the protocol. It should * be somewhere else, I'm sure, but right now it isn't. * * New in version 3: * - Replace dentry votes with a cluster lock * * New in version 2: * - full 64 bit i_size in the metadata lock lvbs * - introduction of "rw" lock and pushing meta/data locking down */ #define O2NET_PROTOCOL_VERSION 2ULL #define O2NET_PROTOCOL_VERSION 3ULL struct o2net_handshake { __be64 protocol_version; __be64 connector_id; Loading fs/ocfs2/export.c +4 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include "dir.h" #include "dlmglue.h" #include "dcache.h" #include "export.h" #include "inode.h" Loading Loading @@ -77,6 +78,7 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp) mlog_errno(-ENOMEM); return ERR_PTR(-ENOMEM); } result->d_op = &ocfs2_dentry_ops; mlog_exit_ptr(result); return result; Loading Loading @@ -127,6 +129,8 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) parent = ERR_PTR(-ENOMEM); } parent->d_op = &ocfs2_dentry_ops; bail_unlock: ocfs2_meta_unlock(dir, 0); Loading fs/ocfs2/inode.c +4 −6 Original line number Diff line number Diff line Loading @@ -1025,11 +1025,9 @@ void ocfs2_drop_inode(struct inode *inode) /* Testing ip_orphaned_slot here wouldn't work because we may * not have gotten a delete_inode vote from any other nodes * yet. */ if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED) { mlog(0, "Inode was orphaned on another node, clearing nlink.\n"); inode->i_nlink = 0; } if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED) generic_delete_inode(inode); else generic_drop_inode(inode); mlog_exit_void(); Loading fs/ocfs2/namei.c +82 −34 Original line number Diff line number Diff line Loading @@ -199,10 +199,32 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, spin_unlock(&oi->ip_lock); bail_add: dentry->d_op = &ocfs2_dentry_ops; ret = d_splice_alias(inode, dentry); if (inode) { /* * If d_splice_alias() finds a DCACHE_DISCONNECTED * dentry, it will d_move() it on top of ourse. The * return value will indicate this however, so in * those cases, we switch them around for the locking * code. * * NOTE: This dentry already has ->d_op set from * ocfs2_get_parent() and ocfs2_get_dentry() */ if (ret) dentry = ret; status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno, 0); if (status) { mlog_errno(status); ret = ERR_PTR(status); goto bail_unlock; } } bail_unlock: /* Don't drop the cluster lock until *after* the d_add -- * unlink on another node will message us to remove that Loading Loading @@ -418,6 +440,13 @@ static int ocfs2_mknod(struct inode *dir, goto leave; } status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno, 1); if (status) { mlog_errno(status); goto leave; } insert_inode_hash(inode); dentry->d_op = &ocfs2_dentry_ops; d_instantiate(dentry, inode); Loading Loading @@ -725,6 +754,13 @@ static int ocfs2_link(struct dentry *old_dentry, goto bail; } err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno, 0); if (err) { mlog_errno(err); goto bail; } atomic_inc(&inode->i_count); dentry->d_op = &ocfs2_dentry_ops; d_instantiate(dentry, inode); Loading @@ -743,6 +779,23 @@ static int ocfs2_link(struct dentry *old_dentry, return err; } /* * Takes and drops an exclusive lock on the given dentry. This will * force other nodes to drop it. */ static int ocfs2_remote_dentry_delete(struct dentry *dentry) { int ret; ret = ocfs2_dentry_lock(dentry, 1); if (ret) mlog_errno(ret); else ocfs2_dentry_unlock(dentry, 1); return ret; } static int ocfs2_unlink(struct inode *dir, struct dentry *dentry) { Loading Loading @@ -832,8 +885,7 @@ static int ocfs2_unlink(struct inode *dir, else inode->i_nlink--; status = ocfs2_request_unlink_vote(inode, dentry, (unsigned int) inode->i_nlink); status = ocfs2_remote_dentry_delete(dentry); if (status < 0) { /* This vote should succeed under all normal * circumstances. */ Loading Loading @@ -1019,7 +1071,6 @@ static int ocfs2_rename(struct inode *old_dir, struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, // this is the 1st dirent bh nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink; unsigned int links_count; /* At some point it might be nice to break this function up a * bit. */ Loading Loading @@ -1093,10 +1144,12 @@ static int ocfs2_rename(struct inode *old_dir, } } if (S_ISDIR(old_inode->i_mode)) { /* Directories actually require metadata updates to * the directory info so we can't get away with not * doing node locking on it. */ /* * Though we don't require an inode meta data update if * old_inode is not a directory, we lock anyway here to ensure * the vote thread on other nodes won't have to concurrently * downconvert the inode and the dentry locks. */ status = ocfs2_meta_lock(old_inode, handle, NULL, 1); if (status < 0) { if (status != -ENOENT) Loading @@ -1104,12 +1157,13 @@ static int ocfs2_rename(struct inode *old_dir, goto bail; } status = ocfs2_request_rename_vote(old_inode, old_dentry); status = ocfs2_remote_dentry_delete(old_dentry); if (status < 0) { mlog_errno(status); goto bail; } if (S_ISDIR(old_inode->i_mode)) { status = -EIO; old_inode_de_bh = ocfs2_bread(old_inode, 0, &status, 0); if (!old_inode_de_bh) Loading @@ -1123,14 +1177,6 @@ static int ocfs2_rename(struct inode *old_dir, if (!new_inode && new_dir!=old_dir && new_dir->i_nlink >= OCFS2_LINK_MAX) goto bail; } else { /* Ah, the simple case - we're a file so just send a * message. */ status = ocfs2_request_rename_vote(old_inode, old_dentry); if (status < 0) { mlog_errno(status); goto bail; } } status = -ENOENT; Loading Loading @@ -1202,13 +1248,7 @@ static int ocfs2_rename(struct inode *old_dir, goto bail; } if (S_ISDIR(new_inode->i_mode)) links_count = 0; else links_count = (unsigned int) (new_inode->i_nlink - 1); status = ocfs2_request_unlink_vote(new_inode, new_dentry, links_count); status = ocfs2_remote_dentry_delete(new_dentry); if (status < 0) { mlog_errno(status); goto bail; Loading Loading @@ -1387,6 +1427,7 @@ static int ocfs2_rename(struct inode *old_dir, } } ocfs2_dentry_move(old_dentry, new_dentry, old_dir, new_dir); status = 0; bail: if (rename_lock) Loading Loading @@ -1675,6 +1716,13 @@ static int ocfs2_symlink(struct inode *dir, goto bail; } status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno, 1); if (status) { mlog_errno(status); goto bail; } insert_inode_hash(inode); dentry->d_op = &ocfs2_dentry_ops; d_instantiate(dentry, inode); Loading Loading
fs/ocfs2/cluster/tcp_internal.h +4 −1 Original line number Diff line number Diff line Loading @@ -44,11 +44,14 @@ * locking semantics of the file system using the protocol. It should * be somewhere else, I'm sure, but right now it isn't. * * New in version 3: * - Replace dentry votes with a cluster lock * * New in version 2: * - full 64 bit i_size in the metadata lock lvbs * - introduction of "rw" lock and pushing meta/data locking down */ #define O2NET_PROTOCOL_VERSION 2ULL #define O2NET_PROTOCOL_VERSION 3ULL struct o2net_handshake { __be64 protocol_version; __be64 connector_id; Loading
fs/ocfs2/export.c +4 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include "dir.h" #include "dlmglue.h" #include "dcache.h" #include "export.h" #include "inode.h" Loading Loading @@ -77,6 +78,7 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp) mlog_errno(-ENOMEM); return ERR_PTR(-ENOMEM); } result->d_op = &ocfs2_dentry_ops; mlog_exit_ptr(result); return result; Loading Loading @@ -127,6 +129,8 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) parent = ERR_PTR(-ENOMEM); } parent->d_op = &ocfs2_dentry_ops; bail_unlock: ocfs2_meta_unlock(dir, 0); Loading
fs/ocfs2/inode.c +4 −6 Original line number Diff line number Diff line Loading @@ -1025,11 +1025,9 @@ void ocfs2_drop_inode(struct inode *inode) /* Testing ip_orphaned_slot here wouldn't work because we may * not have gotten a delete_inode vote from any other nodes * yet. */ if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED) { mlog(0, "Inode was orphaned on another node, clearing nlink.\n"); inode->i_nlink = 0; } if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED) generic_delete_inode(inode); else generic_drop_inode(inode); mlog_exit_void(); Loading
fs/ocfs2/namei.c +82 −34 Original line number Diff line number Diff line Loading @@ -199,10 +199,32 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, spin_unlock(&oi->ip_lock); bail_add: dentry->d_op = &ocfs2_dentry_ops; ret = d_splice_alias(inode, dentry); if (inode) { /* * If d_splice_alias() finds a DCACHE_DISCONNECTED * dentry, it will d_move() it on top of ourse. The * return value will indicate this however, so in * those cases, we switch them around for the locking * code. * * NOTE: This dentry already has ->d_op set from * ocfs2_get_parent() and ocfs2_get_dentry() */ if (ret) dentry = ret; status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno, 0); if (status) { mlog_errno(status); ret = ERR_PTR(status); goto bail_unlock; } } bail_unlock: /* Don't drop the cluster lock until *after* the d_add -- * unlink on another node will message us to remove that Loading Loading @@ -418,6 +440,13 @@ static int ocfs2_mknod(struct inode *dir, goto leave; } status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno, 1); if (status) { mlog_errno(status); goto leave; } insert_inode_hash(inode); dentry->d_op = &ocfs2_dentry_ops; d_instantiate(dentry, inode); Loading Loading @@ -725,6 +754,13 @@ static int ocfs2_link(struct dentry *old_dentry, goto bail; } err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno, 0); if (err) { mlog_errno(err); goto bail; } atomic_inc(&inode->i_count); dentry->d_op = &ocfs2_dentry_ops; d_instantiate(dentry, inode); Loading @@ -743,6 +779,23 @@ static int ocfs2_link(struct dentry *old_dentry, return err; } /* * Takes and drops an exclusive lock on the given dentry. This will * force other nodes to drop it. */ static int ocfs2_remote_dentry_delete(struct dentry *dentry) { int ret; ret = ocfs2_dentry_lock(dentry, 1); if (ret) mlog_errno(ret); else ocfs2_dentry_unlock(dentry, 1); return ret; } static int ocfs2_unlink(struct inode *dir, struct dentry *dentry) { Loading Loading @@ -832,8 +885,7 @@ static int ocfs2_unlink(struct inode *dir, else inode->i_nlink--; status = ocfs2_request_unlink_vote(inode, dentry, (unsigned int) inode->i_nlink); status = ocfs2_remote_dentry_delete(dentry); if (status < 0) { /* This vote should succeed under all normal * circumstances. */ Loading Loading @@ -1019,7 +1071,6 @@ static int ocfs2_rename(struct inode *old_dir, struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, // this is the 1st dirent bh nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink; unsigned int links_count; /* At some point it might be nice to break this function up a * bit. */ Loading Loading @@ -1093,10 +1144,12 @@ static int ocfs2_rename(struct inode *old_dir, } } if (S_ISDIR(old_inode->i_mode)) { /* Directories actually require metadata updates to * the directory info so we can't get away with not * doing node locking on it. */ /* * Though we don't require an inode meta data update if * old_inode is not a directory, we lock anyway here to ensure * the vote thread on other nodes won't have to concurrently * downconvert the inode and the dentry locks. */ status = ocfs2_meta_lock(old_inode, handle, NULL, 1); if (status < 0) { if (status != -ENOENT) Loading @@ -1104,12 +1157,13 @@ static int ocfs2_rename(struct inode *old_dir, goto bail; } status = ocfs2_request_rename_vote(old_inode, old_dentry); status = ocfs2_remote_dentry_delete(old_dentry); if (status < 0) { mlog_errno(status); goto bail; } if (S_ISDIR(old_inode->i_mode)) { status = -EIO; old_inode_de_bh = ocfs2_bread(old_inode, 0, &status, 0); if (!old_inode_de_bh) Loading @@ -1123,14 +1177,6 @@ static int ocfs2_rename(struct inode *old_dir, if (!new_inode && new_dir!=old_dir && new_dir->i_nlink >= OCFS2_LINK_MAX) goto bail; } else { /* Ah, the simple case - we're a file so just send a * message. */ status = ocfs2_request_rename_vote(old_inode, old_dentry); if (status < 0) { mlog_errno(status); goto bail; } } status = -ENOENT; Loading Loading @@ -1202,13 +1248,7 @@ static int ocfs2_rename(struct inode *old_dir, goto bail; } if (S_ISDIR(new_inode->i_mode)) links_count = 0; else links_count = (unsigned int) (new_inode->i_nlink - 1); status = ocfs2_request_unlink_vote(new_inode, new_dentry, links_count); status = ocfs2_remote_dentry_delete(new_dentry); if (status < 0) { mlog_errno(status); goto bail; Loading Loading @@ -1387,6 +1427,7 @@ static int ocfs2_rename(struct inode *old_dir, } } ocfs2_dentry_move(old_dentry, new_dentry, old_dir, new_dir); status = 0; bail: if (rename_lock) Loading Loading @@ -1675,6 +1716,13 @@ static int ocfs2_symlink(struct inode *dir, goto bail; } status = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno, 1); if (status) { mlog_errno(status); goto bail; } insert_inode_hash(inode); dentry->d_op = &ocfs2_dentry_ops; d_instantiate(dentry, inode); Loading