diff options
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 150 |
1 files changed, 1 insertions, 149 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 5a31d426116f..2f94bd723698 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include "inode.h" | 30 | #include "inode.h" |
31 | #include "log.h" | 31 | #include "log.h" |
32 | #include "meta_io.h" | 32 | #include "meta_io.h" |
33 | #include "ops_address.h" | ||
34 | #include "quota.h" | 33 | #include "quota.h" |
35 | #include "rgrp.h" | 34 | #include "rgrp.h" |
36 | #include "trans.h" | 35 | #include "trans.h" |
@@ -1047,154 +1046,7 @@ fail: | |||
1047 | return ERR_PTR(error); | 1046 | return ERR_PTR(error); |
1048 | } | 1047 | } |
1049 | 1048 | ||
1050 | /** | 1049 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1051 | * gfs2_rmdiri - Remove a directory | ||
1052 | * @dip: The parent directory of the directory to be removed | ||
1053 | * @name: The name of the directory to be removed | ||
1054 | * @ip: The GFS2 inode of the directory to be removed | ||
1055 | * | ||
1056 | * Assumes Glocks on dip and ip are held | ||
1057 | * | ||
1058 | * Returns: errno | ||
1059 | */ | ||
1060 | |||
1061 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | ||
1062 | struct gfs2_inode *ip) | ||
1063 | { | ||
1064 | struct qstr dotname; | ||
1065 | int error; | ||
1066 | |||
1067 | if (ip->i_entries != 2) { | ||
1068 | if (gfs2_consist_inode(ip)) | ||
1069 | gfs2_dinode_print(ip); | ||
1070 | return -EIO; | ||
1071 | } | ||
1072 | |||
1073 | error = gfs2_dir_del(dip, name); | ||
1074 | if (error) | ||
1075 | return error; | ||
1076 | |||
1077 | error = gfs2_change_nlink(dip, -1); | ||
1078 | if (error) | ||
1079 | return error; | ||
1080 | |||
1081 | gfs2_str2qstr(&dotname, "."); | ||
1082 | error = gfs2_dir_del(ip, &dotname); | ||
1083 | if (error) | ||
1084 | return error; | ||
1085 | |||
1086 | gfs2_str2qstr(&dotname, ".."); | ||
1087 | error = gfs2_dir_del(ip, &dotname); | ||
1088 | if (error) | ||
1089 | return error; | ||
1090 | |||
1091 | /* It looks odd, but it really should be done twice */ | ||
1092 | error = gfs2_change_nlink(ip, -1); | ||
1093 | if (error) | ||
1094 | return error; | ||
1095 | |||
1096 | error = gfs2_change_nlink(ip, -1); | ||
1097 | if (error) | ||
1098 | return error; | ||
1099 | |||
1100 | return error; | ||
1101 | } | ||
1102 | |||
1103 | /* | ||
1104 | * gfs2_unlink_ok - check to see that a inode is still in a directory | ||
1105 | * @dip: the directory | ||
1106 | * @name: the name of the file | ||
1107 | * @ip: the inode | ||
1108 | * | ||
1109 | * Assumes that the lock on (at least) @dip is held. | ||
1110 | * | ||
1111 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | ||
1112 | */ | ||
1113 | |||
1114 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
1115 | const struct gfs2_inode *ip) | ||
1116 | { | ||
1117 | int error; | ||
1118 | |||
1119 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | ||
1120 | return -EPERM; | ||
1121 | |||
1122 | if ((dip->i_inode.i_mode & S_ISVTX) && | ||
1123 | dip->i_inode.i_uid != current_fsuid() && | ||
1124 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | ||
1125 | return -EPERM; | ||
1126 | |||
1127 | if (IS_APPEND(&dip->i_inode)) | ||
1128 | return -EPERM; | ||
1129 | |||
1130 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | ||
1131 | if (error) | ||
1132 | return error; | ||
1133 | |||
1134 | error = gfs2_dir_check(&dip->i_inode, name, ip); | ||
1135 | if (error) | ||
1136 | return error; | ||
1137 | |||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1141 | /** | ||
1142 | * gfs2_readlinki - return the contents of a symlink | ||
1143 | * @ip: the symlink's inode | ||
1144 | * @buf: a pointer to the buffer to be filled | ||
1145 | * @len: a pointer to the length of @buf | ||
1146 | * | ||
1147 | * If @buf is too small, a piece of memory is kmalloc()ed and needs | ||
1148 | * to be freed by the caller. | ||
1149 | * | ||
1150 | * Returns: errno | ||
1151 | */ | ||
1152 | |||
1153 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | ||
1154 | { | ||
1155 | struct gfs2_holder i_gh; | ||
1156 | struct buffer_head *dibh; | ||
1157 | unsigned int x; | ||
1158 | int error; | ||
1159 | |||
1160 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); | ||
1161 | error = gfs2_glock_nq(&i_gh); | ||
1162 | if (error) { | ||
1163 | gfs2_holder_uninit(&i_gh); | ||
1164 | return error; | ||
1165 | } | ||
1166 | |||
1167 | if (!ip->i_disksize) { | ||
1168 | gfs2_consist_inode(ip); | ||
1169 | error = -EIO; | ||
1170 | goto out; | ||
1171 | } | ||
1172 | |||
1173 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
1174 | if (error) | ||
1175 | goto out; | ||
1176 | |||
1177 | x = ip->i_disksize + 1; | ||
1178 | if (x > *len) { | ||
1179 | *buf = kmalloc(x, GFP_NOFS); | ||
1180 | if (!*buf) { | ||
1181 | error = -ENOMEM; | ||
1182 | goto out_brelse; | ||
1183 | } | ||
1184 | } | ||
1185 | |||
1186 | memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x); | ||
1187 | *len = x; | ||
1188 | |||
1189 | out_brelse: | ||
1190 | brelse(dibh); | ||
1191 | out: | ||
1192 | gfs2_glock_dq_uninit(&i_gh); | ||
1193 | return error; | ||
1194 | } | ||
1195 | |||
1196 | static int | ||
1197 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | ||
1198 | { | 1050 | { |
1199 | struct buffer_head *dibh; | 1051 | struct buffer_head *dibh; |
1200 | int error; | 1052 | int error; |