aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/file.c
diff options
context:
space:
mode:
authorJoel Becker <jlbec@evilplan.org>2011-08-22 00:02:57 -0400
committerJoel Becker <jlbec@evilplan.org>2011-08-22 00:02:57 -0400
commit99b1bb61b225c3eb4d3b196d4f1d041695b19a7e (patch)
tree06cabdc34538f3b38a39e3b802ecc1a2ab2aae00 /fs/ocfs2/file.c
parentc7e25e6e0b0486492c5faaf6312b37413642c48e (diff)
parent93862d5e1ab875664c6cc95254fc365028a48bb1 (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.c96
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
174static int ocfs2_sync_file(struct file *file, int datasync) 174static 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)
200bail: 211bail:
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
1282int ocfs2_permission(struct inode *inode, int mask, unsigned int flags) 1296int 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);
1299out: 1313out:
@@ -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
2256relock: 2270relock:
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
2418out_sems: 2429out_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
2614bail: 2622bail:
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() */
2633static 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
2676out:
2677 mutex_unlock(&inode->i_mutex);
2678 if (ret)
2679 return ret;
2680 return offset;
2681}
2682
2625const struct inode_operations ocfs2_file_iops = { 2683const 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
2636const struct inode_operations ocfs2_special_file_iops = { 2695const 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 */
2646const struct file_operations ocfs2_fops = { 2706const 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 */
2694const struct file_operations ocfs2_fops_no_plocks = { 2754const 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,