aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r--fs/ocfs2/file.c99
1 files changed, 93 insertions, 6 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 781ba6c4ef85..a62b14eb4065 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -397,6 +397,15 @@ static int ocfs2_truncate_file(struct inode *inode,
397 unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); 397 unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1);
398 truncate_inode_pages(inode->i_mapping, new_i_size); 398 truncate_inode_pages(inode->i_mapping, new_i_size);
399 399
400 if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
401 status = ocfs2_truncate_inline(inode, di_bh, new_i_size,
402 i_size_read(inode), 0);
403 if (status)
404 mlog_errno(status);
405
406 goto bail_unlock_data;
407 }
408
400 /* alright, we're going to need to do a full blown alloc size 409 /* alright, we're going to need to do a full blown alloc size
401 * change. Orphan the inode so that recovery can complete the 410 * change. Orphan the inode so that recovery can complete the
402 * truncate if necessary. This does the task of marking 411 * truncate if necessary. This does the task of marking
@@ -908,7 +917,8 @@ static int ocfs2_extend_file(struct inode *inode,
908 struct buffer_head *di_bh, 917 struct buffer_head *di_bh,
909 u64 new_i_size) 918 u64 new_i_size)
910{ 919{
911 int ret = 0; 920 int ret = 0, data_locked = 0;
921 struct ocfs2_inode_info *oi = OCFS2_I(inode);
912 922
913 BUG_ON(!di_bh); 923 BUG_ON(!di_bh);
914 924
@@ -920,7 +930,17 @@ static int ocfs2_extend_file(struct inode *inode,
920 goto out; 930 goto out;
921 BUG_ON(new_i_size < i_size_read(inode)); 931 BUG_ON(new_i_size < i_size_read(inode));
922 932
923 if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) 933 /*
934 * Fall through for converting inline data, even if the fs
935 * supports sparse files.
936 *
937 * The check for inline data here is legal - nobody can add
938 * the feature since we have i_mutex. We must check it again
939 * after acquiring ip_alloc_sem though, as paths like mmap
940 * might have raced us to converting the inode to extents.
941 */
942 if (!(oi->ip_dyn_features & OCFS2_INLINE_DATA_FL)
943 && ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
924 goto out_update_size; 944 goto out_update_size;
925 945
926 /* 946 /*
@@ -935,6 +955,7 @@ static int ocfs2_extend_file(struct inode *inode,
935 mlog_errno(ret); 955 mlog_errno(ret);
936 goto out; 956 goto out;
937 } 957 }
958 data_locked = 1;
938 959
939 /* 960 /*
940 * The alloc sem blocks people in read/write from reading our 961 * The alloc sem blocks people in read/write from reading our
@@ -942,9 +963,31 @@ static int ocfs2_extend_file(struct inode *inode,
942 * i_mutex to block other extend/truncate calls while we're 963 * i_mutex to block other extend/truncate calls while we're
943 * here. 964 * here.
944 */ 965 */
945 down_write(&OCFS2_I(inode)->ip_alloc_sem); 966 down_write(&oi->ip_alloc_sem);
946 ret = ocfs2_extend_no_holes(inode, new_i_size, new_i_size); 967
947 up_write(&OCFS2_I(inode)->ip_alloc_sem); 968 if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
969 /*
970 * We can optimize small extends by keeping the inodes
971 * inline data.
972 */
973 if (ocfs2_size_fits_inline_data(di_bh, new_i_size)) {
974 up_write(&oi->ip_alloc_sem);
975 goto out_update_size;
976 }
977
978 ret = ocfs2_convert_inline_data_to_extents(inode, di_bh);
979 if (ret) {
980 up_write(&oi->ip_alloc_sem);
981
982 mlog_errno(ret);
983 goto out_unlock;
984 }
985 }
986
987 if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
988 ret = ocfs2_extend_no_holes(inode, new_i_size, new_i_size);
989
990 up_write(&oi->ip_alloc_sem);
948 991
949 if (ret < 0) { 992 if (ret < 0) {
950 mlog_errno(ret); 993 mlog_errno(ret);
@@ -957,7 +1000,7 @@ out_update_size:
957 mlog_errno(ret); 1000 mlog_errno(ret);
958 1001
959out_unlock: 1002out_unlock:
960 if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) 1003 if (data_locked)
961 ocfs2_data_unlock(inode, 1); 1004 ocfs2_data_unlock(inode, 1);
962 1005
963out: 1006out:
@@ -1231,6 +1274,31 @@ static int ocfs2_allocate_unwritten_extents(struct inode *inode,
1231{ 1274{
1232 int ret; 1275 int ret;
1233 u32 cpos, phys_cpos, clusters, alloc_size; 1276 u32 cpos, phys_cpos, clusters, alloc_size;
1277 u64 end = start + len;
1278 struct buffer_head *di_bh = NULL;
1279
1280 if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
1281 ret = ocfs2_read_block(OCFS2_SB(inode->i_sb),
1282 OCFS2_I(inode)->ip_blkno, &di_bh,
1283 OCFS2_BH_CACHED, inode);
1284 if (ret) {
1285 mlog_errno(ret);
1286 goto out;
1287 }
1288
1289 /*
1290 * Nothing to do if the requested reservation range
1291 * fits within the inode.
1292 */
1293 if (ocfs2_size_fits_inline_data(di_bh, end))
1294 goto out;
1295
1296 ret = ocfs2_convert_inline_data_to_extents(inode, di_bh);
1297 if (ret) {
1298 mlog_errno(ret);
1299 goto out;
1300 }
1301 }
1234 1302
1235 /* 1303 /*
1236 * We consider both start and len to be inclusive. 1304 * We consider both start and len to be inclusive.
@@ -1276,6 +1344,8 @@ next:
1276 1344
1277 ret = 0; 1345 ret = 0;
1278out: 1346out:
1347
1348 brelse(di_bh);
1279 return ret; 1349 return ret;
1280} 1350}
1281 1351
@@ -1457,6 +1527,14 @@ static int ocfs2_remove_inode_range(struct inode *inode,
1457 if (byte_len == 0) 1527 if (byte_len == 0)
1458 return 0; 1528 return 0;
1459 1529
1530 if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
1531 ret = ocfs2_truncate_inline(inode, di_bh, byte_start,
1532 byte_start + byte_len, 1);
1533 if (ret)
1534 mlog_errno(ret);
1535 return ret;
1536 }
1537
1460 trunc_start = ocfs2_clusters_for_bytes(osb->sb, byte_start); 1538 trunc_start = ocfs2_clusters_for_bytes(osb->sb, byte_start);
1461 trunc_len = (byte_start + byte_len) >> osb->s_clustersize_bits; 1539 trunc_len = (byte_start + byte_len) >> osb->s_clustersize_bits;
1462 if (trunc_len >= trunc_start) 1540 if (trunc_len >= trunc_start)
@@ -1759,6 +1837,15 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
1759 break; 1837 break;
1760 1838
1761 /* 1839 /*
1840 * There's no sane way to do direct writes to an inode
1841 * with inline data.
1842 */
1843 if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
1844 *direct_io = 0;
1845 break;
1846 }
1847
1848 /*
1762 * Allowing concurrent direct writes means 1849 * Allowing concurrent direct writes means
1763 * i_size changes wouldn't be synchronized, so 1850 * i_size changes wouldn't be synchronized, so
1764 * one node could wind up truncating another 1851 * one node could wind up truncating another