aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap_util.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-08-12 06:49:45 -0400
committerBen Myers <bpm@sgi.com>2013-08-12 17:53:39 -0400
commitc24b5dfadc4a4f7a13af373067871479c74455e6 (patch)
treeb723f9218cf1d6d7e73ea4241869ad1905798c36 /fs/xfs/xfs_bmap_util.c
parent836a94ad59bf6c1bcea0fdbe945540926fa3ca8b (diff)
xfs: kill xfs_vnodeops.[ch]
Now we have xfs_inode.c for holding kernel-only XFS inode operations, move all the inode operations from xfs_vnodeops.c to this new file as it holds another set of kernel-only inode operations. The name of this file traces back to the days of Irix and it's vnodes which we don't have anymore. Essentially this move consolidates the inode locking functions and a bunch of XFS inode operations into the one file. Eventually the high level functions will be merged into the VFS interface functions in xfs_iops.c. This leaves only internal preallocation, EOF block manipulation and hole punching functions in vnodeops.c. Move these to xfs_bmap_util.c where we are already consolidating various in-kernel physical extent manipulation and querying functions. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_bmap_util.c')
-rw-r--r--fs/xfs/xfs_bmap_util.c861
1 files changed, 861 insertions, 0 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 8e48ddf1c11c..f557022bd0e7 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2000-2006 Silicon Graphics, Inc. 2 * Copyright (c) 2000-2006 Silicon Graphics, Inc.
3 * Copyright (c) 2012 Red Hat, Inc.
3 * All Rights Reserved. 4 * All Rights Reserved.
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -41,6 +42,7 @@
41#include "xfs_quota.h" 42#include "xfs_quota.h"
42#include "xfs_trans_space.h" 43#include "xfs_trans_space.h"
43#include "xfs_trace.h" 44#include "xfs_trace.h"
45#include "xfs_icache.h"
44 46
45/* Kernel only BMAP related definitions and functions */ 47/* Kernel only BMAP related definitions and functions */
46 48
@@ -832,3 +834,862 @@ next_block:
832 834
833 return error; 835 return error;
834} 836}
837
838/*
839 * Test whether it is appropriate to check an inode for and free post EOF
840 * blocks. The 'force' parameter determines whether we should also consider
841 * regular files that are marked preallocated or append-only.
842 */
843bool
844xfs_can_free_eofblocks(struct xfs_inode *ip, bool force)
845{
846 /* prealloc/delalloc exists only on regular files */
847 if (!S_ISREG(ip->i_d.di_mode))
848 return false;
849
850 /*
851 * Zero sized files with no cached pages and delalloc blocks will not
852 * have speculative prealloc/delalloc blocks to remove.
853 */
854 if (VFS_I(ip)->i_size == 0 &&
855 VN_CACHED(VFS_I(ip)) == 0 &&
856 ip->i_delayed_blks == 0)
857 return false;
858
859 /* If we haven't read in the extent list, then don't do it now. */
860 if (!(ip->i_df.if_flags & XFS_IFEXTENTS))
861 return false;
862
863 /*
864 * Do not free real preallocated or append-only files unless the file
865 * has delalloc blocks and we are forced to remove them.
866 */
867 if (ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND))
868 if (!force || ip->i_delayed_blks == 0)
869 return false;
870
871 return true;
872}
873
874/*
875 * This is called by xfs_inactive to free any blocks beyond eof
876 * when the link count isn't zero and by xfs_dm_punch_hole() when
877 * punching a hole to EOF.
878 */
879int
880xfs_free_eofblocks(
881 xfs_mount_t *mp,
882 xfs_inode_t *ip,
883 bool need_iolock)
884{
885 xfs_trans_t *tp;
886 int error;
887 xfs_fileoff_t end_fsb;
888 xfs_fileoff_t last_fsb;
889 xfs_filblks_t map_len;
890 int nimaps;
891 xfs_bmbt_irec_t imap;
892
893 /*
894 * Figure out if there are any blocks beyond the end
895 * of the file. If not, then there is nothing to do.
896 */
897 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip));
898 last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
899 if (last_fsb <= end_fsb)
900 return 0;
901 map_len = last_fsb - end_fsb;
902
903 nimaps = 1;
904 xfs_ilock(ip, XFS_ILOCK_SHARED);
905 error = xfs_bmapi_read(ip, end_fsb, map_len, &imap, &nimaps, 0);
906 xfs_iunlock(ip, XFS_ILOCK_SHARED);
907
908 if (!error && (nimaps != 0) &&
909 (imap.br_startblock != HOLESTARTBLOCK ||
910 ip->i_delayed_blks)) {
911 /*
912 * Attach the dquots to the inode up front.
913 */
914 error = xfs_qm_dqattach(ip, 0);
915 if (error)
916 return error;
917
918 /*
919 * There are blocks after the end of file.
920 * Free them up now by truncating the file to
921 * its current size.
922 */
923 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
924
925 if (need_iolock) {
926 if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
927 xfs_trans_cancel(tp, 0);
928 return EAGAIN;
929 }
930 }
931
932 error = xfs_trans_reserve(tp, 0,
933 XFS_ITRUNCATE_LOG_RES(mp),
934 0, XFS_TRANS_PERM_LOG_RES,
935 XFS_ITRUNCATE_LOG_COUNT);
936 if (error) {
937 ASSERT(XFS_FORCED_SHUTDOWN(mp));
938 xfs_trans_cancel(tp, 0);
939 if (need_iolock)
940 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
941 return error;
942 }
943
944 xfs_ilock(ip, XFS_ILOCK_EXCL);
945 xfs_trans_ijoin(tp, ip, 0);
946
947 /*
948 * Do not update the on-disk file size. If we update the
949 * on-disk file size and then the system crashes before the
950 * contents of the file are flushed to disk then the files
951 * may be full of holes (ie NULL files bug).
952 */
953 error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK,
954 XFS_ISIZE(ip));
955 if (error) {
956 /*
957 * If we get an error at this point we simply don't
958 * bother truncating the file.
959 */
960 xfs_trans_cancel(tp,
961 (XFS_TRANS_RELEASE_LOG_RES |
962 XFS_TRANS_ABORT));
963 } else {
964 error = xfs_trans_commit(tp,
965 XFS_TRANS_RELEASE_LOG_RES);
966 if (!error)
967 xfs_inode_clear_eofblocks_tag(ip);
968 }
969
970 xfs_iunlock(ip, XFS_ILOCK_EXCL);
971 if (need_iolock)
972 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
973 }
974 return error;
975}
976
977/*
978 * xfs_alloc_file_space()
979 * This routine allocates disk space for the given file.
980 *
981 * If alloc_type == 0, this request is for an ALLOCSP type
982 * request which will change the file size. In this case, no
983 * DMAPI event will be generated by the call. A TRUNCATE event
984 * will be generated later by xfs_setattr.
985 *
986 * If alloc_type != 0, this request is for a RESVSP type
987 * request, and a DMAPI DM_EVENT_WRITE will be generated if the
988 * lower block boundary byte address is less than the file's
989 * length.
990 *
991 * RETURNS:
992 * 0 on success
993 * errno on error
994 *
995 */
996STATIC int
997xfs_alloc_file_space(
998 xfs_inode_t *ip,
999 xfs_off_t offset,
1000 xfs_off_t len,
1001 int alloc_type,
1002 int attr_flags)
1003{
1004 xfs_mount_t *mp = ip->i_mount;
1005 xfs_off_t count;
1006 xfs_filblks_t allocated_fsb;
1007 xfs_filblks_t allocatesize_fsb;
1008 xfs_extlen_t extsz, temp;
1009 xfs_fileoff_t startoffset_fsb;
1010 xfs_fsblock_t firstfsb;
1011 int nimaps;
1012 int quota_flag;
1013 int rt;
1014 xfs_trans_t *tp;
1015 xfs_bmbt_irec_t imaps[1], *imapp;
1016 xfs_bmap_free_t free_list;
1017 uint qblocks, resblks, resrtextents;
1018 int committed;
1019 int error;
1020
1021 trace_xfs_alloc_file_space(ip);
1022
1023 if (XFS_FORCED_SHUTDOWN(mp))
1024 return XFS_ERROR(EIO);
1025
1026 error = xfs_qm_dqattach(ip, 0);
1027 if (error)
1028 return error;
1029
1030 if (len <= 0)
1031 return XFS_ERROR(EINVAL);
1032
1033 rt = XFS_IS_REALTIME_INODE(ip);
1034 extsz = xfs_get_extsz_hint(ip);
1035
1036 count = len;
1037 imapp = &imaps[0];
1038 nimaps = 1;
1039 startoffset_fsb = XFS_B_TO_FSBT(mp, offset);
1040 allocatesize_fsb = XFS_B_TO_FSB(mp, count);
1041
1042 /*
1043 * Allocate file space until done or until there is an error
1044 */
1045 while (allocatesize_fsb && !error) {
1046 xfs_fileoff_t s, e;
1047
1048 /*
1049 * Determine space reservations for data/realtime.
1050 */
1051 if (unlikely(extsz)) {
1052 s = startoffset_fsb;
1053 do_div(s, extsz);
1054 s *= extsz;
1055 e = startoffset_fsb + allocatesize_fsb;
1056 if ((temp = do_mod(startoffset_fsb, extsz)))
1057 e += temp;
1058 if ((temp = do_mod(e, extsz)))
1059 e += extsz - temp;
1060 } else {
1061 s = 0;
1062 e = allocatesize_fsb;
1063 }
1064
1065 /*
1066 * The transaction reservation is limited to a 32-bit block
1067 * count, hence we need to limit the number of blocks we are
1068 * trying to reserve to avoid an overflow. We can't allocate
1069 * more than @nimaps extents, and an extent is limited on disk
1070 * to MAXEXTLEN (21 bits), so use that to enforce the limit.
1071 */
1072 resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps));
1073 if (unlikely(rt)) {
1074 resrtextents = qblocks = resblks;
1075 resrtextents /= mp->m_sb.sb_rextsize;
1076 resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
1077 quota_flag = XFS_QMOPT_RES_RTBLKS;
1078 } else {
1079 resrtextents = 0;
1080 resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks);
1081 quota_flag = XFS_QMOPT_RES_REGBLKS;
1082 }
1083
1084 /*
1085 * Allocate and setup the transaction.
1086 */
1087 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
1088 error = xfs_trans_reserve(tp, resblks,
1089 XFS_WRITE_LOG_RES(mp), resrtextents,
1090 XFS_TRANS_PERM_LOG_RES,
1091 XFS_WRITE_LOG_COUNT);
1092 /*
1093 * Check for running out of space
1094 */
1095 if (error) {
1096 /*
1097 * Free the transaction structure.
1098 */
1099 ASSERT(error == ENOSPC || XFS_FORCED_SHUTDOWN(mp));
1100 xfs_trans_cancel(tp, 0);
1101 break;
1102 }
1103 xfs_ilock(ip, XFS_ILOCK_EXCL);
1104 error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks,
1105 0, quota_flag);
1106 if (error)
1107 goto error1;
1108
1109 xfs_trans_ijoin(tp, ip, 0);
1110
1111 xfs_bmap_init(&free_list, &firstfsb);
1112 error = xfs_bmapi_write(tp, ip, startoffset_fsb,
1113 allocatesize_fsb, alloc_type, &firstfsb,
1114 0, imapp, &nimaps, &free_list);
1115 if (error) {
1116 goto error0;
1117 }
1118
1119 /*
1120 * Complete the transaction
1121 */
1122 error = xfs_bmap_finish(&tp, &free_list, &committed);
1123 if (error) {
1124 goto error0;
1125 }
1126
1127 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1128 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1129 if (error) {
1130 break;
1131 }
1132
1133 allocated_fsb = imapp->br_blockcount;
1134
1135 if (nimaps == 0) {
1136 error = XFS_ERROR(ENOSPC);
1137 break;
1138 }
1139
1140 startoffset_fsb += allocated_fsb;
1141 allocatesize_fsb -= allocated_fsb;
1142 }
1143
1144 return error;
1145
1146error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
1147 xfs_bmap_cancel(&free_list);
1148 xfs_trans_unreserve_quota_nblks(tp, ip, (long)qblocks, 0, quota_flag);
1149
1150error1: /* Just cancel transaction */
1151 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
1152 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1153 return error;
1154}
1155
1156/*
1157 * Zero file bytes between startoff and endoff inclusive.
1158 * The iolock is held exclusive and no blocks are buffered.
1159 *
1160 * This function is used by xfs_free_file_space() to zero
1161 * partial blocks when the range to free is not block aligned.
1162 * When unreserving space with boundaries that are not block
1163 * aligned we round up the start and round down the end
1164 * boundaries and then use this function to zero the parts of
1165 * the blocks that got dropped during the rounding.
1166 */
1167STATIC int
1168xfs_zero_remaining_bytes(
1169 xfs_inode_t *ip,
1170 xfs_off_t startoff,
1171 xfs_off_t endoff)
1172{
1173 xfs_bmbt_irec_t imap;
1174 xfs_fileoff_t offset_fsb;
1175 xfs_off_t lastoffset;
1176 xfs_off_t offset;
1177 xfs_buf_t *bp;
1178 xfs_mount_t *mp = ip->i_mount;
1179 int nimap;
1180 int error = 0;
1181
1182 /*
1183 * Avoid doing I/O beyond eof - it's not necessary
1184 * since nothing can read beyond eof. The space will
1185 * be zeroed when the file is extended anyway.
1186 */
1187 if (startoff >= XFS_ISIZE(ip))
1188 return 0;
1189
1190 if (endoff > XFS_ISIZE(ip))
1191 endoff = XFS_ISIZE(ip);
1192
1193 bp = xfs_buf_get_uncached(XFS_IS_REALTIME_INODE(ip) ?
1194 mp->m_rtdev_targp : mp->m_ddev_targp,
1195 BTOBB(mp->m_sb.sb_blocksize), 0);
1196 if (!bp)
1197 return XFS_ERROR(ENOMEM);
1198
1199 xfs_buf_unlock(bp);
1200
1201 for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
1202 offset_fsb = XFS_B_TO_FSBT(mp, offset);
1203 nimap = 1;
1204 error = xfs_bmapi_read(ip, offset_fsb, 1, &imap, &nimap, 0);
1205 if (error || nimap < 1)
1206 break;
1207 ASSERT(imap.br_blockcount >= 1);
1208 ASSERT(imap.br_startoff == offset_fsb);
1209 lastoffset = XFS_FSB_TO_B(mp, imap.br_startoff + 1) - 1;
1210 if (lastoffset > endoff)
1211 lastoffset = endoff;
1212 if (imap.br_startblock == HOLESTARTBLOCK)
1213 continue;
1214 ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
1215 if (imap.br_state == XFS_EXT_UNWRITTEN)
1216 continue;
1217 XFS_BUF_UNDONE(bp);
1218 XFS_BUF_UNWRITE(bp);
1219 XFS_BUF_READ(bp);
1220 XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock));
1221 xfsbdstrat(mp, bp);
1222 error = xfs_buf_iowait(bp);
1223 if (error) {
1224 xfs_buf_ioerror_alert(bp,
1225 "xfs_zero_remaining_bytes(read)");
1226 break;
1227 }
1228 memset(bp->b_addr +
1229 (offset - XFS_FSB_TO_B(mp, imap.br_startoff)),
1230 0, lastoffset - offset + 1);
1231 XFS_BUF_UNDONE(bp);
1232 XFS_BUF_UNREAD(bp);
1233 XFS_BUF_WRITE(bp);
1234 xfsbdstrat(mp, bp);
1235 error = xfs_buf_iowait(bp);
1236 if (error) {
1237 xfs_buf_ioerror_alert(bp,
1238 "xfs_zero_remaining_bytes(write)");
1239 break;
1240 }
1241 }
1242 xfs_buf_free(bp);
1243 return error;
1244}
1245
1246/*
1247 * xfs_free_file_space()
1248 * This routine frees disk space for the given file.
1249 *
1250 * This routine is only called by xfs_change_file_space
1251 * for an UNRESVSP type call.
1252 *
1253 * RETURNS:
1254 * 0 on success
1255 * errno on error
1256 *
1257 */
1258STATIC int
1259xfs_free_file_space(
1260 xfs_inode_t *ip,
1261 xfs_off_t offset,
1262 xfs_off_t len,
1263 int attr_flags)
1264{
1265 int committed;
1266 int done;
1267 xfs_fileoff_t endoffset_fsb;
1268 int error;
1269 xfs_fsblock_t firstfsb;
1270 xfs_bmap_free_t free_list;
1271 xfs_bmbt_irec_t imap;
1272 xfs_off_t ioffset;
1273 xfs_extlen_t mod=0;
1274 xfs_mount_t *mp;
1275 int nimap;
1276 uint resblks;
1277 xfs_off_t rounding;
1278 int rt;
1279 xfs_fileoff_t startoffset_fsb;
1280 xfs_trans_t *tp;
1281 int need_iolock = 1;
1282
1283 mp = ip->i_mount;
1284
1285 trace_xfs_free_file_space(ip);
1286
1287 error = xfs_qm_dqattach(ip, 0);
1288 if (error)
1289 return error;
1290
1291 error = 0;
1292 if (len <= 0) /* if nothing being freed */
1293 return error;
1294 rt = XFS_IS_REALTIME_INODE(ip);
1295 startoffset_fsb = XFS_B_TO_FSB(mp, offset);
1296 endoffset_fsb = XFS_B_TO_FSBT(mp, offset + len);
1297
1298 if (attr_flags & XFS_ATTR_NOLOCK)
1299 need_iolock = 0;
1300 if (need_iolock) {
1301 xfs_ilock(ip, XFS_IOLOCK_EXCL);
1302 /* wait for the completion of any pending DIOs */
1303 inode_dio_wait(VFS_I(ip));
1304 }
1305
1306 rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
1307 ioffset = offset & ~(rounding - 1);
1308 error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
1309 ioffset, -1);
1310 if (error)
1311 goto out_unlock_iolock;
1312 truncate_pagecache_range(VFS_I(ip), ioffset, -1);
1313
1314 /*
1315 * Need to zero the stuff we're not freeing, on disk.
1316 * If it's a realtime file & can't use unwritten extents then we
1317 * actually need to zero the extent edges. Otherwise xfs_bunmapi
1318 * will take care of it for us.
1319 */
1320 if (rt && !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
1321 nimap = 1;
1322 error = xfs_bmapi_read(ip, startoffset_fsb, 1,
1323 &imap, &nimap, 0);
1324 if (error)
1325 goto out_unlock_iolock;
1326 ASSERT(nimap == 0 || nimap == 1);
1327 if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
1328 xfs_daddr_t block;
1329
1330 ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
1331 block = imap.br_startblock;
1332 mod = do_div(block, mp->m_sb.sb_rextsize);
1333 if (mod)
1334 startoffset_fsb += mp->m_sb.sb_rextsize - mod;
1335 }
1336 nimap = 1;
1337 error = xfs_bmapi_read(ip, endoffset_fsb - 1, 1,
1338 &imap, &nimap, 0);
1339 if (error)
1340 goto out_unlock_iolock;
1341 ASSERT(nimap == 0 || nimap == 1);
1342 if (nimap && imap.br_startblock != HOLESTARTBLOCK) {
1343 ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
1344 mod++;
1345 if (mod && (mod != mp->m_sb.sb_rextsize))
1346 endoffset_fsb -= mod;
1347 }
1348 }
1349 if ((done = (endoffset_fsb <= startoffset_fsb)))
1350 /*
1351 * One contiguous piece to clear
1352 */
1353 error = xfs_zero_remaining_bytes(ip, offset, offset + len - 1);
1354 else {
1355 /*
1356 * Some full blocks, possibly two pieces to clear
1357 */
1358 if (offset < XFS_FSB_TO_B(mp, startoffset_fsb))
1359 error = xfs_zero_remaining_bytes(ip, offset,
1360 XFS_FSB_TO_B(mp, startoffset_fsb) - 1);
1361 if (!error &&
1362 XFS_FSB_TO_B(mp, endoffset_fsb) < offset + len)
1363 error = xfs_zero_remaining_bytes(ip,
1364 XFS_FSB_TO_B(mp, endoffset_fsb),
1365 offset + len - 1);
1366 }
1367
1368 /*
1369 * free file space until done or until there is an error
1370 */
1371 resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
1372 while (!error && !done) {
1373
1374 /*
1375 * allocate and setup the transaction. Allow this
1376 * transaction to dip into the reserve blocks to ensure
1377 * the freeing of the space succeeds at ENOSPC.
1378 */
1379 tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT);
1380 tp->t_flags |= XFS_TRANS_RESERVE;
1381 error = xfs_trans_reserve(tp,
1382 resblks,
1383 XFS_WRITE_LOG_RES(mp),
1384 0,
1385 XFS_TRANS_PERM_LOG_RES,
1386 XFS_WRITE_LOG_COUNT);
1387
1388 /*
1389 * check for running out of space
1390 */
1391 if (error) {
1392 /*
1393 * Free the transaction structure.
1394 */
1395 ASSERT(error == ENOSPC || XFS_FORCED_SHUTDOWN(mp));
1396 xfs_trans_cancel(tp, 0);
1397 break;
1398 }
1399 xfs_ilock(ip, XFS_ILOCK_EXCL);
1400 error = xfs_trans_reserve_quota(tp, mp,
1401 ip->i_udquot, ip->i_gdquot, ip->i_pdquot,
1402 resblks, 0, XFS_QMOPT_RES_REGBLKS);
1403 if (error)
1404 goto error1;
1405
1406 xfs_trans_ijoin(tp, ip, 0);
1407
1408 /*
1409 * issue the bunmapi() call to free the blocks
1410 */
1411 xfs_bmap_init(&free_list, &firstfsb);
1412 error = xfs_bunmapi(tp, ip, startoffset_fsb,
1413 endoffset_fsb - startoffset_fsb,
1414 0, 2, &firstfsb, &free_list, &done);
1415 if (error) {
1416 goto error0;
1417 }
1418
1419 /*
1420 * complete the transaction
1421 */
1422 error = xfs_bmap_finish(&tp, &free_list, &committed);
1423 if (error) {
1424 goto error0;
1425 }
1426
1427 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1428 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1429 }
1430
1431 out_unlock_iolock:
1432 if (need_iolock)
1433 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1434 return error;
1435
1436 error0:
1437 xfs_bmap_cancel(&free_list);
1438 error1:
1439 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
1440 xfs_iunlock(ip, need_iolock ? (XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL) :
1441 XFS_ILOCK_EXCL);
1442 return error;
1443}
1444
1445
1446STATIC int
1447xfs_zero_file_space(
1448 struct xfs_inode *ip,
1449 xfs_off_t offset,
1450 xfs_off_t len,
1451 int attr_flags)
1452{
1453 struct xfs_mount *mp = ip->i_mount;
1454 uint granularity;
1455 xfs_off_t start_boundary;
1456 xfs_off_t end_boundary;
1457 int error;
1458
1459 granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
1460
1461 /*
1462 * Round the range of extents we are going to convert inwards. If the
1463 * offset is aligned, then it doesn't get changed so we zero from the
1464 * start of the block offset points to.
1465 */
1466 start_boundary = round_up(offset, granularity);
1467 end_boundary = round_down(offset + len, granularity);
1468
1469 ASSERT(start_boundary >= offset);
1470 ASSERT(end_boundary <= offset + len);
1471
1472 if (!(attr_flags & XFS_ATTR_NOLOCK))
1473 xfs_ilock(ip, XFS_IOLOCK_EXCL);
1474
1475 if (start_boundary < end_boundary - 1) {
1476 /* punch out the page cache over the conversion range */
1477 truncate_pagecache_range(VFS_I(ip), start_boundary,
1478 end_boundary - 1);
1479 /* convert the blocks */
1480 error = xfs_alloc_file_space(ip, start_boundary,
1481 end_boundary - start_boundary - 1,
1482 XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT,
1483 attr_flags);
1484 if (error)
1485 goto out_unlock;
1486
1487 /* We've handled the interior of the range, now for the edges */
1488 if (start_boundary != offset)
1489 error = xfs_iozero(ip, offset, start_boundary - offset);
1490 if (error)
1491 goto out_unlock;
1492
1493 if (end_boundary != offset + len)
1494 error = xfs_iozero(ip, end_boundary,
1495 offset + len - end_boundary);
1496
1497 } else {
1498 /*
1499 * It's either a sub-granularity range or the range spanned lies
1500 * partially across two adjacent blocks.
1501 */
1502 error = xfs_iozero(ip, offset, len);
1503 }
1504
1505out_unlock:
1506 if (!(attr_flags & XFS_ATTR_NOLOCK))
1507 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1508 return error;
1509
1510}
1511
1512/*
1513 * xfs_change_file_space()
1514 * This routine allocates or frees disk space for the given file.
1515 * The user specified parameters are checked for alignment and size
1516 * limitations.
1517 *
1518 * RETURNS:
1519 * 0 on success
1520 * errno on error
1521 *
1522 */
1523int
1524xfs_change_file_space(
1525 xfs_inode_t *ip,
1526 int cmd,
1527 xfs_flock64_t *bf,
1528 xfs_off_t offset,
1529 int attr_flags)
1530{
1531 xfs_mount_t *mp = ip->i_mount;
1532 int clrprealloc;
1533 int error;
1534 xfs_fsize_t fsize;
1535 int setprealloc;
1536 xfs_off_t startoffset;
1537 xfs_trans_t *tp;
1538 struct iattr iattr;
1539
1540 if (!S_ISREG(ip->i_d.di_mode))
1541 return XFS_ERROR(EINVAL);
1542
1543 switch (bf->l_whence) {
1544 case 0: /*SEEK_SET*/
1545 break;
1546 case 1: /*SEEK_CUR*/
1547 bf->l_start += offset;
1548 break;
1549 case 2: /*SEEK_END*/
1550 bf->l_start += XFS_ISIZE(ip);
1551 break;
1552 default:
1553 return XFS_ERROR(EINVAL);
1554 }
1555
1556 /*
1557 * length of <= 0 for resv/unresv/zero is invalid. length for
1558 * alloc/free is ignored completely and we have no idea what userspace
1559 * might have set it to, so set it to zero to allow range
1560 * checks to pass.
1561 */
1562 switch (cmd) {
1563 case XFS_IOC_ZERO_RANGE:
1564 case XFS_IOC_RESVSP:
1565 case XFS_IOC_RESVSP64:
1566 case XFS_IOC_UNRESVSP:
1567 case XFS_IOC_UNRESVSP64:
1568 if (bf->l_len <= 0)
1569 return XFS_ERROR(EINVAL);
1570 break;
1571 default:
1572 bf->l_len = 0;
1573 break;
1574 }
1575
1576 if (bf->l_start < 0 ||
1577 bf->l_start > mp->m_super->s_maxbytes ||
1578 bf->l_start + bf->l_len < 0 ||
1579 bf->l_start + bf->l_len >= mp->m_super->s_maxbytes)
1580 return XFS_ERROR(EINVAL);
1581
1582 bf->l_whence = 0;
1583
1584 startoffset = bf->l_start;
1585 fsize = XFS_ISIZE(ip);
1586
1587 setprealloc = clrprealloc = 0;
1588 switch (cmd) {
1589 case XFS_IOC_ZERO_RANGE:
1590 error = xfs_zero_file_space(ip, startoffset, bf->l_len,
1591 attr_flags);
1592 if (error)
1593 return error;
1594 setprealloc = 1;
1595 break;
1596
1597 case XFS_IOC_RESVSP:
1598 case XFS_IOC_RESVSP64:
1599 error = xfs_alloc_file_space(ip, startoffset, bf->l_len,
1600 XFS_BMAPI_PREALLOC, attr_flags);
1601 if (error)
1602 return error;
1603 setprealloc = 1;
1604 break;
1605
1606 case XFS_IOC_UNRESVSP:
1607 case XFS_IOC_UNRESVSP64:
1608 if ((error = xfs_free_file_space(ip, startoffset, bf->l_len,
1609 attr_flags)))
1610 return error;
1611 break;
1612
1613 case XFS_IOC_ALLOCSP:
1614 case XFS_IOC_ALLOCSP64:
1615 case XFS_IOC_FREESP:
1616 case XFS_IOC_FREESP64:
1617 /*
1618 * These operations actually do IO when extending the file, but
1619 * the allocation is done seperately to the zeroing that is
1620 * done. This set of operations need to be serialised against
1621 * other IO operations, such as truncate and buffered IO. We
1622 * need to take the IOLOCK here to serialise the allocation and
1623 * zeroing IO to prevent other IOLOCK holders (e.g. getbmap,
1624 * truncate, direct IO) from racing against the transient
1625 * allocated but not written state we can have here.
1626 */
1627 xfs_ilock(ip, XFS_IOLOCK_EXCL);
1628 if (startoffset > fsize) {
1629 error = xfs_alloc_file_space(ip, fsize,
1630 startoffset - fsize, 0,
1631 attr_flags | XFS_ATTR_NOLOCK);
1632 if (error) {
1633 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1634 break;
1635 }
1636 }
1637
1638 iattr.ia_valid = ATTR_SIZE;
1639 iattr.ia_size = startoffset;
1640
1641 error = xfs_setattr_size(ip, &iattr,
1642 attr_flags | XFS_ATTR_NOLOCK);
1643 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1644
1645 if (error)
1646 return error;
1647
1648 clrprealloc = 1;
1649 break;
1650
1651 default:
1652 ASSERT(0);
1653 return XFS_ERROR(EINVAL);
1654 }
1655
1656 /*
1657 * update the inode timestamp, mode, and prealloc flag bits
1658 */
1659 tp = xfs_trans_alloc(mp, XFS_TRANS_WRITEID);
1660
1661 if ((error = xfs_trans_reserve(tp, 0, XFS_WRITEID_LOG_RES(mp),
1662 0, 0, 0))) {
1663 /* ASSERT(0); */
1664 xfs_trans_cancel(tp, 0);
1665 return error;
1666 }
1667
1668 xfs_ilock(ip, XFS_ILOCK_EXCL);
1669 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1670
1671 if ((attr_flags & XFS_ATTR_DMI) == 0) {
1672 ip->i_d.di_mode &= ~S_ISUID;
1673
1674 /*
1675 * Note that we don't have to worry about mandatory
1676 * file locking being disabled here because we only
1677 * clear the S_ISGID bit if the Group execute bit is
1678 * on, but if it was on then mandatory locking wouldn't
1679 * have been enabled.
1680 */
1681 if (ip->i_d.di_mode & S_IXGRP)
1682 ip->i_d.di_mode &= ~S_ISGID;
1683
1684 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
1685 }
1686 if (setprealloc)
1687 ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC;
1688 else if (clrprealloc)
1689 ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC;
1690
1691 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1692 if (attr_flags & XFS_ATTR_SYNC)
1693 xfs_trans_set_sync(tp);
1694 return xfs_trans_commit(tp, 0);
1695}