diff options
author | Joel Becker <jlbec@evilplan.org> | 2011-08-22 00:02:57 -0400 |
---|---|---|
committer | Joel Becker <jlbec@evilplan.org> | 2011-08-22 00:02:57 -0400 |
commit | 99b1bb61b225c3eb4d3b196d4f1d041695b19a7e (patch) | |
tree | 06cabdc34538f3b38a39e3b802ecc1a2ab2aae00 /fs/ocfs2/file.c | |
parent | c7e25e6e0b0486492c5faaf6312b37413642c48e (diff) | |
parent | 93862d5e1ab875664c6cc95254fc365028a48bb1 (diff) |
Merge branch 'mw-3.1-jul25' of git://oss.oracle.com/git/smushran/linux-2.6 into ocfs2-fixes
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 96 |
1 files changed, 78 insertions, 18 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 145f4533a936..5c4a74e04ab4 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -171,7 +171,8 @@ static int ocfs2_dir_release(struct inode *inode, struct file *file) | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
174 | static int ocfs2_sync_file(struct file *file, int datasync) | 174 | static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end, |
175 | int datasync) | ||
175 | { | 176 | { |
176 | int err = 0; | 177 | int err = 0; |
177 | journal_t *journal; | 178 | journal_t *journal; |
@@ -184,6 +185,16 @@ static int ocfs2_sync_file(struct file *file, int datasync) | |||
184 | file->f_path.dentry->d_name.name, | 185 | file->f_path.dentry->d_name.name, |
185 | (unsigned long long)datasync); | 186 | (unsigned long long)datasync); |
186 | 187 | ||
188 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); | ||
189 | if (err) | ||
190 | return err; | ||
191 | |||
192 | /* | ||
193 | * Probably don't need the i_mutex at all in here, just putting it here | ||
194 | * to be consistent with how fsync used to be called, someone more | ||
195 | * familiar with the fs could possibly remove it. | ||
196 | */ | ||
197 | mutex_lock(&inode->i_mutex); | ||
187 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) { | 198 | if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) { |
188 | /* | 199 | /* |
189 | * We still have to flush drive's caches to get data to the | 200 | * We still have to flush drive's caches to get data to the |
@@ -200,6 +211,7 @@ static int ocfs2_sync_file(struct file *file, int datasync) | |||
200 | bail: | 211 | bail: |
201 | if (err) | 212 | if (err) |
202 | mlog_errno(err); | 213 | mlog_errno(err); |
214 | mutex_unlock(&inode->i_mutex); | ||
203 | 215 | ||
204 | return (err < 0) ? -EIO : 0; | 216 | return (err < 0) ? -EIO : 0; |
205 | } | 217 | } |
@@ -1142,6 +1154,8 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1142 | if (status) | 1154 | if (status) |
1143 | goto bail_unlock; | 1155 | goto bail_unlock; |
1144 | 1156 | ||
1157 | inode_dio_wait(inode); | ||
1158 | |||
1145 | if (i_size_read(inode) > attr->ia_size) { | 1159 | if (i_size_read(inode) > attr->ia_size) { |
1146 | if (ocfs2_should_order_data(inode)) { | 1160 | if (ocfs2_should_order_data(inode)) { |
1147 | status = ocfs2_begin_ordered_truncate(inode, | 1161 | status = ocfs2_begin_ordered_truncate(inode, |
@@ -1279,11 +1293,11 @@ bail: | |||
1279 | return err; | 1293 | return err; |
1280 | } | 1294 | } |
1281 | 1295 | ||
1282 | int ocfs2_permission(struct inode *inode, int mask, unsigned int flags) | 1296 | int ocfs2_permission(struct inode *inode, int mask) |
1283 | { | 1297 | { |
1284 | int ret; | 1298 | int ret; |
1285 | 1299 | ||
1286 | if (flags & IPERM_FLAG_RCU) | 1300 | if (mask & MAY_NOT_BLOCK) |
1287 | return -ECHILD; | 1301 | return -ECHILD; |
1288 | 1302 | ||
1289 | ret = ocfs2_inode_lock(inode, NULL, 0); | 1303 | ret = ocfs2_inode_lock(inode, NULL, 0); |
@@ -1293,7 +1307,7 @@ int ocfs2_permission(struct inode *inode, int mask, unsigned int flags) | |||
1293 | goto out; | 1307 | goto out; |
1294 | } | 1308 | } |
1295 | 1309 | ||
1296 | ret = generic_permission(inode, mask, flags, ocfs2_check_acl); | 1310 | ret = generic_permission(inode, mask); |
1297 | 1311 | ||
1298 | ocfs2_inode_unlock(inode, 0); | 1312 | ocfs2_inode_unlock(inode, 0); |
1299 | out: | 1313 | out: |
@@ -2254,9 +2268,8 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
2254 | ocfs2_iocb_clear_sem_locked(iocb); | 2268 | ocfs2_iocb_clear_sem_locked(iocb); |
2255 | 2269 | ||
2256 | relock: | 2270 | relock: |
2257 | /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ | 2271 | /* to match setattr's i_mutex -> rw_lock ordering */ |
2258 | if (direct_io) { | 2272 | if (direct_io) { |
2259 | down_read(&inode->i_alloc_sem); | ||
2260 | have_alloc_sem = 1; | 2273 | have_alloc_sem = 1; |
2261 | /* communicate with ocfs2_dio_end_io */ | 2274 | /* communicate with ocfs2_dio_end_io */ |
2262 | ocfs2_iocb_set_sem_locked(iocb); | 2275 | ocfs2_iocb_set_sem_locked(iocb); |
@@ -2312,7 +2325,6 @@ relock: | |||
2312 | */ | 2325 | */ |
2313 | if (direct_io && !can_do_direct) { | 2326 | if (direct_io && !can_do_direct) { |
2314 | ocfs2_rw_unlock(inode, rw_level); | 2327 | ocfs2_rw_unlock(inode, rw_level); |
2315 | up_read(&inode->i_alloc_sem); | ||
2316 | 2328 | ||
2317 | have_alloc_sem = 0; | 2329 | have_alloc_sem = 0; |
2318 | rw_level = -1; | 2330 | rw_level = -1; |
@@ -2395,8 +2407,7 @@ out_dio: | |||
2395 | /* | 2407 | /* |
2396 | * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io | 2408 | * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io |
2397 | * function pointer which is called when o_direct io completes so that | 2409 | * function pointer which is called when o_direct io completes so that |
2398 | * it can unlock our rw lock. (it's the clustered equivalent of | 2410 | * it can unlock our rw lock. |
2399 | * i_alloc_sem; protects truncate from racing with pending ios). | ||
2400 | * Unfortunately there are error cases which call end_io and others | 2411 | * Unfortunately there are error cases which call end_io and others |
2401 | * that don't. so we don't have to unlock the rw_lock if either an | 2412 | * that don't. so we don't have to unlock the rw_lock if either an |
2402 | * async dio is going to do it in the future or an end_io after an | 2413 | * async dio is going to do it in the future or an end_io after an |
@@ -2416,10 +2427,8 @@ out: | |||
2416 | ocfs2_rw_unlock(inode, rw_level); | 2427 | ocfs2_rw_unlock(inode, rw_level); |
2417 | 2428 | ||
2418 | out_sems: | 2429 | out_sems: |
2419 | if (have_alloc_sem) { | 2430 | if (have_alloc_sem) |
2420 | up_read(&inode->i_alloc_sem); | ||
2421 | ocfs2_iocb_clear_sem_locked(iocb); | 2431 | ocfs2_iocb_clear_sem_locked(iocb); |
2422 | } | ||
2423 | 2432 | ||
2424 | mutex_unlock(&inode->i_mutex); | 2433 | mutex_unlock(&inode->i_mutex); |
2425 | 2434 | ||
@@ -2569,7 +2578,6 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
2569 | * need locks to protect pending reads from racing with truncate. | 2578 | * need locks to protect pending reads from racing with truncate. |
2570 | */ | 2579 | */ |
2571 | if (filp->f_flags & O_DIRECT) { | 2580 | if (filp->f_flags & O_DIRECT) { |
2572 | down_read(&inode->i_alloc_sem); | ||
2573 | have_alloc_sem = 1; | 2581 | have_alloc_sem = 1; |
2574 | ocfs2_iocb_set_sem_locked(iocb); | 2582 | ocfs2_iocb_set_sem_locked(iocb); |
2575 | 2583 | ||
@@ -2612,16 +2620,66 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
2612 | } | 2620 | } |
2613 | 2621 | ||
2614 | bail: | 2622 | bail: |
2615 | if (have_alloc_sem) { | 2623 | if (have_alloc_sem) |
2616 | up_read(&inode->i_alloc_sem); | ||
2617 | ocfs2_iocb_clear_sem_locked(iocb); | 2624 | ocfs2_iocb_clear_sem_locked(iocb); |
2618 | } | 2625 | |
2619 | if (rw_level != -1) | 2626 | if (rw_level != -1) |
2620 | ocfs2_rw_unlock(inode, rw_level); | 2627 | ocfs2_rw_unlock(inode, rw_level); |
2621 | 2628 | ||
2622 | return ret; | 2629 | return ret; |
2623 | } | 2630 | } |
2624 | 2631 | ||
2632 | /* Refer generic_file_llseek_unlocked() */ | ||
2633 | static loff_t ocfs2_file_llseek(struct file *file, loff_t offset, int origin) | ||
2634 | { | ||
2635 | struct inode *inode = file->f_mapping->host; | ||
2636 | int ret = 0; | ||
2637 | |||
2638 | mutex_lock(&inode->i_mutex); | ||
2639 | |||
2640 | switch (origin) { | ||
2641 | case SEEK_SET: | ||
2642 | break; | ||
2643 | case SEEK_END: | ||
2644 | offset += inode->i_size; | ||
2645 | break; | ||
2646 | case SEEK_CUR: | ||
2647 | if (offset == 0) { | ||
2648 | offset = file->f_pos; | ||
2649 | goto out; | ||
2650 | } | ||
2651 | offset += file->f_pos; | ||
2652 | break; | ||
2653 | case SEEK_DATA: | ||
2654 | case SEEK_HOLE: | ||
2655 | ret = ocfs2_seek_data_hole_offset(file, &offset, origin); | ||
2656 | if (ret) | ||
2657 | goto out; | ||
2658 | break; | ||
2659 | default: | ||
2660 | ret = -EINVAL; | ||
2661 | goto out; | ||
2662 | } | ||
2663 | |||
2664 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) | ||
2665 | ret = -EINVAL; | ||
2666 | if (!ret && offset > inode->i_sb->s_maxbytes) | ||
2667 | ret = -EINVAL; | ||
2668 | if (ret) | ||
2669 | goto out; | ||
2670 | |||
2671 | if (offset != file->f_pos) { | ||
2672 | file->f_pos = offset; | ||
2673 | file->f_version = 0; | ||
2674 | } | ||
2675 | |||
2676 | out: | ||
2677 | mutex_unlock(&inode->i_mutex); | ||
2678 | if (ret) | ||
2679 | return ret; | ||
2680 | return offset; | ||
2681 | } | ||
2682 | |||
2625 | const struct inode_operations ocfs2_file_iops = { | 2683 | const struct inode_operations ocfs2_file_iops = { |
2626 | .setattr = ocfs2_setattr, | 2684 | .setattr = ocfs2_setattr, |
2627 | .getattr = ocfs2_getattr, | 2685 | .getattr = ocfs2_getattr, |
@@ -2631,12 +2689,14 @@ const struct inode_operations ocfs2_file_iops = { | |||
2631 | .listxattr = ocfs2_listxattr, | 2689 | .listxattr = ocfs2_listxattr, |
2632 | .removexattr = generic_removexattr, | 2690 | .removexattr = generic_removexattr, |
2633 | .fiemap = ocfs2_fiemap, | 2691 | .fiemap = ocfs2_fiemap, |
2692 | .check_acl = ocfs2_check_acl, | ||
2634 | }; | 2693 | }; |
2635 | 2694 | ||
2636 | const struct inode_operations ocfs2_special_file_iops = { | 2695 | const struct inode_operations ocfs2_special_file_iops = { |
2637 | .setattr = ocfs2_setattr, | 2696 | .setattr = ocfs2_setattr, |
2638 | .getattr = ocfs2_getattr, | 2697 | .getattr = ocfs2_getattr, |
2639 | .permission = ocfs2_permission, | 2698 | .permission = ocfs2_permission, |
2699 | .check_acl = ocfs2_check_acl, | ||
2640 | }; | 2700 | }; |
2641 | 2701 | ||
2642 | /* | 2702 | /* |
@@ -2644,7 +2704,7 @@ const struct inode_operations ocfs2_special_file_iops = { | |||
2644 | * ocfs2_fops_no_plocks and ocfs2_dops_no_plocks! | 2704 | * ocfs2_fops_no_plocks and ocfs2_dops_no_plocks! |
2645 | */ | 2705 | */ |
2646 | const struct file_operations ocfs2_fops = { | 2706 | const struct file_operations ocfs2_fops = { |
2647 | .llseek = generic_file_llseek, | 2707 | .llseek = ocfs2_file_llseek, |
2648 | .read = do_sync_read, | 2708 | .read = do_sync_read, |
2649 | .write = do_sync_write, | 2709 | .write = do_sync_write, |
2650 | .mmap = ocfs2_mmap, | 2710 | .mmap = ocfs2_mmap, |
@@ -2692,7 +2752,7 @@ const struct file_operations ocfs2_dops = { | |||
2692 | * the cluster. | 2752 | * the cluster. |
2693 | */ | 2753 | */ |
2694 | const struct file_operations ocfs2_fops_no_plocks = { | 2754 | const struct file_operations ocfs2_fops_no_plocks = { |
2695 | .llseek = generic_file_llseek, | 2755 | .llseek = ocfs2_file_llseek, |
2696 | .read = do_sync_read, | 2756 | .read = do_sync_read, |
2697 | .write = do_sync_write, | 2757 | .write = do_sync_write, |
2698 | .mmap = ocfs2_mmap, | 2758 | .mmap = ocfs2_mmap, |