diff options
-rw-r--r-- | fs/gfs2/inode.c | 39 | ||||
-rw-r--r-- | fs/gfs2/inode.h | 2 | ||||
-rw-r--r-- | fs/gfs2/ops_inode.c | 38 |
3 files changed, 38 insertions, 41 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 676e750fc84c..2f94bd723698 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -1046,45 +1046,6 @@ fail: | |||
1046 | return ERR_PTR(error); | 1046 | return ERR_PTR(error); |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | |||
1050 | /* | ||
1051 | * gfs2_unlink_ok - check to see that a inode is still in a directory | ||
1052 | * @dip: the directory | ||
1053 | * @name: the name of the file | ||
1054 | * @ip: the inode | ||
1055 | * | ||
1056 | * Assumes that the lock on (at least) @dip is held. | ||
1057 | * | ||
1058 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | ||
1059 | */ | ||
1060 | |||
1061 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
1062 | const struct gfs2_inode *ip) | ||
1063 | { | ||
1064 | int error; | ||
1065 | |||
1066 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | ||
1067 | return -EPERM; | ||
1068 | |||
1069 | if ((dip->i_inode.i_mode & S_ISVTX) && | ||
1070 | dip->i_inode.i_uid != current_fsuid() && | ||
1071 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | ||
1072 | return -EPERM; | ||
1073 | |||
1074 | if (IS_APPEND(&dip->i_inode)) | ||
1075 | return -EPERM; | ||
1076 | |||
1077 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | ||
1078 | if (error) | ||
1079 | return error; | ||
1080 | |||
1081 | error = gfs2_dir_check(&dip->i_inode, name, ip); | ||
1082 | if (error) | ||
1083 | return error; | ||
1084 | |||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1049 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1089 | { | 1050 | { |
1090 | struct buffer_head *dibh; | 1051 | struct buffer_head *dibh; |
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index fc9a08f45be7..c341aaf67adb 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -96,8 +96,6 @@ extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
96 | extern struct inode *gfs2_createi(struct gfs2_holder *ghs, | 96 | extern struct inode *gfs2_createi(struct gfs2_holder *ghs, |
97 | const struct qstr *name, | 97 | const struct qstr *name, |
98 | unsigned int mode, dev_t dev); | 98 | unsigned int mode, dev_t dev); |
99 | extern int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
100 | const struct gfs2_inode *ip); | ||
101 | extern int gfs2_permission(struct inode *inode, int mask); | 99 | extern int gfs2_permission(struct inode *inode, int mask); |
102 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 100 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
103 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 101 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index f607f0908cff..f8bd20baf99c 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -262,6 +262,44 @@ out_parent: | |||
262 | return error; | 262 | return error; |
263 | } | 263 | } |
264 | 264 | ||
265 | /* | ||
266 | * gfs2_unlink_ok - check to see that a inode is still in a directory | ||
267 | * @dip: the directory | ||
268 | * @name: the name of the file | ||
269 | * @ip: the inode | ||
270 | * | ||
271 | * Assumes that the lock on (at least) @dip is held. | ||
272 | * | ||
273 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | ||
274 | */ | ||
275 | |||
276 | static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
277 | const struct gfs2_inode *ip) | ||
278 | { | ||
279 | int error; | ||
280 | |||
281 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | ||
282 | return -EPERM; | ||
283 | |||
284 | if ((dip->i_inode.i_mode & S_ISVTX) && | ||
285 | dip->i_inode.i_uid != current_fsuid() && | ||
286 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | ||
287 | return -EPERM; | ||
288 | |||
289 | if (IS_APPEND(&dip->i_inode)) | ||
290 | return -EPERM; | ||
291 | |||
292 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | ||
293 | if (error) | ||
294 | return error; | ||
295 | |||
296 | error = gfs2_dir_check(&dip->i_inode, name, ip); | ||
297 | if (error) | ||
298 | return error; | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
265 | /** | 303 | /** |
266 | * gfs2_unlink - Unlink a file | 304 | * gfs2_unlink - Unlink a file |
267 | * @dir: The inode of the directory containing the file to unlink | 305 | * @dir: The inode of the directory containing the file to unlink |