aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/inode.c39
-rw-r--r--fs/gfs2/inode.h2
-rw-r--r--fs/gfs2/ops_inode.c38
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
1061int 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
1088static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) 1049static 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,
96extern struct inode *gfs2_createi(struct gfs2_holder *ghs, 96extern 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);
99extern int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
100 const struct gfs2_inode *ip);
101extern int gfs2_permission(struct inode *inode, int mask); 99extern int gfs2_permission(struct inode *inode, int mask);
102extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); 100extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
103extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); 101extern 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
276static 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