diff options
| -rw-r--r-- | fs/ocfs2/aops.c | 24 | ||||
| -rw-r--r-- | fs/ocfs2/cluster/heartbeat.c | 17 | ||||
| -rw-r--r-- | fs/ocfs2/dlmglue.c | 10 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 13 |
4 files changed, 54 insertions, 10 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index ef6cd30108a9..93628b02ef5d 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
| @@ -540,8 +540,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock, | |||
| 540 | struct buffer_head *bh_result, int create) | 540 | struct buffer_head *bh_result, int create) |
| 541 | { | 541 | { |
| 542 | int ret; | 542 | int ret; |
| 543 | u64 vbo_max; /* file offset, max_blocks from iblock */ | 543 | u64 p_blkno, inode_blocks; |
| 544 | u64 p_blkno; | ||
| 545 | int contig_blocks; | 544 | int contig_blocks; |
| 546 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; | 545 | unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits; |
| 547 | unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; | 546 | unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; |
| @@ -550,12 +549,23 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock, | |||
| 550 | * nicely aligned and of the right size, so there's no need | 549 | * nicely aligned and of the right size, so there's no need |
| 551 | * for us to check any of that. */ | 550 | * for us to check any of that. */ |
| 552 | 551 | ||
| 553 | vbo_max = ((u64)iblock + max_blocks) << blocksize_bits; | ||
| 554 | |||
| 555 | spin_lock(&OCFS2_I(inode)->ip_lock); | 552 | spin_lock(&OCFS2_I(inode)->ip_lock); |
| 556 | if ((iblock + max_blocks) > | 553 | inode_blocks = ocfs2_clusters_to_blocks(inode->i_sb, |
| 557 | ocfs2_clusters_to_blocks(inode->i_sb, | 554 | OCFS2_I(inode)->ip_clusters); |
| 558 | OCFS2_I(inode)->ip_clusters)) { | 555 | |
| 556 | /* | ||
| 557 | * For a read which begins past the end of file, we return a hole. | ||
| 558 | */ | ||
| 559 | if (!create && (iblock >= inode_blocks)) { | ||
| 560 | spin_unlock(&OCFS2_I(inode)->ip_lock); | ||
| 561 | ret = 0; | ||
| 562 | goto bail; | ||
| 563 | } | ||
| 564 | |||
| 565 | /* | ||
| 566 | * Any write past EOF is not allowed because we'd be extending. | ||
| 567 | */ | ||
| 568 | if (create && (iblock + max_blocks) > inode_blocks) { | ||
| 559 | spin_unlock(&OCFS2_I(inode)->ip_lock); | 569 | spin_unlock(&OCFS2_I(inode)->ip_lock); |
| 560 | ret = -EIO; | 570 | ret = -EIO; |
| 561 | goto bail; | 571 | goto bail; |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index a25ef5a50386..277ca67a2ad6 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
| @@ -1447,6 +1447,15 @@ out: | |||
| 1447 | return ret; | 1447 | return ret; |
| 1448 | } | 1448 | } |
| 1449 | 1449 | ||
| 1450 | static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, | ||
| 1451 | char *page) | ||
| 1452 | { | ||
| 1453 | if (!reg->hr_task) | ||
| 1454 | return 0; | ||
| 1455 | |||
| 1456 | return sprintf(page, "%u\n", reg->hr_task->pid); | ||
| 1457 | } | ||
| 1458 | |||
| 1450 | struct o2hb_region_attribute { | 1459 | struct o2hb_region_attribute { |
| 1451 | struct configfs_attribute attr; | 1460 | struct configfs_attribute attr; |
| 1452 | ssize_t (*show)(struct o2hb_region *, char *); | 1461 | ssize_t (*show)(struct o2hb_region *, char *); |
| @@ -1485,11 +1494,19 @@ static struct o2hb_region_attribute o2hb_region_attr_dev = { | |||
| 1485 | .store = o2hb_region_dev_write, | 1494 | .store = o2hb_region_dev_write, |
| 1486 | }; | 1495 | }; |
| 1487 | 1496 | ||
| 1497 | static struct o2hb_region_attribute o2hb_region_attr_pid = { | ||
| 1498 | .attr = { .ca_owner = THIS_MODULE, | ||
| 1499 | .ca_name = "pid", | ||
| 1500 | .ca_mode = S_IRUGO | S_IRUSR }, | ||
| 1501 | .show = o2hb_region_pid_read, | ||
| 1502 | }; | ||
| 1503 | |||
| 1488 | static struct configfs_attribute *o2hb_region_attrs[] = { | 1504 | static struct configfs_attribute *o2hb_region_attrs[] = { |
| 1489 | &o2hb_region_attr_block_bytes.attr, | 1505 | &o2hb_region_attr_block_bytes.attr, |
| 1490 | &o2hb_region_attr_start_block.attr, | 1506 | &o2hb_region_attr_start_block.attr, |
| 1491 | &o2hb_region_attr_blocks.attr, | 1507 | &o2hb_region_attr_blocks.attr, |
| 1492 | &o2hb_region_attr_dev.attr, | 1508 | &o2hb_region_attr_dev.attr, |
| 1509 | &o2hb_region_attr_pid.attr, | ||
| 1493 | NULL, | 1510 | NULL, |
| 1494 | }; | 1511 | }; |
| 1495 | 1512 | ||
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index e6220137bf69..e335541727f9 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
| @@ -2718,6 +2718,15 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres, | |||
| 2718 | inode = ocfs2_lock_res_inode(lockres); | 2718 | inode = ocfs2_lock_res_inode(lockres); |
| 2719 | mapping = inode->i_mapping; | 2719 | mapping = inode->i_mapping; |
| 2720 | 2720 | ||
| 2721 | /* | ||
| 2722 | * We need this before the filemap_fdatawrite() so that it can | ||
| 2723 | * transfer the dirty bit from the PTE to the | ||
| 2724 | * page. Unfortunately this means that even for EX->PR | ||
| 2725 | * downconverts, we'll lose our mappings and have to build | ||
| 2726 | * them up again. | ||
| 2727 | */ | ||
| 2728 | unmap_mapping_range(mapping, 0, 0, 0); | ||
| 2729 | |||
| 2721 | if (filemap_fdatawrite(mapping)) { | 2730 | if (filemap_fdatawrite(mapping)) { |
| 2722 | mlog(ML_ERROR, "Could not sync inode %llu for downconvert!", | 2731 | mlog(ML_ERROR, "Could not sync inode %llu for downconvert!", |
| 2723 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | 2732 | (unsigned long long)OCFS2_I(inode)->ip_blkno); |
| @@ -2725,7 +2734,6 @@ static int ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres, | |||
| 2725 | sync_mapping_buffers(mapping); | 2734 | sync_mapping_buffers(mapping); |
| 2726 | if (blocking == LKM_EXMODE) { | 2735 | if (blocking == LKM_EXMODE) { |
| 2727 | truncate_inode_pages(mapping, 0); | 2736 | truncate_inode_pages(mapping, 0); |
| 2728 | unmap_mapping_range(mapping, 0, 0, 0); | ||
| 2729 | } else { | 2737 | } else { |
| 2730 | /* We only need to wait on the I/O if we're not also | 2738 | /* We only need to wait on the I/O if we're not also |
| 2731 | * truncating pages because truncate_inode_pages waits | 2739 | * truncating pages because truncate_inode_pages waits |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 9fd590b9bde3..10953a508f2f 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -149,6 +149,17 @@ int ocfs2_should_update_atime(struct inode *inode, | |||
| 149 | ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))) | 149 | ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))) |
| 150 | return 0; | 150 | return 0; |
| 151 | 151 | ||
| 152 | /* | ||
| 153 | * We can be called with no vfsmnt structure - NFSD will | ||
| 154 | * sometimes do this. | ||
| 155 | * | ||
| 156 | * Note that our action here is different than touch_atime() - | ||
| 157 | * if we can't tell whether this is a noatime mount, then we | ||
| 158 | * don't know whether to trust the value of s_atime_quantum. | ||
| 159 | */ | ||
| 160 | if (vfsmnt == NULL) | ||
| 161 | return 0; | ||
| 162 | |||
| 152 | if ((vfsmnt->mnt_flags & MNT_NOATIME) || | 163 | if ((vfsmnt->mnt_flags & MNT_NOATIME) || |
| 153 | ((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) | 164 | ((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) |
| 154 | return 0; | 165 | return 0; |
| @@ -966,8 +977,6 @@ int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 966 | } | 977 | } |
| 967 | 978 | ||
| 968 | ret = generic_permission(inode, mask, NULL); | 979 | ret = generic_permission(inode, mask, NULL); |
| 969 | if (ret) | ||
| 970 | mlog_errno(ret); | ||
| 971 | 980 | ||
| 972 | ocfs2_meta_unlock(inode, 0); | 981 | ocfs2_meta_unlock(inode, 0); |
| 973 | out: | 982 | out: |
