|
@@ -75,12 +75,12 @@ static int inline ocfs2_search_dirblock(struct buffer_head *bh,
|
|
unsigned long offset,
|
|
unsigned long offset,
|
|
struct ocfs2_dir_entry **res_dir);
|
|
struct ocfs2_dir_entry **res_dir);
|
|
|
|
|
|
-static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+static int ocfs2_delete_entry(handle_t *handle,
|
|
struct inode *dir,
|
|
struct inode *dir,
|
|
struct ocfs2_dir_entry *de_del,
|
|
struct ocfs2_dir_entry *de_del,
|
|
struct buffer_head *bh);
|
|
struct buffer_head *bh);
|
|
|
|
|
|
-static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+static int __ocfs2_add_entry(handle_t *handle,
|
|
struct inode *dir,
|
|
struct inode *dir,
|
|
const char *name, int namelen,
|
|
const char *name, int namelen,
|
|
struct inode *inode, u64 blkno,
|
|
struct inode *inode, u64 blkno,
|
|
@@ -93,43 +93,37 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
|
|
dev_t dev,
|
|
dev_t dev,
|
|
struct buffer_head **new_fe_bh,
|
|
struct buffer_head **new_fe_bh,
|
|
struct buffer_head *parent_fe_bh,
|
|
struct buffer_head *parent_fe_bh,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ handle_t *handle,
|
|
struct inode **ret_inode,
|
|
struct inode **ret_inode,
|
|
struct ocfs2_alloc_context *inode_ac);
|
|
struct ocfs2_alloc_context *inode_ac);
|
|
|
|
|
|
static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
|
|
static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ handle_t *handle,
|
|
struct inode *parent,
|
|
struct inode *parent,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
struct buffer_head *fe_bh,
|
|
struct buffer_head *fe_bh,
|
|
struct ocfs2_alloc_context *data_ac);
|
|
struct ocfs2_alloc_context *data_ac);
|
|
|
|
|
|
-static int ocfs2_double_lock(struct ocfs2_super *osb,
|
|
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
- struct buffer_head **bh1,
|
|
|
|
- struct inode *inode1,
|
|
|
|
- struct buffer_head **bh2,
|
|
|
|
- struct inode *inode2);
|
|
|
|
-
|
|
|
|
static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
|
|
static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ struct inode **ret_orphan_dir,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
char *name,
|
|
char *name,
|
|
struct buffer_head **de_bh);
|
|
struct buffer_head **de_bh);
|
|
|
|
|
|
static int ocfs2_orphan_add(struct ocfs2_super *osb,
|
|
static int ocfs2_orphan_add(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ handle_t *handle,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
struct ocfs2_dinode *fe,
|
|
struct ocfs2_dinode *fe,
|
|
char *name,
|
|
char *name,
|
|
- struct buffer_head *de_bh);
|
|
|
|
|
|
+ struct buffer_head *de_bh,
|
|
|
|
+ struct inode *orphan_dir_inode);
|
|
|
|
|
|
static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
|
|
static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ handle_t *handle,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
const char *symname);
|
|
const char *symname);
|
|
|
|
|
|
-static inline int ocfs2_add_entry(struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+static inline int ocfs2_add_entry(handle_t *handle,
|
|
struct dentry *dentry,
|
|
struct dentry *dentry,
|
|
struct inode *inode, u64 blkno,
|
|
struct inode *inode, u64 blkno,
|
|
struct buffer_head *parent_fe_bh,
|
|
struct buffer_head *parent_fe_bh,
|
|
@@ -165,7 +159,7 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
|
|
mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len,
|
|
mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len,
|
|
dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno);
|
|
dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno);
|
|
|
|
|
|
- status = ocfs2_meta_lock(dir, NULL, NULL, 0);
|
|
|
|
|
|
+ status = ocfs2_meta_lock(dir, NULL, 0);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOENT)
|
|
if (status != -ENOENT)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
@@ -242,7 +236,7 @@ bail:
|
|
}
|
|
}
|
|
|
|
|
|
static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
|
|
static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ handle_t *handle,
|
|
struct inode *parent,
|
|
struct inode *parent,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
struct buffer_head *fe_bh,
|
|
struct buffer_head *fe_bh,
|
|
@@ -317,7 +311,7 @@ static int ocfs2_mknod(struct inode *dir,
|
|
{
|
|
{
|
|
int status = 0;
|
|
int status = 0;
|
|
struct buffer_head *parent_fe_bh = NULL;
|
|
struct buffer_head *parent_fe_bh = NULL;
|
|
- struct ocfs2_journal_handle *handle = NULL;
|
|
|
|
|
|
+ handle_t *handle = NULL;
|
|
struct ocfs2_super *osb;
|
|
struct ocfs2_super *osb;
|
|
struct ocfs2_dinode *dirfe;
|
|
struct ocfs2_dinode *dirfe;
|
|
struct buffer_head *new_fe_bh = NULL;
|
|
struct buffer_head *new_fe_bh = NULL;
|
|
@@ -333,18 +327,11 @@ static int ocfs2_mknod(struct inode *dir,
|
|
/* get our super block */
|
|
/* get our super block */
|
|
osb = OCFS2_SB(dir->i_sb);
|
|
osb = OCFS2_SB(dir->i_sb);
|
|
|
|
|
|
- handle = ocfs2_alloc_handle(osb);
|
|
|
|
- if (handle == NULL) {
|
|
|
|
- status = -ENOMEM;
|
|
|
|
- mlog_errno(status);
|
|
|
|
- goto leave;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1);
|
|
|
|
|
|
+ status = ocfs2_meta_lock(dir, &parent_fe_bh, 1);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOENT)
|
|
if (status != -ENOENT)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
- goto leave;
|
|
|
|
|
|
+ return status;
|
|
}
|
|
}
|
|
|
|
|
|
if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
|
|
if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
|
|
@@ -374,7 +361,7 @@ static int ocfs2_mknod(struct inode *dir,
|
|
}
|
|
}
|
|
|
|
|
|
/* reserve an inode spot */
|
|
/* reserve an inode spot */
|
|
- status = ocfs2_reserve_new_inode(osb, handle, &inode_ac);
|
|
|
|
|
|
+ status = ocfs2_reserve_new_inode(osb, &inode_ac);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOSPC)
|
|
if (status != -ENOSPC)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
@@ -384,7 +371,7 @@ static int ocfs2_mknod(struct inode *dir,
|
|
/* are we making a directory? If so, reserve a cluster for his
|
|
/* are we making a directory? If so, reserve a cluster for his
|
|
* 1st extent. */
|
|
* 1st extent. */
|
|
if (S_ISDIR(mode)) {
|
|
if (S_ISDIR(mode)) {
|
|
- status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac);
|
|
|
|
|
|
+ status = ocfs2_reserve_clusters(osb, 1, &data_ac);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOSPC)
|
|
if (status != -ENOSPC)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
@@ -392,7 +379,7 @@ static int ocfs2_mknod(struct inode *dir,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- handle = ocfs2_start_trans(osb, handle, OCFS2_MKNOD_CREDITS);
|
|
|
|
|
|
+ handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS);
|
|
if (IS_ERR(handle)) {
|
|
if (IS_ERR(handle)) {
|
|
status = PTR_ERR(handle);
|
|
status = PTR_ERR(handle);
|
|
handle = NULL;
|
|
handle = NULL;
|
|
@@ -453,7 +440,9 @@ static int ocfs2_mknod(struct inode *dir,
|
|
status = 0;
|
|
status = 0;
|
|
leave:
|
|
leave:
|
|
if (handle)
|
|
if (handle)
|
|
- ocfs2_commit_trans(handle);
|
|
|
|
|
|
+ ocfs2_commit_trans(osb, handle);
|
|
|
|
+
|
|
|
|
+ ocfs2_meta_unlock(dir, 1);
|
|
|
|
|
|
if (status == -ENOSPC)
|
|
if (status == -ENOSPC)
|
|
mlog(0, "Disk is full\n");
|
|
mlog(0, "Disk is full\n");
|
|
@@ -487,7 +476,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
|
|
dev_t dev,
|
|
dev_t dev,
|
|
struct buffer_head **new_fe_bh,
|
|
struct buffer_head **new_fe_bh,
|
|
struct buffer_head *parent_fe_bh,
|
|
struct buffer_head *parent_fe_bh,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ handle_t *handle,
|
|
struct inode **ret_inode,
|
|
struct inode **ret_inode,
|
|
struct ocfs2_alloc_context *inode_ac)
|
|
struct ocfs2_alloc_context *inode_ac)
|
|
{
|
|
{
|
|
@@ -653,7 +642,7 @@ static int ocfs2_link(struct dentry *old_dentry,
|
|
struct inode *dir,
|
|
struct inode *dir,
|
|
struct dentry *dentry)
|
|
struct dentry *dentry)
|
|
{
|
|
{
|
|
- struct ocfs2_journal_handle *handle = NULL;
|
|
|
|
|
|
+ handle_t *handle;
|
|
struct inode *inode = old_dentry->d_inode;
|
|
struct inode *inode = old_dentry->d_inode;
|
|
int err;
|
|
int err;
|
|
struct buffer_head *fe_bh = NULL;
|
|
struct buffer_head *fe_bh = NULL;
|
|
@@ -666,68 +655,60 @@ static int ocfs2_link(struct dentry *old_dentry,
|
|
old_dentry->d_name.len, old_dentry->d_name.name,
|
|
old_dentry->d_name.len, old_dentry->d_name.name,
|
|
dentry->d_name.len, dentry->d_name.name);
|
|
dentry->d_name.len, dentry->d_name.name);
|
|
|
|
|
|
- if (S_ISDIR(inode->i_mode)) {
|
|
|
|
- err = -EPERM;
|
|
|
|
- goto bail;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- handle = ocfs2_alloc_handle(osb);
|
|
|
|
- if (handle == NULL) {
|
|
|
|
- err = -ENOMEM;
|
|
|
|
- goto bail;
|
|
|
|
- }
|
|
|
|
|
|
+ if (S_ISDIR(inode->i_mode))
|
|
|
|
+ return -EPERM;
|
|
|
|
|
|
- err = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1);
|
|
|
|
|
|
+ err = ocfs2_meta_lock(dir, &parent_fe_bh, 1);
|
|
if (err < 0) {
|
|
if (err < 0) {
|
|
if (err != -ENOENT)
|
|
if (err != -ENOENT)
|
|
mlog_errno(err);
|
|
mlog_errno(err);
|
|
- goto bail;
|
|
|
|
|
|
+ return err;
|
|
}
|
|
}
|
|
|
|
|
|
if (!dir->i_nlink) {
|
|
if (!dir->i_nlink) {
|
|
err = -ENOENT;
|
|
err = -ENOENT;
|
|
- goto bail;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
|
|
|
|
err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
|
|
err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
|
|
dentry->d_name.len);
|
|
dentry->d_name.len);
|
|
if (err)
|
|
if (err)
|
|
- goto bail;
|
|
|
|
|
|
+ goto out;
|
|
|
|
|
|
err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
|
|
err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
|
|
dentry->d_name.name,
|
|
dentry->d_name.name,
|
|
dentry->d_name.len, &de_bh);
|
|
dentry->d_name.len, &de_bh);
|
|
if (err < 0) {
|
|
if (err < 0) {
|
|
mlog_errno(err);
|
|
mlog_errno(err);
|
|
- goto bail;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- err = ocfs2_meta_lock(inode, handle, &fe_bh, 1);
|
|
|
|
|
|
+ err = ocfs2_meta_lock(inode, &fe_bh, 1);
|
|
if (err < 0) {
|
|
if (err < 0) {
|
|
if (err != -ENOENT)
|
|
if (err != -ENOENT)
|
|
mlog_errno(err);
|
|
mlog_errno(err);
|
|
- goto bail;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
|
|
|
|
fe = (struct ocfs2_dinode *) fe_bh->b_data;
|
|
fe = (struct ocfs2_dinode *) fe_bh->b_data;
|
|
if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) {
|
|
if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) {
|
|
err = -EMLINK;
|
|
err = -EMLINK;
|
|
- goto bail;
|
|
|
|
|
|
+ goto out_unlock_inode;
|
|
}
|
|
}
|
|
|
|
|
|
- handle = ocfs2_start_trans(osb, handle, OCFS2_LINK_CREDITS);
|
|
|
|
|
|
+ handle = ocfs2_start_trans(osb, OCFS2_LINK_CREDITS);
|
|
if (IS_ERR(handle)) {
|
|
if (IS_ERR(handle)) {
|
|
err = PTR_ERR(handle);
|
|
err = PTR_ERR(handle);
|
|
handle = NULL;
|
|
handle = NULL;
|
|
mlog_errno(err);
|
|
mlog_errno(err);
|
|
- goto bail;
|
|
|
|
|
|
+ goto out_unlock_inode;
|
|
}
|
|
}
|
|
|
|
|
|
err = ocfs2_journal_access(handle, inode, fe_bh,
|
|
err = ocfs2_journal_access(handle, inode, fe_bh,
|
|
OCFS2_JOURNAL_ACCESS_WRITE);
|
|
OCFS2_JOURNAL_ACCESS_WRITE);
|
|
if (err < 0) {
|
|
if (err < 0) {
|
|
mlog_errno(err);
|
|
mlog_errno(err);
|
|
- goto bail;
|
|
|
|
|
|
+ goto out_commit;
|
|
}
|
|
}
|
|
|
|
|
|
inc_nlink(inode);
|
|
inc_nlink(inode);
|
|
@@ -741,7 +722,7 @@ static int ocfs2_link(struct dentry *old_dentry,
|
|
le16_add_cpu(&fe->i_links_count, -1);
|
|
le16_add_cpu(&fe->i_links_count, -1);
|
|
drop_nlink(inode);
|
|
drop_nlink(inode);
|
|
mlog_errno(err);
|
|
mlog_errno(err);
|
|
- goto bail;
|
|
|
|
|
|
+ goto out_commit;
|
|
}
|
|
}
|
|
|
|
|
|
err = ocfs2_add_entry(handle, dentry, inode,
|
|
err = ocfs2_add_entry(handle, dentry, inode,
|
|
@@ -751,21 +732,27 @@ static int ocfs2_link(struct dentry *old_dentry,
|
|
le16_add_cpu(&fe->i_links_count, -1);
|
|
le16_add_cpu(&fe->i_links_count, -1);
|
|
drop_nlink(inode);
|
|
drop_nlink(inode);
|
|
mlog_errno(err);
|
|
mlog_errno(err);
|
|
- goto bail;
|
|
|
|
|
|
+ goto out_commit;
|
|
}
|
|
}
|
|
|
|
|
|
err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
|
|
err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
|
|
if (err) {
|
|
if (err) {
|
|
mlog_errno(err);
|
|
mlog_errno(err);
|
|
- goto bail;
|
|
|
|
|
|
+ goto out_commit;
|
|
}
|
|
}
|
|
|
|
|
|
atomic_inc(&inode->i_count);
|
|
atomic_inc(&inode->i_count);
|
|
dentry->d_op = &ocfs2_dentry_ops;
|
|
dentry->d_op = &ocfs2_dentry_ops;
|
|
d_instantiate(dentry, inode);
|
|
d_instantiate(dentry, inode);
|
|
-bail:
|
|
|
|
- if (handle)
|
|
|
|
- ocfs2_commit_trans(handle);
|
|
|
|
|
|
+
|
|
|
|
+out_commit:
|
|
|
|
+ ocfs2_commit_trans(osb, handle);
|
|
|
|
+out_unlock_inode:
|
|
|
|
+ ocfs2_meta_unlock(inode, 1);
|
|
|
|
+
|
|
|
|
+out:
|
|
|
|
+ ocfs2_meta_unlock(dir, 1);
|
|
|
|
+
|
|
if (de_bh)
|
|
if (de_bh)
|
|
brelse(de_bh);
|
|
brelse(de_bh);
|
|
if (fe_bh)
|
|
if (fe_bh)
|
|
@@ -812,13 +799,15 @@ static int ocfs2_unlink(struct inode *dir,
|
|
struct dentry *dentry)
|
|
struct dentry *dentry)
|
|
{
|
|
{
|
|
int status;
|
|
int status;
|
|
|
|
+ int child_locked = 0;
|
|
struct inode *inode = dentry->d_inode;
|
|
struct inode *inode = dentry->d_inode;
|
|
|
|
+ struct inode *orphan_dir = NULL;
|
|
struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
|
|
struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
|
|
u64 blkno;
|
|
u64 blkno;
|
|
struct ocfs2_dinode *fe = NULL;
|
|
struct ocfs2_dinode *fe = NULL;
|
|
struct buffer_head *fe_bh = NULL;
|
|
struct buffer_head *fe_bh = NULL;
|
|
struct buffer_head *parent_node_bh = NULL;
|
|
struct buffer_head *parent_node_bh = NULL;
|
|
- struct ocfs2_journal_handle *handle = NULL;
|
|
|
|
|
|
+ handle_t *handle = NULL;
|
|
struct ocfs2_dir_entry *dirent = NULL;
|
|
struct ocfs2_dir_entry *dirent = NULL;
|
|
struct buffer_head *dirent_bh = NULL;
|
|
struct buffer_head *dirent_bh = NULL;
|
|
char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
|
|
char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
|
|
@@ -833,22 +822,14 @@ static int ocfs2_unlink(struct inode *dir,
|
|
|
|
|
|
if (inode == osb->root_inode) {
|
|
if (inode == osb->root_inode) {
|
|
mlog(0, "Cannot delete the root directory\n");
|
|
mlog(0, "Cannot delete the root directory\n");
|
|
- status = -EPERM;
|
|
|
|
- goto leave;
|
|
|
|
|
|
+ return -EPERM;
|
|
}
|
|
}
|
|
|
|
|
|
- handle = ocfs2_alloc_handle(osb);
|
|
|
|
- if (handle == NULL) {
|
|
|
|
- status = -ENOMEM;
|
|
|
|
- mlog_errno(status);
|
|
|
|
- goto leave;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- status = ocfs2_meta_lock(dir, handle, &parent_node_bh, 1);
|
|
|
|
|
|
+ status = ocfs2_meta_lock(dir, &parent_node_bh, 1);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOENT)
|
|
if (status != -ENOENT)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
- goto leave;
|
|
|
|
|
|
+ return status;
|
|
}
|
|
}
|
|
|
|
|
|
status = ocfs2_find_files_on_disk(dentry->d_name.name,
|
|
status = ocfs2_find_files_on_disk(dentry->d_name.name,
|
|
@@ -869,12 +850,13 @@ static int ocfs2_unlink(struct inode *dir,
|
|
goto leave;
|
|
goto leave;
|
|
}
|
|
}
|
|
|
|
|
|
- status = ocfs2_meta_lock(inode, handle, &fe_bh, 1);
|
|
|
|
|
|
+ status = ocfs2_meta_lock(inode, &fe_bh, 1);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOENT)
|
|
if (status != -ENOENT)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
goto leave;
|
|
goto leave;
|
|
}
|
|
}
|
|
|
|
+ child_locked = 1;
|
|
|
|
|
|
if (S_ISDIR(inode->i_mode)) {
|
|
if (S_ISDIR(inode->i_mode)) {
|
|
if (!ocfs2_empty_dir(inode)) {
|
|
if (!ocfs2_empty_dir(inode)) {
|
|
@@ -895,7 +877,7 @@ static int ocfs2_unlink(struct inode *dir,
|
|
}
|
|
}
|
|
|
|
|
|
if (inode_is_unlinkable(inode)) {
|
|
if (inode_is_unlinkable(inode)) {
|
|
- status = ocfs2_prepare_orphan_dir(osb, handle, inode,
|
|
|
|
|
|
+ status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, inode,
|
|
orphan_name,
|
|
orphan_name,
|
|
&orphan_entry_bh);
|
|
&orphan_entry_bh);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
@@ -904,7 +886,7 @@ static int ocfs2_unlink(struct inode *dir,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- handle = ocfs2_start_trans(osb, handle, OCFS2_UNLINK_CREDITS);
|
|
|
|
|
|
+ handle = ocfs2_start_trans(osb, OCFS2_UNLINK_CREDITS);
|
|
if (IS_ERR(handle)) {
|
|
if (IS_ERR(handle)) {
|
|
status = PTR_ERR(handle);
|
|
status = PTR_ERR(handle);
|
|
handle = NULL;
|
|
handle = NULL;
|
|
@@ -923,7 +905,7 @@ static int ocfs2_unlink(struct inode *dir,
|
|
|
|
|
|
if (inode_is_unlinkable(inode)) {
|
|
if (inode_is_unlinkable(inode)) {
|
|
status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
|
|
status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
|
|
- orphan_entry_bh);
|
|
|
|
|
|
+ orphan_entry_bh, orphan_dir);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
goto leave;
|
|
goto leave;
|
|
@@ -960,7 +942,19 @@ static int ocfs2_unlink(struct inode *dir,
|
|
|
|
|
|
leave:
|
|
leave:
|
|
if (handle)
|
|
if (handle)
|
|
- ocfs2_commit_trans(handle);
|
|
|
|
|
|
+ ocfs2_commit_trans(osb, handle);
|
|
|
|
+
|
|
|
|
+ if (child_locked)
|
|
|
|
+ ocfs2_meta_unlock(inode, 1);
|
|
|
|
+
|
|
|
|
+ ocfs2_meta_unlock(dir, 1);
|
|
|
|
+
|
|
|
|
+ if (orphan_dir) {
|
|
|
|
+ /* This was locked for us in ocfs2_prepare_orphan_dir() */
|
|
|
|
+ ocfs2_meta_unlock(orphan_dir, 1);
|
|
|
|
+ mutex_unlock(&orphan_dir->i_mutex);
|
|
|
|
+ iput(orphan_dir);
|
|
|
|
+ }
|
|
|
|
|
|
if (fe_bh)
|
|
if (fe_bh)
|
|
brelse(fe_bh);
|
|
brelse(fe_bh);
|
|
@@ -984,7 +978,6 @@ leave:
|
|
* if they have the same id, then the 1st one is the only one locked.
|
|
* if they have the same id, then the 1st one is the only one locked.
|
|
*/
|
|
*/
|
|
static int ocfs2_double_lock(struct ocfs2_super *osb,
|
|
static int ocfs2_double_lock(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
struct buffer_head **bh1,
|
|
struct buffer_head **bh1,
|
|
struct inode *inode1,
|
|
struct inode *inode1,
|
|
struct buffer_head **bh2,
|
|
struct buffer_head **bh2,
|
|
@@ -1000,8 +993,6 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
|
|
(unsigned long long)oi1->ip_blkno,
|
|
(unsigned long long)oi1->ip_blkno,
|
|
(unsigned long long)oi2->ip_blkno);
|
|
(unsigned long long)oi2->ip_blkno);
|
|
|
|
|
|
- BUG_ON(!handle);
|
|
|
|
-
|
|
|
|
if (*bh1)
|
|
if (*bh1)
|
|
*bh1 = NULL;
|
|
*bh1 = NULL;
|
|
if (*bh2)
|
|
if (*bh2)
|
|
@@ -1021,25 +1012,41 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
|
|
inode1 = tmpinode;
|
|
inode1 = tmpinode;
|
|
}
|
|
}
|
|
/* lock id2 */
|
|
/* lock id2 */
|
|
- status = ocfs2_meta_lock(inode2, handle, bh2, 1);
|
|
|
|
|
|
+ status = ocfs2_meta_lock(inode2, bh2, 1);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOENT)
|
|
if (status != -ENOENT)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
goto bail;
|
|
goto bail;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
/* lock id1 */
|
|
/* lock id1 */
|
|
- status = ocfs2_meta_lock(inode1, handle, bh1, 1);
|
|
|
|
|
|
+ status = ocfs2_meta_lock(inode1, bh1, 1);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
|
|
+ /*
|
|
|
|
+ * An error return must mean that no cluster locks
|
|
|
|
+ * were held on function exit.
|
|
|
|
+ */
|
|
|
|
+ if (oi1->ip_blkno != oi2->ip_blkno)
|
|
|
|
+ ocfs2_meta_unlock(inode2, 1);
|
|
|
|
+
|
|
if (status != -ENOENT)
|
|
if (status != -ENOENT)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
- goto bail;
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
bail:
|
|
bail:
|
|
mlog_exit(status);
|
|
mlog_exit(status);
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2)
|
|
|
|
+{
|
|
|
|
+ ocfs2_meta_unlock(inode1, 1);
|
|
|
|
+
|
|
|
|
+ if (inode1 != inode2)
|
|
|
|
+ ocfs2_meta_unlock(inode2, 1);
|
|
|
|
+}
|
|
|
|
+
|
|
#define PARENT_INO(buffer) \
|
|
#define PARENT_INO(buffer) \
|
|
((struct ocfs2_dir_entry *) \
|
|
((struct ocfs2_dir_entry *) \
|
|
((char *)buffer + \
|
|
((char *)buffer + \
|
|
@@ -1050,9 +1057,11 @@ static int ocfs2_rename(struct inode *old_dir,
|
|
struct inode *new_dir,
|
|
struct inode *new_dir,
|
|
struct dentry *new_dentry)
|
|
struct dentry *new_dentry)
|
|
{
|
|
{
|
|
- int status = 0, rename_lock = 0;
|
|
|
|
|
|
+ int status = 0, rename_lock = 0, parents_locked = 0;
|
|
|
|
+ int old_child_locked = 0, new_child_locked = 0;
|
|
struct inode *old_inode = old_dentry->d_inode;
|
|
struct inode *old_inode = old_dentry->d_inode;
|
|
struct inode *new_inode = new_dentry->d_inode;
|
|
struct inode *new_inode = new_dentry->d_inode;
|
|
|
|
+ struct inode *orphan_dir = NULL;
|
|
struct ocfs2_dinode *newfe = NULL;
|
|
struct ocfs2_dinode *newfe = NULL;
|
|
char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
|
|
char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
|
|
struct buffer_head *orphan_entry_bh = NULL;
|
|
struct buffer_head *orphan_entry_bh = NULL;
|
|
@@ -1060,7 +1069,7 @@ static int ocfs2_rename(struct inode *old_dir,
|
|
struct buffer_head *insert_entry_bh = NULL;
|
|
struct buffer_head *insert_entry_bh = NULL;
|
|
struct ocfs2_super *osb = NULL;
|
|
struct ocfs2_super *osb = NULL;
|
|
u64 newfe_blkno;
|
|
u64 newfe_blkno;
|
|
- struct ocfs2_journal_handle *handle = NULL;
|
|
|
|
|
|
+ handle_t *handle = NULL;
|
|
struct buffer_head *old_dir_bh = NULL;
|
|
struct buffer_head *old_dir_bh = NULL;
|
|
struct buffer_head *new_dir_bh = NULL;
|
|
struct buffer_head *new_dir_bh = NULL;
|
|
struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry
|
|
struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry
|
|
@@ -1105,21 +1114,14 @@ static int ocfs2_rename(struct inode *old_dir,
|
|
rename_lock = 1;
|
|
rename_lock = 1;
|
|
}
|
|
}
|
|
|
|
|
|
- handle = ocfs2_alloc_handle(osb);
|
|
|
|
- if (handle == NULL) {
|
|
|
|
- status = -ENOMEM;
|
|
|
|
- mlog_errno(status);
|
|
|
|
- goto bail;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* if old and new are the same, this'll just do one lock. */
|
|
/* if old and new are the same, this'll just do one lock. */
|
|
- status = ocfs2_double_lock(osb, handle,
|
|
|
|
- &old_dir_bh, old_dir,
|
|
|
|
- &new_dir_bh, new_dir);
|
|
|
|
|
|
+ status = ocfs2_double_lock(osb, &old_dir_bh, old_dir,
|
|
|
|
+ &new_dir_bh, new_dir);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
goto bail;
|
|
goto bail;
|
|
}
|
|
}
|
|
|
|
+ parents_locked = 1;
|
|
|
|
|
|
/* make sure both dirs have bhs
|
|
/* make sure both dirs have bhs
|
|
* get an extra ref on old_dir_bh if old==new */
|
|
* get an extra ref on old_dir_bh if old==new */
|
|
@@ -1140,12 +1142,13 @@ static int ocfs2_rename(struct inode *old_dir,
|
|
* the vote thread on other nodes won't have to concurrently
|
|
* the vote thread on other nodes won't have to concurrently
|
|
* downconvert the inode and the dentry locks.
|
|
* downconvert the inode and the dentry locks.
|
|
*/
|
|
*/
|
|
- status = ocfs2_meta_lock(old_inode, handle, NULL, 1);
|
|
|
|
|
|
+ status = ocfs2_meta_lock(old_inode, NULL, 1);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOENT)
|
|
if (status != -ENOENT)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
goto bail;
|
|
goto bail;
|
|
}
|
|
}
|
|
|
|
+ old_child_locked = 1;
|
|
|
|
|
|
status = ocfs2_remote_dentry_delete(old_dentry);
|
|
status = ocfs2_remote_dentry_delete(old_dentry);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
@@ -1231,12 +1234,13 @@ static int ocfs2_rename(struct inode *old_dir,
|
|
goto bail;
|
|
goto bail;
|
|
}
|
|
}
|
|
|
|
|
|
- status = ocfs2_meta_lock(new_inode, handle, &newfe_bh, 1);
|
|
|
|
|
|
+ status = ocfs2_meta_lock(new_inode, &newfe_bh, 1);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOENT)
|
|
if (status != -ENOENT)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
goto bail;
|
|
goto bail;
|
|
}
|
|
}
|
|
|
|
+ new_child_locked = 1;
|
|
|
|
|
|
status = ocfs2_remote_dentry_delete(new_dentry);
|
|
status = ocfs2_remote_dentry_delete(new_dentry);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
@@ -1252,7 +1256,7 @@ static int ocfs2_rename(struct inode *old_dir,
|
|
(unsigned long long)newfe_bh->b_blocknr : 0ULL);
|
|
(unsigned long long)newfe_bh->b_blocknr : 0ULL);
|
|
|
|
|
|
if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) {
|
|
if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) {
|
|
- status = ocfs2_prepare_orphan_dir(osb, handle,
|
|
|
|
|
|
+ status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
|
|
new_inode,
|
|
new_inode,
|
|
orphan_name,
|
|
orphan_name,
|
|
&orphan_entry_bh);
|
|
&orphan_entry_bh);
|
|
@@ -1280,7 +1284,7 @@ static int ocfs2_rename(struct inode *old_dir,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- handle = ocfs2_start_trans(osb, handle, OCFS2_RENAME_CREDITS);
|
|
|
|
|
|
+ handle = ocfs2_start_trans(osb, OCFS2_RENAME_CREDITS);
|
|
if (IS_ERR(handle)) {
|
|
if (IS_ERR(handle)) {
|
|
status = PTR_ERR(handle);
|
|
status = PTR_ERR(handle);
|
|
handle = NULL;
|
|
handle = NULL;
|
|
@@ -1307,7 +1311,7 @@ static int ocfs2_rename(struct inode *old_dir,
|
|
(newfe->i_links_count == cpu_to_le16(1))){
|
|
(newfe->i_links_count == cpu_to_le16(1))){
|
|
status = ocfs2_orphan_add(osb, handle, new_inode,
|
|
status = ocfs2_orphan_add(osb, handle, new_inode,
|
|
newfe, orphan_name,
|
|
newfe, orphan_name,
|
|
- orphan_entry_bh);
|
|
|
|
|
|
+ orphan_entry_bh, orphan_dir);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
goto bail;
|
|
goto bail;
|
|
@@ -1424,7 +1428,23 @@ bail:
|
|
ocfs2_rename_unlock(osb);
|
|
ocfs2_rename_unlock(osb);
|
|
|
|
|
|
if (handle)
|
|
if (handle)
|
|
- ocfs2_commit_trans(handle);
|
|
|
|
|
|
+ ocfs2_commit_trans(osb, handle);
|
|
|
|
+
|
|
|
|
+ if (parents_locked)
|
|
|
|
+ ocfs2_double_unlock(old_dir, new_dir);
|
|
|
|
+
|
|
|
|
+ if (old_child_locked)
|
|
|
|
+ ocfs2_meta_unlock(old_inode, 1);
|
|
|
|
+
|
|
|
|
+ if (new_child_locked)
|
|
|
|
+ ocfs2_meta_unlock(new_inode, 1);
|
|
|
|
+
|
|
|
|
+ if (orphan_dir) {
|
|
|
|
+ /* This was locked for us in ocfs2_prepare_orphan_dir() */
|
|
|
|
+ ocfs2_meta_unlock(orphan_dir, 1);
|
|
|
|
+ mutex_unlock(&orphan_dir->i_mutex);
|
|
|
|
+ iput(orphan_dir);
|
|
|
|
+ }
|
|
|
|
|
|
if (new_inode)
|
|
if (new_inode)
|
|
sync_mapping_buffers(old_inode->i_mapping);
|
|
sync_mapping_buffers(old_inode->i_mapping);
|
|
@@ -1458,7 +1478,7 @@ bail:
|
|
* data, including the null terminator.
|
|
* data, including the null terminator.
|
|
*/
|
|
*/
|
|
static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
|
|
static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ handle_t *handle,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
const char *symname)
|
|
const char *symname)
|
|
{
|
|
{
|
|
@@ -1573,7 +1593,7 @@ static int ocfs2_symlink(struct inode *dir,
|
|
struct buffer_head *parent_fe_bh = NULL;
|
|
struct buffer_head *parent_fe_bh = NULL;
|
|
struct ocfs2_dinode *fe = NULL;
|
|
struct ocfs2_dinode *fe = NULL;
|
|
struct ocfs2_dinode *dirfe;
|
|
struct ocfs2_dinode *dirfe;
|
|
- struct ocfs2_journal_handle *handle = NULL;
|
|
|
|
|
|
+ handle_t *handle = NULL;
|
|
struct ocfs2_alloc_context *inode_ac = NULL;
|
|
struct ocfs2_alloc_context *inode_ac = NULL;
|
|
struct ocfs2_alloc_context *data_ac = NULL;
|
|
struct ocfs2_alloc_context *data_ac = NULL;
|
|
|
|
|
|
@@ -1587,19 +1607,12 @@ static int ocfs2_symlink(struct inode *dir,
|
|
|
|
|
|
credits = ocfs2_calc_symlink_credits(sb);
|
|
credits = ocfs2_calc_symlink_credits(sb);
|
|
|
|
|
|
- handle = ocfs2_alloc_handle(osb);
|
|
|
|
- if (handle == NULL) {
|
|
|
|
- status = -ENOMEM;
|
|
|
|
- mlog_errno(status);
|
|
|
|
- goto bail;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* lock the parent directory */
|
|
/* lock the parent directory */
|
|
- status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1);
|
|
|
|
|
|
+ status = ocfs2_meta_lock(dir, &parent_fe_bh, 1);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOENT)
|
|
if (status != -ENOENT)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
- goto bail;
|
|
|
|
|
|
+ return status;
|
|
}
|
|
}
|
|
|
|
|
|
dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
|
|
dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
|
|
@@ -1622,7 +1635,7 @@ static int ocfs2_symlink(struct inode *dir,
|
|
goto bail;
|
|
goto bail;
|
|
}
|
|
}
|
|
|
|
|
|
- status = ocfs2_reserve_new_inode(osb, handle, &inode_ac);
|
|
|
|
|
|
+ status = ocfs2_reserve_new_inode(osb, &inode_ac);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOSPC)
|
|
if (status != -ENOSPC)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
@@ -1631,7 +1644,7 @@ static int ocfs2_symlink(struct inode *dir,
|
|
|
|
|
|
/* don't reserve bitmap space for fast symlinks. */
|
|
/* don't reserve bitmap space for fast symlinks. */
|
|
if (l > ocfs2_fast_symlink_chars(sb)) {
|
|
if (l > ocfs2_fast_symlink_chars(sb)) {
|
|
- status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac);
|
|
|
|
|
|
+ status = ocfs2_reserve_clusters(osb, 1, &data_ac);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
if (status != -ENOSPC)
|
|
if (status != -ENOSPC)
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
@@ -1639,7 +1652,7 @@ static int ocfs2_symlink(struct inode *dir,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- handle = ocfs2_start_trans(osb, handle, credits);
|
|
|
|
|
|
+ handle = ocfs2_start_trans(osb, credits);
|
|
if (IS_ERR(handle)) {
|
|
if (IS_ERR(handle)) {
|
|
status = PTR_ERR(handle);
|
|
status = PTR_ERR(handle);
|
|
handle = NULL;
|
|
handle = NULL;
|
|
@@ -1717,7 +1730,10 @@ static int ocfs2_symlink(struct inode *dir,
|
|
d_instantiate(dentry, inode);
|
|
d_instantiate(dentry, inode);
|
|
bail:
|
|
bail:
|
|
if (handle)
|
|
if (handle)
|
|
- ocfs2_commit_trans(handle);
|
|
|
|
|
|
+ ocfs2_commit_trans(osb, handle);
|
|
|
|
+
|
|
|
|
+ ocfs2_meta_unlock(dir, 1);
|
|
|
|
+
|
|
if (new_fe_bh)
|
|
if (new_fe_bh)
|
|
brelse(new_fe_bh);
|
|
brelse(new_fe_bh);
|
|
if (parent_fe_bh)
|
|
if (parent_fe_bh)
|
|
@@ -1768,7 +1784,7 @@ int ocfs2_check_dir_entry(struct inode * dir,
|
|
* If you pass me insert_bh, I'll skip the search of the other dir
|
|
* If you pass me insert_bh, I'll skip the search of the other dir
|
|
* blocks and put the record in there.
|
|
* blocks and put the record in there.
|
|
*/
|
|
*/
|
|
-static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+static int __ocfs2_add_entry(handle_t *handle,
|
|
struct inode *dir,
|
|
struct inode *dir,
|
|
const char *name, int namelen,
|
|
const char *name, int namelen,
|
|
struct inode *inode, u64 blkno,
|
|
struct inode *inode, u64 blkno,
|
|
@@ -1854,7 +1870,7 @@ bail:
|
|
* ocfs2_delete_entry deletes a directory entry by merging it with the
|
|
* ocfs2_delete_entry deletes a directory entry by merging it with the
|
|
* previous entry
|
|
* previous entry
|
|
*/
|
|
*/
|
|
-static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+static int ocfs2_delete_entry(handle_t *handle,
|
|
struct inode *dir,
|
|
struct inode *dir,
|
|
struct ocfs2_dir_entry *de_del,
|
|
struct ocfs2_dir_entry *de_del,
|
|
struct buffer_head *bh)
|
|
struct buffer_head *bh)
|
|
@@ -2085,19 +2101,19 @@ bail:
|
|
}
|
|
}
|
|
|
|
|
|
static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
|
|
static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ struct inode **ret_orphan_dir,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
char *name,
|
|
char *name,
|
|
struct buffer_head **de_bh)
|
|
struct buffer_head **de_bh)
|
|
{
|
|
{
|
|
- struct inode *orphan_dir_inode = NULL;
|
|
|
|
|
|
+ struct inode *orphan_dir_inode;
|
|
struct buffer_head *orphan_dir_bh = NULL;
|
|
struct buffer_head *orphan_dir_bh = NULL;
|
|
int status = 0;
|
|
int status = 0;
|
|
|
|
|
|
status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
|
|
status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
- goto leave;
|
|
|
|
|
|
+ return status;
|
|
}
|
|
}
|
|
|
|
|
|
orphan_dir_inode = ocfs2_get_system_file_inode(osb,
|
|
orphan_dir_inode = ocfs2_get_system_file_inode(osb,
|
|
@@ -2106,11 +2122,12 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
|
|
if (!orphan_dir_inode) {
|
|
if (!orphan_dir_inode) {
|
|
status = -ENOENT;
|
|
status = -ENOENT;
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
- goto leave;
|
|
|
|
|
|
+ return status;
|
|
}
|
|
}
|
|
|
|
|
|
- ocfs2_handle_add_inode(handle, orphan_dir_inode);
|
|
|
|
- status = ocfs2_meta_lock(orphan_dir_inode, handle, &orphan_dir_bh, 1);
|
|
|
|
|
|
+ mutex_lock(&orphan_dir_inode->i_mutex);
|
|
|
|
+
|
|
|
|
+ status = ocfs2_meta_lock(orphan_dir_inode, &orphan_dir_bh, 1);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
goto leave;
|
|
goto leave;
|
|
@@ -2120,13 +2137,19 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
|
|
orphan_dir_bh, name,
|
|
orphan_dir_bh, name,
|
|
OCFS2_ORPHAN_NAMELEN, de_bh);
|
|
OCFS2_ORPHAN_NAMELEN, de_bh);
|
|
if (status < 0) {
|
|
if (status < 0) {
|
|
|
|
+ ocfs2_meta_unlock(orphan_dir_inode, 1);
|
|
|
|
+
|
|
mlog_errno(status);
|
|
mlog_errno(status);
|
|
goto leave;
|
|
goto leave;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ *ret_orphan_dir = orphan_dir_inode;
|
|
|
|
+
|
|
leave:
|
|
leave:
|
|
- if (orphan_dir_inode)
|
|
|
|
|
|
+ if (status) {
|
|
|
|
+ mutex_unlock(&orphan_dir_inode->i_mutex);
|
|
iput(orphan_dir_inode);
|
|
iput(orphan_dir_inode);
|
|
|
|
+ }
|
|
|
|
|
|
if (orphan_dir_bh)
|
|
if (orphan_dir_bh)
|
|
brelse(orphan_dir_bh);
|
|
brelse(orphan_dir_bh);
|
|
@@ -2136,28 +2159,19 @@ leave:
|
|
}
|
|
}
|
|
|
|
|
|
static int ocfs2_orphan_add(struct ocfs2_super *osb,
|
|
static int ocfs2_orphan_add(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ handle_t *handle,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
struct ocfs2_dinode *fe,
|
|
struct ocfs2_dinode *fe,
|
|
char *name,
|
|
char *name,
|
|
- struct buffer_head *de_bh)
|
|
|
|
|
|
+ struct buffer_head *de_bh,
|
|
|
|
+ struct inode *orphan_dir_inode)
|
|
{
|
|
{
|
|
- struct inode *orphan_dir_inode = NULL;
|
|
|
|
struct buffer_head *orphan_dir_bh = NULL;
|
|
struct buffer_head *orphan_dir_bh = NULL;
|
|
int status = 0;
|
|
int status = 0;
|
|
struct ocfs2_dinode *orphan_fe;
|
|
struct ocfs2_dinode *orphan_fe;
|
|
|
|
|
|
mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
|
|
mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
|
|
|
|
|
|
- orphan_dir_inode = ocfs2_get_system_file_inode(osb,
|
|
|
|
- ORPHAN_DIR_SYSTEM_INODE,
|
|
|
|
- osb->slot_num);
|
|
|
|
- if (!orphan_dir_inode) {
|
|
|
|
- status = -ENOENT;
|
|
|
|
- mlog_errno(status);
|
|
|
|
- goto leave;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
status = ocfs2_read_block(osb,
|
|
status = ocfs2_read_block(osb,
|
|
OCFS2_I(orphan_dir_inode)->ip_blkno,
|
|
OCFS2_I(orphan_dir_inode)->ip_blkno,
|
|
&orphan_dir_bh, OCFS2_BH_CACHED,
|
|
&orphan_dir_bh, OCFS2_BH_CACHED,
|
|
@@ -2209,9 +2223,6 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
|
|
(unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num);
|
|
(unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num);
|
|
|
|
|
|
leave:
|
|
leave:
|
|
- if (orphan_dir_inode)
|
|
|
|
- iput(orphan_dir_inode);
|
|
|
|
-
|
|
|
|
if (orphan_dir_bh)
|
|
if (orphan_dir_bh)
|
|
brelse(orphan_dir_bh);
|
|
brelse(orphan_dir_bh);
|
|
|
|
|
|
@@ -2221,7 +2232,7 @@ leave:
|
|
|
|
|
|
/* unlike orphan_add, we expect the orphan dir to already be locked here. */
|
|
/* unlike orphan_add, we expect the orphan dir to already be locked here. */
|
|
int ocfs2_orphan_del(struct ocfs2_super *osb,
|
|
int ocfs2_orphan_del(struct ocfs2_super *osb,
|
|
- struct ocfs2_journal_handle *handle,
|
|
|
|
|
|
+ handle_t *handle,
|
|
struct inode *orphan_dir_inode,
|
|
struct inode *orphan_dir_inode,
|
|
struct inode *inode,
|
|
struct inode *inode,
|
|
struct buffer_head *orphan_dir_bh)
|
|
struct buffer_head *orphan_dir_bh)
|
|
@@ -2300,4 +2311,5 @@ struct inode_operations ocfs2_dir_iops = {
|
|
.rename = ocfs2_rename,
|
|
.rename = ocfs2_rename,
|
|
.setattr = ocfs2_setattr,
|
|
.setattr = ocfs2_setattr,
|
|
.getattr = ocfs2_getattr,
|
|
.getattr = ocfs2_getattr,
|
|
|
|
+ .permission = ocfs2_permission,
|
|
};
|
|
};
|