diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 61 |
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. */ | ||
1491 | static void | ||
1492 | xfs_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 |