aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c61
1 files changed, 26 insertions, 35 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 801274126648..6f95bdb408ce 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -749,7 +749,6 @@ xfs_ialloc(
749 xfs_nlink_t nlink, 749 xfs_nlink_t nlink,
750 dev_t rdev, 750 dev_t rdev,
751 prid_t prid, 751 prid_t prid,
752 int okalloc,
753 xfs_buf_t **ialloc_context, 752 xfs_buf_t **ialloc_context,
754 xfs_inode_t **ipp) 753 xfs_inode_t **ipp)
755{ 754{
@@ -765,7 +764,7 @@ xfs_ialloc(
765 * Call the space management code to pick 764 * Call the space management code to pick
766 * the on-disk inode to be allocated. 765 * the on-disk inode to be allocated.
767 */ 766 */
768 error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, 767 error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode,
769 ialloc_context, &ino); 768 ialloc_context, &ino);
770 if (error) 769 if (error)
771 return error; 770 return error;
@@ -957,7 +956,6 @@ xfs_dir_ialloc(
957 xfs_nlink_t nlink, 956 xfs_nlink_t nlink,
958 dev_t rdev, 957 dev_t rdev,
959 prid_t prid, /* project id */ 958 prid_t prid, /* project id */
960 int okalloc, /* ok to allocate new space */
961 xfs_inode_t **ipp, /* pointer to inode; it will be 959 xfs_inode_t **ipp, /* pointer to inode; it will be
962 locked. */ 960 locked. */
963 int *committed) 961 int *committed)
@@ -988,8 +986,8 @@ xfs_dir_ialloc(
988 * transaction commit so that no other process can steal 986 * transaction commit so that no other process can steal
989 * the inode(s) that we've just allocated. 987 * the inode(s) that we've just allocated.
990 */ 988 */
991 code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid, okalloc, 989 code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid, &ialloc_context,
992 &ialloc_context, &ip); 990 &ip);
993 991
994 /* 992 /*
995 * Return an error if we were unable to allocate a new inode. 993 * Return an error if we were unable to allocate a new inode.
@@ -1061,7 +1059,7 @@ xfs_dir_ialloc(
1061 * this call should always succeed. 1059 * this call should always succeed.
1062 */ 1060 */
1063 code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid, 1061 code = xfs_ialloc(tp, dp, mode, nlink, rdev, prid,
1064 okalloc, &ialloc_context, &ip); 1062 &ialloc_context, &ip);
1065 1063
1066 /* 1064 /*
1067 * If we get an error at this point, return to the caller 1065 * If we get an error at this point, return to the caller
@@ -1182,11 +1180,6 @@ xfs_create(
1182 xfs_flush_inodes(mp); 1180 xfs_flush_inodes(mp);
1183 error = xfs_trans_alloc(mp, tres, resblks, 0, 0, &tp); 1181 error = xfs_trans_alloc(mp, tres, resblks, 0, 0, &tp);
1184 } 1182 }
1185 if (error == -ENOSPC) {
1186 /* No space at all so try a "no-allocation" reservation */
1187 resblks = 0;
1188 error = xfs_trans_alloc(mp, tres, 0, 0, 0, &tp);
1189 }
1190 if (error) 1183 if (error)
1191 goto out_release_inode; 1184 goto out_release_inode;
1192 1185
@@ -1203,19 +1196,13 @@ xfs_create(
1203 if (error) 1196 if (error)
1204 goto out_trans_cancel; 1197 goto out_trans_cancel;
1205 1198
1206 if (!resblks) {
1207 error = xfs_dir_canenter(tp, dp, name);
1208 if (error)
1209 goto out_trans_cancel;
1210 }
1211
1212 /* 1199 /*
1213 * A newly created regular or special file just has one directory 1200 * A newly created regular or special file just has one directory
1214 * entry pointing to them, but a directory also the "." entry 1201 * entry pointing to them, but a directory also the "." entry
1215 * pointing to itself. 1202 * pointing to itself.
1216 */ 1203 */
1217 error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev, 1204 error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev, prid, &ip,
1218 prid, resblks > 0, &ip, NULL); 1205 NULL);
1219 if (error) 1206 if (error)
1220 goto out_trans_cancel; 1207 goto out_trans_cancel;
1221 1208
@@ -1340,11 +1327,6 @@ xfs_create_tmpfile(
1340 tres = &M_RES(mp)->tr_create_tmpfile; 1327 tres = &M_RES(mp)->tr_create_tmpfile;
1341 1328
1342 error = xfs_trans_alloc(mp, tres, resblks, 0, 0, &tp); 1329 error = xfs_trans_alloc(mp, tres, resblks, 0, 0, &tp);
1343 if (error == -ENOSPC) {
1344 /* No space at all so try a "no-allocation" reservation */
1345 resblks = 0;
1346 error = xfs_trans_alloc(mp, tres, 0, 0, 0, &tp);
1347 }
1348 if (error) 1330 if (error)
1349 goto out_release_inode; 1331 goto out_release_inode;
1350 1332
@@ -1353,8 +1335,7 @@ xfs_create_tmpfile(
1353 if (error) 1335 if (error)
1354 goto out_trans_cancel; 1336 goto out_trans_cancel;
1355 1337
1356 error = xfs_dir_ialloc(&tp, dp, mode, 1, 0, 1338 error = xfs_dir_ialloc(&tp, dp, mode, 1, 0, prid, &ip, NULL);
1357 prid, resblks > 0, &ip, NULL);
1358 if (error) 1339 if (error)
1359 goto out_trans_cancel; 1340 goto out_trans_cancel;
1360 1341
@@ -1506,6 +1487,24 @@ xfs_link(
1506 return error; 1487 return error;
1507} 1488}
1508 1489
1490/* Clear the reflink flag and the cowblocks tag if possible. */
1491static void
1492xfs_itruncate_clear_reflink_flags(
1493 struct xfs_inode *ip)
1494{
1495 struct xfs_ifork *dfork;
1496 struct xfs_ifork *cfork;
1497
1498 if (!xfs_is_reflink_inode(ip))
1499 return;
1500 dfork = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
1501 cfork = XFS_IFORK_PTR(ip, XFS_COW_FORK);
1502 if (dfork->if_bytes == 0 && cfork->if_bytes == 0)
1503 ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
1504 if (cfork->if_bytes == 0)
1505 xfs_inode_clear_cowblocks_tag(ip);
1506}
1507
1509/* 1508/*
1510 * Free up the underlying blocks past new_size. The new size must be smaller 1509 * Free up the underlying blocks past new_size. The new size must be smaller
1511 * than the current size. This routine can be used both for the attribute and 1510 * than the current size. This routine can be used both for the attribute and
@@ -1602,15 +1601,7 @@ xfs_itruncate_extents(
1602 if (error) 1601 if (error)
1603 goto out; 1602 goto out;
1604 1603
1605 /* 1604 xfs_itruncate_clear_reflink_flags(ip);
1606 * Clear the reflink flag if there are no data fork blocks and
1607 * there are no extents staged in the cow fork.
1608 */
1609 if (xfs_is_reflink_inode(ip) && ip->i_cnextents == 0) {
1610 if (ip->i_d.di_nblocks == 0)
1611 ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
1612 xfs_inode_clear_cowblocks_tag(ip);
1613 }
1614 1605
1615 /* 1606 /*
1616 * Always re-log the inode so that our permanent transaction can keep 1607 * Always re-log the inode so that our permanent transaction can keep