diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/Makefile | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_acl.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_aops.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_attr.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_attr.h | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_util.c | 861 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap_util.h | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_dfrag.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2.h | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_dir2_priv.h | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_export.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_file.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 1004 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.h | 23 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_buf.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_fork.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl.c | 36 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl.h | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_ioctl32.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_iops.h | 13 | ||||
-rw-r--r-- | fs/xfs/xfs_rename.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 1872 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.h | 55 | ||||
-rw-r--r-- | fs/xfs/xfs_xattr.c | 1 |
29 files changed, 1931 insertions, 1991 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index dcd21b95cd98..8691dba546cd 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile | |||
@@ -55,7 +55,6 @@ xfs-y += xfs_aops.o \ | |||
55 | xfs_symlink.o \ | 55 | xfs_symlink.o \ |
56 | xfs_trans.o \ | 56 | xfs_trans.o \ |
57 | xfs_utils.o \ | 57 | xfs_utils.o \ |
58 | xfs_vnodeops.o \ | ||
59 | xfs_xattr.o \ | 58 | xfs_xattr.o \ |
60 | kmem.o \ | 59 | kmem.o \ |
61 | uuid.o | 60 | uuid.o |
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 150c670e15fa..0c4368aac449 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "xfs_attr.h" | 22 | #include "xfs_attr.h" |
23 | #include "xfs_bmap_btree.h" | 23 | #include "xfs_bmap_btree.h" |
24 | #include "xfs_inode.h" | 24 | #include "xfs_inode.h" |
25 | #include "xfs_vnodeops.h" | ||
26 | #include "xfs_sb.h" | 25 | #include "xfs_sb.h" |
27 | #include "xfs_mount.h" | 26 | #include "xfs_mount.h" |
28 | #include "xfs_trace.h" | 27 | #include "xfs_trace.h" |
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 709347d6f468..a82c83707324 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "xfs_alloc.h" | 28 | #include "xfs_alloc.h" |
29 | #include "xfs_error.h" | 29 | #include "xfs_error.h" |
30 | #include "xfs_iomap.h" | 30 | #include "xfs_iomap.h" |
31 | #include "xfs_vnodeops.h" | ||
32 | #include "xfs_trace.h" | 31 | #include "xfs_trace.h" |
33 | #include "xfs_bmap.h" | 32 | #include "xfs_bmap.h" |
34 | #include "xfs_bmap_util.h" | 33 | #include "xfs_bmap_util.h" |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 91acc38f664b..046cf3d7f52f 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include "xfs_error.h" | 40 | #include "xfs_error.h" |
41 | #include "xfs_quota.h" | 41 | #include "xfs_quota.h" |
42 | #include "xfs_trans_space.h" | 42 | #include "xfs_trans_space.h" |
43 | #include "xfs_vnodeops.h" | ||
44 | #include "xfs_trace.h" | 43 | #include "xfs_trace.h" |
45 | 44 | ||
46 | /* | 45 | /* |
diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index cb604b53e2f6..dd4824589470 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h | |||
@@ -142,5 +142,13 @@ typedef struct xfs_attr_list_context { | |||
142 | int xfs_attr_inactive(struct xfs_inode *dp); | 142 | int xfs_attr_inactive(struct xfs_inode *dp); |
143 | int xfs_attr_list_int(struct xfs_attr_list_context *); | 143 | int xfs_attr_list_int(struct xfs_attr_list_context *); |
144 | int xfs_inode_hasattr(struct xfs_inode *ip); | 144 | int xfs_inode_hasattr(struct xfs_inode *ip); |
145 | int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name, | ||
146 | unsigned char *value, int *valuelenp, int flags); | ||
147 | int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name, | ||
148 | unsigned char *value, int valuelen, int flags); | ||
149 | int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags); | ||
150 | int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, | ||
151 | int flags, struct attrlist_cursor_kern *cursor); | ||
152 | |||
145 | 153 | ||
146 | #endif /* __XFS_ATTR_H__ */ | 154 | #endif /* __XFS_ATTR_H__ */ |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index a9331a6b36fb..51e07e7a0092 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include "xfs_trans_space.h" | 48 | #include "xfs_trans_space.h" |
49 | #include "xfs_buf_item.h" | 49 | #include "xfs_buf_item.h" |
50 | #include "xfs_filestream.h" | 50 | #include "xfs_filestream.h" |
51 | #include "xfs_vnodeops.h" | ||
52 | #include "xfs_trace.h" | 51 | #include "xfs_trace.h" |
53 | #include "xfs_symlink.h" | 52 | #include "xfs_symlink.h" |
54 | 53 | ||
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 | */ | ||
843 | bool | ||
844 | xfs_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 | */ | ||
879 | int | ||
880 | xfs_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 | */ | ||
996 | STATIC int | ||
997 | xfs_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 | |||
1146 | error0: /* 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 | |||
1150 | error1: /* 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 | */ | ||
1167 | STATIC int | ||
1168 | xfs_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 | */ | ||
1258 | STATIC int | ||
1259 | xfs_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 | |||
1446 | STATIC int | ||
1447 | xfs_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 | |||
1505 | out_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 | */ | ||
1523 | int | ||
1524 | xfs_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 | } | ||
diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h index 004fe4b28d49..a6d207769dee 100644 --- a/fs/xfs/xfs_bmap_util.h +++ b/fs/xfs/xfs_bmap_util.h | |||
@@ -21,6 +21,7 @@ | |||
21 | /* Kernel only BMAP related definitions and functions */ | 21 | /* Kernel only BMAP related definitions and functions */ |
22 | 22 | ||
23 | struct xfs_bmbt_irec; | 23 | struct xfs_bmbt_irec; |
24 | struct xfs_bmap_free_item; | ||
24 | struct xfs_ifork; | 25 | struct xfs_ifork; |
25 | struct xfs_inode; | 26 | struct xfs_inode; |
26 | struct xfs_mount; | 27 | struct xfs_mount; |
@@ -91,6 +92,16 @@ int xfs_bmap_last_extent(struct xfs_trans *tp, struct xfs_inode *ip, | |||
91 | int whichfork, struct xfs_bmbt_irec *rec, | 92 | int whichfork, struct xfs_bmbt_irec *rec, |
92 | int *is_empty); | 93 | int *is_empty); |
93 | 94 | ||
95 | /* preallocation and hole punch interface */ | ||
96 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, | ||
97 | xfs_flock64_t *bf, xfs_off_t offset, | ||
98 | int attr_flags); | ||
99 | |||
100 | /* EOF block manipulation functions */ | ||
101 | bool xfs_can_free_eofblocks(struct xfs_inode *ip, bool force); | ||
102 | int xfs_free_eofblocks(struct xfs_mount *mp, struct xfs_inode *ip, | ||
103 | bool need_iolock); | ||
104 | |||
94 | xfs_daddr_t xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb); | 105 | xfs_daddr_t xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb); |
95 | 106 | ||
96 | #endif /* __XFS_BMAP_UTIL_H__ */ | 107 | #endif /* __XFS_BMAP_UTIL_H__ */ |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 815dace5e57a..b83d45f8cb12 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "xfs_itable.h" | 35 | #include "xfs_itable.h" |
36 | #include "xfs_dfrag.h" | 36 | #include "xfs_dfrag.h" |
37 | #include "xfs_error.h" | 37 | #include "xfs_error.h" |
38 | #include "xfs_vnodeops.h" | ||
39 | #include "xfs_trace.h" | 38 | #include "xfs_trace.h" |
40 | 39 | ||
41 | 40 | ||
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index c3263a56b861..841933c9e80f 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "xfs_dir2.h" | 35 | #include "xfs_dir2.h" |
36 | #include "xfs_dir2_priv.h" | 36 | #include "xfs_dir2_priv.h" |
37 | #include "xfs_error.h" | 37 | #include "xfs_error.h" |
38 | #include "xfs_vnodeops.h" | ||
39 | #include "xfs_trace.h" | 38 | #include "xfs_trace.h" |
40 | 39 | ||
41 | struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2}; | 40 | struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2}; |
diff --git a/fs/xfs/xfs_dir2.h b/fs/xfs/xfs_dir2.h index 7ef6b0fb951a..7fe2b8f0a9e3 100644 --- a/fs/xfs/xfs_dir2.h +++ b/fs/xfs/xfs_dir2.h | |||
@@ -63,12 +63,6 @@ extern int xfs_dir_canenter(struct xfs_trans *tp, struct xfs_inode *dp, | |||
63 | extern int xfs_dir2_sf_to_block(struct xfs_da_args *args); | 63 | extern int xfs_dir2_sf_to_block(struct xfs_da_args *args); |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * Direct call on directory open, before entering the readdir code. | ||
67 | */ | ||
68 | extern int xfs_dir3_data_readahead(struct xfs_trans *tp, struct xfs_inode *dp, | ||
69 | xfs_dablk_t bno, xfs_daddr_t mapped_bno); | ||
70 | |||
71 | /* | ||
72 | * Interface routines used by userspace utilities | 66 | * Interface routines used by userspace utilities |
73 | */ | 67 | */ |
74 | extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp); | 68 | extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp); |
diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h index 807eb658107c..6d2a99c224b7 100644 --- a/fs/xfs/xfs_dir2_priv.h +++ b/fs/xfs/xfs_dir2_priv.h | |||
@@ -45,6 +45,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args, | |||
45 | extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); | 45 | extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp); |
46 | extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, | 46 | extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp, |
47 | xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp); | 47 | xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp); |
48 | extern int xfs_dir3_data_readahead(struct xfs_trans *tp, struct xfs_inode *dp, | ||
49 | xfs_dablk_t bno, xfs_daddr_t mapped_bno); | ||
48 | 50 | ||
49 | extern struct xfs_dir2_data_free * | 51 | extern struct xfs_dir2_data_free * |
50 | xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr, | 52 | xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr, |
@@ -124,4 +126,8 @@ extern int xfs_dir2_sf_lookup(struct xfs_da_args *args); | |||
124 | extern int xfs_dir2_sf_removename(struct xfs_da_args *args); | 126 | extern int xfs_dir2_sf_removename(struct xfs_da_args *args); |
125 | extern int xfs_dir2_sf_replace(struct xfs_da_args *args); | 127 | extern int xfs_dir2_sf_replace(struct xfs_da_args *args); |
126 | 128 | ||
129 | /* xfs_dir2_readdir.c */ | ||
130 | extern int xfs_readdir(struct xfs_inode *dp, struct dir_context *ctx, | ||
131 | size_t bufsize); | ||
132 | |||
127 | #endif /* __XFS_DIR2_PRIV_H__ */ | 133 | #endif /* __XFS_DIR2_PRIV_H__ */ |
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c index 29c880fbdb1b..066df425c14f 100644 --- a/fs/xfs/xfs_export.c +++ b/fs/xfs/xfs_export.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "xfs_dir2_format.h" | 26 | #include "xfs_dir2_format.h" |
27 | #include "xfs_dir2.h" | 27 | #include "xfs_dir2.h" |
28 | #include "xfs_export.h" | 28 | #include "xfs_export.h" |
29 | #include "xfs_vnodeops.h" | ||
30 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
31 | #include "xfs_inode.h" | 30 | #include "xfs_inode.h" |
32 | #include "xfs_inode_item.h" | 31 | #include "xfs_inode_item.h" |
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 1ba3c7998b9a..4c749ab543d0 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c | |||
@@ -28,11 +28,12 @@ | |||
28 | #include "xfs_inode.h" | 28 | #include "xfs_inode.h" |
29 | #include "xfs_inode_item.h" | 29 | #include "xfs_inode_item.h" |
30 | #include "xfs_bmap.h" | 30 | #include "xfs_bmap.h" |
31 | #include "xfs_bmap_util.h" | ||
31 | #include "xfs_error.h" | 32 | #include "xfs_error.h" |
32 | #include "xfs_vnodeops.h" | ||
33 | #include "xfs_da_btree.h" | 33 | #include "xfs_da_btree.h" |
34 | #include "xfs_dir2_format.h" | 34 | #include "xfs_dir2_format.h" |
35 | #include "xfs_dir2.h" | 35 | #include "xfs_dir2.h" |
36 | #include "xfs_dir2_priv.h" | ||
36 | #include "xfs_ioctl.h" | 37 | #include "xfs_ioctl.h" |
37 | #include "xfs_trace.h" | 38 | #include "xfs_trace.h" |
38 | 39 | ||
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index d9a41671a4ad..2abc9450ce20 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
@@ -32,12 +32,12 @@ | |||
32 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
33 | #include "xfs_error.h" | 33 | #include "xfs_error.h" |
34 | #include "xfs_filestream.h" | 34 | #include "xfs_filestream.h" |
35 | #include "xfs_vnodeops.h" | ||
36 | #include "xfs_inode_item.h" | 35 | #include "xfs_inode_item.h" |
37 | #include "xfs_quota.h" | 36 | #include "xfs_quota.h" |
38 | #include "xfs_trace.h" | 37 | #include "xfs_trace.h" |
39 | #include "xfs_fsops.h" | 38 | #include "xfs_fsops.h" |
40 | #include "xfs_icache.h" | 39 | #include "xfs_icache.h" |
40 | #include "xfs_bmap_util.h" | ||
41 | 41 | ||
42 | #include <linux/kthread.h> | 42 | #include <linux/kthread.h> |
43 | #include <linux/freezer.h> | 43 | #include <linux/freezer.h> |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 1029f5670207..73a7a1d84243 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -23,14 +23,19 @@ | |||
23 | #include "xfs_log.h" | 23 | #include "xfs_log.h" |
24 | #include "xfs_inum.h" | 24 | #include "xfs_inum.h" |
25 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
26 | #include "xfs_trans_space.h" | ||
26 | #include "xfs_trans_priv.h" | 27 | #include "xfs_trans_priv.h" |
27 | #include "xfs_sb.h" | 28 | #include "xfs_sb.h" |
28 | #include "xfs_ag.h" | 29 | #include "xfs_ag.h" |
29 | #include "xfs_mount.h" | 30 | #include "xfs_mount.h" |
31 | #include "xfs_da_btree.h" | ||
32 | #include "xfs_dir2_format.h" | ||
33 | #include "xfs_dir2.h" | ||
30 | #include "xfs_bmap_btree.h" | 34 | #include "xfs_bmap_btree.h" |
31 | #include "xfs_alloc_btree.h" | 35 | #include "xfs_alloc_btree.h" |
32 | #include "xfs_ialloc_btree.h" | 36 | #include "xfs_ialloc_btree.h" |
33 | #include "xfs_attr_sf.h" | 37 | #include "xfs_attr_sf.h" |
38 | #include "xfs_attr.h" | ||
34 | #include "xfs_dinode.h" | 39 | #include "xfs_dinode.h" |
35 | #include "xfs_inode.h" | 40 | #include "xfs_inode.h" |
36 | #include "xfs_buf_item.h" | 41 | #include "xfs_buf_item.h" |
@@ -44,10 +49,10 @@ | |||
44 | #include "xfs_utils.h" | 49 | #include "xfs_utils.h" |
45 | #include "xfs_quota.h" | 50 | #include "xfs_quota.h" |
46 | #include "xfs_filestream.h" | 51 | #include "xfs_filestream.h" |
47 | #include "xfs_vnodeops.h" | ||
48 | #include "xfs_cksum.h" | 52 | #include "xfs_cksum.h" |
49 | #include "xfs_trace.h" | 53 | #include "xfs_trace.h" |
50 | #include "xfs_icache.h" | 54 | #include "xfs_icache.h" |
55 | #include "xfs_symlink.h" | ||
51 | 56 | ||
52 | kmem_zone_t *xfs_inode_zone; | 57 | kmem_zone_t *xfs_inode_zone; |
53 | 58 | ||
@@ -307,6 +312,188 @@ xfs_isilocked( | |||
307 | } | 312 | } |
308 | #endif | 313 | #endif |
309 | 314 | ||
315 | #ifdef DEBUG | ||
316 | int xfs_locked_n; | ||
317 | int xfs_small_retries; | ||
318 | int xfs_middle_retries; | ||
319 | int xfs_lots_retries; | ||
320 | int xfs_lock_delays; | ||
321 | #endif | ||
322 | |||
323 | /* | ||
324 | * Bump the subclass so xfs_lock_inodes() acquires each lock with | ||
325 | * a different value | ||
326 | */ | ||
327 | static inline int | ||
328 | xfs_lock_inumorder(int lock_mode, int subclass) | ||
329 | { | ||
330 | if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) | ||
331 | lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_IOLOCK_SHIFT; | ||
332 | if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) | ||
333 | lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_ILOCK_SHIFT; | ||
334 | |||
335 | return lock_mode; | ||
336 | } | ||
337 | |||
338 | /* | ||
339 | * The following routine will lock n inodes in exclusive mode. | ||
340 | * We assume the caller calls us with the inodes in i_ino order. | ||
341 | * | ||
342 | * We need to detect deadlock where an inode that we lock | ||
343 | * is in the AIL and we start waiting for another inode that is locked | ||
344 | * by a thread in a long running transaction (such as truncate). This can | ||
345 | * result in deadlock since the long running trans might need to wait | ||
346 | * for the inode we just locked in order to push the tail and free space | ||
347 | * in the log. | ||
348 | */ | ||
349 | void | ||
350 | xfs_lock_inodes( | ||
351 | xfs_inode_t **ips, | ||
352 | int inodes, | ||
353 | uint lock_mode) | ||
354 | { | ||
355 | int attempts = 0, i, j, try_lock; | ||
356 | xfs_log_item_t *lp; | ||
357 | |||
358 | ASSERT(ips && (inodes >= 2)); /* we need at least two */ | ||
359 | |||
360 | try_lock = 0; | ||
361 | i = 0; | ||
362 | |||
363 | again: | ||
364 | for (; i < inodes; i++) { | ||
365 | ASSERT(ips[i]); | ||
366 | |||
367 | if (i && (ips[i] == ips[i-1])) /* Already locked */ | ||
368 | continue; | ||
369 | |||
370 | /* | ||
371 | * If try_lock is not set yet, make sure all locked inodes | ||
372 | * are not in the AIL. | ||
373 | * If any are, set try_lock to be used later. | ||
374 | */ | ||
375 | |||
376 | if (!try_lock) { | ||
377 | for (j = (i - 1); j >= 0 && !try_lock; j--) { | ||
378 | lp = (xfs_log_item_t *)ips[j]->i_itemp; | ||
379 | if (lp && (lp->li_flags & XFS_LI_IN_AIL)) { | ||
380 | try_lock++; | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * If any of the previous locks we have locked is in the AIL, | ||
387 | * we must TRY to get the second and subsequent locks. If | ||
388 | * we can't get any, we must release all we have | ||
389 | * and try again. | ||
390 | */ | ||
391 | |||
392 | if (try_lock) { | ||
393 | /* try_lock must be 0 if i is 0. */ | ||
394 | /* | ||
395 | * try_lock means we have an inode locked | ||
396 | * that is in the AIL. | ||
397 | */ | ||
398 | ASSERT(i != 0); | ||
399 | if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) { | ||
400 | attempts++; | ||
401 | |||
402 | /* | ||
403 | * Unlock all previous guys and try again. | ||
404 | * xfs_iunlock will try to push the tail | ||
405 | * if the inode is in the AIL. | ||
406 | */ | ||
407 | |||
408 | for(j = i - 1; j >= 0; j--) { | ||
409 | |||
410 | /* | ||
411 | * Check to see if we've already | ||
412 | * unlocked this one. | ||
413 | * Not the first one going back, | ||
414 | * and the inode ptr is the same. | ||
415 | */ | ||
416 | if ((j != (i - 1)) && ips[j] == | ||
417 | ips[j+1]) | ||
418 | continue; | ||
419 | |||
420 | xfs_iunlock(ips[j], lock_mode); | ||
421 | } | ||
422 | |||
423 | if ((attempts % 5) == 0) { | ||
424 | delay(1); /* Don't just spin the CPU */ | ||
425 | #ifdef DEBUG | ||
426 | xfs_lock_delays++; | ||
427 | #endif | ||
428 | } | ||
429 | i = 0; | ||
430 | try_lock = 0; | ||
431 | goto again; | ||
432 | } | ||
433 | } else { | ||
434 | xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i)); | ||
435 | } | ||
436 | } | ||
437 | |||
438 | #ifdef DEBUG | ||
439 | if (attempts) { | ||
440 | if (attempts < 5) xfs_small_retries++; | ||
441 | else if (attempts < 100) xfs_middle_retries++; | ||
442 | else xfs_lots_retries++; | ||
443 | } else { | ||
444 | xfs_locked_n++; | ||
445 | } | ||
446 | #endif | ||
447 | } | ||
448 | |||
449 | /* | ||
450 | * xfs_lock_two_inodes() can only be used to lock one type of lock | ||
451 | * at a time - the iolock or the ilock, but not both at once. If | ||
452 | * we lock both at once, lockdep will report false positives saying | ||
453 | * we have violated locking orders. | ||
454 | */ | ||
455 | void | ||
456 | xfs_lock_two_inodes( | ||
457 | xfs_inode_t *ip0, | ||
458 | xfs_inode_t *ip1, | ||
459 | uint lock_mode) | ||
460 | { | ||
461 | xfs_inode_t *temp; | ||
462 | int attempts = 0; | ||
463 | xfs_log_item_t *lp; | ||
464 | |||
465 | if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) | ||
466 | ASSERT((lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) == 0); | ||
467 | ASSERT(ip0->i_ino != ip1->i_ino); | ||
468 | |||
469 | if (ip0->i_ino > ip1->i_ino) { | ||
470 | temp = ip0; | ||
471 | ip0 = ip1; | ||
472 | ip1 = temp; | ||
473 | } | ||
474 | |||
475 | again: | ||
476 | xfs_ilock(ip0, xfs_lock_inumorder(lock_mode, 0)); | ||
477 | |||
478 | /* | ||
479 | * If the first lock we have locked is in the AIL, we must TRY to get | ||
480 | * the second lock. If we can't get it, we must release the first one | ||
481 | * and try again. | ||
482 | */ | ||
483 | lp = (xfs_log_item_t *)ip0->i_itemp; | ||
484 | if (lp && (lp->li_flags & XFS_LI_IN_AIL)) { | ||
485 | if (!xfs_ilock_nowait(ip1, xfs_lock_inumorder(lock_mode, 1))) { | ||
486 | xfs_iunlock(ip0, lock_mode); | ||
487 | if ((++attempts % 5) == 0) | ||
488 | delay(1); /* Don't just spin the CPU */ | ||
489 | goto again; | ||
490 | } | ||
491 | } else { | ||
492 | xfs_ilock(ip1, xfs_lock_inumorder(lock_mode, 1)); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | |||
310 | void | 497 | void |
311 | __xfs_iflock( | 498 | __xfs_iflock( |
312 | struct xfs_inode *ip) | 499 | struct xfs_inode *ip) |
@@ -382,6 +569,49 @@ xfs_dic2xflags( | |||
382 | } | 569 | } |
383 | 570 | ||
384 | /* | 571 | /* |
572 | * Lookups up an inode from "name". If ci_name is not NULL, then a CI match | ||
573 | * is allowed, otherwise it has to be an exact match. If a CI match is found, | ||
574 | * ci_name->name will point to a the actual name (caller must free) or | ||
575 | * will be set to NULL if an exact match is found. | ||
576 | */ | ||
577 | int | ||
578 | xfs_lookup( | ||
579 | xfs_inode_t *dp, | ||
580 | struct xfs_name *name, | ||
581 | xfs_inode_t **ipp, | ||
582 | struct xfs_name *ci_name) | ||
583 | { | ||
584 | xfs_ino_t inum; | ||
585 | int error; | ||
586 | uint lock_mode; | ||
587 | |||
588 | trace_xfs_lookup(dp, name); | ||
589 | |||
590 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | ||
591 | return XFS_ERROR(EIO); | ||
592 | |||
593 | lock_mode = xfs_ilock_map_shared(dp); | ||
594 | error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name); | ||
595 | xfs_iunlock_map_shared(dp, lock_mode); | ||
596 | |||
597 | if (error) | ||
598 | goto out; | ||
599 | |||
600 | error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp); | ||
601 | if (error) | ||
602 | goto out_free_name; | ||
603 | |||
604 | return 0; | ||
605 | |||
606 | out_free_name: | ||
607 | if (ci_name) | ||
608 | kmem_free(ci_name->name); | ||
609 | out: | ||
610 | *ipp = NULL; | ||
611 | return error; | ||
612 | } | ||
613 | |||
614 | /* | ||
385 | * Allocate an inode on disk and return a copy of its in-core version. | 615 | * Allocate an inode on disk and return a copy of its in-core version. |
386 | * The in-core inode is locked exclusively. Set mode, nlink, and rdev | 616 | * The in-core inode is locked exclusively. Set mode, nlink, and rdev |
387 | * appropriately within the inode. The uid and gid for the inode are | 617 | * appropriately within the inode. The uid and gid for the inode are |
@@ -632,6 +862,308 @@ xfs_ialloc( | |||
632 | return 0; | 862 | return 0; |
633 | } | 863 | } |
634 | 864 | ||
865 | int | ||
866 | xfs_create( | ||
867 | xfs_inode_t *dp, | ||
868 | struct xfs_name *name, | ||
869 | umode_t mode, | ||
870 | xfs_dev_t rdev, | ||
871 | xfs_inode_t **ipp) | ||
872 | { | ||
873 | int is_dir = S_ISDIR(mode); | ||
874 | struct xfs_mount *mp = dp->i_mount; | ||
875 | struct xfs_inode *ip = NULL; | ||
876 | struct xfs_trans *tp = NULL; | ||
877 | int error; | ||
878 | xfs_bmap_free_t free_list; | ||
879 | xfs_fsblock_t first_block; | ||
880 | bool unlock_dp_on_error = false; | ||
881 | uint cancel_flags; | ||
882 | int committed; | ||
883 | prid_t prid; | ||
884 | struct xfs_dquot *udqp = NULL; | ||
885 | struct xfs_dquot *gdqp = NULL; | ||
886 | struct xfs_dquot *pdqp = NULL; | ||
887 | uint resblks; | ||
888 | uint log_res; | ||
889 | uint log_count; | ||
890 | |||
891 | trace_xfs_create(dp, name); | ||
892 | |||
893 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
894 | return XFS_ERROR(EIO); | ||
895 | |||
896 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | ||
897 | prid = xfs_get_projid(dp); | ||
898 | else | ||
899 | prid = XFS_PROJID_DEFAULT; | ||
900 | |||
901 | /* | ||
902 | * Make sure that we have allocated dquot(s) on disk. | ||
903 | */ | ||
904 | error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid, | ||
905 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, | ||
906 | &udqp, &gdqp, &pdqp); | ||
907 | if (error) | ||
908 | return error; | ||
909 | |||
910 | if (is_dir) { | ||
911 | rdev = 0; | ||
912 | resblks = XFS_MKDIR_SPACE_RES(mp, name->len); | ||
913 | log_res = XFS_MKDIR_LOG_RES(mp); | ||
914 | log_count = XFS_MKDIR_LOG_COUNT; | ||
915 | tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR); | ||
916 | } else { | ||
917 | resblks = XFS_CREATE_SPACE_RES(mp, name->len); | ||
918 | log_res = XFS_CREATE_LOG_RES(mp); | ||
919 | log_count = XFS_CREATE_LOG_COUNT; | ||
920 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); | ||
921 | } | ||
922 | |||
923 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
924 | |||
925 | /* | ||
926 | * Initially assume that the file does not exist and | ||
927 | * reserve the resources for that case. If that is not | ||
928 | * the case we'll drop the one we have and get a more | ||
929 | * appropriate transaction later. | ||
930 | */ | ||
931 | error = xfs_trans_reserve(tp, resblks, log_res, 0, | ||
932 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
933 | if (error == ENOSPC) { | ||
934 | /* flush outstanding delalloc blocks and retry */ | ||
935 | xfs_flush_inodes(mp); | ||
936 | error = xfs_trans_reserve(tp, resblks, log_res, 0, | ||
937 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
938 | } | ||
939 | if (error == ENOSPC) { | ||
940 | /* No space at all so try a "no-allocation" reservation */ | ||
941 | resblks = 0; | ||
942 | error = xfs_trans_reserve(tp, 0, log_res, 0, | ||
943 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
944 | } | ||
945 | if (error) { | ||
946 | cancel_flags = 0; | ||
947 | goto out_trans_cancel; | ||
948 | } | ||
949 | |||
950 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | ||
951 | unlock_dp_on_error = true; | ||
952 | |||
953 | xfs_bmap_init(&free_list, &first_block); | ||
954 | |||
955 | /* | ||
956 | * Reserve disk quota and the inode. | ||
957 | */ | ||
958 | error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, | ||
959 | pdqp, resblks, 1, 0); | ||
960 | if (error) | ||
961 | goto out_trans_cancel; | ||
962 | |||
963 | error = xfs_dir_canenter(tp, dp, name, resblks); | ||
964 | if (error) | ||
965 | goto out_trans_cancel; | ||
966 | |||
967 | /* | ||
968 | * A newly created regular or special file just has one directory | ||
969 | * entry pointing to them, but a directory also the "." entry | ||
970 | * pointing to itself. | ||
971 | */ | ||
972 | error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev, | ||
973 | prid, resblks > 0, &ip, &committed); | ||
974 | if (error) { | ||
975 | if (error == ENOSPC) | ||
976 | goto out_trans_cancel; | ||
977 | goto out_trans_abort; | ||
978 | } | ||
979 | |||
980 | /* | ||
981 | * Now we join the directory inode to the transaction. We do not do it | ||
982 | * earlier because xfs_dir_ialloc might commit the previous transaction | ||
983 | * (and release all the locks). An error from here on will result in | ||
984 | * the transaction cancel unlocking dp so don't do it explicitly in the | ||
985 | * error path. | ||
986 | */ | ||
987 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | ||
988 | unlock_dp_on_error = false; | ||
989 | |||
990 | error = xfs_dir_createname(tp, dp, name, ip->i_ino, | ||
991 | &first_block, &free_list, resblks ? | ||
992 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); | ||
993 | if (error) { | ||
994 | ASSERT(error != ENOSPC); | ||
995 | goto out_trans_abort; | ||
996 | } | ||
997 | xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
998 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | ||
999 | |||
1000 | if (is_dir) { | ||
1001 | error = xfs_dir_init(tp, ip, dp); | ||
1002 | if (error) | ||
1003 | goto out_bmap_cancel; | ||
1004 | |||
1005 | error = xfs_bumplink(tp, dp); | ||
1006 | if (error) | ||
1007 | goto out_bmap_cancel; | ||
1008 | } | ||
1009 | |||
1010 | /* | ||
1011 | * If this is a synchronous mount, make sure that the | ||
1012 | * create transaction goes to disk before returning to | ||
1013 | * the user. | ||
1014 | */ | ||
1015 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) | ||
1016 | xfs_trans_set_sync(tp); | ||
1017 | |||
1018 | /* | ||
1019 | * Attach the dquot(s) to the inodes and modify them incore. | ||
1020 | * These ids of the inode couldn't have changed since the new | ||
1021 | * inode has been locked ever since it was created. | ||
1022 | */ | ||
1023 | xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); | ||
1024 | |||
1025 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
1026 | if (error) | ||
1027 | goto out_bmap_cancel; | ||
1028 | |||
1029 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
1030 | if (error) | ||
1031 | goto out_release_inode; | ||
1032 | |||
1033 | xfs_qm_dqrele(udqp); | ||
1034 | xfs_qm_dqrele(gdqp); | ||
1035 | xfs_qm_dqrele(pdqp); | ||
1036 | |||
1037 | *ipp = ip; | ||
1038 | return 0; | ||
1039 | |||
1040 | out_bmap_cancel: | ||
1041 | xfs_bmap_cancel(&free_list); | ||
1042 | out_trans_abort: | ||
1043 | cancel_flags |= XFS_TRANS_ABORT; | ||
1044 | out_trans_cancel: | ||
1045 | xfs_trans_cancel(tp, cancel_flags); | ||
1046 | out_release_inode: | ||
1047 | /* | ||
1048 | * Wait until after the current transaction is aborted to | ||
1049 | * release the inode. This prevents recursive transactions | ||
1050 | * and deadlocks from xfs_inactive. | ||
1051 | */ | ||
1052 | if (ip) | ||
1053 | IRELE(ip); | ||
1054 | |||
1055 | xfs_qm_dqrele(udqp); | ||
1056 | xfs_qm_dqrele(gdqp); | ||
1057 | xfs_qm_dqrele(pdqp); | ||
1058 | |||
1059 | if (unlock_dp_on_error) | ||
1060 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
1061 | return error; | ||
1062 | } | ||
1063 | |||
1064 | int | ||
1065 | xfs_link( | ||
1066 | xfs_inode_t *tdp, | ||
1067 | xfs_inode_t *sip, | ||
1068 | struct xfs_name *target_name) | ||
1069 | { | ||
1070 | xfs_mount_t *mp = tdp->i_mount; | ||
1071 | xfs_trans_t *tp; | ||
1072 | int error; | ||
1073 | xfs_bmap_free_t free_list; | ||
1074 | xfs_fsblock_t first_block; | ||
1075 | int cancel_flags; | ||
1076 | int committed; | ||
1077 | int resblks; | ||
1078 | |||
1079 | trace_xfs_link(tdp, target_name); | ||
1080 | |||
1081 | ASSERT(!S_ISDIR(sip->i_d.di_mode)); | ||
1082 | |||
1083 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
1084 | return XFS_ERROR(EIO); | ||
1085 | |||
1086 | error = xfs_qm_dqattach(sip, 0); | ||
1087 | if (error) | ||
1088 | goto std_return; | ||
1089 | |||
1090 | error = xfs_qm_dqattach(tdp, 0); | ||
1091 | if (error) | ||
1092 | goto std_return; | ||
1093 | |||
1094 | tp = xfs_trans_alloc(mp, XFS_TRANS_LINK); | ||
1095 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
1096 | resblks = XFS_LINK_SPACE_RES(mp, target_name->len); | ||
1097 | error = xfs_trans_reserve(tp, resblks, XFS_LINK_LOG_RES(mp), 0, | ||
1098 | XFS_TRANS_PERM_LOG_RES, XFS_LINK_LOG_COUNT); | ||
1099 | if (error == ENOSPC) { | ||
1100 | resblks = 0; | ||
1101 | error = xfs_trans_reserve(tp, 0, XFS_LINK_LOG_RES(mp), 0, | ||
1102 | XFS_TRANS_PERM_LOG_RES, XFS_LINK_LOG_COUNT); | ||
1103 | } | ||
1104 | if (error) { | ||
1105 | cancel_flags = 0; | ||
1106 | goto error_return; | ||
1107 | } | ||
1108 | |||
1109 | xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL); | ||
1110 | |||
1111 | xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL); | ||
1112 | xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL); | ||
1113 | |||
1114 | /* | ||
1115 | * If we are using project inheritance, we only allow hard link | ||
1116 | * creation in our tree when the project IDs are the same; else | ||
1117 | * the tree quota mechanism could be circumvented. | ||
1118 | */ | ||
1119 | if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && | ||
1120 | (xfs_get_projid(tdp) != xfs_get_projid(sip)))) { | ||
1121 | error = XFS_ERROR(EXDEV); | ||
1122 | goto error_return; | ||
1123 | } | ||
1124 | |||
1125 | error = xfs_dir_canenter(tp, tdp, target_name, resblks); | ||
1126 | if (error) | ||
1127 | goto error_return; | ||
1128 | |||
1129 | xfs_bmap_init(&free_list, &first_block); | ||
1130 | |||
1131 | error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, | ||
1132 | &first_block, &free_list, resblks); | ||
1133 | if (error) | ||
1134 | goto abort_return; | ||
1135 | xfs_trans_ichgtime(tp, tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
1136 | xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE); | ||
1137 | |||
1138 | error = xfs_bumplink(tp, sip); | ||
1139 | if (error) | ||
1140 | goto abort_return; | ||
1141 | |||
1142 | /* | ||
1143 | * If this is a synchronous mount, make sure that the | ||
1144 | * link transaction goes to disk before returning to | ||
1145 | * the user. | ||
1146 | */ | ||
1147 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) { | ||
1148 | xfs_trans_set_sync(tp); | ||
1149 | } | ||
1150 | |||
1151 | error = xfs_bmap_finish (&tp, &free_list, &committed); | ||
1152 | if (error) { | ||
1153 | xfs_bmap_cancel(&free_list); | ||
1154 | goto abort_return; | ||
1155 | } | ||
1156 | |||
1157 | return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
1158 | |||
1159 | abort_return: | ||
1160 | cancel_flags |= XFS_TRANS_ABORT; | ||
1161 | error_return: | ||
1162 | xfs_trans_cancel(tp, cancel_flags); | ||
1163 | std_return: | ||
1164 | return error; | ||
1165 | } | ||
1166 | |||
635 | /* | 1167 | /* |
636 | * Free up the underlying blocks past new_size. The new size must be smaller | 1168 | * Free up the underlying blocks past new_size. The new size must be smaller |
637 | * than the current size. This routine can be used both for the attribute and | 1169 | * than the current size. This routine can be used both for the attribute and |
@@ -771,6 +1303,276 @@ out_bmap_cancel: | |||
771 | goto out; | 1303 | goto out; |
772 | } | 1304 | } |
773 | 1305 | ||
1306 | int | ||
1307 | xfs_release( | ||
1308 | xfs_inode_t *ip) | ||
1309 | { | ||
1310 | xfs_mount_t *mp = ip->i_mount; | ||
1311 | int error; | ||
1312 | |||
1313 | if (!S_ISREG(ip->i_d.di_mode) || (ip->i_d.di_mode == 0)) | ||
1314 | return 0; | ||
1315 | |||
1316 | /* If this is a read-only mount, don't do this (would generate I/O) */ | ||
1317 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
1318 | return 0; | ||
1319 | |||
1320 | if (!XFS_FORCED_SHUTDOWN(mp)) { | ||
1321 | int truncated; | ||
1322 | |||
1323 | /* | ||
1324 | * If we are using filestreams, and we have an unlinked | ||
1325 | * file that we are processing the last close on, then nothing | ||
1326 | * will be able to reopen and write to this file. Purge this | ||
1327 | * inode from the filestreams cache so that it doesn't delay | ||
1328 | * teardown of the inode. | ||
1329 | */ | ||
1330 | if ((ip->i_d.di_nlink == 0) && xfs_inode_is_filestream(ip)) | ||
1331 | xfs_filestream_deassociate(ip); | ||
1332 | |||
1333 | /* | ||
1334 | * If we previously truncated this file and removed old data | ||
1335 | * in the process, we want to initiate "early" writeout on | ||
1336 | * the last close. This is an attempt to combat the notorious | ||
1337 | * NULL files problem which is particularly noticeable from a | ||
1338 | * truncate down, buffered (re-)write (delalloc), followed by | ||
1339 | * a crash. What we are effectively doing here is | ||
1340 | * significantly reducing the time window where we'd otherwise | ||
1341 | * be exposed to that problem. | ||
1342 | */ | ||
1343 | truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); | ||
1344 | if (truncated) { | ||
1345 | xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE); | ||
1346 | if (VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0) { | ||
1347 | error = -filemap_flush(VFS_I(ip)->i_mapping); | ||
1348 | if (error) | ||
1349 | return error; | ||
1350 | } | ||
1351 | } | ||
1352 | } | ||
1353 | |||
1354 | if (ip->i_d.di_nlink == 0) | ||
1355 | return 0; | ||
1356 | |||
1357 | if (xfs_can_free_eofblocks(ip, false)) { | ||
1358 | |||
1359 | /* | ||
1360 | * If we can't get the iolock just skip truncating the blocks | ||
1361 | * past EOF because we could deadlock with the mmap_sem | ||
1362 | * otherwise. We'll get another chance to drop them once the | ||
1363 | * last reference to the inode is dropped, so we'll never leak | ||
1364 | * blocks permanently. | ||
1365 | * | ||
1366 | * Further, check if the inode is being opened, written and | ||
1367 | * closed frequently and we have delayed allocation blocks | ||
1368 | * outstanding (e.g. streaming writes from the NFS server), | ||
1369 | * truncating the blocks past EOF will cause fragmentation to | ||
1370 | * occur. | ||
1371 | * | ||
1372 | * In this case don't do the truncation, either, but we have to | ||
1373 | * be careful how we detect this case. Blocks beyond EOF show | ||
1374 | * up as i_delayed_blks even when the inode is clean, so we | ||
1375 | * need to truncate them away first before checking for a dirty | ||
1376 | * release. Hence on the first dirty close we will still remove | ||
1377 | * the speculative allocation, but after that we will leave it | ||
1378 | * in place. | ||
1379 | */ | ||
1380 | if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) | ||
1381 | return 0; | ||
1382 | |||
1383 | error = xfs_free_eofblocks(mp, ip, true); | ||
1384 | if (error && error != EAGAIN) | ||
1385 | return error; | ||
1386 | |||
1387 | /* delalloc blocks after truncation means it really is dirty */ | ||
1388 | if (ip->i_delayed_blks) | ||
1389 | xfs_iflags_set(ip, XFS_IDIRTY_RELEASE); | ||
1390 | } | ||
1391 | return 0; | ||
1392 | } | ||
1393 | |||
1394 | /* | ||
1395 | * xfs_inactive | ||
1396 | * | ||
1397 | * This is called when the vnode reference count for the vnode | ||
1398 | * goes to zero. If the file has been unlinked, then it must | ||
1399 | * now be truncated. Also, we clear all of the read-ahead state | ||
1400 | * kept for the inode here since the file is now closed. | ||
1401 | */ | ||
1402 | int | ||
1403 | xfs_inactive( | ||
1404 | xfs_inode_t *ip) | ||
1405 | { | ||
1406 | xfs_bmap_free_t free_list; | ||
1407 | xfs_fsblock_t first_block; | ||
1408 | int committed; | ||
1409 | xfs_trans_t *tp; | ||
1410 | xfs_mount_t *mp; | ||
1411 | int error; | ||
1412 | int truncate = 0; | ||
1413 | |||
1414 | /* | ||
1415 | * If the inode is already free, then there can be nothing | ||
1416 | * to clean up here. | ||
1417 | */ | ||
1418 | if (ip->i_d.di_mode == 0 || is_bad_inode(VFS_I(ip))) { | ||
1419 | ASSERT(ip->i_df.if_real_bytes == 0); | ||
1420 | ASSERT(ip->i_df.if_broot_bytes == 0); | ||
1421 | return VN_INACTIVE_CACHE; | ||
1422 | } | ||
1423 | |||
1424 | mp = ip->i_mount; | ||
1425 | |||
1426 | error = 0; | ||
1427 | |||
1428 | /* If this is a read-only mount, don't do this (would generate I/O) */ | ||
1429 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
1430 | goto out; | ||
1431 | |||
1432 | if (ip->i_d.di_nlink != 0) { | ||
1433 | /* | ||
1434 | * force is true because we are evicting an inode from the | ||
1435 | * cache. Post-eof blocks must be freed, lest we end up with | ||
1436 | * broken free space accounting. | ||
1437 | */ | ||
1438 | if (xfs_can_free_eofblocks(ip, true)) { | ||
1439 | error = xfs_free_eofblocks(mp, ip, false); | ||
1440 | if (error) | ||
1441 | return VN_INACTIVE_CACHE; | ||
1442 | } | ||
1443 | goto out; | ||
1444 | } | ||
1445 | |||
1446 | if (S_ISREG(ip->i_d.di_mode) && | ||
1447 | (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || | ||
1448 | ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) | ||
1449 | truncate = 1; | ||
1450 | |||
1451 | error = xfs_qm_dqattach(ip, 0); | ||
1452 | if (error) | ||
1453 | return VN_INACTIVE_CACHE; | ||
1454 | |||
1455 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | ||
1456 | error = xfs_trans_reserve(tp, 0, | ||
1457 | (truncate || S_ISLNK(ip->i_d.di_mode)) ? | ||
1458 | XFS_ITRUNCATE_LOG_RES(mp) : | ||
1459 | XFS_IFREE_LOG_RES(mp), | ||
1460 | 0, | ||
1461 | XFS_TRANS_PERM_LOG_RES, | ||
1462 | XFS_ITRUNCATE_LOG_COUNT); | ||
1463 | if (error) { | ||
1464 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
1465 | xfs_trans_cancel(tp, 0); | ||
1466 | return VN_INACTIVE_CACHE; | ||
1467 | } | ||
1468 | |||
1469 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
1470 | xfs_trans_ijoin(tp, ip, 0); | ||
1471 | |||
1472 | if (S_ISLNK(ip->i_d.di_mode)) { | ||
1473 | error = xfs_inactive_symlink(ip, &tp); | ||
1474 | if (error) | ||
1475 | goto out_cancel; | ||
1476 | } else if (truncate) { | ||
1477 | ip->i_d.di_size = 0; | ||
1478 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
1479 | |||
1480 | error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0); | ||
1481 | if (error) | ||
1482 | goto out_cancel; | ||
1483 | |||
1484 | ASSERT(ip->i_d.di_nextents == 0); | ||
1485 | } | ||
1486 | |||
1487 | /* | ||
1488 | * If there are attributes associated with the file then blow them away | ||
1489 | * now. The code calls a routine that recursively deconstructs the | ||
1490 | * attribute fork. We need to just commit the current transaction | ||
1491 | * because we can't use it for xfs_attr_inactive(). | ||
1492 | */ | ||
1493 | if (ip->i_d.di_anextents > 0) { | ||
1494 | ASSERT(ip->i_d.di_forkoff != 0); | ||
1495 | |||
1496 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
1497 | if (error) | ||
1498 | goto out_unlock; | ||
1499 | |||
1500 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
1501 | |||
1502 | error = xfs_attr_inactive(ip); | ||
1503 | if (error) | ||
1504 | goto out; | ||
1505 | |||
1506 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | ||
1507 | error = xfs_trans_reserve(tp, 0, | ||
1508 | XFS_IFREE_LOG_RES(mp), | ||
1509 | 0, XFS_TRANS_PERM_LOG_RES, | ||
1510 | XFS_INACTIVE_LOG_COUNT); | ||
1511 | if (error) { | ||
1512 | xfs_trans_cancel(tp, 0); | ||
1513 | goto out; | ||
1514 | } | ||
1515 | |||
1516 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
1517 | xfs_trans_ijoin(tp, ip, 0); | ||
1518 | } | ||
1519 | |||
1520 | if (ip->i_afp) | ||
1521 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); | ||
1522 | |||
1523 | ASSERT(ip->i_d.di_anextents == 0); | ||
1524 | |||
1525 | /* | ||
1526 | * Free the inode. | ||
1527 | */ | ||
1528 | xfs_bmap_init(&free_list, &first_block); | ||
1529 | error = xfs_ifree(tp, ip, &free_list); | ||
1530 | if (error) { | ||
1531 | /* | ||
1532 | * If we fail to free the inode, shut down. The cancel | ||
1533 | * might do that, we need to make sure. Otherwise the | ||
1534 | * inode might be lost for a long time or forever. | ||
1535 | */ | ||
1536 | if (!XFS_FORCED_SHUTDOWN(mp)) { | ||
1537 | xfs_notice(mp, "%s: xfs_ifree returned error %d", | ||
1538 | __func__, error); | ||
1539 | xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); | ||
1540 | } | ||
1541 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); | ||
1542 | } else { | ||
1543 | /* | ||
1544 | * Credit the quota account(s). The inode is gone. | ||
1545 | */ | ||
1546 | xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_ICOUNT, -1); | ||
1547 | |||
1548 | /* | ||
1549 | * Just ignore errors at this point. There is nothing we can | ||
1550 | * do except to try to keep going. Make sure it's not a silent | ||
1551 | * error. | ||
1552 | */ | ||
1553 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
1554 | if (error) | ||
1555 | xfs_notice(mp, "%s: xfs_bmap_finish returned error %d", | ||
1556 | __func__, error); | ||
1557 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
1558 | if (error) | ||
1559 | xfs_notice(mp, "%s: xfs_trans_commit returned error %d", | ||
1560 | __func__, error); | ||
1561 | } | ||
1562 | |||
1563 | /* | ||
1564 | * Release the dquots held by inode, if any. | ||
1565 | */ | ||
1566 | xfs_qm_dqdetach(ip); | ||
1567 | out_unlock: | ||
1568 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
1569 | out: | ||
1570 | return VN_INACTIVE_CACHE; | ||
1571 | out_cancel: | ||
1572 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
1573 | goto out_unlock; | ||
1574 | } | ||
1575 | |||
774 | /* | 1576 | /* |
775 | * This is called when the inode's link count goes to 0. | 1577 | * This is called when the inode's link count goes to 0. |
776 | * We place the on-disk inode on a list in the AGI. It | 1578 | * We place the on-disk inode on a list in the AGI. It |
@@ -1302,6 +2104,170 @@ xfs_iunpin_wait( | |||
1302 | __xfs_iunpin_wait(ip); | 2104 | __xfs_iunpin_wait(ip); |
1303 | } | 2105 | } |
1304 | 2106 | ||
2107 | int | ||
2108 | xfs_remove( | ||
2109 | xfs_inode_t *dp, | ||
2110 | struct xfs_name *name, | ||
2111 | xfs_inode_t *ip) | ||
2112 | { | ||
2113 | xfs_mount_t *mp = dp->i_mount; | ||
2114 | xfs_trans_t *tp = NULL; | ||
2115 | int is_dir = S_ISDIR(ip->i_d.di_mode); | ||
2116 | int error = 0; | ||
2117 | xfs_bmap_free_t free_list; | ||
2118 | xfs_fsblock_t first_block; | ||
2119 | int cancel_flags; | ||
2120 | int committed; | ||
2121 | int link_zero; | ||
2122 | uint resblks; | ||
2123 | uint log_count; | ||
2124 | |||
2125 | trace_xfs_remove(dp, name); | ||
2126 | |||
2127 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
2128 | return XFS_ERROR(EIO); | ||
2129 | |||
2130 | error = xfs_qm_dqattach(dp, 0); | ||
2131 | if (error) | ||
2132 | goto std_return; | ||
2133 | |||
2134 | error = xfs_qm_dqattach(ip, 0); | ||
2135 | if (error) | ||
2136 | goto std_return; | ||
2137 | |||
2138 | if (is_dir) { | ||
2139 | tp = xfs_trans_alloc(mp, XFS_TRANS_RMDIR); | ||
2140 | log_count = XFS_DEFAULT_LOG_COUNT; | ||
2141 | } else { | ||
2142 | tp = xfs_trans_alloc(mp, XFS_TRANS_REMOVE); | ||
2143 | log_count = XFS_REMOVE_LOG_COUNT; | ||
2144 | } | ||
2145 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
2146 | |||
2147 | /* | ||
2148 | * We try to get the real space reservation first, | ||
2149 | * allowing for directory btree deletion(s) implying | ||
2150 | * possible bmap insert(s). If we can't get the space | ||
2151 | * reservation then we use 0 instead, and avoid the bmap | ||
2152 | * btree insert(s) in the directory code by, if the bmap | ||
2153 | * insert tries to happen, instead trimming the LAST | ||
2154 | * block from the directory. | ||
2155 | */ | ||
2156 | resblks = XFS_REMOVE_SPACE_RES(mp); | ||
2157 | error = xfs_trans_reserve(tp, resblks, XFS_REMOVE_LOG_RES(mp), 0, | ||
2158 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
2159 | if (error == ENOSPC) { | ||
2160 | resblks = 0; | ||
2161 | error = xfs_trans_reserve(tp, 0, XFS_REMOVE_LOG_RES(mp), 0, | ||
2162 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
2163 | } | ||
2164 | if (error) { | ||
2165 | ASSERT(error != ENOSPC); | ||
2166 | cancel_flags = 0; | ||
2167 | goto out_trans_cancel; | ||
2168 | } | ||
2169 | |||
2170 | xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL); | ||
2171 | |||
2172 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | ||
2173 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
2174 | |||
2175 | /* | ||
2176 | * If we're removing a directory perform some additional validation. | ||
2177 | */ | ||
2178 | if (is_dir) { | ||
2179 | ASSERT(ip->i_d.di_nlink >= 2); | ||
2180 | if (ip->i_d.di_nlink != 2) { | ||
2181 | error = XFS_ERROR(ENOTEMPTY); | ||
2182 | goto out_trans_cancel; | ||
2183 | } | ||
2184 | if (!xfs_dir_isempty(ip)) { | ||
2185 | error = XFS_ERROR(ENOTEMPTY); | ||
2186 | goto out_trans_cancel; | ||
2187 | } | ||
2188 | } | ||
2189 | |||
2190 | xfs_bmap_init(&free_list, &first_block); | ||
2191 | error = xfs_dir_removename(tp, dp, name, ip->i_ino, | ||
2192 | &first_block, &free_list, resblks); | ||
2193 | if (error) { | ||
2194 | ASSERT(error != ENOENT); | ||
2195 | goto out_bmap_cancel; | ||
2196 | } | ||
2197 | xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
2198 | |||
2199 | if (is_dir) { | ||
2200 | /* | ||
2201 | * Drop the link from ip's "..". | ||
2202 | */ | ||
2203 | error = xfs_droplink(tp, dp); | ||
2204 | if (error) | ||
2205 | goto out_bmap_cancel; | ||
2206 | |||
2207 | /* | ||
2208 | * Drop the "." link from ip to self. | ||
2209 | */ | ||
2210 | error = xfs_droplink(tp, ip); | ||
2211 | if (error) | ||
2212 | goto out_bmap_cancel; | ||
2213 | } else { | ||
2214 | /* | ||
2215 | * When removing a non-directory we need to log the parent | ||
2216 | * inode here. For a directory this is done implicitly | ||
2217 | * by the xfs_droplink call for the ".." entry. | ||
2218 | */ | ||
2219 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | ||
2220 | } | ||
2221 | |||
2222 | /* | ||
2223 | * Drop the link from dp to ip. | ||
2224 | */ | ||
2225 | error = xfs_droplink(tp, ip); | ||
2226 | if (error) | ||
2227 | goto out_bmap_cancel; | ||
2228 | |||
2229 | /* | ||
2230 | * Determine if this is the last link while | ||
2231 | * we are in the transaction. | ||
2232 | */ | ||
2233 | link_zero = (ip->i_d.di_nlink == 0); | ||
2234 | |||
2235 | /* | ||
2236 | * If this is a synchronous mount, make sure that the | ||
2237 | * remove transaction goes to disk before returning to | ||
2238 | * the user. | ||
2239 | */ | ||
2240 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) | ||
2241 | xfs_trans_set_sync(tp); | ||
2242 | |||
2243 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
2244 | if (error) | ||
2245 | goto out_bmap_cancel; | ||
2246 | |||
2247 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
2248 | if (error) | ||
2249 | goto std_return; | ||
2250 | |||
2251 | /* | ||
2252 | * If we are using filestreams, kill the stream association. | ||
2253 | * If the file is still open it may get a new one but that | ||
2254 | * will get killed on last close in xfs_close() so we don't | ||
2255 | * have to worry about that. | ||
2256 | */ | ||
2257 | if (!is_dir && link_zero && xfs_inode_is_filestream(ip)) | ||
2258 | xfs_filestream_deassociate(ip); | ||
2259 | |||
2260 | return 0; | ||
2261 | |||
2262 | out_bmap_cancel: | ||
2263 | xfs_bmap_cancel(&free_list); | ||
2264 | cancel_flags |= XFS_TRANS_ABORT; | ||
2265 | out_trans_cancel: | ||
2266 | xfs_trans_cancel(tp, cancel_flags); | ||
2267 | std_return: | ||
2268 | return error; | ||
2269 | } | ||
2270 | |||
1305 | STATIC int | 2271 | STATIC int |
1306 | xfs_iflush_cluster( | 2272 | xfs_iflush_cluster( |
1307 | xfs_inode_t *ip, | 2273 | xfs_inode_t *ip, |
@@ -1746,39 +2712,3 @@ xfs_iflush_int( | |||
1746 | corrupt_out: | 2712 | corrupt_out: |
1747 | return XFS_ERROR(EFSCORRUPTED); | 2713 | return XFS_ERROR(EFSCORRUPTED); |
1748 | } | 2714 | } |
1749 | |||
1750 | /* | ||
1751 | * Test whether it is appropriate to check an inode for and free post EOF | ||
1752 | * blocks. The 'force' parameter determines whether we should also consider | ||
1753 | * regular files that are marked preallocated or append-only. | ||
1754 | */ | ||
1755 | bool | ||
1756 | xfs_can_free_eofblocks(struct xfs_inode *ip, bool force) | ||
1757 | { | ||
1758 | /* prealloc/delalloc exists only on regular files */ | ||
1759 | if (!S_ISREG(ip->i_d.di_mode)) | ||
1760 | return false; | ||
1761 | |||
1762 | /* | ||
1763 | * Zero sized files with no cached pages and delalloc blocks will not | ||
1764 | * have speculative prealloc/delalloc blocks to remove. | ||
1765 | */ | ||
1766 | if (VFS_I(ip)->i_size == 0 && | ||
1767 | VN_CACHED(VFS_I(ip)) == 0 && | ||
1768 | ip->i_delayed_blks == 0) | ||
1769 | return false; | ||
1770 | |||
1771 | /* If we haven't read in the extent list, then don't do it now. */ | ||
1772 | if (!(ip->i_df.if_flags & XFS_IFEXTENTS)) | ||
1773 | return false; | ||
1774 | |||
1775 | /* | ||
1776 | * Do not free real preallocated or append-only files unless the file | ||
1777 | * has delalloc blocks and we are forced to remove them. | ||
1778 | */ | ||
1779 | if (ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) | ||
1780 | if (!force || ip->i_delayed_blks == 0) | ||
1781 | return false; | ||
1782 | |||
1783 | return true; | ||
1784 | } | ||
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 8f775ed722a9..2a6347038cd8 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -315,9 +315,21 @@ static inline int xfs_isiflocked(struct xfs_inode *ip) | |||
315 | ((pip)->i_d.di_mode & S_ISGID)) | 315 | ((pip)->i_d.di_mode & S_ISGID)) |
316 | 316 | ||
317 | 317 | ||
318 | /* | 318 | int xfs_release(struct xfs_inode *ip); |
319 | * xfs_inode.c prototypes. | 319 | int xfs_inactive(struct xfs_inode *ip); |
320 | */ | 320 | int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, |
321 | struct xfs_inode **ipp, struct xfs_name *ci_name); | ||
322 | int xfs_create(struct xfs_inode *dp, struct xfs_name *name, | ||
323 | umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp); | ||
324 | int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, | ||
325 | struct xfs_inode *ip); | ||
326 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, | ||
327 | struct xfs_name *target_name); | ||
328 | int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name, | ||
329 | struct xfs_inode *src_ip, struct xfs_inode *target_dp, | ||
330 | struct xfs_name *target_name, | ||
331 | struct xfs_inode *target_ip); | ||
332 | |||
321 | void xfs_ilock(xfs_inode_t *, uint); | 333 | void xfs_ilock(xfs_inode_t *, uint); |
322 | int xfs_ilock_nowait(xfs_inode_t *, uint); | 334 | int xfs_ilock_nowait(xfs_inode_t *, uint); |
323 | void xfs_iunlock(xfs_inode_t *, uint); | 335 | void xfs_iunlock(xfs_inode_t *, uint); |
@@ -348,6 +360,11 @@ void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); | |||
348 | 360 | ||
349 | xfs_extlen_t xfs_get_extsz_hint(struct xfs_inode *ip); | 361 | xfs_extlen_t xfs_get_extsz_hint(struct xfs_inode *ip); |
350 | 362 | ||
363 | /* from xfs_file.c */ | ||
364 | int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t); | ||
365 | int xfs_iozero(struct xfs_inode *, loff_t, size_t); | ||
366 | |||
367 | |||
351 | #define IHOLD(ip) \ | 368 | #define IHOLD(ip) \ |
352 | do { \ | 369 | do { \ |
353 | ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ | 370 | ASSERT(atomic_read(&VFS_I(ip)->i_count) > 0) ; \ |
diff --git a/fs/xfs/xfs_inode_buf.h b/fs/xfs/xfs_inode_buf.h index b5f1e22bf44e..aae9fc465fe0 100644 --- a/fs/xfs/xfs_inode_buf.h +++ b/fs/xfs/xfs_inode_buf.h | |||
@@ -40,7 +40,6 @@ int xfs_iread(struct xfs_mount *, struct xfs_trans *, | |||
40 | void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *); | 40 | void xfs_dinode_calc_crc(struct xfs_mount *, struct xfs_dinode *); |
41 | void xfs_dinode_to_disk(struct xfs_dinode *, | 41 | void xfs_dinode_to_disk(struct xfs_dinode *, |
42 | struct xfs_icdinode *); | 42 | struct xfs_icdinode *); |
43 | bool xfs_can_free_eofblocks(struct xfs_inode *, bool); | ||
44 | 43 | ||
45 | #if defined(DEBUG) | 44 | #if defined(DEBUG) |
46 | void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); | 45 | void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); |
diff --git a/fs/xfs/xfs_inode_fork.c b/fs/xfs/xfs_inode_fork.c index f06570bb36bd..3f9ff99d6007 100644 --- a/fs/xfs/xfs_inode_fork.c +++ b/fs/xfs/xfs_inode_fork.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include "xfs_utils.h" | 43 | #include "xfs_utils.h" |
44 | #include "xfs_quota.h" | 44 | #include "xfs_quota.h" |
45 | #include "xfs_filestream.h" | 45 | #include "xfs_filestream.h" |
46 | #include "xfs_vnodeops.h" | ||
47 | #include "xfs_cksum.h" | 46 | #include "xfs_cksum.h" |
48 | #include "xfs_trace.h" | 47 | #include "xfs_trace.h" |
49 | #include "xfs_icache.h" | 48 | #include "xfs_icache.h" |
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 7c275380d40a..ce636bf0d550 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
@@ -38,13 +38,13 @@ | |||
38 | #include "xfs_utils.h" | 38 | #include "xfs_utils.h" |
39 | #include "xfs_dfrag.h" | 39 | #include "xfs_dfrag.h" |
40 | #include "xfs_fsops.h" | 40 | #include "xfs_fsops.h" |
41 | #include "xfs_vnodeops.h" | ||
42 | #include "xfs_discard.h" | 41 | #include "xfs_discard.h" |
43 | #include "xfs_quota.h" | 42 | #include "xfs_quota.h" |
44 | #include "xfs_inode_item.h" | 43 | #include "xfs_inode_item.h" |
45 | #include "xfs_export.h" | 44 | #include "xfs_export.h" |
46 | #include "xfs_trace.h" | 45 | #include "xfs_trace.h" |
47 | #include "xfs_icache.h" | 46 | #include "xfs_icache.h" |
47 | #include "xfs_symlink.h" | ||
48 | 48 | ||
49 | #include <linux/capability.h> | 49 | #include <linux/capability.h> |
50 | #include <linux/dcache.h> | 50 | #include <linux/dcache.h> |
@@ -352,6 +352,40 @@ xfs_readlink_by_handle( | |||
352 | return error; | 352 | return error; |
353 | } | 353 | } |
354 | 354 | ||
355 | int | ||
356 | xfs_set_dmattrs( | ||
357 | xfs_inode_t *ip, | ||
358 | u_int evmask, | ||
359 | u_int16_t state) | ||
360 | { | ||
361 | xfs_mount_t *mp = ip->i_mount; | ||
362 | xfs_trans_t *tp; | ||
363 | int error; | ||
364 | |||
365 | if (!capable(CAP_SYS_ADMIN)) | ||
366 | return XFS_ERROR(EPERM); | ||
367 | |||
368 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
369 | return XFS_ERROR(EIO); | ||
370 | |||
371 | tp = xfs_trans_alloc(mp, XFS_TRANS_SET_DMATTRS); | ||
372 | error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES (mp), 0, 0, 0); | ||
373 | if (error) { | ||
374 | xfs_trans_cancel(tp, 0); | ||
375 | return error; | ||
376 | } | ||
377 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
378 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
379 | |||
380 | ip->i_d.di_dmevmask = evmask; | ||
381 | ip->i_d.di_dmstate = state; | ||
382 | |||
383 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
384 | error = xfs_trans_commit(tp, 0); | ||
385 | |||
386 | return error; | ||
387 | } | ||
388 | |||
355 | STATIC int | 389 | STATIC int |
356 | xfs_fssetdm_by_handle( | 390 | xfs_fssetdm_by_handle( |
357 | struct file *parfilp, | 391 | struct file *parfilp, |
diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h index d56173b34a2a..1233dee4fef0 100644 --- a/fs/xfs/xfs_ioctl.h +++ b/fs/xfs/xfs_ioctl.h | |||
@@ -82,4 +82,10 @@ xfs_file_compat_ioctl( | |||
82 | unsigned int cmd, | 82 | unsigned int cmd, |
83 | unsigned long arg); | 83 | unsigned long arg); |
84 | 84 | ||
85 | extern int | ||
86 | xfs_set_dmattrs( | ||
87 | struct xfs_inode *ip, | ||
88 | u_int evmask, | ||
89 | u_int16_t state); | ||
90 | |||
85 | #endif | 91 | #endif |
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index c0c66259cc91..55a3072e7f56 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include "xfs_itable.h" | 34 | #include "xfs_itable.h" |
35 | #include "xfs_error.h" | 35 | #include "xfs_error.h" |
36 | #include "xfs_dfrag.h" | 36 | #include "xfs_dfrag.h" |
37 | #include "xfs_vnodeops.h" | ||
38 | #include "xfs_fsops.h" | 37 | #include "xfs_fsops.h" |
39 | #include "xfs_alloc.h" | 38 | #include "xfs_alloc.h" |
40 | #include "xfs_rtalloc.h" | 39 | #include "xfs_rtalloc.h" |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 17b70f0ccf8a..e0cefd417bf8 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -37,10 +37,10 @@ | |||
37 | #include "xfs_attr.h" | 37 | #include "xfs_attr.h" |
38 | #include "xfs_buf_item.h" | 38 | #include "xfs_buf_item.h" |
39 | #include "xfs_utils.h" | 39 | #include "xfs_utils.h" |
40 | #include "xfs_vnodeops.h" | ||
41 | #include "xfs_inode_item.h" | 40 | #include "xfs_inode_item.h" |
42 | #include "xfs_trace.h" | 41 | #include "xfs_trace.h" |
43 | #include "xfs_icache.h" | 42 | #include "xfs_icache.h" |
43 | #include "xfs_symlink.h" | ||
44 | 44 | ||
45 | #include <linux/capability.h> | 45 | #include <linux/capability.h> |
46 | #include <linux/xattr.h> | 46 | #include <linux/xattr.h> |
diff --git a/fs/xfs/xfs_iops.h b/fs/xfs/xfs_iops.h index ef41c92ce66e..d81fb41205ec 100644 --- a/fs/xfs/xfs_iops.h +++ b/fs/xfs/xfs_iops.h | |||
@@ -27,4 +27,17 @@ extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size); | |||
27 | 27 | ||
28 | extern void xfs_setup_inode(struct xfs_inode *); | 28 | extern void xfs_setup_inode(struct xfs_inode *); |
29 | 29 | ||
30 | /* | ||
31 | * Internal setattr interfaces. | ||
32 | */ | ||
33 | #define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */ | ||
34 | #define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if op would block */ | ||
35 | #define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */ | ||
36 | #define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */ | ||
37 | #define XFS_ATTR_SYNC 0x10 /* synchronous operation required */ | ||
38 | |||
39 | extern int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap, | ||
40 | int flags); | ||
41 | extern int xfs_setattr_size(struct xfs_inode *ip, struct iattr *vap, int flags); | ||
42 | |||
30 | #endif /* __XFS_IOPS_H__ */ | 43 | #endif /* __XFS_IOPS_H__ */ |
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 68cb7251cb99..c15c6c581d56 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include "xfs_quota.h" | 36 | #include "xfs_quota.h" |
37 | #include "xfs_utils.h" | 37 | #include "xfs_utils.h" |
38 | #include "xfs_trans_space.h" | 38 | #include "xfs_trans_space.h" |
39 | #include "xfs_vnodeops.h" | ||
40 | #include "xfs_trace.h" | 39 | #include "xfs_trace.h" |
41 | 40 | ||
42 | 41 | ||
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index aefc0044237d..978a2845f9af 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include "xfs_attr.h" | 41 | #include "xfs_attr.h" |
42 | #include "xfs_buf_item.h" | 42 | #include "xfs_buf_item.h" |
43 | #include "xfs_utils.h" | 43 | #include "xfs_utils.h" |
44 | #include "xfs_vnodeops.h" | ||
45 | #include "xfs_log_priv.h" | 44 | #include "xfs_log_priv.h" |
46 | #include "xfs_trans_priv.h" | 45 | #include "xfs_trans_priv.h" |
47 | #include "xfs_filestream.h" | 46 | #include "xfs_filestream.h" |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c deleted file mode 100644 index dc81a8d86ba5..000000000000 --- a/fs/xfs/xfs_vnodeops.c +++ /dev/null | |||
@@ -1,1872 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. | ||
3 | * Copyright (c) 2012 Red Hat, Inc. | ||
4 | * All Rights Reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it would be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write the Free Software Foundation, | ||
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
18 | */ | ||
19 | |||
20 | #include "xfs.h" | ||
21 | #include "xfs_fs.h" | ||
22 | #include "xfs_format.h" | ||
23 | #include "xfs_bit.h" | ||
24 | #include "xfs_log.h" | ||
25 | #include "xfs_trans.h" | ||
26 | #include "xfs_sb.h" | ||
27 | #include "xfs_ag.h" | ||
28 | #include "xfs_mount.h" | ||
29 | #include "xfs_da_btree.h" | ||
30 | #include "xfs_dir2_format.h" | ||
31 | #include "xfs_dir2.h" | ||
32 | #include "xfs_bmap_btree.h" | ||
33 | #include "xfs_ialloc_btree.h" | ||
34 | #include "xfs_dinode.h" | ||
35 | #include "xfs_inode.h" | ||
36 | #include "xfs_inode_item.h" | ||
37 | #include "xfs_itable.h" | ||
38 | #include "xfs_ialloc.h" | ||
39 | #include "xfs_alloc.h" | ||
40 | #include "xfs_bmap.h" | ||
41 | #include "xfs_bmap_util.h" | ||
42 | #include "xfs_acl.h" | ||
43 | #include "xfs_attr.h" | ||
44 | #include "xfs_error.h" | ||
45 | #include "xfs_quota.h" | ||
46 | #include "xfs_utils.h" | ||
47 | #include "xfs_rtalloc.h" | ||
48 | #include "xfs_trans_space.h" | ||
49 | #include "xfs_log_priv.h" | ||
50 | #include "xfs_filestream.h" | ||
51 | #include "xfs_vnodeops.h" | ||
52 | #include "xfs_trace.h" | ||
53 | #include "xfs_icache.h" | ||
54 | #include "xfs_symlink.h" | ||
55 | |||
56 | |||
57 | /* | ||
58 | * This is called by xfs_inactive to free any blocks beyond eof | ||
59 | * when the link count isn't zero and by xfs_dm_punch_hole() when | ||
60 | * punching a hole to EOF. | ||
61 | */ | ||
62 | int | ||
63 | xfs_free_eofblocks( | ||
64 | xfs_mount_t *mp, | ||
65 | xfs_inode_t *ip, | ||
66 | bool need_iolock) | ||
67 | { | ||
68 | xfs_trans_t *tp; | ||
69 | int error; | ||
70 | xfs_fileoff_t end_fsb; | ||
71 | xfs_fileoff_t last_fsb; | ||
72 | xfs_filblks_t map_len; | ||
73 | int nimaps; | ||
74 | xfs_bmbt_irec_t imap; | ||
75 | |||
76 | /* | ||
77 | * Figure out if there are any blocks beyond the end | ||
78 | * of the file. If not, then there is nothing to do. | ||
79 | */ | ||
80 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); | ||
81 | last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); | ||
82 | if (last_fsb <= end_fsb) | ||
83 | return 0; | ||
84 | map_len = last_fsb - end_fsb; | ||
85 | |||
86 | nimaps = 1; | ||
87 | xfs_ilock(ip, XFS_ILOCK_SHARED); | ||
88 | error = xfs_bmapi_read(ip, end_fsb, map_len, &imap, &nimaps, 0); | ||
89 | xfs_iunlock(ip, XFS_ILOCK_SHARED); | ||
90 | |||
91 | if (!error && (nimaps != 0) && | ||
92 | (imap.br_startblock != HOLESTARTBLOCK || | ||
93 | ip->i_delayed_blks)) { | ||
94 | /* | ||
95 | * Attach the dquots to the inode up front. | ||
96 | */ | ||
97 | error = xfs_qm_dqattach(ip, 0); | ||
98 | if (error) | ||
99 | return error; | ||
100 | |||
101 | /* | ||
102 | * There are blocks after the end of file. | ||
103 | * Free them up now by truncating the file to | ||
104 | * its current size. | ||
105 | */ | ||
106 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | ||
107 | |||
108 | if (need_iolock) { | ||
109 | if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { | ||
110 | xfs_trans_cancel(tp, 0); | ||
111 | return EAGAIN; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | error = xfs_trans_reserve(tp, 0, | ||
116 | XFS_ITRUNCATE_LOG_RES(mp), | ||
117 | 0, XFS_TRANS_PERM_LOG_RES, | ||
118 | XFS_ITRUNCATE_LOG_COUNT); | ||
119 | if (error) { | ||
120 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
121 | xfs_trans_cancel(tp, 0); | ||
122 | if (need_iolock) | ||
123 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
124 | return error; | ||
125 | } | ||
126 | |||
127 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
128 | xfs_trans_ijoin(tp, ip, 0); | ||
129 | |||
130 | /* | ||
131 | * Do not update the on-disk file size. If we update the | ||
132 | * on-disk file size and then the system crashes before the | ||
133 | * contents of the file are flushed to disk then the files | ||
134 | * may be full of holes (ie NULL files bug). | ||
135 | */ | ||
136 | error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, | ||
137 | XFS_ISIZE(ip)); | ||
138 | if (error) { | ||
139 | /* | ||
140 | * If we get an error at this point we simply don't | ||
141 | * bother truncating the file. | ||
142 | */ | ||
143 | xfs_trans_cancel(tp, | ||
144 | (XFS_TRANS_RELEASE_LOG_RES | | ||
145 | XFS_TRANS_ABORT)); | ||
146 | } else { | ||
147 | error = xfs_trans_commit(tp, | ||
148 | XFS_TRANS_RELEASE_LOG_RES); | ||
149 | if (!error) | ||
150 | xfs_inode_clear_eofblocks_tag(ip); | ||
151 | } | ||
152 | |||
153 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
154 | if (need_iolock) | ||
155 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
156 | } | ||
157 | return error; | ||
158 | } | ||
159 | |||
160 | int | ||
161 | xfs_release( | ||
162 | xfs_inode_t *ip) | ||
163 | { | ||
164 | xfs_mount_t *mp = ip->i_mount; | ||
165 | int error; | ||
166 | |||
167 | if (!S_ISREG(ip->i_d.di_mode) || (ip->i_d.di_mode == 0)) | ||
168 | return 0; | ||
169 | |||
170 | /* If this is a read-only mount, don't do this (would generate I/O) */ | ||
171 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
172 | return 0; | ||
173 | |||
174 | if (!XFS_FORCED_SHUTDOWN(mp)) { | ||
175 | int truncated; | ||
176 | |||
177 | /* | ||
178 | * If we are using filestreams, and we have an unlinked | ||
179 | * file that we are processing the last close on, then nothing | ||
180 | * will be able to reopen and write to this file. Purge this | ||
181 | * inode from the filestreams cache so that it doesn't delay | ||
182 | * teardown of the inode. | ||
183 | */ | ||
184 | if ((ip->i_d.di_nlink == 0) && xfs_inode_is_filestream(ip)) | ||
185 | xfs_filestream_deassociate(ip); | ||
186 | |||
187 | /* | ||
188 | * If we previously truncated this file and removed old data | ||
189 | * in the process, we want to initiate "early" writeout on | ||
190 | * the last close. This is an attempt to combat the notorious | ||
191 | * NULL files problem which is particularly noticeable from a | ||
192 | * truncate down, buffered (re-)write (delalloc), followed by | ||
193 | * a crash. What we are effectively doing here is | ||
194 | * significantly reducing the time window where we'd otherwise | ||
195 | * be exposed to that problem. | ||
196 | */ | ||
197 | truncated = xfs_iflags_test_and_clear(ip, XFS_ITRUNCATED); | ||
198 | if (truncated) { | ||
199 | xfs_iflags_clear(ip, XFS_IDIRTY_RELEASE); | ||
200 | if (VN_DIRTY(VFS_I(ip)) && ip->i_delayed_blks > 0) { | ||
201 | error = -filemap_flush(VFS_I(ip)->i_mapping); | ||
202 | if (error) | ||
203 | return error; | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | |||
208 | if (ip->i_d.di_nlink == 0) | ||
209 | return 0; | ||
210 | |||
211 | if (xfs_can_free_eofblocks(ip, false)) { | ||
212 | |||
213 | /* | ||
214 | * If we can't get the iolock just skip truncating the blocks | ||
215 | * past EOF because we could deadlock with the mmap_sem | ||
216 | * otherwise. We'll get another chance to drop them once the | ||
217 | * last reference to the inode is dropped, so we'll never leak | ||
218 | * blocks permanently. | ||
219 | * | ||
220 | * Further, check if the inode is being opened, written and | ||
221 | * closed frequently and we have delayed allocation blocks | ||
222 | * outstanding (e.g. streaming writes from the NFS server), | ||
223 | * truncating the blocks past EOF will cause fragmentation to | ||
224 | * occur. | ||
225 | * | ||
226 | * In this case don't do the truncation, either, but we have to | ||
227 | * be careful how we detect this case. Blocks beyond EOF show | ||
228 | * up as i_delayed_blks even when the inode is clean, so we | ||
229 | * need to truncate them away first before checking for a dirty | ||
230 | * release. Hence on the first dirty close we will still remove | ||
231 | * the speculative allocation, but after that we will leave it | ||
232 | * in place. | ||
233 | */ | ||
234 | if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) | ||
235 | return 0; | ||
236 | |||
237 | error = xfs_free_eofblocks(mp, ip, true); | ||
238 | if (error && error != EAGAIN) | ||
239 | return error; | ||
240 | |||
241 | /* delalloc blocks after truncation means it really is dirty */ | ||
242 | if (ip->i_delayed_blks) | ||
243 | xfs_iflags_set(ip, XFS_IDIRTY_RELEASE); | ||
244 | } | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * xfs_inactive | ||
250 | * | ||
251 | * This is called when the vnode reference count for the vnode | ||
252 | * goes to zero. If the file has been unlinked, then it must | ||
253 | * now be truncated. Also, we clear all of the read-ahead state | ||
254 | * kept for the inode here since the file is now closed. | ||
255 | */ | ||
256 | int | ||
257 | xfs_inactive( | ||
258 | xfs_inode_t *ip) | ||
259 | { | ||
260 | xfs_bmap_free_t free_list; | ||
261 | xfs_fsblock_t first_block; | ||
262 | int committed; | ||
263 | xfs_trans_t *tp; | ||
264 | xfs_mount_t *mp; | ||
265 | int error; | ||
266 | int truncate = 0; | ||
267 | |||
268 | /* | ||
269 | * If the inode is already free, then there can be nothing | ||
270 | * to clean up here. | ||
271 | */ | ||
272 | if (ip->i_d.di_mode == 0 || is_bad_inode(VFS_I(ip))) { | ||
273 | ASSERT(ip->i_df.if_real_bytes == 0); | ||
274 | ASSERT(ip->i_df.if_broot_bytes == 0); | ||
275 | return VN_INACTIVE_CACHE; | ||
276 | } | ||
277 | |||
278 | mp = ip->i_mount; | ||
279 | |||
280 | error = 0; | ||
281 | |||
282 | /* If this is a read-only mount, don't do this (would generate I/O) */ | ||
283 | if (mp->m_flags & XFS_MOUNT_RDONLY) | ||
284 | goto out; | ||
285 | |||
286 | if (ip->i_d.di_nlink != 0) { | ||
287 | /* | ||
288 | * force is true because we are evicting an inode from the | ||
289 | * cache. Post-eof blocks must be freed, lest we end up with | ||
290 | * broken free space accounting. | ||
291 | */ | ||
292 | if (xfs_can_free_eofblocks(ip, true)) { | ||
293 | error = xfs_free_eofblocks(mp, ip, false); | ||
294 | if (error) | ||
295 | return VN_INACTIVE_CACHE; | ||
296 | } | ||
297 | goto out; | ||
298 | } | ||
299 | |||
300 | if (S_ISREG(ip->i_d.di_mode) && | ||
301 | (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || | ||
302 | ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) | ||
303 | truncate = 1; | ||
304 | |||
305 | error = xfs_qm_dqattach(ip, 0); | ||
306 | if (error) | ||
307 | return VN_INACTIVE_CACHE; | ||
308 | |||
309 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | ||
310 | error = xfs_trans_reserve(tp, 0, | ||
311 | (truncate || S_ISLNK(ip->i_d.di_mode)) ? | ||
312 | XFS_ITRUNCATE_LOG_RES(mp) : | ||
313 | XFS_IFREE_LOG_RES(mp), | ||
314 | 0, | ||
315 | XFS_TRANS_PERM_LOG_RES, | ||
316 | XFS_ITRUNCATE_LOG_COUNT); | ||
317 | if (error) { | ||
318 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
319 | xfs_trans_cancel(tp, 0); | ||
320 | return VN_INACTIVE_CACHE; | ||
321 | } | ||
322 | |||
323 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
324 | xfs_trans_ijoin(tp, ip, 0); | ||
325 | |||
326 | if (S_ISLNK(ip->i_d.di_mode)) { | ||
327 | error = xfs_inactive_symlink(ip, &tp); | ||
328 | if (error) | ||
329 | goto out_cancel; | ||
330 | } else if (truncate) { | ||
331 | ip->i_d.di_size = 0; | ||
332 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
333 | |||
334 | error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0); | ||
335 | if (error) | ||
336 | goto out_cancel; | ||
337 | |||
338 | ASSERT(ip->i_d.di_nextents == 0); | ||
339 | } | ||
340 | |||
341 | /* | ||
342 | * If there are attributes associated with the file then blow them away | ||
343 | * now. The code calls a routine that recursively deconstructs the | ||
344 | * attribute fork. We need to just commit the current transaction | ||
345 | * because we can't use it for xfs_attr_inactive(). | ||
346 | */ | ||
347 | if (ip->i_d.di_anextents > 0) { | ||
348 | ASSERT(ip->i_d.di_forkoff != 0); | ||
349 | |||
350 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
351 | if (error) | ||
352 | goto out_unlock; | ||
353 | |||
354 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
355 | |||
356 | error = xfs_attr_inactive(ip); | ||
357 | if (error) | ||
358 | goto out; | ||
359 | |||
360 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | ||
361 | error = xfs_trans_reserve(tp, 0, | ||
362 | XFS_IFREE_LOG_RES(mp), | ||
363 | 0, XFS_TRANS_PERM_LOG_RES, | ||
364 | XFS_INACTIVE_LOG_COUNT); | ||
365 | if (error) { | ||
366 | xfs_trans_cancel(tp, 0); | ||
367 | goto out; | ||
368 | } | ||
369 | |||
370 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
371 | xfs_trans_ijoin(tp, ip, 0); | ||
372 | } | ||
373 | |||
374 | if (ip->i_afp) | ||
375 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); | ||
376 | |||
377 | ASSERT(ip->i_d.di_anextents == 0); | ||
378 | |||
379 | /* | ||
380 | * Free the inode. | ||
381 | */ | ||
382 | xfs_bmap_init(&free_list, &first_block); | ||
383 | error = xfs_ifree(tp, ip, &free_list); | ||
384 | if (error) { | ||
385 | /* | ||
386 | * If we fail to free the inode, shut down. The cancel | ||
387 | * might do that, we need to make sure. Otherwise the | ||
388 | * inode might be lost for a long time or forever. | ||
389 | */ | ||
390 | if (!XFS_FORCED_SHUTDOWN(mp)) { | ||
391 | xfs_notice(mp, "%s: xfs_ifree returned error %d", | ||
392 | __func__, error); | ||
393 | xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); | ||
394 | } | ||
395 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT); | ||
396 | } else { | ||
397 | /* | ||
398 | * Credit the quota account(s). The inode is gone. | ||
399 | */ | ||
400 | xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_ICOUNT, -1); | ||
401 | |||
402 | /* | ||
403 | * Just ignore errors at this point. There is nothing we can | ||
404 | * do except to try to keep going. Make sure it's not a silent | ||
405 | * error. | ||
406 | */ | ||
407 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
408 | if (error) | ||
409 | xfs_notice(mp, "%s: xfs_bmap_finish returned error %d", | ||
410 | __func__, error); | ||
411 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
412 | if (error) | ||
413 | xfs_notice(mp, "%s: xfs_trans_commit returned error %d", | ||
414 | __func__, error); | ||
415 | } | ||
416 | |||
417 | /* | ||
418 | * Release the dquots held by inode, if any. | ||
419 | */ | ||
420 | xfs_qm_dqdetach(ip); | ||
421 | out_unlock: | ||
422 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
423 | out: | ||
424 | return VN_INACTIVE_CACHE; | ||
425 | out_cancel: | ||
426 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
427 | goto out_unlock; | ||
428 | } | ||
429 | |||
430 | /* | ||
431 | * Lookups up an inode from "name". If ci_name is not NULL, then a CI match | ||
432 | * is allowed, otherwise it has to be an exact match. If a CI match is found, | ||
433 | * ci_name->name will point to a the actual name (caller must free) or | ||
434 | * will be set to NULL if an exact match is found. | ||
435 | */ | ||
436 | int | ||
437 | xfs_lookup( | ||
438 | xfs_inode_t *dp, | ||
439 | struct xfs_name *name, | ||
440 | xfs_inode_t **ipp, | ||
441 | struct xfs_name *ci_name) | ||
442 | { | ||
443 | xfs_ino_t inum; | ||
444 | int error; | ||
445 | uint lock_mode; | ||
446 | |||
447 | trace_xfs_lookup(dp, name); | ||
448 | |||
449 | if (XFS_FORCED_SHUTDOWN(dp->i_mount)) | ||
450 | return XFS_ERROR(EIO); | ||
451 | |||
452 | lock_mode = xfs_ilock_map_shared(dp); | ||
453 | error = xfs_dir_lookup(NULL, dp, name, &inum, ci_name); | ||
454 | xfs_iunlock_map_shared(dp, lock_mode); | ||
455 | |||
456 | if (error) | ||
457 | goto out; | ||
458 | |||
459 | error = xfs_iget(dp->i_mount, NULL, inum, 0, 0, ipp); | ||
460 | if (error) | ||
461 | goto out_free_name; | ||
462 | |||
463 | return 0; | ||
464 | |||
465 | out_free_name: | ||
466 | if (ci_name) | ||
467 | kmem_free(ci_name->name); | ||
468 | out: | ||
469 | *ipp = NULL; | ||
470 | return error; | ||
471 | } | ||
472 | |||
473 | int | ||
474 | xfs_create( | ||
475 | xfs_inode_t *dp, | ||
476 | struct xfs_name *name, | ||
477 | umode_t mode, | ||
478 | xfs_dev_t rdev, | ||
479 | xfs_inode_t **ipp) | ||
480 | { | ||
481 | int is_dir = S_ISDIR(mode); | ||
482 | struct xfs_mount *mp = dp->i_mount; | ||
483 | struct xfs_inode *ip = NULL; | ||
484 | struct xfs_trans *tp = NULL; | ||
485 | int error; | ||
486 | xfs_bmap_free_t free_list; | ||
487 | xfs_fsblock_t first_block; | ||
488 | bool unlock_dp_on_error = false; | ||
489 | uint cancel_flags; | ||
490 | int committed; | ||
491 | prid_t prid; | ||
492 | struct xfs_dquot *udqp = NULL; | ||
493 | struct xfs_dquot *gdqp = NULL; | ||
494 | struct xfs_dquot *pdqp = NULL; | ||
495 | uint resblks; | ||
496 | uint log_res; | ||
497 | uint log_count; | ||
498 | |||
499 | trace_xfs_create(dp, name); | ||
500 | |||
501 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
502 | return XFS_ERROR(EIO); | ||
503 | |||
504 | if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) | ||
505 | prid = xfs_get_projid(dp); | ||
506 | else | ||
507 | prid = XFS_PROJID_DEFAULT; | ||
508 | |||
509 | /* | ||
510 | * Make sure that we have allocated dquot(s) on disk. | ||
511 | */ | ||
512 | error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid, | ||
513 | XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, | ||
514 | &udqp, &gdqp, &pdqp); | ||
515 | if (error) | ||
516 | return error; | ||
517 | |||
518 | if (is_dir) { | ||
519 | rdev = 0; | ||
520 | resblks = XFS_MKDIR_SPACE_RES(mp, name->len); | ||
521 | log_res = XFS_MKDIR_LOG_RES(mp); | ||
522 | log_count = XFS_MKDIR_LOG_COUNT; | ||
523 | tp = xfs_trans_alloc(mp, XFS_TRANS_MKDIR); | ||
524 | } else { | ||
525 | resblks = XFS_CREATE_SPACE_RES(mp, name->len); | ||
526 | log_res = XFS_CREATE_LOG_RES(mp); | ||
527 | log_count = XFS_CREATE_LOG_COUNT; | ||
528 | tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE); | ||
529 | } | ||
530 | |||
531 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
532 | |||
533 | /* | ||
534 | * Initially assume that the file does not exist and | ||
535 | * reserve the resources for that case. If that is not | ||
536 | * the case we'll drop the one we have and get a more | ||
537 | * appropriate transaction later. | ||
538 | */ | ||
539 | error = xfs_trans_reserve(tp, resblks, log_res, 0, | ||
540 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
541 | if (error == ENOSPC) { | ||
542 | /* flush outstanding delalloc blocks and retry */ | ||
543 | xfs_flush_inodes(mp); | ||
544 | error = xfs_trans_reserve(tp, resblks, log_res, 0, | ||
545 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
546 | } | ||
547 | if (error == ENOSPC) { | ||
548 | /* No space at all so try a "no-allocation" reservation */ | ||
549 | resblks = 0; | ||
550 | error = xfs_trans_reserve(tp, 0, log_res, 0, | ||
551 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
552 | } | ||
553 | if (error) { | ||
554 | cancel_flags = 0; | ||
555 | goto out_trans_cancel; | ||
556 | } | ||
557 | |||
558 | xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT); | ||
559 | unlock_dp_on_error = true; | ||
560 | |||
561 | xfs_bmap_init(&free_list, &first_block); | ||
562 | |||
563 | /* | ||
564 | * Reserve disk quota and the inode. | ||
565 | */ | ||
566 | error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp, | ||
567 | pdqp, resblks, 1, 0); | ||
568 | if (error) | ||
569 | goto out_trans_cancel; | ||
570 | |||
571 | error = xfs_dir_canenter(tp, dp, name, resblks); | ||
572 | if (error) | ||
573 | goto out_trans_cancel; | ||
574 | |||
575 | /* | ||
576 | * A newly created regular or special file just has one directory | ||
577 | * entry pointing to them, but a directory also the "." entry | ||
578 | * pointing to itself. | ||
579 | */ | ||
580 | error = xfs_dir_ialloc(&tp, dp, mode, is_dir ? 2 : 1, rdev, | ||
581 | prid, resblks > 0, &ip, &committed); | ||
582 | if (error) { | ||
583 | if (error == ENOSPC) | ||
584 | goto out_trans_cancel; | ||
585 | goto out_trans_abort; | ||
586 | } | ||
587 | |||
588 | /* | ||
589 | * Now we join the directory inode to the transaction. We do not do it | ||
590 | * earlier because xfs_dir_ialloc might commit the previous transaction | ||
591 | * (and release all the locks). An error from here on will result in | ||
592 | * the transaction cancel unlocking dp so don't do it explicitly in the | ||
593 | * error path. | ||
594 | */ | ||
595 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | ||
596 | unlock_dp_on_error = false; | ||
597 | |||
598 | error = xfs_dir_createname(tp, dp, name, ip->i_ino, | ||
599 | &first_block, &free_list, resblks ? | ||
600 | resblks - XFS_IALLOC_SPACE_RES(mp) : 0); | ||
601 | if (error) { | ||
602 | ASSERT(error != ENOSPC); | ||
603 | goto out_trans_abort; | ||
604 | } | ||
605 | xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
606 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | ||
607 | |||
608 | if (is_dir) { | ||
609 | error = xfs_dir_init(tp, ip, dp); | ||
610 | if (error) | ||
611 | goto out_bmap_cancel; | ||
612 | |||
613 | error = xfs_bumplink(tp, dp); | ||
614 | if (error) | ||
615 | goto out_bmap_cancel; | ||
616 | } | ||
617 | |||
618 | /* | ||
619 | * If this is a synchronous mount, make sure that the | ||
620 | * create transaction goes to disk before returning to | ||
621 | * the user. | ||
622 | */ | ||
623 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) | ||
624 | xfs_trans_set_sync(tp); | ||
625 | |||
626 | /* | ||
627 | * Attach the dquot(s) to the inodes and modify them incore. | ||
628 | * These ids of the inode couldn't have changed since the new | ||
629 | * inode has been locked ever since it was created. | ||
630 | */ | ||
631 | xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); | ||
632 | |||
633 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
634 | if (error) | ||
635 | goto out_bmap_cancel; | ||
636 | |||
637 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
638 | if (error) | ||
639 | goto out_release_inode; | ||
640 | |||
641 | xfs_qm_dqrele(udqp); | ||
642 | xfs_qm_dqrele(gdqp); | ||
643 | xfs_qm_dqrele(pdqp); | ||
644 | |||
645 | *ipp = ip; | ||
646 | return 0; | ||
647 | |||
648 | out_bmap_cancel: | ||
649 | xfs_bmap_cancel(&free_list); | ||
650 | out_trans_abort: | ||
651 | cancel_flags |= XFS_TRANS_ABORT; | ||
652 | out_trans_cancel: | ||
653 | xfs_trans_cancel(tp, cancel_flags); | ||
654 | out_release_inode: | ||
655 | /* | ||
656 | * Wait until after the current transaction is aborted to | ||
657 | * release the inode. This prevents recursive transactions | ||
658 | * and deadlocks from xfs_inactive. | ||
659 | */ | ||
660 | if (ip) | ||
661 | IRELE(ip); | ||
662 | |||
663 | xfs_qm_dqrele(udqp); | ||
664 | xfs_qm_dqrele(gdqp); | ||
665 | xfs_qm_dqrele(pdqp); | ||
666 | |||
667 | if (unlock_dp_on_error) | ||
668 | xfs_iunlock(dp, XFS_ILOCK_EXCL); | ||
669 | return error; | ||
670 | } | ||
671 | |||
672 | #ifdef DEBUG | ||
673 | int xfs_locked_n; | ||
674 | int xfs_small_retries; | ||
675 | int xfs_middle_retries; | ||
676 | int xfs_lots_retries; | ||
677 | int xfs_lock_delays; | ||
678 | #endif | ||
679 | |||
680 | /* | ||
681 | * Bump the subclass so xfs_lock_inodes() acquires each lock with | ||
682 | * a different value | ||
683 | */ | ||
684 | static inline int | ||
685 | xfs_lock_inumorder(int lock_mode, int subclass) | ||
686 | { | ||
687 | if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) | ||
688 | lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_IOLOCK_SHIFT; | ||
689 | if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) | ||
690 | lock_mode |= (subclass + XFS_LOCK_INUMORDER) << XFS_ILOCK_SHIFT; | ||
691 | |||
692 | return lock_mode; | ||
693 | } | ||
694 | |||
695 | /* | ||
696 | * The following routine will lock n inodes in exclusive mode. | ||
697 | * We assume the caller calls us with the inodes in i_ino order. | ||
698 | * | ||
699 | * We need to detect deadlock where an inode that we lock | ||
700 | * is in the AIL and we start waiting for another inode that is locked | ||
701 | * by a thread in a long running transaction (such as truncate). This can | ||
702 | * result in deadlock since the long running trans might need to wait | ||
703 | * for the inode we just locked in order to push the tail and free space | ||
704 | * in the log. | ||
705 | */ | ||
706 | void | ||
707 | xfs_lock_inodes( | ||
708 | xfs_inode_t **ips, | ||
709 | int inodes, | ||
710 | uint lock_mode) | ||
711 | { | ||
712 | int attempts = 0, i, j, try_lock; | ||
713 | xfs_log_item_t *lp; | ||
714 | |||
715 | ASSERT(ips && (inodes >= 2)); /* we need at least two */ | ||
716 | |||
717 | try_lock = 0; | ||
718 | i = 0; | ||
719 | |||
720 | again: | ||
721 | for (; i < inodes; i++) { | ||
722 | ASSERT(ips[i]); | ||
723 | |||
724 | if (i && (ips[i] == ips[i-1])) /* Already locked */ | ||
725 | continue; | ||
726 | |||
727 | /* | ||
728 | * If try_lock is not set yet, make sure all locked inodes | ||
729 | * are not in the AIL. | ||
730 | * If any are, set try_lock to be used later. | ||
731 | */ | ||
732 | |||
733 | if (!try_lock) { | ||
734 | for (j = (i - 1); j >= 0 && !try_lock; j--) { | ||
735 | lp = (xfs_log_item_t *)ips[j]->i_itemp; | ||
736 | if (lp && (lp->li_flags & XFS_LI_IN_AIL)) { | ||
737 | try_lock++; | ||
738 | } | ||
739 | } | ||
740 | } | ||
741 | |||
742 | /* | ||
743 | * If any of the previous locks we have locked is in the AIL, | ||
744 | * we must TRY to get the second and subsequent locks. If | ||
745 | * we can't get any, we must release all we have | ||
746 | * and try again. | ||
747 | */ | ||
748 | |||
749 | if (try_lock) { | ||
750 | /* try_lock must be 0 if i is 0. */ | ||
751 | /* | ||
752 | * try_lock means we have an inode locked | ||
753 | * that is in the AIL. | ||
754 | */ | ||
755 | ASSERT(i != 0); | ||
756 | if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) { | ||
757 | attempts++; | ||
758 | |||
759 | /* | ||
760 | * Unlock all previous guys and try again. | ||
761 | * xfs_iunlock will try to push the tail | ||
762 | * if the inode is in the AIL. | ||
763 | */ | ||
764 | |||
765 | for(j = i - 1; j >= 0; j--) { | ||
766 | |||
767 | /* | ||
768 | * Check to see if we've already | ||
769 | * unlocked this one. | ||
770 | * Not the first one going back, | ||
771 | * and the inode ptr is the same. | ||
772 | */ | ||
773 | if ((j != (i - 1)) && ips[j] == | ||
774 | ips[j+1]) | ||
775 | continue; | ||
776 | |||
777 | xfs_iunlock(ips[j], lock_mode); | ||
778 | } | ||
779 | |||
780 | if ((attempts % 5) == 0) { | ||
781 | delay(1); /* Don't just spin the CPU */ | ||
782 | #ifdef DEBUG | ||
783 | xfs_lock_delays++; | ||
784 | #endif | ||
785 | } | ||
786 | i = 0; | ||
787 | try_lock = 0; | ||
788 | goto again; | ||
789 | } | ||
790 | } else { | ||
791 | xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i)); | ||
792 | } | ||
793 | } | ||
794 | |||
795 | #ifdef DEBUG | ||
796 | if (attempts) { | ||
797 | if (attempts < 5) xfs_small_retries++; | ||
798 | else if (attempts < 100) xfs_middle_retries++; | ||
799 | else xfs_lots_retries++; | ||
800 | } else { | ||
801 | xfs_locked_n++; | ||
802 | } | ||
803 | #endif | ||
804 | } | ||
805 | |||
806 | /* | ||
807 | * xfs_lock_two_inodes() can only be used to lock one type of lock | ||
808 | * at a time - the iolock or the ilock, but not both at once. If | ||
809 | * we lock both at once, lockdep will report false positives saying | ||
810 | * we have violated locking orders. | ||
811 | */ | ||
812 | void | ||
813 | xfs_lock_two_inodes( | ||
814 | xfs_inode_t *ip0, | ||
815 | xfs_inode_t *ip1, | ||
816 | uint lock_mode) | ||
817 | { | ||
818 | xfs_inode_t *temp; | ||
819 | int attempts = 0; | ||
820 | xfs_log_item_t *lp; | ||
821 | |||
822 | if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL)) | ||
823 | ASSERT((lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) == 0); | ||
824 | ASSERT(ip0->i_ino != ip1->i_ino); | ||
825 | |||
826 | if (ip0->i_ino > ip1->i_ino) { | ||
827 | temp = ip0; | ||
828 | ip0 = ip1; | ||
829 | ip1 = temp; | ||
830 | } | ||
831 | |||
832 | again: | ||
833 | xfs_ilock(ip0, xfs_lock_inumorder(lock_mode, 0)); | ||
834 | |||
835 | /* | ||
836 | * If the first lock we have locked is in the AIL, we must TRY to get | ||
837 | * the second lock. If we can't get it, we must release the first one | ||
838 | * and try again. | ||
839 | */ | ||
840 | lp = (xfs_log_item_t *)ip0->i_itemp; | ||
841 | if (lp && (lp->li_flags & XFS_LI_IN_AIL)) { | ||
842 | if (!xfs_ilock_nowait(ip1, xfs_lock_inumorder(lock_mode, 1))) { | ||
843 | xfs_iunlock(ip0, lock_mode); | ||
844 | if ((++attempts % 5) == 0) | ||
845 | delay(1); /* Don't just spin the CPU */ | ||
846 | goto again; | ||
847 | } | ||
848 | } else { | ||
849 | xfs_ilock(ip1, xfs_lock_inumorder(lock_mode, 1)); | ||
850 | } | ||
851 | } | ||
852 | |||
853 | int | ||
854 | xfs_remove( | ||
855 | xfs_inode_t *dp, | ||
856 | struct xfs_name *name, | ||
857 | xfs_inode_t *ip) | ||
858 | { | ||
859 | xfs_mount_t *mp = dp->i_mount; | ||
860 | xfs_trans_t *tp = NULL; | ||
861 | int is_dir = S_ISDIR(ip->i_d.di_mode); | ||
862 | int error = 0; | ||
863 | xfs_bmap_free_t free_list; | ||
864 | xfs_fsblock_t first_block; | ||
865 | int cancel_flags; | ||
866 | int committed; | ||
867 | int link_zero; | ||
868 | uint resblks; | ||
869 | uint log_count; | ||
870 | |||
871 | trace_xfs_remove(dp, name); | ||
872 | |||
873 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
874 | return XFS_ERROR(EIO); | ||
875 | |||
876 | error = xfs_qm_dqattach(dp, 0); | ||
877 | if (error) | ||
878 | goto std_return; | ||
879 | |||
880 | error = xfs_qm_dqattach(ip, 0); | ||
881 | if (error) | ||
882 | goto std_return; | ||
883 | |||
884 | if (is_dir) { | ||
885 | tp = xfs_trans_alloc(mp, XFS_TRANS_RMDIR); | ||
886 | log_count = XFS_DEFAULT_LOG_COUNT; | ||
887 | } else { | ||
888 | tp = xfs_trans_alloc(mp, XFS_TRANS_REMOVE); | ||
889 | log_count = XFS_REMOVE_LOG_COUNT; | ||
890 | } | ||
891 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
892 | |||
893 | /* | ||
894 | * We try to get the real space reservation first, | ||
895 | * allowing for directory btree deletion(s) implying | ||
896 | * possible bmap insert(s). If we can't get the space | ||
897 | * reservation then we use 0 instead, and avoid the bmap | ||
898 | * btree insert(s) in the directory code by, if the bmap | ||
899 | * insert tries to happen, instead trimming the LAST | ||
900 | * block from the directory. | ||
901 | */ | ||
902 | resblks = XFS_REMOVE_SPACE_RES(mp); | ||
903 | error = xfs_trans_reserve(tp, resblks, XFS_REMOVE_LOG_RES(mp), 0, | ||
904 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
905 | if (error == ENOSPC) { | ||
906 | resblks = 0; | ||
907 | error = xfs_trans_reserve(tp, 0, XFS_REMOVE_LOG_RES(mp), 0, | ||
908 | XFS_TRANS_PERM_LOG_RES, log_count); | ||
909 | } | ||
910 | if (error) { | ||
911 | ASSERT(error != ENOSPC); | ||
912 | cancel_flags = 0; | ||
913 | goto out_trans_cancel; | ||
914 | } | ||
915 | |||
916 | xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL); | ||
917 | |||
918 | xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL); | ||
919 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
920 | |||
921 | /* | ||
922 | * If we're removing a directory perform some additional validation. | ||
923 | */ | ||
924 | if (is_dir) { | ||
925 | ASSERT(ip->i_d.di_nlink >= 2); | ||
926 | if (ip->i_d.di_nlink != 2) { | ||
927 | error = XFS_ERROR(ENOTEMPTY); | ||
928 | goto out_trans_cancel; | ||
929 | } | ||
930 | if (!xfs_dir_isempty(ip)) { | ||
931 | error = XFS_ERROR(ENOTEMPTY); | ||
932 | goto out_trans_cancel; | ||
933 | } | ||
934 | } | ||
935 | |||
936 | xfs_bmap_init(&free_list, &first_block); | ||
937 | error = xfs_dir_removename(tp, dp, name, ip->i_ino, | ||
938 | &first_block, &free_list, resblks); | ||
939 | if (error) { | ||
940 | ASSERT(error != ENOENT); | ||
941 | goto out_bmap_cancel; | ||
942 | } | ||
943 | xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
944 | |||
945 | if (is_dir) { | ||
946 | /* | ||
947 | * Drop the link from ip's "..". | ||
948 | */ | ||
949 | error = xfs_droplink(tp, dp); | ||
950 | if (error) | ||
951 | goto out_bmap_cancel; | ||
952 | |||
953 | /* | ||
954 | * Drop the "." link from ip to self. | ||
955 | */ | ||
956 | error = xfs_droplink(tp, ip); | ||
957 | if (error) | ||
958 | goto out_bmap_cancel; | ||
959 | } else { | ||
960 | /* | ||
961 | * When removing a non-directory we need to log the parent | ||
962 | * inode here. For a directory this is done implicitly | ||
963 | * by the xfs_droplink call for the ".." entry. | ||
964 | */ | ||
965 | xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); | ||
966 | } | ||
967 | |||
968 | /* | ||
969 | * Drop the link from dp to ip. | ||
970 | */ | ||
971 | error = xfs_droplink(tp, ip); | ||
972 | if (error) | ||
973 | goto out_bmap_cancel; | ||
974 | |||
975 | /* | ||
976 | * Determine if this is the last link while | ||
977 | * we are in the transaction. | ||
978 | */ | ||
979 | link_zero = (ip->i_d.di_nlink == 0); | ||
980 | |||
981 | /* | ||
982 | * If this is a synchronous mount, make sure that the | ||
983 | * remove transaction goes to disk before returning to | ||
984 | * the user. | ||
985 | */ | ||
986 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) | ||
987 | xfs_trans_set_sync(tp); | ||
988 | |||
989 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
990 | if (error) | ||
991 | goto out_bmap_cancel; | ||
992 | |||
993 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
994 | if (error) | ||
995 | goto std_return; | ||
996 | |||
997 | /* | ||
998 | * If we are using filestreams, kill the stream association. | ||
999 | * If the file is still open it may get a new one but that | ||
1000 | * will get killed on last close in xfs_close() so we don't | ||
1001 | * have to worry about that. | ||
1002 | */ | ||
1003 | if (!is_dir && link_zero && xfs_inode_is_filestream(ip)) | ||
1004 | xfs_filestream_deassociate(ip); | ||
1005 | |||
1006 | return 0; | ||
1007 | |||
1008 | out_bmap_cancel: | ||
1009 | xfs_bmap_cancel(&free_list); | ||
1010 | cancel_flags |= XFS_TRANS_ABORT; | ||
1011 | out_trans_cancel: | ||
1012 | xfs_trans_cancel(tp, cancel_flags); | ||
1013 | std_return: | ||
1014 | return error; | ||
1015 | } | ||
1016 | |||
1017 | int | ||
1018 | xfs_link( | ||
1019 | xfs_inode_t *tdp, | ||
1020 | xfs_inode_t *sip, | ||
1021 | struct xfs_name *target_name) | ||
1022 | { | ||
1023 | xfs_mount_t *mp = tdp->i_mount; | ||
1024 | xfs_trans_t *tp; | ||
1025 | int error; | ||
1026 | xfs_bmap_free_t free_list; | ||
1027 | xfs_fsblock_t first_block; | ||
1028 | int cancel_flags; | ||
1029 | int committed; | ||
1030 | int resblks; | ||
1031 | |||
1032 | trace_xfs_link(tdp, target_name); | ||
1033 | |||
1034 | ASSERT(!S_ISDIR(sip->i_d.di_mode)); | ||
1035 | |||
1036 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
1037 | return XFS_ERROR(EIO); | ||
1038 | |||
1039 | error = xfs_qm_dqattach(sip, 0); | ||
1040 | if (error) | ||
1041 | goto std_return; | ||
1042 | |||
1043 | error = xfs_qm_dqattach(tdp, 0); | ||
1044 | if (error) | ||
1045 | goto std_return; | ||
1046 | |||
1047 | tp = xfs_trans_alloc(mp, XFS_TRANS_LINK); | ||
1048 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | ||
1049 | resblks = XFS_LINK_SPACE_RES(mp, target_name->len); | ||
1050 | error = xfs_trans_reserve(tp, resblks, XFS_LINK_LOG_RES(mp), 0, | ||
1051 | XFS_TRANS_PERM_LOG_RES, XFS_LINK_LOG_COUNT); | ||
1052 | if (error == ENOSPC) { | ||
1053 | resblks = 0; | ||
1054 | error = xfs_trans_reserve(tp, 0, XFS_LINK_LOG_RES(mp), 0, | ||
1055 | XFS_TRANS_PERM_LOG_RES, XFS_LINK_LOG_COUNT); | ||
1056 | } | ||
1057 | if (error) { | ||
1058 | cancel_flags = 0; | ||
1059 | goto error_return; | ||
1060 | } | ||
1061 | |||
1062 | xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL); | ||
1063 | |||
1064 | xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL); | ||
1065 | xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL); | ||
1066 | |||
1067 | /* | ||
1068 | * If we are using project inheritance, we only allow hard link | ||
1069 | * creation in our tree when the project IDs are the same; else | ||
1070 | * the tree quota mechanism could be circumvented. | ||
1071 | */ | ||
1072 | if (unlikely((tdp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT) && | ||
1073 | (xfs_get_projid(tdp) != xfs_get_projid(sip)))) { | ||
1074 | error = XFS_ERROR(EXDEV); | ||
1075 | goto error_return; | ||
1076 | } | ||
1077 | |||
1078 | error = xfs_dir_canenter(tp, tdp, target_name, resblks); | ||
1079 | if (error) | ||
1080 | goto error_return; | ||
1081 | |||
1082 | xfs_bmap_init(&free_list, &first_block); | ||
1083 | |||
1084 | error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino, | ||
1085 | &first_block, &free_list, resblks); | ||
1086 | if (error) | ||
1087 | goto abort_return; | ||
1088 | xfs_trans_ichgtime(tp, tdp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
1089 | xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE); | ||
1090 | |||
1091 | error = xfs_bumplink(tp, sip); | ||
1092 | if (error) | ||
1093 | goto abort_return; | ||
1094 | |||
1095 | /* | ||
1096 | * If this is a synchronous mount, make sure that the | ||
1097 | * link transaction goes to disk before returning to | ||
1098 | * the user. | ||
1099 | */ | ||
1100 | if (mp->m_flags & (XFS_MOUNT_WSYNC|XFS_MOUNT_DIRSYNC)) { | ||
1101 | xfs_trans_set_sync(tp); | ||
1102 | } | ||
1103 | |||
1104 | error = xfs_bmap_finish (&tp, &free_list, &committed); | ||
1105 | if (error) { | ||
1106 | xfs_bmap_cancel(&free_list); | ||
1107 | goto abort_return; | ||
1108 | } | ||
1109 | |||
1110 | return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
1111 | |||
1112 | abort_return: | ||
1113 | cancel_flags |= XFS_TRANS_ABORT; | ||
1114 | error_return: | ||
1115 | xfs_trans_cancel(tp, cancel_flags); | ||
1116 | std_return: | ||
1117 | return error; | ||
1118 | } | ||
1119 | |||
1120 | int | ||
1121 | xfs_set_dmattrs( | ||
1122 | xfs_inode_t *ip, | ||
1123 | u_int evmask, | ||
1124 | u_int16_t state) | ||
1125 | { | ||
1126 | xfs_mount_t *mp = ip->i_mount; | ||
1127 | xfs_trans_t *tp; | ||
1128 | int error; | ||
1129 | |||
1130 | if (!capable(CAP_SYS_ADMIN)) | ||
1131 | return XFS_ERROR(EPERM); | ||
1132 | |||
1133 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
1134 | return XFS_ERROR(EIO); | ||
1135 | |||
1136 | tp = xfs_trans_alloc(mp, XFS_TRANS_SET_DMATTRS); | ||
1137 | error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES (mp), 0, 0, 0); | ||
1138 | if (error) { | ||
1139 | xfs_trans_cancel(tp, 0); | ||
1140 | return error; | ||
1141 | } | ||
1142 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
1143 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
1144 | |||
1145 | ip->i_d.di_dmevmask = evmask; | ||
1146 | ip->i_d.di_dmstate = state; | ||
1147 | |||
1148 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
1149 | error = xfs_trans_commit(tp, 0); | ||
1150 | |||
1151 | return error; | ||
1152 | } | ||
1153 | |||
1154 | /* | ||
1155 | * xfs_alloc_file_space() | ||
1156 | * This routine allocates disk space for the given file. | ||
1157 | * | ||
1158 | * If alloc_type == 0, this request is for an ALLOCSP type | ||
1159 | * request which will change the file size. In this case, no | ||
1160 | * DMAPI event will be generated by the call. A TRUNCATE event | ||
1161 | * will be generated later by xfs_setattr. | ||
1162 | * | ||
1163 | * If alloc_type != 0, this request is for a RESVSP type | ||
1164 | * request, and a DMAPI DM_EVENT_WRITE will be generated if the | ||
1165 | * lower block boundary byte address is less than the file's | ||
1166 | * length. | ||
1167 | * | ||
1168 | * RETURNS: | ||
1169 | * 0 on success | ||
1170 | * errno on error | ||
1171 | * | ||
1172 | */ | ||
1173 | STATIC int | ||
1174 | xfs_alloc_file_space( | ||
1175 | xfs_inode_t *ip, | ||
1176 | xfs_off_t offset, | ||
1177 | xfs_off_t len, | ||
1178 | int alloc_type, | ||
1179 | int attr_flags) | ||
1180 | { | ||
1181 | xfs_mount_t *mp = ip->i_mount; | ||
1182 | xfs_off_t count; | ||
1183 | xfs_filblks_t allocated_fsb; | ||
1184 | xfs_filblks_t allocatesize_fsb; | ||
1185 | xfs_extlen_t extsz, temp; | ||
1186 | xfs_fileoff_t startoffset_fsb; | ||
1187 | xfs_fsblock_t firstfsb; | ||
1188 | int nimaps; | ||
1189 | int quota_flag; | ||
1190 | int rt; | ||
1191 | xfs_trans_t *tp; | ||
1192 | xfs_bmbt_irec_t imaps[1], *imapp; | ||
1193 | xfs_bmap_free_t free_list; | ||
1194 | uint qblocks, resblks, resrtextents; | ||
1195 | int committed; | ||
1196 | int error; | ||
1197 | |||
1198 | trace_xfs_alloc_file_space(ip); | ||
1199 | |||
1200 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
1201 | return XFS_ERROR(EIO); | ||
1202 | |||
1203 | error = xfs_qm_dqattach(ip, 0); | ||
1204 | if (error) | ||
1205 | return error; | ||
1206 | |||
1207 | if (len <= 0) | ||
1208 | return XFS_ERROR(EINVAL); | ||
1209 | |||
1210 | rt = XFS_IS_REALTIME_INODE(ip); | ||
1211 | extsz = xfs_get_extsz_hint(ip); | ||
1212 | |||
1213 | count = len; | ||
1214 | imapp = &imaps[0]; | ||
1215 | nimaps = 1; | ||
1216 | startoffset_fsb = XFS_B_TO_FSBT(mp, offset); | ||
1217 | allocatesize_fsb = XFS_B_TO_FSB(mp, count); | ||
1218 | |||
1219 | /* | ||
1220 | * Allocate file space until done or until there is an error | ||
1221 | */ | ||
1222 | while (allocatesize_fsb && !error) { | ||
1223 | xfs_fileoff_t s, e; | ||
1224 | |||
1225 | /* | ||
1226 | * Determine space reservations for data/realtime. | ||
1227 | */ | ||
1228 | if (unlikely(extsz)) { | ||
1229 | s = startoffset_fsb; | ||
1230 | do_div(s, extsz); | ||
1231 | s *= extsz; | ||
1232 | e = startoffset_fsb + allocatesize_fsb; | ||
1233 | if ((temp = do_mod(startoffset_fsb, extsz))) | ||
1234 | e += temp; | ||
1235 | if ((temp = do_mod(e, extsz))) | ||
1236 | e += extsz - temp; | ||
1237 | } else { | ||
1238 | s = 0; | ||
1239 | e = allocatesize_fsb; | ||
1240 | } | ||
1241 | |||
1242 | /* | ||
1243 | * The transaction reservation is limited to a 32-bit block | ||
1244 | * count, hence we need to limit the number of blocks we are | ||
1245 | * trying to reserve to avoid an overflow. We can't allocate | ||
1246 | * more than @nimaps extents, and an extent is limited on disk | ||
1247 | * to MAXEXTLEN (21 bits), so use that to enforce the limit. | ||
1248 | */ | ||
1249 | resblks = min_t(xfs_fileoff_t, (e - s), (MAXEXTLEN * nimaps)); | ||
1250 | if (unlikely(rt)) { | ||
1251 | resrtextents = qblocks = resblks; | ||
1252 | resrtextents /= mp->m_sb.sb_rextsize; | ||
1253 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); | ||
1254 | quota_flag = XFS_QMOPT_RES_RTBLKS; | ||
1255 | } else { | ||
1256 | resrtextents = 0; | ||
1257 | resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resblks); | ||
1258 | quota_flag = XFS_QMOPT_RES_REGBLKS; | ||
1259 | } | ||
1260 | |||
1261 | /* | ||
1262 | * Allocate and setup the transaction. | ||
1263 | */ | ||
1264 | tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); | ||
1265 | error = xfs_trans_reserve(tp, resblks, | ||
1266 | XFS_WRITE_LOG_RES(mp), resrtextents, | ||
1267 | XFS_TRANS_PERM_LOG_RES, | ||
1268 | XFS_WRITE_LOG_COUNT); | ||
1269 | /* | ||
1270 | * Check for running out of space | ||
1271 | */ | ||
1272 | if (error) { | ||
1273 | /* | ||
1274 | * Free the transaction structure. | ||
1275 | */ | ||
1276 | ASSERT(error == ENOSPC || XFS_FORCED_SHUTDOWN(mp)); | ||
1277 | xfs_trans_cancel(tp, 0); | ||
1278 | break; | ||
1279 | } | ||
1280 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
1281 | error = xfs_trans_reserve_quota_nblks(tp, ip, qblocks, | ||
1282 | 0, quota_flag); | ||
1283 | if (error) | ||
1284 | goto error1; | ||
1285 | |||
1286 | xfs_trans_ijoin(tp, ip, 0); | ||
1287 | |||
1288 | xfs_bmap_init(&free_list, &firstfsb); | ||
1289 | error = xfs_bmapi_write(tp, ip, startoffset_fsb, | ||
1290 | allocatesize_fsb, alloc_type, &firstfsb, | ||
1291 | 0, imapp, &nimaps, &free_list); | ||
1292 | if (error) { | ||
1293 | goto error0; | ||
1294 | } | ||
1295 | |||
1296 | /* | ||
1297 | * Complete the transaction | ||
1298 | */ | ||
1299 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
1300 | if (error) { | ||
1301 | goto error0; | ||
1302 | } | ||
1303 | |||
1304 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
1305 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
1306 | if (error) { | ||
1307 | break; | ||
1308 | } | ||
1309 | |||
1310 | allocated_fsb = imapp->br_blockcount; | ||
1311 | |||
1312 | if (nimaps == 0) { | ||
1313 | error = XFS_ERROR(ENOSPC); | ||
1314 | break; | ||
1315 | } | ||
1316 | |||
1317 | startoffset_fsb += allocated_fsb; | ||
1318 | allocatesize_fsb -= allocated_fsb; | ||
1319 | } | ||
1320 | |||
1321 | return error; | ||
1322 | |||
1323 | error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ | ||
1324 | xfs_bmap_cancel(&free_list); | ||
1325 | xfs_trans_unreserve_quota_nblks(tp, ip, (long)qblocks, 0, quota_flag); | ||
1326 | |||
1327 | error1: /* Just cancel transaction */ | ||
1328 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
1329 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
1330 | return error; | ||
1331 | } | ||
1332 | |||
1333 | /* | ||
1334 | * Zero file bytes between startoff and endoff inclusive. | ||
1335 | * The iolock is held exclusive and no blocks are buffered. | ||
1336 | * | ||
1337 | * This function is used by xfs_free_file_space() to zero | ||
1338 | * partial blocks when the range to free is not block aligned. | ||
1339 | * When unreserving space with boundaries that are not block | ||
1340 | * aligned we round up the start and round down the end | ||
1341 | * boundaries and then use this function to zero the parts of | ||
1342 | * the blocks that got dropped during the rounding. | ||
1343 | */ | ||
1344 | STATIC int | ||
1345 | xfs_zero_remaining_bytes( | ||
1346 | xfs_inode_t *ip, | ||
1347 | xfs_off_t startoff, | ||
1348 | xfs_off_t endoff) | ||
1349 | { | ||
1350 | xfs_bmbt_irec_t imap; | ||
1351 | xfs_fileoff_t offset_fsb; | ||
1352 | xfs_off_t lastoffset; | ||
1353 | xfs_off_t offset; | ||
1354 | xfs_buf_t *bp; | ||
1355 | xfs_mount_t *mp = ip->i_mount; | ||
1356 | int nimap; | ||
1357 | int error = 0; | ||
1358 | |||
1359 | /* | ||
1360 | * Avoid doing I/O beyond eof - it's not necessary | ||
1361 | * since nothing can read beyond eof. The space will | ||
1362 | * be zeroed when the file is extended anyway. | ||
1363 | */ | ||
1364 | if (startoff >= XFS_ISIZE(ip)) | ||
1365 | return 0; | ||
1366 | |||
1367 | if (endoff > XFS_ISIZE(ip)) | ||
1368 | endoff = XFS_ISIZE(ip); | ||
1369 | |||
1370 | bp = xfs_buf_get_uncached(XFS_IS_REALTIME_INODE(ip) ? | ||
1371 | mp->m_rtdev_targp : mp->m_ddev_targp, | ||
1372 | BTOBB(mp->m_sb.sb_blocksize), 0); | ||
1373 | if (!bp) | ||
1374 | return XFS_ERROR(ENOMEM); | ||
1375 | |||
1376 | xfs_buf_unlock(bp); | ||
1377 | |||
1378 | for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { | ||
1379 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | ||
1380 | nimap = 1; | ||
1381 | error = xfs_bmapi_read(ip, offset_fsb, 1, &imap, &nimap, 0); | ||
1382 | if (error || nimap < 1) | ||
1383 | break; | ||
1384 | ASSERT(imap.br_blockcount >= 1); | ||
1385 | ASSERT(imap.br_startoff == offset_fsb); | ||
1386 | lastoffset = XFS_FSB_TO_B(mp, imap.br_startoff + 1) - 1; | ||
1387 | if (lastoffset > endoff) | ||
1388 | lastoffset = endoff; | ||
1389 | if (imap.br_startblock == HOLESTARTBLOCK) | ||
1390 | continue; | ||
1391 | ASSERT(imap.br_startblock != DELAYSTARTBLOCK); | ||
1392 | if (imap.br_state == XFS_EXT_UNWRITTEN) | ||
1393 | continue; | ||
1394 | XFS_BUF_UNDONE(bp); | ||
1395 | XFS_BUF_UNWRITE(bp); | ||
1396 | XFS_BUF_READ(bp); | ||
1397 | XFS_BUF_SET_ADDR(bp, xfs_fsb_to_db(ip, imap.br_startblock)); | ||
1398 | xfsbdstrat(mp, bp); | ||
1399 | error = xfs_buf_iowait(bp); | ||
1400 | if (error) { | ||
1401 | xfs_buf_ioerror_alert(bp, | ||
1402 | "xfs_zero_remaining_bytes(read)"); | ||
1403 | break; | ||
1404 | } | ||
1405 | memset(bp->b_addr + | ||
1406 | (offset - XFS_FSB_TO_B(mp, imap.br_startoff)), | ||
1407 | 0, lastoffset - offset + 1); | ||
1408 | XFS_BUF_UNDONE(bp); | ||
1409 | XFS_BUF_UNREAD(bp); | ||
1410 | XFS_BUF_WRITE(bp); | ||
1411 | xfsbdstrat(mp, bp); | ||
1412 | error = xfs_buf_iowait(bp); | ||
1413 | if (error) { | ||
1414 | xfs_buf_ioerror_alert(bp, | ||
1415 | "xfs_zero_remaining_bytes(write)"); | ||
1416 | break; | ||
1417 | } | ||
1418 | } | ||
1419 | xfs_buf_free(bp); | ||
1420 | return error; | ||
1421 | } | ||
1422 | |||
1423 | /* | ||
1424 | * xfs_free_file_space() | ||
1425 | * This routine frees disk space for the given file. | ||
1426 | * | ||
1427 | * This routine is only called by xfs_change_file_space | ||
1428 | * for an UNRESVSP type call. | ||
1429 | * | ||
1430 | * RETURNS: | ||
1431 | * 0 on success | ||
1432 | * errno on error | ||
1433 | * | ||
1434 | */ | ||
1435 | STATIC int | ||
1436 | xfs_free_file_space( | ||
1437 | xfs_inode_t *ip, | ||
1438 | xfs_off_t offset, | ||
1439 | xfs_off_t len, | ||
1440 | int attr_flags) | ||
1441 | { | ||
1442 | int committed; | ||
1443 | int done; | ||
1444 | xfs_fileoff_t endoffset_fsb; | ||
1445 | int error; | ||
1446 | xfs_fsblock_t firstfsb; | ||
1447 | xfs_bmap_free_t free_list; | ||
1448 | xfs_bmbt_irec_t imap; | ||
1449 | xfs_off_t ioffset; | ||
1450 | xfs_extlen_t mod=0; | ||
1451 | xfs_mount_t *mp; | ||
1452 | int nimap; | ||
1453 | uint resblks; | ||
1454 | xfs_off_t rounding; | ||
1455 | int rt; | ||
1456 | xfs_fileoff_t startoffset_fsb; | ||
1457 | xfs_trans_t *tp; | ||
1458 | int need_iolock = 1; | ||
1459 | |||
1460 | mp = ip->i_mount; | ||
1461 | |||
1462 | trace_xfs_free_file_space(ip); | ||
1463 | |||
1464 | error = xfs_qm_dqattach(ip, 0); | ||
1465 | if (error) | ||
1466 | return error; | ||
1467 | |||
1468 | error = 0; | ||
1469 | if (len <= 0) /* if nothing being freed */ | ||
1470 | return error; | ||
1471 | rt = XFS_IS_REALTIME_INODE(ip); | ||
1472 | startoffset_fsb = XFS_B_TO_FSB(mp, offset); | ||
1473 | endoffset_fsb = XFS_B_TO_FSBT(mp, offset + len); | ||
1474 | |||
1475 | if (attr_flags & XFS_ATTR_NOLOCK) | ||
1476 | need_iolock = 0; | ||
1477 | if (need_iolock) { | ||
1478 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
1479 | /* wait for the completion of any pending DIOs */ | ||
1480 | inode_dio_wait(VFS_I(ip)); | ||
1481 | } | ||
1482 | |||
1483 | rounding = max_t(xfs_off_t, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); | ||
1484 | ioffset = offset & ~(rounding - 1); | ||
1485 | error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping, | ||
1486 | ioffset, -1); | ||
1487 | if (error) | ||
1488 | goto out_unlock_iolock; | ||
1489 | truncate_pagecache_range(VFS_I(ip), ioffset, -1); | ||
1490 | |||
1491 | /* | ||
1492 | * Need to zero the stuff we're not freeing, on disk. | ||
1493 | * If it's a realtime file & can't use unwritten extents then we | ||
1494 | * actually need to zero the extent edges. Otherwise xfs_bunmapi | ||
1495 | * will take care of it for us. | ||
1496 | */ | ||
1497 | if (rt && !xfs_sb_version_hasextflgbit(&mp->m_sb)) { | ||
1498 | nimap = 1; | ||
1499 | error = xfs_bmapi_read(ip, startoffset_fsb, 1, | ||
1500 | &imap, &nimap, 0); | ||
1501 | if (error) | ||
1502 | goto out_unlock_iolock; | ||
1503 | ASSERT(nimap == 0 || nimap == 1); | ||
1504 | if (nimap && imap.br_startblock != HOLESTARTBLOCK) { | ||
1505 | xfs_daddr_t block; | ||
1506 | |||
1507 | ASSERT(imap.br_startblock != DELAYSTARTBLOCK); | ||
1508 | block = imap.br_startblock; | ||
1509 | mod = do_div(block, mp->m_sb.sb_rextsize); | ||
1510 | if (mod) | ||
1511 | startoffset_fsb += mp->m_sb.sb_rextsize - mod; | ||
1512 | } | ||
1513 | nimap = 1; | ||
1514 | error = xfs_bmapi_read(ip, endoffset_fsb - 1, 1, | ||
1515 | &imap, &nimap, 0); | ||
1516 | if (error) | ||
1517 | goto out_unlock_iolock; | ||
1518 | ASSERT(nimap == 0 || nimap == 1); | ||
1519 | if (nimap && imap.br_startblock != HOLESTARTBLOCK) { | ||
1520 | ASSERT(imap.br_startblock != DELAYSTARTBLOCK); | ||
1521 | mod++; | ||
1522 | if (mod && (mod != mp->m_sb.sb_rextsize)) | ||
1523 | endoffset_fsb -= mod; | ||
1524 | } | ||
1525 | } | ||
1526 | if ((done = (endoffset_fsb <= startoffset_fsb))) | ||
1527 | /* | ||
1528 | * One contiguous piece to clear | ||
1529 | */ | ||
1530 | error = xfs_zero_remaining_bytes(ip, offset, offset + len - 1); | ||
1531 | else { | ||
1532 | /* | ||
1533 | * Some full blocks, possibly two pieces to clear | ||
1534 | */ | ||
1535 | if (offset < XFS_FSB_TO_B(mp, startoffset_fsb)) | ||
1536 | error = xfs_zero_remaining_bytes(ip, offset, | ||
1537 | XFS_FSB_TO_B(mp, startoffset_fsb) - 1); | ||
1538 | if (!error && | ||
1539 | XFS_FSB_TO_B(mp, endoffset_fsb) < offset + len) | ||
1540 | error = xfs_zero_remaining_bytes(ip, | ||
1541 | XFS_FSB_TO_B(mp, endoffset_fsb), | ||
1542 | offset + len - 1); | ||
1543 | } | ||
1544 | |||
1545 | /* | ||
1546 | * free file space until done or until there is an error | ||
1547 | */ | ||
1548 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); | ||
1549 | while (!error && !done) { | ||
1550 | |||
1551 | /* | ||
1552 | * allocate and setup the transaction. Allow this | ||
1553 | * transaction to dip into the reserve blocks to ensure | ||
1554 | * the freeing of the space succeeds at ENOSPC. | ||
1555 | */ | ||
1556 | tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); | ||
1557 | tp->t_flags |= XFS_TRANS_RESERVE; | ||
1558 | error = xfs_trans_reserve(tp, | ||
1559 | resblks, | ||
1560 | XFS_WRITE_LOG_RES(mp), | ||
1561 | 0, | ||
1562 | XFS_TRANS_PERM_LOG_RES, | ||
1563 | XFS_WRITE_LOG_COUNT); | ||
1564 | |||
1565 | /* | ||
1566 | * check for running out of space | ||
1567 | */ | ||
1568 | if (error) { | ||
1569 | /* | ||
1570 | * Free the transaction structure. | ||
1571 | */ | ||
1572 | ASSERT(error == ENOSPC || XFS_FORCED_SHUTDOWN(mp)); | ||
1573 | xfs_trans_cancel(tp, 0); | ||
1574 | break; | ||
1575 | } | ||
1576 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
1577 | error = xfs_trans_reserve_quota(tp, mp, | ||
1578 | ip->i_udquot, ip->i_gdquot, ip->i_pdquot, | ||
1579 | resblks, 0, XFS_QMOPT_RES_REGBLKS); | ||
1580 | if (error) | ||
1581 | goto error1; | ||
1582 | |||
1583 | xfs_trans_ijoin(tp, ip, 0); | ||
1584 | |||
1585 | /* | ||
1586 | * issue the bunmapi() call to free the blocks | ||
1587 | */ | ||
1588 | xfs_bmap_init(&free_list, &firstfsb); | ||
1589 | error = xfs_bunmapi(tp, ip, startoffset_fsb, | ||
1590 | endoffset_fsb - startoffset_fsb, | ||
1591 | 0, 2, &firstfsb, &free_list, &done); | ||
1592 | if (error) { | ||
1593 | goto error0; | ||
1594 | } | ||
1595 | |||
1596 | /* | ||
1597 | * complete the transaction | ||
1598 | */ | ||
1599 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
1600 | if (error) { | ||
1601 | goto error0; | ||
1602 | } | ||
1603 | |||
1604 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
1605 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
1606 | } | ||
1607 | |||
1608 | out_unlock_iolock: | ||
1609 | if (need_iolock) | ||
1610 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
1611 | return error; | ||
1612 | |||
1613 | error0: | ||
1614 | xfs_bmap_cancel(&free_list); | ||
1615 | error1: | ||
1616 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
1617 | xfs_iunlock(ip, need_iolock ? (XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL) : | ||
1618 | XFS_ILOCK_EXCL); | ||
1619 | return error; | ||
1620 | } | ||
1621 | |||
1622 | |||
1623 | STATIC int | ||
1624 | xfs_zero_file_space( | ||
1625 | struct xfs_inode *ip, | ||
1626 | xfs_off_t offset, | ||
1627 | xfs_off_t len, | ||
1628 | int attr_flags) | ||
1629 | { | ||
1630 | struct xfs_mount *mp = ip->i_mount; | ||
1631 | uint granularity; | ||
1632 | xfs_off_t start_boundary; | ||
1633 | xfs_off_t end_boundary; | ||
1634 | int error; | ||
1635 | |||
1636 | granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); | ||
1637 | |||
1638 | /* | ||
1639 | * Round the range of extents we are going to convert inwards. If the | ||
1640 | * offset is aligned, then it doesn't get changed so we zero from the | ||
1641 | * start of the block offset points to. | ||
1642 | */ | ||
1643 | start_boundary = round_up(offset, granularity); | ||
1644 | end_boundary = round_down(offset + len, granularity); | ||
1645 | |||
1646 | ASSERT(start_boundary >= offset); | ||
1647 | ASSERT(end_boundary <= offset + len); | ||
1648 | |||
1649 | if (!(attr_flags & XFS_ATTR_NOLOCK)) | ||
1650 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
1651 | |||
1652 | if (start_boundary < end_boundary - 1) { | ||
1653 | /* punch out the page cache over the conversion range */ | ||
1654 | truncate_pagecache_range(VFS_I(ip), start_boundary, | ||
1655 | end_boundary - 1); | ||
1656 | /* convert the blocks */ | ||
1657 | error = xfs_alloc_file_space(ip, start_boundary, | ||
1658 | end_boundary - start_boundary - 1, | ||
1659 | XFS_BMAPI_PREALLOC | XFS_BMAPI_CONVERT, | ||
1660 | attr_flags); | ||
1661 | if (error) | ||
1662 | goto out_unlock; | ||
1663 | |||
1664 | /* We've handled the interior of the range, now for the edges */ | ||
1665 | if (start_boundary != offset) | ||
1666 | error = xfs_iozero(ip, offset, start_boundary - offset); | ||
1667 | if (error) | ||
1668 | goto out_unlock; | ||
1669 | |||
1670 | if (end_boundary != offset + len) | ||
1671 | error = xfs_iozero(ip, end_boundary, | ||
1672 | offset + len - end_boundary); | ||
1673 | |||
1674 | } else { | ||
1675 | /* | ||
1676 | * It's either a sub-granularity range or the range spanned lies | ||
1677 | * partially across two adjacent blocks. | ||
1678 | */ | ||
1679 | error = xfs_iozero(ip, offset, len); | ||
1680 | } | ||
1681 | |||
1682 | out_unlock: | ||
1683 | if (!(attr_flags & XFS_ATTR_NOLOCK)) | ||
1684 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
1685 | return error; | ||
1686 | |||
1687 | } | ||
1688 | |||
1689 | /* | ||
1690 | * xfs_change_file_space() | ||
1691 | * This routine allocates or frees disk space for the given file. | ||
1692 | * The user specified parameters are checked for alignment and size | ||
1693 | * limitations. | ||
1694 | * | ||
1695 | * RETURNS: | ||
1696 | * 0 on success | ||
1697 | * errno on error | ||
1698 | * | ||
1699 | */ | ||
1700 | int | ||
1701 | xfs_change_file_space( | ||
1702 | xfs_inode_t *ip, | ||
1703 | int cmd, | ||
1704 | xfs_flock64_t *bf, | ||
1705 | xfs_off_t offset, | ||
1706 | int attr_flags) | ||
1707 | { | ||
1708 | xfs_mount_t *mp = ip->i_mount; | ||
1709 | int clrprealloc; | ||
1710 | int error; | ||
1711 | xfs_fsize_t fsize; | ||
1712 | int setprealloc; | ||
1713 | xfs_off_t startoffset; | ||
1714 | xfs_trans_t *tp; | ||
1715 | struct iattr iattr; | ||
1716 | |||
1717 | if (!S_ISREG(ip->i_d.di_mode)) | ||
1718 | return XFS_ERROR(EINVAL); | ||
1719 | |||
1720 | switch (bf->l_whence) { | ||
1721 | case 0: /*SEEK_SET*/ | ||
1722 | break; | ||
1723 | case 1: /*SEEK_CUR*/ | ||
1724 | bf->l_start += offset; | ||
1725 | break; | ||
1726 | case 2: /*SEEK_END*/ | ||
1727 | bf->l_start += XFS_ISIZE(ip); | ||
1728 | break; | ||
1729 | default: | ||
1730 | return XFS_ERROR(EINVAL); | ||
1731 | } | ||
1732 | |||
1733 | /* | ||
1734 | * length of <= 0 for resv/unresv/zero is invalid. length for | ||
1735 | * alloc/free is ignored completely and we have no idea what userspace | ||
1736 | * might have set it to, so set it to zero to allow range | ||
1737 | * checks to pass. | ||
1738 | */ | ||
1739 | switch (cmd) { | ||
1740 | case XFS_IOC_ZERO_RANGE: | ||
1741 | case XFS_IOC_RESVSP: | ||
1742 | case XFS_IOC_RESVSP64: | ||
1743 | case XFS_IOC_UNRESVSP: | ||
1744 | case XFS_IOC_UNRESVSP64: | ||
1745 | if (bf->l_len <= 0) | ||
1746 | return XFS_ERROR(EINVAL); | ||
1747 | break; | ||
1748 | default: | ||
1749 | bf->l_len = 0; | ||
1750 | break; | ||
1751 | } | ||
1752 | |||
1753 | if (bf->l_start < 0 || | ||
1754 | bf->l_start > mp->m_super->s_maxbytes || | ||
1755 | bf->l_start + bf->l_len < 0 || | ||
1756 | bf->l_start + bf->l_len >= mp->m_super->s_maxbytes) | ||
1757 | return XFS_ERROR(EINVAL); | ||
1758 | |||
1759 | bf->l_whence = 0; | ||
1760 | |||
1761 | startoffset = bf->l_start; | ||
1762 | fsize = XFS_ISIZE(ip); | ||
1763 | |||
1764 | setprealloc = clrprealloc = 0; | ||
1765 | switch (cmd) { | ||
1766 | case XFS_IOC_ZERO_RANGE: | ||
1767 | error = xfs_zero_file_space(ip, startoffset, bf->l_len, | ||
1768 | attr_flags); | ||
1769 | if (error) | ||
1770 | return error; | ||
1771 | setprealloc = 1; | ||
1772 | break; | ||
1773 | |||
1774 | case XFS_IOC_RESVSP: | ||
1775 | case XFS_IOC_RESVSP64: | ||
1776 | error = xfs_alloc_file_space(ip, startoffset, bf->l_len, | ||
1777 | XFS_BMAPI_PREALLOC, attr_flags); | ||
1778 | if (error) | ||
1779 | return error; | ||
1780 | setprealloc = 1; | ||
1781 | break; | ||
1782 | |||
1783 | case XFS_IOC_UNRESVSP: | ||
1784 | case XFS_IOC_UNRESVSP64: | ||
1785 | if ((error = xfs_free_file_space(ip, startoffset, bf->l_len, | ||
1786 | attr_flags))) | ||
1787 | return error; | ||
1788 | break; | ||
1789 | |||
1790 | case XFS_IOC_ALLOCSP: | ||
1791 | case XFS_IOC_ALLOCSP64: | ||
1792 | case XFS_IOC_FREESP: | ||
1793 | case XFS_IOC_FREESP64: | ||
1794 | /* | ||
1795 | * These operations actually do IO when extending the file, but | ||
1796 | * the allocation is done seperately to the zeroing that is | ||
1797 | * done. This set of operations need to be serialised against | ||
1798 | * other IO operations, such as truncate and buffered IO. We | ||
1799 | * need to take the IOLOCK here to serialise the allocation and | ||
1800 | * zeroing IO to prevent other IOLOCK holders (e.g. getbmap, | ||
1801 | * truncate, direct IO) from racing against the transient | ||
1802 | * allocated but not written state we can have here. | ||
1803 | */ | ||
1804 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
1805 | if (startoffset > fsize) { | ||
1806 | error = xfs_alloc_file_space(ip, fsize, | ||
1807 | startoffset - fsize, 0, | ||
1808 | attr_flags | XFS_ATTR_NOLOCK); | ||
1809 | if (error) { | ||
1810 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
1811 | break; | ||
1812 | } | ||
1813 | } | ||
1814 | |||
1815 | iattr.ia_valid = ATTR_SIZE; | ||
1816 | iattr.ia_size = startoffset; | ||
1817 | |||
1818 | error = xfs_setattr_size(ip, &iattr, | ||
1819 | attr_flags | XFS_ATTR_NOLOCK); | ||
1820 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
1821 | |||
1822 | if (error) | ||
1823 | return error; | ||
1824 | |||
1825 | clrprealloc = 1; | ||
1826 | break; | ||
1827 | |||
1828 | default: | ||
1829 | ASSERT(0); | ||
1830 | return XFS_ERROR(EINVAL); | ||
1831 | } | ||
1832 | |||
1833 | /* | ||
1834 | * update the inode timestamp, mode, and prealloc flag bits | ||
1835 | */ | ||
1836 | tp = xfs_trans_alloc(mp, XFS_TRANS_WRITEID); | ||
1837 | |||
1838 | if ((error = xfs_trans_reserve(tp, 0, XFS_WRITEID_LOG_RES(mp), | ||
1839 | 0, 0, 0))) { | ||
1840 | /* ASSERT(0); */ | ||
1841 | xfs_trans_cancel(tp, 0); | ||
1842 | return error; | ||
1843 | } | ||
1844 | |||
1845 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
1846 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
1847 | |||
1848 | if ((attr_flags & XFS_ATTR_DMI) == 0) { | ||
1849 | ip->i_d.di_mode &= ~S_ISUID; | ||
1850 | |||
1851 | /* | ||
1852 | * Note that we don't have to worry about mandatory | ||
1853 | * file locking being disabled here because we only | ||
1854 | * clear the S_ISGID bit if the Group execute bit is | ||
1855 | * on, but if it was on then mandatory locking wouldn't | ||
1856 | * have been enabled. | ||
1857 | */ | ||
1858 | if (ip->i_d.di_mode & S_IXGRP) | ||
1859 | ip->i_d.di_mode &= ~S_ISGID; | ||
1860 | |||
1861 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); | ||
1862 | } | ||
1863 | if (setprealloc) | ||
1864 | ip->i_d.di_flags |= XFS_DIFLAG_PREALLOC; | ||
1865 | else if (clrprealloc) | ||
1866 | ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC; | ||
1867 | |||
1868 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
1869 | if (attr_flags & XFS_ATTR_SYNC) | ||
1870 | xfs_trans_set_sync(tp); | ||
1871 | return xfs_trans_commit(tp, 0); | ||
1872 | } | ||
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h deleted file mode 100644 index 38c67c34d73f..000000000000 --- a/fs/xfs/xfs_vnodeops.h +++ /dev/null | |||
@@ -1,55 +0,0 @@ | |||
1 | #ifndef _XFS_VNODEOPS_H | ||
2 | #define _XFS_VNODEOPS_H 1 | ||
3 | |||
4 | struct attrlist_cursor_kern; | ||
5 | struct file; | ||
6 | struct iattr; | ||
7 | struct inode; | ||
8 | struct iovec; | ||
9 | struct kiocb; | ||
10 | struct pipe_inode_info; | ||
11 | struct uio; | ||
12 | struct xfs_inode; | ||
13 | |||
14 | |||
15 | int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap, int flags); | ||
16 | int xfs_setattr_size(struct xfs_inode *ip, struct iattr *vap, int flags); | ||
17 | #define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */ | ||
18 | #define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */ | ||
19 | #define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */ | ||
20 | #define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */ | ||
21 | #define XFS_ATTR_SYNC 0x10 /* synchronous operation required */ | ||
22 | |||
23 | int xfs_readlink(struct xfs_inode *ip, char *link); | ||
24 | int xfs_release(struct xfs_inode *ip); | ||
25 | int xfs_inactive(struct xfs_inode *ip); | ||
26 | int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, | ||
27 | struct xfs_inode **ipp, struct xfs_name *ci_name); | ||
28 | int xfs_create(struct xfs_inode *dp, struct xfs_name *name, umode_t mode, | ||
29 | xfs_dev_t rdev, struct xfs_inode **ipp); | ||
30 | int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, | ||
31 | struct xfs_inode *ip); | ||
32 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, | ||
33 | struct xfs_name *target_name); | ||
34 | int xfs_readdir(struct xfs_inode *dp, struct dir_context *ctx, size_t bufsize); | ||
35 | int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, | ||
36 | const char *target_path, umode_t mode, struct xfs_inode **ipp); | ||
37 | int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); | ||
38 | int xfs_change_file_space(struct xfs_inode *ip, int cmd, | ||
39 | xfs_flock64_t *bf, xfs_off_t offset, int attr_flags); | ||
40 | int xfs_rename(struct xfs_inode *src_dp, struct xfs_name *src_name, | ||
41 | struct xfs_inode *src_ip, struct xfs_inode *target_dp, | ||
42 | struct xfs_name *target_name, struct xfs_inode *target_ip); | ||
43 | int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name, | ||
44 | unsigned char *value, int *valuelenp, int flags); | ||
45 | int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name, | ||
46 | unsigned char *value, int valuelen, int flags); | ||
47 | int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags); | ||
48 | int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, | ||
49 | int flags, struct attrlist_cursor_kern *cursor); | ||
50 | |||
51 | int xfs_iozero(struct xfs_inode *, loff_t, size_t); | ||
52 | int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t); | ||
53 | int xfs_free_eofblocks(struct xfs_mount *, struct xfs_inode *, bool); | ||
54 | |||
55 | #endif /* _XFS_VNODEOPS_H */ | ||
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index b7311aaa5f0e..e01f35ea76ba 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include "xfs_attr.h" | 24 | #include "xfs_attr.h" |
25 | #include "xfs_attr_leaf.h" | 25 | #include "xfs_attr_leaf.h" |
26 | #include "xfs_acl.h" | 26 | #include "xfs_acl.h" |
27 | #include "xfs_vnodeops.h" | ||
28 | 27 | ||
29 | #include <linux/posix_acl_xattr.h> | 28 | #include <linux/posix_acl_xattr.h> |
30 | #include <linux/xattr.h> | 29 | #include <linux/xattr.h> |