diff options
Diffstat (limited to 'fs/ocfs2')
| -rw-r--r-- | fs/ocfs2/acl.c | 3 | ||||
| -rw-r--r-- | fs/ocfs2/alloc.c | 2 | ||||
| -rw-r--r-- | fs/ocfs2/blockcheck.c | 4 | ||||
| -rw-r--r-- | fs/ocfs2/cluster/tcp.c | 2 | ||||
| -rw-r--r-- | fs/ocfs2/dir.c | 24 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmcommon.h | 1 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmdebug.c | 9 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmdomain.c | 1 | ||||
| -rw-r--r-- | fs/ocfs2/dlm/dlmmaster.c | 40 | ||||
| -rw-r--r-- | fs/ocfs2/dlmglue.h | 1 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 15 | ||||
| -rw-r--r-- | fs/ocfs2/inode.c | 6 | ||||
| -rw-r--r-- | fs/ocfs2/mmap.c | 8 | ||||
| -rw-r--r-- | fs/ocfs2/namei.c | 302 | ||||
| -rw-r--r-- | fs/ocfs2/ocfs2_fs.h | 37 | ||||
| -rw-r--r-- | fs/ocfs2/ocfs2_ioctl.h | 8 | ||||
| -rw-r--r-- | fs/ocfs2/refcounttree.c | 10 | ||||
| -rw-r--r-- | fs/ocfs2/reservations.c | 22 | ||||
| -rw-r--r-- | fs/ocfs2/suballoc.c | 223 | ||||
| -rw-r--r-- | fs/ocfs2/suballoc.h | 21 | ||||
| -rw-r--r-- | fs/ocfs2/xattr.c | 4 |
21 files changed, 592 insertions, 151 deletions
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index a76e0aa5cd3f..391915093fe1 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
| @@ -209,7 +209,10 @@ static int ocfs2_acl_set_mode(struct inode *inode, struct buffer_head *di_bh, | |||
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | inode->i_mode = new_mode; | 211 | inode->i_mode = new_mode; |
| 212 | inode->i_ctime = CURRENT_TIME; | ||
| 212 | di->i_mode = cpu_to_le16(inode->i_mode); | 213 | di->i_mode = cpu_to_le16(inode->i_mode); |
| 214 | di->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec); | ||
| 215 | di->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); | ||
| 213 | 216 | ||
| 214 | ocfs2_journal_dirty(handle, di_bh); | 217 | ocfs2_journal_dirty(handle, di_bh); |
| 215 | 218 | ||
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 215e12ce1d85..592fae5007d1 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -6672,7 +6672,7 @@ int ocfs2_grab_pages(struct inode *inode, loff_t start, loff_t end, | |||
| 6672 | last_page_bytes = PAGE_ALIGN(end); | 6672 | last_page_bytes = PAGE_ALIGN(end); |
| 6673 | index = start >> PAGE_CACHE_SHIFT; | 6673 | index = start >> PAGE_CACHE_SHIFT; |
| 6674 | do { | 6674 | do { |
| 6675 | pages[numpages] = grab_cache_page(mapping, index); | 6675 | pages[numpages] = find_or_create_page(mapping, index, GFP_NOFS); |
| 6676 | if (!pages[numpages]) { | 6676 | if (!pages[numpages]) { |
| 6677 | ret = -ENOMEM; | 6677 | ret = -ENOMEM; |
| 6678 | mlog_errno(ret); | 6678 | mlog_errno(ret); |
diff --git a/fs/ocfs2/blockcheck.c b/fs/ocfs2/blockcheck.c index ec6d12339593..c7ee03c22226 100644 --- a/fs/ocfs2/blockcheck.c +++ b/fs/ocfs2/blockcheck.c | |||
| @@ -439,7 +439,7 @@ int ocfs2_block_check_validate(void *data, size_t blocksize, | |||
| 439 | 439 | ||
| 440 | ocfs2_blockcheck_inc_failure(stats); | 440 | ocfs2_blockcheck_inc_failure(stats); |
| 441 | mlog(ML_ERROR, | 441 | mlog(ML_ERROR, |
| 442 | "CRC32 failed: stored: %u, computed %u. Applying ECC.\n", | 442 | "CRC32 failed: stored: 0x%x, computed 0x%x. Applying ECC.\n", |
| 443 | (unsigned int)check.bc_crc32e, (unsigned int)crc); | 443 | (unsigned int)check.bc_crc32e, (unsigned int)crc); |
| 444 | 444 | ||
| 445 | /* Ok, try ECC fixups */ | 445 | /* Ok, try ECC fixups */ |
| @@ -453,7 +453,7 @@ int ocfs2_block_check_validate(void *data, size_t blocksize, | |||
| 453 | goto out; | 453 | goto out; |
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | mlog(ML_ERROR, "Fixed CRC32 failed: stored: %u, computed %u\n", | 456 | mlog(ML_ERROR, "Fixed CRC32 failed: stored: 0x%x, computed 0x%x\n", |
| 457 | (unsigned int)check.bc_crc32e, (unsigned int)crc); | 457 | (unsigned int)check.bc_crc32e, (unsigned int)crc); |
| 458 | 458 | ||
| 459 | rc = -EIO; | 459 | rc = -EIO; |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 1361997cf205..cbe2f057cc28 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
| @@ -977,7 +977,7 @@ static int o2net_tx_can_proceed(struct o2net_node *nn, | |||
| 977 | int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, | 977 | int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, |
| 978 | size_t caller_veclen, u8 target_node, int *status) | 978 | size_t caller_veclen, u8 target_node, int *status) |
| 979 | { | 979 | { |
| 980 | int ret; | 980 | int ret = 0; |
| 981 | struct o2net_msg *msg = NULL; | 981 | struct o2net_msg *msg = NULL; |
| 982 | size_t veclen, caller_bytes = 0; | 982 | size_t veclen, caller_bytes = 0; |
| 983 | struct kvec *vec = NULL; | 983 | struct kvec *vec = NULL; |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index f04ebcfffc4a..c49f6de0e7ab 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
| @@ -3931,6 +3931,15 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir, | |||
| 3931 | goto out_commit; | 3931 | goto out_commit; |
| 3932 | } | 3932 | } |
| 3933 | 3933 | ||
| 3934 | cpos = split_hash; | ||
| 3935 | ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle, | ||
| 3936 | data_ac, meta_ac, new_dx_leaves, | ||
| 3937 | num_dx_leaves); | ||
| 3938 | if (ret) { | ||
| 3939 | mlog_errno(ret); | ||
| 3940 | goto out_commit; | ||
| 3941 | } | ||
| 3942 | |||
| 3934 | for (i = 0; i < num_dx_leaves; i++) { | 3943 | for (i = 0; i < num_dx_leaves; i++) { |
| 3935 | ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), | 3944 | ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), |
| 3936 | orig_dx_leaves[i], | 3945 | orig_dx_leaves[i], |
| @@ -3939,15 +3948,14 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir, | |||
| 3939 | mlog_errno(ret); | 3948 | mlog_errno(ret); |
| 3940 | goto out_commit; | 3949 | goto out_commit; |
| 3941 | } | 3950 | } |
| 3942 | } | ||
| 3943 | 3951 | ||
| 3944 | cpos = split_hash; | 3952 | ret = ocfs2_journal_access_dl(handle, INODE_CACHE(dir), |
| 3945 | ret = ocfs2_dx_dir_new_cluster(dir, &et, cpos, handle, | 3953 | new_dx_leaves[i], |
| 3946 | data_ac, meta_ac, new_dx_leaves, | 3954 | OCFS2_JOURNAL_ACCESS_WRITE); |
| 3947 | num_dx_leaves); | 3955 | if (ret) { |
| 3948 | if (ret) { | 3956 | mlog_errno(ret); |
| 3949 | mlog_errno(ret); | 3957 | goto out_commit; |
| 3950 | goto out_commit; | 3958 | } |
| 3951 | } | 3959 | } |
| 3952 | 3960 | ||
| 3953 | ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf, | 3961 | ocfs2_dx_dir_transfer_leaf(dir, split_hash, handle, tmp_dx_leaf, |
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 4b6ae2c13b47..765298908f1d 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
| @@ -1030,6 +1030,7 @@ int dlm_drop_lockres_ref(struct dlm_ctxt *dlm, | |||
| 1030 | struct dlm_lock_resource *res); | 1030 | struct dlm_lock_resource *res); |
| 1031 | void dlm_clean_master_list(struct dlm_ctxt *dlm, | 1031 | void dlm_clean_master_list(struct dlm_ctxt *dlm, |
| 1032 | u8 dead_node); | 1032 | u8 dead_node); |
| 1033 | void dlm_force_free_mles(struct dlm_ctxt *dlm); | ||
| 1033 | int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock); | 1034 | int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock); |
| 1034 | int __dlm_lockres_has_locks(struct dlm_lock_resource *res); | 1035 | int __dlm_lockres_has_locks(struct dlm_lock_resource *res); |
| 1035 | int __dlm_lockres_unused(struct dlm_lock_resource *res); | 1036 | int __dlm_lockres_unused(struct dlm_lock_resource *res); |
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index 5efdd37dfe48..901ca52bf86b 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c | |||
| @@ -636,8 +636,14 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos) | |||
| 636 | spin_lock(&dlm->track_lock); | 636 | spin_lock(&dlm->track_lock); |
| 637 | if (oldres) | 637 | if (oldres) |
| 638 | track_list = &oldres->tracking; | 638 | track_list = &oldres->tracking; |
| 639 | else | 639 | else { |
| 640 | track_list = &dlm->tracking_list; | 640 | track_list = &dlm->tracking_list; |
| 641 | if (list_empty(track_list)) { | ||
| 642 | dl = NULL; | ||
| 643 | spin_unlock(&dlm->track_lock); | ||
| 644 | goto bail; | ||
| 645 | } | ||
| 646 | } | ||
| 641 | 647 | ||
| 642 | list_for_each_entry(res, track_list, tracking) { | 648 | list_for_each_entry(res, track_list, tracking) { |
| 643 | if (&res->tracking == &dlm->tracking_list) | 649 | if (&res->tracking == &dlm->tracking_list) |
| @@ -660,6 +666,7 @@ static void *lockres_seq_start(struct seq_file *m, loff_t *pos) | |||
| 660 | } else | 666 | } else |
| 661 | dl = NULL; | 667 | dl = NULL; |
| 662 | 668 | ||
| 669 | bail: | ||
| 663 | /* passed to seq_show */ | 670 | /* passed to seq_show */ |
| 664 | return dl; | 671 | return dl; |
| 665 | } | 672 | } |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 153abb5abef0..11a5c87fd7f7 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
| @@ -693,6 +693,7 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm) | |||
| 693 | 693 | ||
| 694 | dlm_mark_domain_leaving(dlm); | 694 | dlm_mark_domain_leaving(dlm); |
| 695 | dlm_leave_domain(dlm); | 695 | dlm_leave_domain(dlm); |
| 696 | dlm_force_free_mles(dlm); | ||
| 696 | dlm_complete_dlm_shutdown(dlm); | 697 | dlm_complete_dlm_shutdown(dlm); |
| 697 | } | 698 | } |
| 698 | dlm_put(dlm); | 699 | dlm_put(dlm); |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index ffb4c68dafa4..f564b0e5f80d 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
| @@ -3433,3 +3433,43 @@ void dlm_lockres_release_ast(struct dlm_ctxt *dlm, | |||
| 3433 | wake_up(&res->wq); | 3433 | wake_up(&res->wq); |
| 3434 | wake_up(&dlm->migration_wq); | 3434 | wake_up(&dlm->migration_wq); |
| 3435 | } | 3435 | } |
| 3436 | |||
| 3437 | void dlm_force_free_mles(struct dlm_ctxt *dlm) | ||
| 3438 | { | ||
| 3439 | int i; | ||
| 3440 | struct hlist_head *bucket; | ||
| 3441 | struct dlm_master_list_entry *mle; | ||
| 3442 | struct hlist_node *tmp, *list; | ||
| 3443 | |||
| 3444 | /* | ||
| 3445 | * We notified all other nodes that we are exiting the domain and | ||
| 3446 | * marked the dlm state to DLM_CTXT_LEAVING. If any mles are still | ||
| 3447 | * around we force free them and wake any processes that are waiting | ||
| 3448 | * on the mles | ||
| 3449 | */ | ||
| 3450 | spin_lock(&dlm->spinlock); | ||
| 3451 | spin_lock(&dlm->master_lock); | ||
| 3452 | |||
| 3453 | BUG_ON(dlm->dlm_state != DLM_CTXT_LEAVING); | ||
| 3454 | BUG_ON((find_next_bit(dlm->domain_map, O2NM_MAX_NODES, 0) < O2NM_MAX_NODES)); | ||
| 3455 | |||
| 3456 | for (i = 0; i < DLM_HASH_BUCKETS; i++) { | ||
| 3457 | bucket = dlm_master_hash(dlm, i); | ||
| 3458 | hlist_for_each_safe(list, tmp, bucket) { | ||
| 3459 | mle = hlist_entry(list, struct dlm_master_list_entry, | ||
| 3460 | master_hash_node); | ||
| 3461 | if (mle->type != DLM_MLE_BLOCK) { | ||
| 3462 | mlog(ML_ERROR, "bad mle: %p\n", mle); | ||
| 3463 | dlm_print_one_mle(mle); | ||
| 3464 | } | ||
| 3465 | atomic_set(&mle->woken, 1); | ||
| 3466 | wake_up(&mle->wq); | ||
| 3467 | |||
| 3468 | __dlm_unlink_mle(dlm, mle); | ||
| 3469 | __dlm_mle_detach_hb_events(dlm, mle); | ||
| 3470 | __dlm_put_mle(mle); | ||
| 3471 | } | ||
| 3472 | } | ||
| 3473 | spin_unlock(&dlm->master_lock); | ||
| 3474 | spin_unlock(&dlm->spinlock); | ||
| 3475 | } | ||
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index d1ce48e1b3d6..1d596d8c4a4a 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
| @@ -84,6 +84,7 @@ enum { | |||
| 84 | OI_LS_PARENT, | 84 | OI_LS_PARENT, |
| 85 | OI_LS_RENAME1, | 85 | OI_LS_RENAME1, |
| 86 | OI_LS_RENAME2, | 86 | OI_LS_RENAME2, |
| 87 | OI_LS_REFLINK_TARGET, | ||
| 87 | }; | 88 | }; |
| 88 | 89 | ||
| 89 | int ocfs2_dlm_init(struct ocfs2_super *osb); | 90 | int ocfs2_dlm_init(struct ocfs2_super *osb); |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 81296b4e3646..9a03c151b5ce 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/writeback.h> | 36 | #include <linux/writeback.h> |
| 37 | #include <linux/falloc.h> | 37 | #include <linux/falloc.h> |
| 38 | #include <linux/quotaops.h> | 38 | #include <linux/quotaops.h> |
| 39 | #include <linux/blkdev.h> | ||
| 39 | 40 | ||
| 40 | #define MLOG_MASK_PREFIX ML_INODE | 41 | #define MLOG_MASK_PREFIX ML_INODE |
| 41 | #include <cluster/masklog.h> | 42 | #include <cluster/masklog.h> |
| @@ -190,8 +191,16 @@ static int ocfs2_sync_file(struct file *file, int datasync) | |||
| 190 | if (err) | 191 | if (err) |
| 191 | goto bail; | 192 | goto bail; |
| 192 | 193 | ||
| 193 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) | 194 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) { |
| 195 | /* | ||
| 196 | * We still have to flush drive's caches to get data to the | ||
| 197 | * platter | ||
| 198 | */ | ||
| 199 | if (osb->s_mount_opt & OCFS2_MOUNT_BARRIER) | ||
| 200 | blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, | ||
| 201 | NULL, BLKDEV_IFL_WAIT); | ||
| 194 | goto bail; | 202 | goto bail; |
| 203 | } | ||
| 195 | 204 | ||
| 196 | journal = osb->journal->j_journal; | 205 | journal = osb->journal->j_journal; |
| 197 | err = jbd2_journal_force_commit(journal); | 206 | err = jbd2_journal_force_commit(journal); |
| @@ -774,7 +783,7 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 774 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); | 783 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); |
| 775 | BUG_ON(abs_from & (inode->i_blkbits - 1)); | 784 | BUG_ON(abs_from & (inode->i_blkbits - 1)); |
| 776 | 785 | ||
| 777 | page = grab_cache_page(mapping, index); | 786 | page = find_or_create_page(mapping, index, GFP_NOFS); |
| 778 | if (!page) { | 787 | if (!page) { |
| 779 | ret = -ENOMEM; | 788 | ret = -ENOMEM; |
| 780 | mlog_errno(ret); | 789 | mlog_errno(ret); |
| @@ -2329,7 +2338,7 @@ out_dio: | |||
| 2329 | BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); | 2338 | BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT)); |
| 2330 | 2339 | ||
| 2331 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || | 2340 | if (((file->f_flags & O_DSYNC) && !direct_io) || IS_SYNC(inode) || |
| 2332 | ((file->f_flags & O_DIRECT) && has_refcount)) { | 2341 | ((file->f_flags & O_DIRECT) && !direct_io)) { |
| 2333 | ret = filemap_fdatawrite_range(file->f_mapping, pos, | 2342 | ret = filemap_fdatawrite_range(file->f_mapping, pos, |
| 2334 | pos + count - 1); | 2343 | pos + count - 1); |
| 2335 | if (ret < 0) | 2344 | if (ret < 0) |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 0492464916b1..eece3e05d9d0 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
| @@ -488,7 +488,11 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
| 488 | OCFS2_BH_IGNORE_CACHE); | 488 | OCFS2_BH_IGNORE_CACHE); |
| 489 | } else { | 489 | } else { |
| 490 | status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh); | 490 | status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh); |
| 491 | if (!status) | 491 | /* |
| 492 | * If buffer is in jbd, then its checksum may not have been | ||
| 493 | * computed as yet. | ||
| 494 | */ | ||
| 495 | if (!status && !buffer_jbd(bh)) | ||
| 492 | status = ocfs2_validate_inode_block(osb->sb, bh); | 496 | status = ocfs2_validate_inode_block(osb->sb, bh); |
| 493 | } | 497 | } |
| 494 | if (status < 0) { | 498 | if (status < 0) { |
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index af2b8fe1f139..4c18f4ad93b4 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c | |||
| @@ -74,9 +74,11 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, | |||
| 74 | /* | 74 | /* |
| 75 | * Another node might have truncated while we were waiting on | 75 | * Another node might have truncated while we were waiting on |
| 76 | * cluster locks. | 76 | * cluster locks. |
| 77 | * We don't check size == 0 before the shift. This is borrowed | ||
| 78 | * from do_generic_file_read. | ||
| 77 | */ | 79 | */ |
| 78 | last_index = size >> PAGE_CACHE_SHIFT; | 80 | last_index = (size - 1) >> PAGE_CACHE_SHIFT; |
| 79 | if (page->index > last_index) { | 81 | if (unlikely(!size || page->index > last_index)) { |
| 80 | ret = -EINVAL; | 82 | ret = -EINVAL; |
| 81 | goto out; | 83 | goto out; |
| 82 | } | 84 | } |
| @@ -107,7 +109,7 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, | |||
| 107 | * because the "write" would invalidate their data. | 109 | * because the "write" would invalidate their data. |
| 108 | */ | 110 | */ |
| 109 | if (page->index == last_index) | 111 | if (page->index == last_index) |
| 110 | len = size & ~PAGE_CACHE_MASK; | 112 | len = ((size - 1) & ~PAGE_CACHE_MASK) + 1; |
| 111 | 113 | ||
| 112 | ret = ocfs2_write_begin_nolock(mapping, pos, len, 0, &locked_page, | 114 | ret = ocfs2_write_begin_nolock(mapping, pos, len, 0, &locked_page, |
| 113 | &fsdata, di_bh, page); | 115 | &fsdata, di_bh, page); |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f171b51a74f7..a00dda2e4f16 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -472,32 +472,23 @@ leave: | |||
| 472 | return status; | 472 | return status; |
| 473 | } | 473 | } |
| 474 | 474 | ||
| 475 | static int ocfs2_mknod_locked(struct ocfs2_super *osb, | 475 | static int __ocfs2_mknod_locked(struct inode *dir, |
| 476 | struct inode *dir, | 476 | struct inode *inode, |
| 477 | struct inode *inode, | 477 | dev_t dev, |
| 478 | dev_t dev, | 478 | struct buffer_head **new_fe_bh, |
| 479 | struct buffer_head **new_fe_bh, | 479 | struct buffer_head *parent_fe_bh, |
| 480 | struct buffer_head *parent_fe_bh, | 480 | handle_t *handle, |
| 481 | handle_t *handle, | 481 | struct ocfs2_alloc_context *inode_ac, |
| 482 | struct ocfs2_alloc_context *inode_ac) | 482 | u64 fe_blkno, u64 suballoc_loc, u16 suballoc_bit) |
| 483 | { | 483 | { |
| 484 | int status = 0; | 484 | int status = 0; |
| 485 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | ||
| 485 | struct ocfs2_dinode *fe = NULL; | 486 | struct ocfs2_dinode *fe = NULL; |
| 486 | struct ocfs2_extent_list *fel; | 487 | struct ocfs2_extent_list *fel; |
| 487 | u64 suballoc_loc, fe_blkno = 0; | ||
| 488 | u16 suballoc_bit; | ||
| 489 | u16 feat; | 488 | u16 feat; |
| 490 | 489 | ||
| 491 | *new_fe_bh = NULL; | 490 | *new_fe_bh = NULL; |
| 492 | 491 | ||
| 493 | status = ocfs2_claim_new_inode(handle, dir, parent_fe_bh, | ||
| 494 | inode_ac, &suballoc_loc, | ||
| 495 | &suballoc_bit, &fe_blkno); | ||
| 496 | if (status < 0) { | ||
| 497 | mlog_errno(status); | ||
| 498 | goto leave; | ||
| 499 | } | ||
| 500 | |||
| 501 | /* populate as many fields early on as possible - many of | 492 | /* populate as many fields early on as possible - many of |
| 502 | * these are used by the support functions here and in | 493 | * these are used by the support functions here and in |
| 503 | * callers. */ | 494 | * callers. */ |
| @@ -591,6 +582,34 @@ leave: | |||
| 591 | return status; | 582 | return status; |
| 592 | } | 583 | } |
| 593 | 584 | ||
| 585 | static int ocfs2_mknod_locked(struct ocfs2_super *osb, | ||
| 586 | struct inode *dir, | ||
| 587 | struct inode *inode, | ||
| 588 | dev_t dev, | ||
| 589 | struct buffer_head **new_fe_bh, | ||
| 590 | struct buffer_head *parent_fe_bh, | ||
| 591 | handle_t *handle, | ||
| 592 | struct ocfs2_alloc_context *inode_ac) | ||
| 593 | { | ||
| 594 | int status = 0; | ||
| 595 | u64 suballoc_loc, fe_blkno = 0; | ||
| 596 | u16 suballoc_bit; | ||
| 597 | |||
| 598 | *new_fe_bh = NULL; | ||
| 599 | |||
| 600 | status = ocfs2_claim_new_inode(handle, dir, parent_fe_bh, | ||
| 601 | inode_ac, &suballoc_loc, | ||
| 602 | &suballoc_bit, &fe_blkno); | ||
| 603 | if (status < 0) { | ||
| 604 | mlog_errno(status); | ||
| 605 | return status; | ||
| 606 | } | ||
| 607 | |||
| 608 | return __ocfs2_mknod_locked(dir, inode, dev, new_fe_bh, | ||
| 609 | parent_fe_bh, handle, inode_ac, | ||
| 610 | fe_blkno, suballoc_loc, suballoc_bit); | ||
| 611 | } | ||
| 612 | |||
| 594 | static int ocfs2_mkdir(struct inode *dir, | 613 | static int ocfs2_mkdir(struct inode *dir, |
| 595 | struct dentry *dentry, | 614 | struct dentry *dentry, |
| 596 | int mode) | 615 | int mode) |
| @@ -1852,61 +1871,117 @@ bail: | |||
| 1852 | return status; | 1871 | return status; |
| 1853 | } | 1872 | } |
| 1854 | 1873 | ||
| 1855 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 1874 | static int ocfs2_lookup_lock_orphan_dir(struct ocfs2_super *osb, |
| 1856 | struct inode **ret_orphan_dir, | 1875 | struct inode **ret_orphan_dir, |
| 1857 | u64 blkno, | 1876 | struct buffer_head **ret_orphan_dir_bh) |
| 1858 | char *name, | ||
| 1859 | struct ocfs2_dir_lookup_result *lookup) | ||
| 1860 | { | 1877 | { |
| 1861 | struct inode *orphan_dir_inode; | 1878 | struct inode *orphan_dir_inode; |
| 1862 | struct buffer_head *orphan_dir_bh = NULL; | 1879 | struct buffer_head *orphan_dir_bh = NULL; |
| 1863 | int status = 0; | 1880 | int ret = 0; |
| 1864 | |||
| 1865 | status = ocfs2_blkno_stringify(blkno, name); | ||
| 1866 | if (status < 0) { | ||
| 1867 | mlog_errno(status); | ||
| 1868 | return status; | ||
| 1869 | } | ||
| 1870 | 1881 | ||
| 1871 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | 1882 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, |
| 1872 | ORPHAN_DIR_SYSTEM_INODE, | 1883 | ORPHAN_DIR_SYSTEM_INODE, |
| 1873 | osb->slot_num); | 1884 | osb->slot_num); |
| 1874 | if (!orphan_dir_inode) { | 1885 | if (!orphan_dir_inode) { |
| 1875 | status = -ENOENT; | 1886 | ret = -ENOENT; |
| 1876 | mlog_errno(status); | 1887 | mlog_errno(ret); |
| 1877 | return status; | 1888 | return ret; |
| 1878 | } | 1889 | } |
| 1879 | 1890 | ||
| 1880 | mutex_lock(&orphan_dir_inode->i_mutex); | 1891 | mutex_lock(&orphan_dir_inode->i_mutex); |
| 1881 | 1892 | ||
| 1882 | status = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); | 1893 | ret = ocfs2_inode_lock(orphan_dir_inode, &orphan_dir_bh, 1); |
| 1883 | if (status < 0) { | 1894 | if (ret < 0) { |
| 1884 | mlog_errno(status); | 1895 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 1885 | goto leave; | 1896 | iput(orphan_dir_inode); |
| 1897 | |||
| 1898 | mlog_errno(ret); | ||
| 1899 | return ret; | ||
| 1886 | } | 1900 | } |
| 1887 | 1901 | ||
| 1888 | status = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode, | 1902 | *ret_orphan_dir = orphan_dir_inode; |
| 1889 | orphan_dir_bh, name, | 1903 | *ret_orphan_dir_bh = orphan_dir_bh; |
| 1890 | OCFS2_ORPHAN_NAMELEN, lookup); | ||
| 1891 | if (status < 0) { | ||
| 1892 | ocfs2_inode_unlock(orphan_dir_inode, 1); | ||
| 1893 | 1904 | ||
| 1894 | mlog_errno(status); | 1905 | return 0; |
| 1895 | goto leave; | 1906 | } |
| 1907 | |||
| 1908 | static int __ocfs2_prepare_orphan_dir(struct inode *orphan_dir_inode, | ||
| 1909 | struct buffer_head *orphan_dir_bh, | ||
| 1910 | u64 blkno, | ||
| 1911 | char *name, | ||
| 1912 | struct ocfs2_dir_lookup_result *lookup) | ||
| 1913 | { | ||
| 1914 | int ret; | ||
| 1915 | struct ocfs2_super *osb = OCFS2_SB(orphan_dir_inode->i_sb); | ||
| 1916 | |||
| 1917 | ret = ocfs2_blkno_stringify(blkno, name); | ||
| 1918 | if (ret < 0) { | ||
| 1919 | mlog_errno(ret); | ||
| 1920 | return ret; | ||
| 1921 | } | ||
| 1922 | |||
| 1923 | ret = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode, | ||
| 1924 | orphan_dir_bh, name, | ||
| 1925 | OCFS2_ORPHAN_NAMELEN, lookup); | ||
| 1926 | if (ret < 0) { | ||
| 1927 | mlog_errno(ret); | ||
| 1928 | return ret; | ||
| 1929 | } | ||
| 1930 | |||
| 1931 | return 0; | ||
| 1932 | } | ||
| 1933 | |||
| 1934 | /** | ||
| 1935 | * ocfs2_prepare_orphan_dir() - Prepare an orphan directory for | ||
| 1936 | * insertion of an orphan. | ||
| 1937 | * @osb: ocfs2 file system | ||
| 1938 | * @ret_orphan_dir: Orphan dir inode - returned locked! | ||
| 1939 | * @blkno: Actual block number of the inode to be inserted into orphan dir. | ||
| 1940 | * @lookup: dir lookup result, to be passed back into functions like | ||
| 1941 | * ocfs2_orphan_add | ||
| 1942 | * | ||
| 1943 | * Returns zero on success and the ret_orphan_dir, name and lookup | ||
| 1944 | * fields will be populated. | ||
| 1945 | * | ||
| 1946 | * Returns non-zero on failure. | ||
| 1947 | */ | ||
| 1948 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | ||
| 1949 | struct inode **ret_orphan_dir, | ||
| 1950 | u64 blkno, | ||
| 1951 | char *name, | ||
| 1952 | struct ocfs2_dir_lookup_result *lookup) | ||
| 1953 | { | ||
| 1954 | struct inode *orphan_dir_inode = NULL; | ||
| 1955 | struct buffer_head *orphan_dir_bh = NULL; | ||
| 1956 | int ret = 0; | ||
| 1957 | |||
| 1958 | ret = ocfs2_lookup_lock_orphan_dir(osb, &orphan_dir_inode, | ||
| 1959 | &orphan_dir_bh); | ||
| 1960 | if (ret < 0) { | ||
| 1961 | mlog_errno(ret); | ||
| 1962 | return ret; | ||
| 1963 | } | ||
| 1964 | |||
| 1965 | ret = __ocfs2_prepare_orphan_dir(orphan_dir_inode, orphan_dir_bh, | ||
| 1966 | blkno, name, lookup); | ||
| 1967 | if (ret < 0) { | ||
| 1968 | mlog_errno(ret); | ||
| 1969 | goto out; | ||
| 1896 | } | 1970 | } |
| 1897 | 1971 | ||
| 1898 | *ret_orphan_dir = orphan_dir_inode; | 1972 | *ret_orphan_dir = orphan_dir_inode; |
| 1899 | 1973 | ||
| 1900 | leave: | 1974 | out: |
| 1901 | if (status) { | 1975 | brelse(orphan_dir_bh); |
| 1976 | |||
| 1977 | if (ret) { | ||
| 1978 | ocfs2_inode_unlock(orphan_dir_inode, 1); | ||
| 1902 | mutex_unlock(&orphan_dir_inode->i_mutex); | 1979 | mutex_unlock(&orphan_dir_inode->i_mutex); |
| 1903 | iput(orphan_dir_inode); | 1980 | iput(orphan_dir_inode); |
| 1904 | } | 1981 | } |
| 1905 | 1982 | ||
| 1906 | brelse(orphan_dir_bh); | 1983 | mlog_exit(ret); |
| 1907 | 1984 | return ret; | |
| 1908 | mlog_exit(status); | ||
| 1909 | return status; | ||
| 1910 | } | 1985 | } |
| 1911 | 1986 | ||
| 1912 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 1987 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |
| @@ -2053,6 +2128,99 @@ leave: | |||
| 2053 | return status; | 2128 | return status; |
| 2054 | } | 2129 | } |
| 2055 | 2130 | ||
| 2131 | /** | ||
| 2132 | * ocfs2_prep_new_orphaned_file() - Prepare the orphan dir to recieve a newly | ||
| 2133 | * allocated file. This is different from the typical 'add to orphan dir' | ||
| 2134 | * operation in that the inode does not yet exist. This is a problem because | ||
| 2135 | * the orphan dir stringifies the inode block number to come up with it's | ||
| 2136 | * dirent. Obviously if the inode does not yet exist we have a chicken and egg | ||
| 2137 | * problem. This function works around it by calling deeper into the orphan | ||
| 2138 | * and suballoc code than other callers. Use this only by necessity. | ||
| 2139 | * @dir: The directory which this inode will ultimately wind up under - not the | ||
| 2140 | * orphan dir! | ||
| 2141 | * @dir_bh: buffer_head the @dir inode block | ||
| 2142 | * @orphan_name: string of length (CFS2_ORPHAN_NAMELEN + 1). Will be filled | ||
| 2143 | * with the string to be used for orphan dirent. Pass back to the orphan dir | ||
| 2144 | * code. | ||
| 2145 | * @ret_orphan_dir: orphan dir inode returned to be passed back into orphan | ||
| 2146 | * dir code. | ||
| 2147 | * @ret_di_blkno: block number where the new inode will be allocated. | ||
| 2148 | * @orphan_insert: Dir insert context to be passed back into orphan dir code. | ||
| 2149 | * @ret_inode_ac: Inode alloc context to be passed back to the allocator. | ||
| 2150 | * | ||
| 2151 | * Returns zero on success and the ret_orphan_dir, name and lookup | ||
| 2152 | * fields will be populated. | ||
| 2153 | * | ||
| 2154 | * Returns non-zero on failure. | ||
| 2155 | */ | ||
| 2156 | static int ocfs2_prep_new_orphaned_file(struct inode *dir, | ||
| 2157 | struct buffer_head *dir_bh, | ||
| 2158 | char *orphan_name, | ||
| 2159 | struct inode **ret_orphan_dir, | ||
| 2160 | u64 *ret_di_blkno, | ||
| 2161 | struct ocfs2_dir_lookup_result *orphan_insert, | ||
| 2162 | struct ocfs2_alloc_context **ret_inode_ac) | ||
| 2163 | { | ||
| 2164 | int ret; | ||
| 2165 | u64 di_blkno; | ||
| 2166 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | ||
| 2167 | struct inode *orphan_dir = NULL; | ||
| 2168 | struct buffer_head *orphan_dir_bh = NULL; | ||
| 2169 | struct ocfs2_alloc_context *inode_ac = NULL; | ||
| 2170 | |||
| 2171 | ret = ocfs2_lookup_lock_orphan_dir(osb, &orphan_dir, &orphan_dir_bh); | ||
| 2172 | if (ret < 0) { | ||
| 2173 | mlog_errno(ret); | ||
| 2174 | return ret; | ||
| 2175 | } | ||
| 2176 | |||
| 2177 | /* reserve an inode spot */ | ||
| 2178 | ret = ocfs2_reserve_new_inode(osb, &inode_ac); | ||
| 2179 | if (ret < 0) { | ||
| 2180 | if (ret != -ENOSPC) | ||
| 2181 | mlog_errno(ret); | ||
| 2182 | goto out; | ||
| 2183 | } | ||
| 2184 | |||
| 2185 | ret = ocfs2_find_new_inode_loc(dir, dir_bh, inode_ac, | ||
| 2186 | &di_blkno); | ||
| 2187 | if (ret) { | ||
| 2188 | mlog_errno(ret); | ||
| 2189 | goto out; | ||
| 2190 | } | ||
| 2191 | |||
| 2192 | ret = __ocfs2_prepare_orphan_dir(orphan_dir, orphan_dir_bh, | ||
| 2193 | di_blkno, orphan_name, orphan_insert); | ||
| 2194 | if (ret < 0) { | ||
| 2195 | mlog_errno(ret); | ||
| 2196 | goto out; | ||
| 2197 | } | ||
| 2198 | |||
| 2199 | out: | ||
| 2200 | if (ret == 0) { | ||
| 2201 | *ret_orphan_dir = orphan_dir; | ||
| 2202 | *ret_di_blkno = di_blkno; | ||
| 2203 | *ret_inode_ac = inode_ac; | ||
| 2204 | /* | ||
| 2205 | * orphan_name and orphan_insert are already up to | ||
| 2206 | * date via prepare_orphan_dir | ||
| 2207 | */ | ||
| 2208 | } else { | ||
| 2209 | /* Unroll reserve_new_inode* */ | ||
| 2210 | if (inode_ac) | ||
| 2211 | ocfs2_free_alloc_context(inode_ac); | ||
| 2212 | |||
| 2213 | /* Unroll orphan dir locking */ | ||
| 2214 | mutex_unlock(&orphan_dir->i_mutex); | ||
| 2215 | ocfs2_inode_unlock(orphan_dir, 1); | ||
| 2216 | iput(orphan_dir); | ||
| 2217 | } | ||
| 2218 | |||
| 2219 | brelse(orphan_dir_bh); | ||
| 2220 | |||
| 2221 | return 0; | ||
| 2222 | } | ||
| 2223 | |||
| 2056 | int ocfs2_create_inode_in_orphan(struct inode *dir, | 2224 | int ocfs2_create_inode_in_orphan(struct inode *dir, |
| 2057 | int mode, | 2225 | int mode, |
| 2058 | struct inode **new_inode) | 2226 | struct inode **new_inode) |
| @@ -2068,6 +2236,8 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, | |||
| 2068 | struct buffer_head *new_di_bh = NULL; | 2236 | struct buffer_head *new_di_bh = NULL; |
| 2069 | struct ocfs2_alloc_context *inode_ac = NULL; | 2237 | struct ocfs2_alloc_context *inode_ac = NULL; |
| 2070 | struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; | 2238 | struct ocfs2_dir_lookup_result orphan_insert = { NULL, }; |
| 2239 | u64 uninitialized_var(di_blkno), suballoc_loc; | ||
| 2240 | u16 suballoc_bit; | ||
| 2071 | 2241 | ||
| 2072 | status = ocfs2_inode_lock(dir, &parent_di_bh, 1); | 2242 | status = ocfs2_inode_lock(dir, &parent_di_bh, 1); |
| 2073 | if (status < 0) { | 2243 | if (status < 0) { |
| @@ -2076,20 +2246,9 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, | |||
| 2076 | return status; | 2246 | return status; |
| 2077 | } | 2247 | } |
| 2078 | 2248 | ||
| 2079 | /* | 2249 | status = ocfs2_prep_new_orphaned_file(dir, parent_di_bh, |
| 2080 | * We give the orphan dir the root blkno to fake an orphan name, | 2250 | orphan_name, &orphan_dir, |
| 2081 | * and allocate enough space for our insertion. | 2251 | &di_blkno, &orphan_insert, &inode_ac); |
| 2082 | */ | ||
| 2083 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, | ||
| 2084 | osb->root_blkno, | ||
| 2085 | orphan_name, &orphan_insert); | ||
| 2086 | if (status < 0) { | ||
| 2087 | mlog_errno(status); | ||
| 2088 | goto leave; | ||
| 2089 | } | ||
| 2090 | |||
| 2091 | /* reserve an inode spot */ | ||
| 2092 | status = ocfs2_reserve_new_inode(osb, &inode_ac); | ||
| 2093 | if (status < 0) { | 2252 | if (status < 0) { |
| 2094 | if (status != -ENOSPC) | 2253 | if (status != -ENOSPC) |
| 2095 | mlog_errno(status); | 2254 | mlog_errno(status); |
| @@ -2116,17 +2275,20 @@ int ocfs2_create_inode_in_orphan(struct inode *dir, | |||
| 2116 | goto leave; | 2275 | goto leave; |
| 2117 | did_quota_inode = 1; | 2276 | did_quota_inode = 1; |
| 2118 | 2277 | ||
| 2119 | inode->i_nlink = 0; | 2278 | status = ocfs2_claim_new_inode_at_loc(handle, dir, inode_ac, |
| 2120 | /* do the real work now. */ | 2279 | &suballoc_loc, |
| 2121 | status = ocfs2_mknod_locked(osb, dir, inode, | 2280 | &suballoc_bit, di_blkno); |
| 2122 | 0, &new_di_bh, parent_di_bh, handle, | ||
| 2123 | inode_ac); | ||
| 2124 | if (status < 0) { | 2281 | if (status < 0) { |
| 2125 | mlog_errno(status); | 2282 | mlog_errno(status); |
| 2126 | goto leave; | 2283 | goto leave; |
| 2127 | } | 2284 | } |
| 2128 | 2285 | ||
| 2129 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, orphan_name); | 2286 | inode->i_nlink = 0; |
| 2287 | /* do the real work now. */ | ||
| 2288 | status = __ocfs2_mknod_locked(dir, inode, | ||
| 2289 | 0, &new_di_bh, parent_di_bh, handle, | ||
| 2290 | inode_ac, di_blkno, suballoc_loc, | ||
| 2291 | suballoc_bit); | ||
| 2130 | if (status < 0) { | 2292 | if (status < 0) { |
| 2131 | mlog_errno(status); | 2293 | mlog_errno(status); |
| 2132 | goto leave; | 2294 | goto leave; |
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index 33f1c9a8258d..fa31d05e41b7 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h | |||
| @@ -235,18 +235,31 @@ | |||
| 235 | #define OCFS2_HAS_REFCOUNT_FL (0x0010) | 235 | #define OCFS2_HAS_REFCOUNT_FL (0x0010) |
| 236 | 236 | ||
| 237 | /* Inode attributes, keep in sync with EXT2 */ | 237 | /* Inode attributes, keep in sync with EXT2 */ |
| 238 | #define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */ | 238 | #define OCFS2_SECRM_FL FS_SECRM_FL /* Secure deletion */ |
| 239 | #define OCFS2_UNRM_FL (0x00000002) /* Undelete */ | 239 | #define OCFS2_UNRM_FL FS_UNRM_FL /* Undelete */ |
| 240 | #define OCFS2_COMPR_FL (0x00000004) /* Compress file */ | 240 | #define OCFS2_COMPR_FL FS_COMPR_FL /* Compress file */ |
| 241 | #define OCFS2_SYNC_FL (0x00000008) /* Synchronous updates */ | 241 | #define OCFS2_SYNC_FL FS_SYNC_FL /* Synchronous updates */ |
| 242 | #define OCFS2_IMMUTABLE_FL (0x00000010) /* Immutable file */ | 242 | #define OCFS2_IMMUTABLE_FL FS_IMMUTABLE_FL /* Immutable file */ |
| 243 | #define OCFS2_APPEND_FL (0x00000020) /* writes to file may only append */ | 243 | #define OCFS2_APPEND_FL FS_APPEND_FL /* writes to file may only append */ |
| 244 | #define OCFS2_NODUMP_FL (0x00000040) /* do not dump file */ | 244 | #define OCFS2_NODUMP_FL FS_NODUMP_FL /* do not dump file */ |
| 245 | #define OCFS2_NOATIME_FL (0x00000080) /* do not update atime */ | 245 | #define OCFS2_NOATIME_FL FS_NOATIME_FL /* do not update atime */ |
| 246 | #define OCFS2_DIRSYNC_FL (0x00010000) /* dirsync behaviour (directories only) */ | 246 | /* Reserved for compression usage... */ |
| 247 | 247 | #define OCFS2_DIRTY_FL FS_DIRTY_FL | |
| 248 | #define OCFS2_FL_VISIBLE (0x000100FF) /* User visible flags */ | 248 | #define OCFS2_COMPRBLK_FL FS_COMPRBLK_FL /* One or more compressed clusters */ |
| 249 | #define OCFS2_FL_MODIFIABLE (0x000100FF) /* User modifiable flags */ | 249 | #define OCFS2_NOCOMP_FL FS_NOCOMP_FL /* Don't compress */ |
| 250 | #define OCFS2_ECOMPR_FL FS_ECOMPR_FL /* Compression error */ | ||
| 251 | /* End compression flags --- maybe not all used */ | ||
| 252 | #define OCFS2_BTREE_FL FS_BTREE_FL /* btree format dir */ | ||
| 253 | #define OCFS2_INDEX_FL FS_INDEX_FL /* hash-indexed directory */ | ||
| 254 | #define OCFS2_IMAGIC_FL FS_IMAGIC_FL /* AFS directory */ | ||
| 255 | #define OCFS2_JOURNAL_DATA_FL FS_JOURNAL_DATA_FL /* Reserved for ext3 */ | ||
| 256 | #define OCFS2_NOTAIL_FL FS_NOTAIL_FL /* file tail should not be merged */ | ||
| 257 | #define OCFS2_DIRSYNC_FL FS_DIRSYNC_FL /* dirsync behaviour (directories only) */ | ||
| 258 | #define OCFS2_TOPDIR_FL FS_TOPDIR_FL /* Top of directory hierarchies*/ | ||
| 259 | #define OCFS2_RESERVED_FL FS_RESERVED_FL /* reserved for ext2 lib */ | ||
| 260 | |||
| 261 | #define OCFS2_FL_VISIBLE FS_FL_USER_VISIBLE /* User visible flags */ | ||
| 262 | #define OCFS2_FL_MODIFIABLE FS_FL_USER_MODIFIABLE /* User modifiable flags */ | ||
| 250 | 263 | ||
| 251 | /* | 264 | /* |
| 252 | * Extent record flags (e_node.leaf.flags) | 265 | * Extent record flags (e_node.leaf.flags) |
diff --git a/fs/ocfs2/ocfs2_ioctl.h b/fs/ocfs2/ocfs2_ioctl.h index 2d3420af1a83..5d241505690b 100644 --- a/fs/ocfs2/ocfs2_ioctl.h +++ b/fs/ocfs2/ocfs2_ioctl.h | |||
| @@ -23,10 +23,10 @@ | |||
| 23 | /* | 23 | /* |
| 24 | * ioctl commands | 24 | * ioctl commands |
| 25 | */ | 25 | */ |
| 26 | #define OCFS2_IOC_GETFLAGS _IOR('f', 1, long) | 26 | #define OCFS2_IOC_GETFLAGS FS_IOC_GETFLAGS |
| 27 | #define OCFS2_IOC_SETFLAGS _IOW('f', 2, long) | 27 | #define OCFS2_IOC_SETFLAGS FS_IOC_SETFLAGS |
| 28 | #define OCFS2_IOC32_GETFLAGS _IOR('f', 1, int) | 28 | #define OCFS2_IOC32_GETFLAGS FS_IOC32_GETFLAGS |
| 29 | #define OCFS2_IOC32_SETFLAGS _IOW('f', 2, int) | 29 | #define OCFS2_IOC32_SETFLAGS FS_IOC32_SETFLAGS |
| 30 | 30 | ||
| 31 | /* | 31 | /* |
| 32 | * Space reservation / allocation / free ioctls and argument structure | 32 | * Space reservation / allocation / free ioctls and argument structure |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 73a11ccfd4c2..efdd75607406 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -2960,7 +2960,7 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
| 2960 | if (map_end & (PAGE_CACHE_SIZE - 1)) | 2960 | if (map_end & (PAGE_CACHE_SIZE - 1)) |
| 2961 | to = map_end & (PAGE_CACHE_SIZE - 1); | 2961 | to = map_end & (PAGE_CACHE_SIZE - 1); |
| 2962 | 2962 | ||
| 2963 | page = grab_cache_page(mapping, page_index); | 2963 | page = find_or_create_page(mapping, page_index, GFP_NOFS); |
| 2964 | 2964 | ||
| 2965 | /* | 2965 | /* |
| 2966 | * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page | 2966 | * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page |
| @@ -3179,7 +3179,8 @@ static int ocfs2_cow_sync_writeback(struct super_block *sb, | |||
| 3179 | if (map_end > end) | 3179 | if (map_end > end) |
| 3180 | map_end = end; | 3180 | map_end = end; |
| 3181 | 3181 | ||
| 3182 | page = grab_cache_page(context->inode->i_mapping, page_index); | 3182 | page = find_or_create_page(context->inode->i_mapping, |
| 3183 | page_index, GFP_NOFS); | ||
| 3183 | BUG_ON(!page); | 3184 | BUG_ON(!page); |
| 3184 | 3185 | ||
| 3185 | wait_on_page_writeback(page); | 3186 | wait_on_page_writeback(page); |
| @@ -4200,8 +4201,9 @@ static int __ocfs2_reflink(struct dentry *old_dentry, | |||
| 4200 | goto out; | 4201 | goto out; |
| 4201 | } | 4202 | } |
| 4202 | 4203 | ||
| 4203 | mutex_lock(&new_inode->i_mutex); | 4204 | mutex_lock_nested(&new_inode->i_mutex, I_MUTEX_CHILD); |
| 4204 | ret = ocfs2_inode_lock(new_inode, &new_bh, 1); | 4205 | ret = ocfs2_inode_lock_nested(new_inode, &new_bh, 1, |
| 4206 | OI_LS_REFLINK_TARGET); | ||
| 4205 | if (ret) { | 4207 | if (ret) { |
| 4206 | mlog_errno(ret); | 4208 | mlog_errno(ret); |
| 4207 | goto out_unlock; | 4209 | goto out_unlock; |
diff --git a/fs/ocfs2/reservations.c b/fs/ocfs2/reservations.c index d8b6e4259b80..3e78db361bc7 100644 --- a/fs/ocfs2/reservations.c +++ b/fs/ocfs2/reservations.c | |||
| @@ -732,25 +732,23 @@ int ocfs2_resmap_resv_bits(struct ocfs2_reservation_map *resmap, | |||
| 732 | struct ocfs2_alloc_reservation *resv, | 732 | struct ocfs2_alloc_reservation *resv, |
| 733 | int *cstart, int *clen) | 733 | int *cstart, int *clen) |
| 734 | { | 734 | { |
| 735 | unsigned int wanted = *clen; | ||
| 736 | |||
| 737 | if (resv == NULL || ocfs2_resmap_disabled(resmap)) | 735 | if (resv == NULL || ocfs2_resmap_disabled(resmap)) |
| 738 | return -ENOSPC; | 736 | return -ENOSPC; |
| 739 | 737 | ||
| 740 | spin_lock(&resv_lock); | 738 | spin_lock(&resv_lock); |
| 741 | 739 | ||
| 742 | /* | ||
| 743 | * We don't want to over-allocate for temporary | ||
| 744 | * windows. Otherwise, we run the risk of fragmenting the | ||
| 745 | * allocation space. | ||
| 746 | */ | ||
| 747 | wanted = ocfs2_resv_window_bits(resmap, resv); | ||
| 748 | if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen) | ||
| 749 | wanted = *clen; | ||
| 750 | |||
| 751 | if (ocfs2_resv_empty(resv)) { | 740 | if (ocfs2_resv_empty(resv)) { |
| 752 | mlog(0, "empty reservation, find new window\n"); | 741 | /* |
| 742 | * We don't want to over-allocate for temporary | ||
| 743 | * windows. Otherwise, we run the risk of fragmenting the | ||
| 744 | * allocation space. | ||
| 745 | */ | ||
| 746 | unsigned int wanted = ocfs2_resv_window_bits(resmap, resv); | ||
| 753 | 747 | ||
| 748 | if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen) | ||
| 749 | wanted = *clen; | ||
| 750 | |||
| 751 | mlog(0, "empty reservation, find new window\n"); | ||
| 754 | /* | 752 | /* |
| 755 | * Try to get a window here. If it works, we must fall | 753 | * Try to get a window here. If it works, we must fall |
| 756 | * through and test the bitmap . This avoids some | 754 | * through and test the bitmap . This avoids some |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index a8e6a95a353f..849c2f0e0a0e 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
| @@ -57,11 +57,28 @@ struct ocfs2_suballoc_result { | |||
| 57 | u64 sr_bg_blkno; /* The bg we allocated from. Set | 57 | u64 sr_bg_blkno; /* The bg we allocated from. Set |
| 58 | to 0 when a block group is | 58 | to 0 when a block group is |
| 59 | contiguous. */ | 59 | contiguous. */ |
| 60 | u64 sr_bg_stable_blkno; /* | ||
| 61 | * Doesn't change, always | ||
| 62 | * set to target block | ||
| 63 | * group descriptor | ||
| 64 | * block. | ||
| 65 | */ | ||
| 60 | u64 sr_blkno; /* The first allocated block */ | 66 | u64 sr_blkno; /* The first allocated block */ |
| 61 | unsigned int sr_bit_offset; /* The bit in the bg */ | 67 | unsigned int sr_bit_offset; /* The bit in the bg */ |
| 62 | unsigned int sr_bits; /* How many bits we claimed */ | 68 | unsigned int sr_bits; /* How many bits we claimed */ |
| 63 | }; | 69 | }; |
| 64 | 70 | ||
| 71 | static u64 ocfs2_group_from_res(struct ocfs2_suballoc_result *res) | ||
| 72 | { | ||
| 73 | if (res->sr_blkno == 0) | ||
| 74 | return 0; | ||
| 75 | |||
| 76 | if (res->sr_bg_blkno) | ||
| 77 | return res->sr_bg_blkno; | ||
| 78 | |||
| 79 | return ocfs2_which_suballoc_group(res->sr_blkno, res->sr_bit_offset); | ||
| 80 | } | ||
| 81 | |||
| 65 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); | 82 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); |
| 66 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); | 83 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); |
| 67 | static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl); | 84 | static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl); |
| @@ -138,6 +155,10 @@ void ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac) | |||
| 138 | brelse(ac->ac_bh); | 155 | brelse(ac->ac_bh); |
| 139 | ac->ac_bh = NULL; | 156 | ac->ac_bh = NULL; |
| 140 | ac->ac_resv = NULL; | 157 | ac->ac_resv = NULL; |
| 158 | if (ac->ac_find_loc_priv) { | ||
| 159 | kfree(ac->ac_find_loc_priv); | ||
| 160 | ac->ac_find_loc_priv = NULL; | ||
| 161 | } | ||
| 141 | } | 162 | } |
| 142 | 163 | ||
| 143 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac) | 164 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac) |
| @@ -336,7 +357,7 @@ out: | |||
| 336 | static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, | 357 | static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, |
| 337 | struct ocfs2_group_desc *bg, | 358 | struct ocfs2_group_desc *bg, |
| 338 | struct ocfs2_chain_list *cl, | 359 | struct ocfs2_chain_list *cl, |
| 339 | u64 p_blkno, u32 clusters) | 360 | u64 p_blkno, unsigned int clusters) |
| 340 | { | 361 | { |
| 341 | struct ocfs2_extent_list *el = &bg->bg_list; | 362 | struct ocfs2_extent_list *el = &bg->bg_list; |
| 342 | struct ocfs2_extent_rec *rec; | 363 | struct ocfs2_extent_rec *rec; |
| @@ -348,7 +369,7 @@ static void ocfs2_bg_discontig_add_extent(struct ocfs2_super *osb, | |||
| 348 | rec->e_blkno = cpu_to_le64(p_blkno); | 369 | rec->e_blkno = cpu_to_le64(p_blkno); |
| 349 | rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) / | 370 | rec->e_cpos = cpu_to_le32(le16_to_cpu(bg->bg_bits) / |
| 350 | le16_to_cpu(cl->cl_bpc)); | 371 | le16_to_cpu(cl->cl_bpc)); |
| 351 | rec->e_leaf_clusters = cpu_to_le32(clusters); | 372 | rec->e_leaf_clusters = cpu_to_le16(clusters); |
| 352 | le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc)); | 373 | le16_add_cpu(&bg->bg_bits, clusters * le16_to_cpu(cl->cl_bpc)); |
| 353 | le16_add_cpu(&bg->bg_free_bits_count, | 374 | le16_add_cpu(&bg->bg_free_bits_count, |
| 354 | clusters * le16_to_cpu(cl->cl_bpc)); | 375 | clusters * le16_to_cpu(cl->cl_bpc)); |
| @@ -1678,6 +1699,15 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | |||
| 1678 | if (!ret) | 1699 | if (!ret) |
| 1679 | ocfs2_bg_discontig_fix_result(ac, gd, res); | 1700 | ocfs2_bg_discontig_fix_result(ac, gd, res); |
| 1680 | 1701 | ||
| 1702 | /* | ||
| 1703 | * sr_bg_blkno might have been changed by | ||
| 1704 | * ocfs2_bg_discontig_fix_result | ||
| 1705 | */ | ||
| 1706 | res->sr_bg_stable_blkno = group_bh->b_blocknr; | ||
| 1707 | |||
| 1708 | if (ac->ac_find_loc_only) | ||
| 1709 | goto out_loc_only; | ||
| 1710 | |||
| 1681 | ret = ocfs2_alloc_dinode_update_counts(alloc_inode, handle, ac->ac_bh, | 1711 | ret = ocfs2_alloc_dinode_update_counts(alloc_inode, handle, ac->ac_bh, |
| 1682 | res->sr_bits, | 1712 | res->sr_bits, |
| 1683 | le16_to_cpu(gd->bg_chain)); | 1713 | le16_to_cpu(gd->bg_chain)); |
| @@ -1691,6 +1721,7 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | |||
| 1691 | if (ret < 0) | 1721 | if (ret < 0) |
| 1692 | mlog_errno(ret); | 1722 | mlog_errno(ret); |
| 1693 | 1723 | ||
| 1724 | out_loc_only: | ||
| 1694 | *bits_left = le16_to_cpu(gd->bg_free_bits_count); | 1725 | *bits_left = le16_to_cpu(gd->bg_free_bits_count); |
| 1695 | 1726 | ||
| 1696 | out: | 1727 | out: |
| @@ -1708,7 +1739,6 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
| 1708 | { | 1739 | { |
| 1709 | int status; | 1740 | int status; |
| 1710 | u16 chain; | 1741 | u16 chain; |
| 1711 | u32 tmp_used; | ||
| 1712 | u64 next_group; | 1742 | u64 next_group; |
| 1713 | struct inode *alloc_inode = ac->ac_inode; | 1743 | struct inode *alloc_inode = ac->ac_inode; |
| 1714 | struct buffer_head *group_bh = NULL; | 1744 | struct buffer_head *group_bh = NULL; |
| @@ -1770,6 +1800,11 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
| 1770 | if (!status) | 1800 | if (!status) |
| 1771 | ocfs2_bg_discontig_fix_result(ac, bg, res); | 1801 | ocfs2_bg_discontig_fix_result(ac, bg, res); |
| 1772 | 1802 | ||
| 1803 | /* | ||
| 1804 | * sr_bg_blkno might have been changed by | ||
| 1805 | * ocfs2_bg_discontig_fix_result | ||
| 1806 | */ | ||
| 1807 | res->sr_bg_stable_blkno = group_bh->b_blocknr; | ||
| 1773 | 1808 | ||
| 1774 | /* | 1809 | /* |
| 1775 | * Keep track of previous block descriptor read. When | 1810 | * Keep track of previous block descriptor read. When |
| @@ -1796,22 +1831,17 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
| 1796 | } | 1831 | } |
| 1797 | } | 1832 | } |
| 1798 | 1833 | ||
| 1799 | /* Ok, claim our bits now: set the info on dinode, chainlist | 1834 | if (ac->ac_find_loc_only) |
| 1800 | * and then the group */ | 1835 | goto out_loc_only; |
| 1801 | status = ocfs2_journal_access_di(handle, | 1836 | |
| 1802 | INODE_CACHE(alloc_inode), | 1837 | status = ocfs2_alloc_dinode_update_counts(alloc_inode, handle, |
| 1803 | ac->ac_bh, | 1838 | ac->ac_bh, res->sr_bits, |
| 1804 | OCFS2_JOURNAL_ACCESS_WRITE); | 1839 | chain); |
| 1805 | if (status < 0) { | 1840 | if (status) { |
| 1806 | mlog_errno(status); | 1841 | mlog_errno(status); |
| 1807 | goto bail; | 1842 | goto bail; |
| 1808 | } | 1843 | } |
| 1809 | 1844 | ||
| 1810 | tmp_used = le32_to_cpu(fe->id1.bitmap1.i_used); | ||
| 1811 | fe->id1.bitmap1.i_used = cpu_to_le32(res->sr_bits + tmp_used); | ||
| 1812 | le32_add_cpu(&cl->cl_recs[chain].c_free, -res->sr_bits); | ||
| 1813 | ocfs2_journal_dirty(handle, ac->ac_bh); | ||
| 1814 | |||
| 1815 | status = ocfs2_block_group_set_bits(handle, | 1845 | status = ocfs2_block_group_set_bits(handle, |
| 1816 | alloc_inode, | 1846 | alloc_inode, |
| 1817 | bg, | 1847 | bg, |
| @@ -1826,6 +1856,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
| 1826 | mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits, | 1856 | mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits, |
| 1827 | (unsigned long long)le64_to_cpu(fe->i_blkno)); | 1857 | (unsigned long long)le64_to_cpu(fe->i_blkno)); |
| 1828 | 1858 | ||
| 1859 | out_loc_only: | ||
| 1829 | *bits_left = le16_to_cpu(bg->bg_free_bits_count); | 1860 | *bits_left = le16_to_cpu(bg->bg_free_bits_count); |
| 1830 | bail: | 1861 | bail: |
| 1831 | brelse(group_bh); | 1862 | brelse(group_bh); |
| @@ -1845,6 +1876,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, | |||
| 1845 | int status; | 1876 | int status; |
| 1846 | u16 victim, i; | 1877 | u16 victim, i; |
| 1847 | u16 bits_left = 0; | 1878 | u16 bits_left = 0; |
| 1879 | u64 hint = ac->ac_last_group; | ||
| 1848 | struct ocfs2_chain_list *cl; | 1880 | struct ocfs2_chain_list *cl; |
| 1849 | struct ocfs2_dinode *fe; | 1881 | struct ocfs2_dinode *fe; |
| 1850 | 1882 | ||
| @@ -1872,7 +1904,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, | |||
| 1872 | goto bail; | 1904 | goto bail; |
| 1873 | } | 1905 | } |
| 1874 | 1906 | ||
| 1875 | res->sr_bg_blkno = ac->ac_last_group; | 1907 | res->sr_bg_blkno = hint; |
| 1876 | if (res->sr_bg_blkno) { | 1908 | if (res->sr_bg_blkno) { |
| 1877 | /* Attempt to short-circuit the usual search mechanism | 1909 | /* Attempt to short-circuit the usual search mechanism |
| 1878 | * by jumping straight to the most recently used | 1910 | * by jumping straight to the most recently used |
| @@ -1896,8 +1928,10 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, | |||
| 1896 | 1928 | ||
| 1897 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, | 1929 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, |
| 1898 | res, &bits_left); | 1930 | res, &bits_left); |
| 1899 | if (!status) | 1931 | if (!status) { |
| 1932 | hint = ocfs2_group_from_res(res); | ||
| 1900 | goto set_hint; | 1933 | goto set_hint; |
| 1934 | } | ||
| 1901 | if (status < 0 && status != -ENOSPC) { | 1935 | if (status < 0 && status != -ENOSPC) { |
| 1902 | mlog_errno(status); | 1936 | mlog_errno(status); |
| 1903 | goto bail; | 1937 | goto bail; |
| @@ -1920,8 +1954,10 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, | |||
| 1920 | ac->ac_chain = i; | 1954 | ac->ac_chain = i; |
| 1921 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, | 1955 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, |
| 1922 | res, &bits_left); | 1956 | res, &bits_left); |
| 1923 | if (!status) | 1957 | if (!status) { |
| 1958 | hint = ocfs2_group_from_res(res); | ||
| 1924 | break; | 1959 | break; |
| 1960 | } | ||
| 1925 | if (status < 0 && status != -ENOSPC) { | 1961 | if (status < 0 && status != -ENOSPC) { |
| 1926 | mlog_errno(status); | 1962 | mlog_errno(status); |
| 1927 | goto bail; | 1963 | goto bail; |
| @@ -1936,7 +1972,7 @@ set_hint: | |||
| 1936 | if (bits_left < min_bits) | 1972 | if (bits_left < min_bits) |
| 1937 | ac->ac_last_group = 0; | 1973 | ac->ac_last_group = 0; |
| 1938 | else | 1974 | else |
| 1939 | ac->ac_last_group = res->sr_bg_blkno; | 1975 | ac->ac_last_group = hint; |
| 1940 | } | 1976 | } |
| 1941 | 1977 | ||
| 1942 | bail: | 1978 | bail: |
| @@ -2016,6 +2052,136 @@ static inline void ocfs2_save_inode_ac_group(struct inode *dir, | |||
| 2016 | OCFS2_I(dir)->ip_last_used_slot = ac->ac_alloc_slot; | 2052 | OCFS2_I(dir)->ip_last_used_slot = ac->ac_alloc_slot; |
| 2017 | } | 2053 | } |
| 2018 | 2054 | ||
| 2055 | int ocfs2_find_new_inode_loc(struct inode *dir, | ||
| 2056 | struct buffer_head *parent_fe_bh, | ||
| 2057 | struct ocfs2_alloc_context *ac, | ||
| 2058 | u64 *fe_blkno) | ||
| 2059 | { | ||
| 2060 | int ret; | ||
| 2061 | handle_t *handle = NULL; | ||
| 2062 | struct ocfs2_suballoc_result *res; | ||
| 2063 | |||
| 2064 | BUG_ON(!ac); | ||
| 2065 | BUG_ON(ac->ac_bits_given != 0); | ||
| 2066 | BUG_ON(ac->ac_bits_wanted != 1); | ||
| 2067 | BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); | ||
| 2068 | |||
| 2069 | res = kzalloc(sizeof(*res), GFP_NOFS); | ||
| 2070 | if (res == NULL) { | ||
| 2071 | ret = -ENOMEM; | ||
| 2072 | mlog_errno(ret); | ||
| 2073 | goto out; | ||
| 2074 | } | ||
| 2075 | |||
| 2076 | ocfs2_init_inode_ac_group(dir, parent_fe_bh, ac); | ||
| 2077 | |||
| 2078 | /* | ||
| 2079 | * The handle started here is for chain relink. Alternatively, | ||
| 2080 | * we could just disable relink for these calls. | ||
| 2081 | */ | ||
| 2082 | handle = ocfs2_start_trans(OCFS2_SB(dir->i_sb), OCFS2_SUBALLOC_ALLOC); | ||
| 2083 | if (IS_ERR(handle)) { | ||
| 2084 | ret = PTR_ERR(handle); | ||
| 2085 | handle = NULL; | ||
| 2086 | mlog_errno(ret); | ||
| 2087 | goto out; | ||
| 2088 | } | ||
| 2089 | |||
| 2090 | /* | ||
| 2091 | * This will instruct ocfs2_claim_suballoc_bits and | ||
| 2092 | * ocfs2_search_one_group to search but save actual allocation | ||
| 2093 | * for later. | ||
| 2094 | */ | ||
| 2095 | ac->ac_find_loc_only = 1; | ||
| 2096 | |||
| 2097 | ret = ocfs2_claim_suballoc_bits(ac, handle, 1, 1, res); | ||
| 2098 | if (ret < 0) { | ||
| 2099 | mlog_errno(ret); | ||
| 2100 | goto out; | ||
| 2101 | } | ||
| 2102 | |||
| 2103 | ac->ac_find_loc_priv = res; | ||
| 2104 | *fe_blkno = res->sr_blkno; | ||
| 2105 | |||
| 2106 | out: | ||
| 2107 | if (handle) | ||
| 2108 | ocfs2_commit_trans(OCFS2_SB(dir->i_sb), handle); | ||
| 2109 | |||
| 2110 | if (ret) | ||
| 2111 | kfree(res); | ||
| 2112 | |||
| 2113 | return ret; | ||
| 2114 | } | ||
| 2115 | |||
| 2116 | int ocfs2_claim_new_inode_at_loc(handle_t *handle, | ||
| 2117 | struct inode *dir, | ||
| 2118 | struct ocfs2_alloc_context *ac, | ||
| 2119 | u64 *suballoc_loc, | ||
| 2120 | u16 *suballoc_bit, | ||
| 2121 | u64 di_blkno) | ||
| 2122 | { | ||
| 2123 | int ret; | ||
| 2124 | u16 chain; | ||
| 2125 | struct ocfs2_suballoc_result *res = ac->ac_find_loc_priv; | ||
| 2126 | struct buffer_head *bg_bh = NULL; | ||
| 2127 | struct ocfs2_group_desc *bg; | ||
| 2128 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) ac->ac_bh->b_data; | ||
| 2129 | |||
| 2130 | /* | ||
| 2131 | * Since di_blkno is being passed back in, we check for any | ||
| 2132 | * inconsistencies which may have happened between | ||
| 2133 | * calls. These are code bugs as di_blkno is not expected to | ||
| 2134 | * change once returned from ocfs2_find_new_inode_loc() | ||
| 2135 | */ | ||
| 2136 | BUG_ON(res->sr_blkno != di_blkno); | ||
| 2137 | |||
| 2138 | ret = ocfs2_read_group_descriptor(ac->ac_inode, di, | ||
| 2139 | res->sr_bg_stable_blkno, &bg_bh); | ||
| 2140 | if (ret) { | ||
| 2141 | mlog_errno(ret); | ||
| 2142 | goto out; | ||
| 2143 | } | ||
| 2144 | |||
| 2145 | bg = (struct ocfs2_group_desc *) bg_bh->b_data; | ||
| 2146 | chain = le16_to_cpu(bg->bg_chain); | ||
| 2147 | |||
| 2148 | ret = ocfs2_alloc_dinode_update_counts(ac->ac_inode, handle, | ||
| 2149 | ac->ac_bh, res->sr_bits, | ||
| 2150 | chain); | ||
| 2151 | if (ret) { | ||
| 2152 | mlog_errno(ret); | ||
| 2153 | goto out; | ||
| 2154 | } | ||
| 2155 | |||
| 2156 | ret = ocfs2_block_group_set_bits(handle, | ||
| 2157 | ac->ac_inode, | ||
| 2158 | bg, | ||
| 2159 | bg_bh, | ||
| 2160 | res->sr_bit_offset, | ||
| 2161 | res->sr_bits); | ||
| 2162 | if (ret < 0) { | ||
| 2163 | mlog_errno(ret); | ||
| 2164 | goto out; | ||
| 2165 | } | ||
| 2166 | |||
| 2167 | mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits, | ||
| 2168 | (unsigned long long)di_blkno); | ||
| 2169 | |||
| 2170 | atomic_inc(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs); | ||
| 2171 | |||
| 2172 | BUG_ON(res->sr_bits != 1); | ||
| 2173 | |||
| 2174 | *suballoc_loc = res->sr_bg_blkno; | ||
| 2175 | *suballoc_bit = res->sr_bit_offset; | ||
| 2176 | ac->ac_bits_given++; | ||
| 2177 | ocfs2_save_inode_ac_group(dir, ac); | ||
| 2178 | |||
| 2179 | out: | ||
| 2180 | brelse(bg_bh); | ||
| 2181 | |||
| 2182 | return ret; | ||
| 2183 | } | ||
| 2184 | |||
| 2019 | int ocfs2_claim_new_inode(handle_t *handle, | 2185 | int ocfs2_claim_new_inode(handle_t *handle, |
| 2020 | struct inode *dir, | 2186 | struct inode *dir, |
| 2021 | struct buffer_head *parent_fe_bh, | 2187 | struct buffer_head *parent_fe_bh, |
| @@ -2567,7 +2733,8 @@ out: | |||
| 2567 | * suballoc_bit. | 2733 | * suballoc_bit. |
| 2568 | */ | 2734 | */ |
| 2569 | static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno, | 2735 | static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno, |
| 2570 | u16 *suballoc_slot, u16 *suballoc_bit) | 2736 | u16 *suballoc_slot, u64 *group_blkno, |
| 2737 | u16 *suballoc_bit) | ||
| 2571 | { | 2738 | { |
| 2572 | int status; | 2739 | int status; |
| 2573 | struct buffer_head *inode_bh = NULL; | 2740 | struct buffer_head *inode_bh = NULL; |
| @@ -2604,6 +2771,8 @@ static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno, | |||
| 2604 | *suballoc_slot = le16_to_cpu(inode_fe->i_suballoc_slot); | 2771 | *suballoc_slot = le16_to_cpu(inode_fe->i_suballoc_slot); |
| 2605 | if (suballoc_bit) | 2772 | if (suballoc_bit) |
| 2606 | *suballoc_bit = le16_to_cpu(inode_fe->i_suballoc_bit); | 2773 | *suballoc_bit = le16_to_cpu(inode_fe->i_suballoc_bit); |
| 2774 | if (group_blkno) | ||
| 2775 | *group_blkno = le64_to_cpu(inode_fe->i_suballoc_loc); | ||
| 2607 | 2776 | ||
| 2608 | bail: | 2777 | bail: |
| 2609 | brelse(inode_bh); | 2778 | brelse(inode_bh); |
| @@ -2621,7 +2790,8 @@ bail: | |||
| 2621 | */ | 2790 | */ |
| 2622 | static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb, | 2791 | static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb, |
| 2623 | struct inode *suballoc, | 2792 | struct inode *suballoc, |
| 2624 | struct buffer_head *alloc_bh, u64 blkno, | 2793 | struct buffer_head *alloc_bh, |
| 2794 | u64 group_blkno, u64 blkno, | ||
| 2625 | u16 bit, int *res) | 2795 | u16 bit, int *res) |
| 2626 | { | 2796 | { |
| 2627 | struct ocfs2_dinode *alloc_di; | 2797 | struct ocfs2_dinode *alloc_di; |
| @@ -2642,10 +2812,8 @@ static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb, | |||
| 2642 | goto bail; | 2812 | goto bail; |
| 2643 | } | 2813 | } |
| 2644 | 2814 | ||
| 2645 | if (alloc_di->i_suballoc_loc) | 2815 | bg_blkno = group_blkno ? group_blkno : |
| 2646 | bg_blkno = le64_to_cpu(alloc_di->i_suballoc_loc); | 2816 | ocfs2_which_suballoc_group(blkno, bit); |
| 2647 | else | ||
| 2648 | bg_blkno = ocfs2_which_suballoc_group(blkno, bit); | ||
| 2649 | status = ocfs2_read_group_descriptor(suballoc, alloc_di, bg_blkno, | 2817 | status = ocfs2_read_group_descriptor(suballoc, alloc_di, bg_blkno, |
| 2650 | &group_bh); | 2818 | &group_bh); |
| 2651 | if (status < 0) { | 2819 | if (status < 0) { |
| @@ -2680,6 +2848,7 @@ bail: | |||
| 2680 | int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) | 2848 | int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) |
| 2681 | { | 2849 | { |
| 2682 | int status; | 2850 | int status; |
| 2851 | u64 group_blkno = 0; | ||
| 2683 | u16 suballoc_bit = 0, suballoc_slot = 0; | 2852 | u16 suballoc_bit = 0, suballoc_slot = 0; |
| 2684 | struct inode *inode_alloc_inode; | 2853 | struct inode *inode_alloc_inode; |
| 2685 | struct buffer_head *alloc_bh = NULL; | 2854 | struct buffer_head *alloc_bh = NULL; |
| @@ -2687,7 +2856,7 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) | |||
| 2687 | mlog_entry("blkno: %llu", (unsigned long long)blkno); | 2856 | mlog_entry("blkno: %llu", (unsigned long long)blkno); |
| 2688 | 2857 | ||
| 2689 | status = ocfs2_get_suballoc_slot_bit(osb, blkno, &suballoc_slot, | 2858 | status = ocfs2_get_suballoc_slot_bit(osb, blkno, &suballoc_slot, |
| 2690 | &suballoc_bit); | 2859 | &group_blkno, &suballoc_bit); |
| 2691 | if (status < 0) { | 2860 | if (status < 0) { |
| 2692 | mlog(ML_ERROR, "get alloc slot and bit failed %d\n", status); | 2861 | mlog(ML_ERROR, "get alloc slot and bit failed %d\n", status); |
| 2693 | goto bail; | 2862 | goto bail; |
| @@ -2715,7 +2884,7 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res) | |||
| 2715 | } | 2884 | } |
| 2716 | 2885 | ||
| 2717 | status = ocfs2_test_suballoc_bit(osb, inode_alloc_inode, alloc_bh, | 2886 | status = ocfs2_test_suballoc_bit(osb, inode_alloc_inode, alloc_bh, |
| 2718 | blkno, suballoc_bit, res); | 2887 | group_blkno, blkno, suballoc_bit, res); |
| 2719 | if (status < 0) | 2888 | if (status < 0) |
| 2720 | mlog(ML_ERROR, "test suballoc bit failed %d\n", status); | 2889 | mlog(ML_ERROR, "test suballoc bit failed %d\n", status); |
| 2721 | 2890 | ||
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index a017dd3ee7d9..b8afabfeede4 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h | |||
| @@ -56,6 +56,9 @@ struct ocfs2_alloc_context { | |||
| 56 | u64 ac_max_block; /* Highest block number to allocate. 0 is | 56 | u64 ac_max_block; /* Highest block number to allocate. 0 is |
| 57 | is the same as ~0 - unlimited */ | 57 | is the same as ~0 - unlimited */ |
| 58 | 58 | ||
| 59 | int ac_find_loc_only; /* hack for reflink operation ordering */ | ||
| 60 | struct ocfs2_suballoc_result *ac_find_loc_priv; /* */ | ||
| 61 | |||
| 59 | struct ocfs2_alloc_reservation *ac_resv; | 62 | struct ocfs2_alloc_reservation *ac_resv; |
| 60 | }; | 63 | }; |
| 61 | 64 | ||
| @@ -197,4 +200,22 @@ int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_extent_tree *et, | |||
| 197 | struct ocfs2_alloc_context **meta_ac); | 200 | struct ocfs2_alloc_context **meta_ac); |
| 198 | 201 | ||
| 199 | int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res); | 202 | int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res); |
| 203 | |||
| 204 | |||
| 205 | |||
| 206 | /* | ||
| 207 | * The following two interfaces are for ocfs2_create_inode_in_orphan(). | ||
| 208 | */ | ||
| 209 | int ocfs2_find_new_inode_loc(struct inode *dir, | ||
| 210 | struct buffer_head *parent_fe_bh, | ||
| 211 | struct ocfs2_alloc_context *ac, | ||
| 212 | u64 *fe_blkno); | ||
| 213 | |||
| 214 | int ocfs2_claim_new_inode_at_loc(handle_t *handle, | ||
| 215 | struct inode *dir, | ||
| 216 | struct ocfs2_alloc_context *ac, | ||
| 217 | u64 *suballoc_loc, | ||
| 218 | u16 *suballoc_bit, | ||
| 219 | u64 di_blkno); | ||
| 220 | |||
| 200 | #endif /* _CHAINALLOC_H_ */ | 221 | #endif /* _CHAINALLOC_H_ */ |
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index d03469f61801..06fa5e77c40e 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
| @@ -1286,13 +1286,11 @@ int ocfs2_xattr_get_nolock(struct inode *inode, | |||
| 1286 | xis.inode_bh = xbs.inode_bh = di_bh; | 1286 | xis.inode_bh = xbs.inode_bh = di_bh; |
| 1287 | di = (struct ocfs2_dinode *)di_bh->b_data; | 1287 | di = (struct ocfs2_dinode *)di_bh->b_data; |
| 1288 | 1288 | ||
| 1289 | down_read(&oi->ip_xattr_sem); | ||
| 1290 | ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer, | 1289 | ret = ocfs2_xattr_ibody_get(inode, name_index, name, buffer, |
| 1291 | buffer_size, &xis); | 1290 | buffer_size, &xis); |
| 1292 | if (ret == -ENODATA && di->i_xattr_loc) | 1291 | if (ret == -ENODATA && di->i_xattr_loc) |
| 1293 | ret = ocfs2_xattr_block_get(inode, name_index, name, buffer, | 1292 | ret = ocfs2_xattr_block_get(inode, name_index, name, buffer, |
| 1294 | buffer_size, &xbs); | 1293 | buffer_size, &xbs); |
| 1295 | up_read(&oi->ip_xattr_sem); | ||
| 1296 | 1294 | ||
| 1297 | return ret; | 1295 | return ret; |
| 1298 | } | 1296 | } |
| @@ -1316,8 +1314,10 @@ static int ocfs2_xattr_get(struct inode *inode, | |||
| 1316 | mlog_errno(ret); | 1314 | mlog_errno(ret); |
| 1317 | return ret; | 1315 | return ret; |
| 1318 | } | 1316 | } |
| 1317 | down_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
| 1319 | ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index, | 1318 | ret = ocfs2_xattr_get_nolock(inode, di_bh, name_index, |
| 1320 | name, buffer, buffer_size); | 1319 | name, buffer, buffer_size); |
| 1320 | up_read(&OCFS2_I(inode)->ip_xattr_sem); | ||
| 1321 | 1321 | ||
| 1322 | ocfs2_inode_unlock(inode, 0); | 1322 | ocfs2_inode_unlock(inode, 0); |
| 1323 | 1323 | ||
