diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/ops_inode.c | 113 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 9 | ||||
-rw-r--r-- | fs/gfs2/quota.h | 2 | ||||
-rw-r--r-- | fs/gfs2/super.c | 7 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 2 |
5 files changed, 40 insertions, 93 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 84350e1be66d..4e64352d49de 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -976,122 +976,62 @@ out: | |||
976 | } | 976 | } |
977 | 977 | ||
978 | /** | 978 | /** |
979 | * gfs2_readlinki - return the contents of a symlink | 979 | * gfs2_follow_link - Follow a symbolic link |
980 | * @ip: the symlink's inode | 980 | * @dentry: The dentry of the link |
981 | * @buf: a pointer to the buffer to be filled | 981 | * @nd: Data that we pass to vfs_follow_link() |
982 | * @len: a pointer to the length of @buf | ||
983 | * | 982 | * |
984 | * If @buf is too small, a piece of memory is kmalloc()ed and needs | 983 | * This can handle symlinks of any size. |
985 | * to be freed by the caller. | ||
986 | * | 984 | * |
987 | * Returns: errno | 985 | * Returns: 0 on success or error code |
988 | */ | 986 | */ |
989 | 987 | ||
990 | static int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | 988 | static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) |
991 | { | 989 | { |
990 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
992 | struct gfs2_holder i_gh; | 991 | struct gfs2_holder i_gh; |
993 | struct buffer_head *dibh; | 992 | struct buffer_head *dibh; |
994 | unsigned int x; | 993 | unsigned int x; |
994 | char *buf; | ||
995 | int error; | 995 | int error; |
996 | 996 | ||
997 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); | 997 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); |
998 | error = gfs2_glock_nq(&i_gh); | 998 | error = gfs2_glock_nq(&i_gh); |
999 | if (error) { | 999 | if (error) { |
1000 | gfs2_holder_uninit(&i_gh); | 1000 | gfs2_holder_uninit(&i_gh); |
1001 | return error; | 1001 | nd_set_link(nd, ERR_PTR(error)); |
1002 | return NULL; | ||
1002 | } | 1003 | } |
1003 | 1004 | ||
1004 | if (!ip->i_disksize) { | 1005 | if (!ip->i_disksize) { |
1005 | gfs2_consist_inode(ip); | 1006 | gfs2_consist_inode(ip); |
1006 | error = -EIO; | 1007 | buf = ERR_PTR(-EIO); |
1007 | goto out; | 1008 | goto out; |
1008 | } | 1009 | } |
1009 | 1010 | ||
1010 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1011 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1011 | if (error) | 1012 | if (error) { |
1013 | buf = ERR_PTR(error); | ||
1012 | goto out; | 1014 | goto out; |
1013 | |||
1014 | x = ip->i_disksize + 1; | ||
1015 | if (x > *len) { | ||
1016 | *buf = kmalloc(x, GFP_NOFS); | ||
1017 | if (!*buf) { | ||
1018 | error = -ENOMEM; | ||
1019 | goto out_brelse; | ||
1020 | } | ||
1021 | } | 1015 | } |
1022 | 1016 | ||
1023 | memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x); | 1017 | x = ip->i_disksize + 1; |
1024 | *len = x; | 1018 | buf = kmalloc(x, GFP_NOFS); |
1025 | 1019 | if (!buf) | |
1026 | out_brelse: | 1020 | buf = ERR_PTR(-ENOMEM); |
1021 | else | ||
1022 | memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), x); | ||
1027 | brelse(dibh); | 1023 | brelse(dibh); |
1028 | out: | 1024 | out: |
1029 | gfs2_glock_dq_uninit(&i_gh); | 1025 | gfs2_glock_dq_uninit(&i_gh); |
1030 | return error; | 1026 | nd_set_link(nd, buf); |
1031 | } | 1027 | return NULL; |
1032 | |||
1033 | /** | ||
1034 | * gfs2_readlink - Read the value of a symlink | ||
1035 | * @dentry: the symlink | ||
1036 | * @buf: the buffer to read the symlink data into | ||
1037 | * @size: the size of the buffer | ||
1038 | * | ||
1039 | * Returns: errno | ||
1040 | */ | ||
1041 | |||
1042 | static int gfs2_readlink(struct dentry *dentry, char __user *user_buf, | ||
1043 | int user_size) | ||
1044 | { | ||
1045 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
1046 | char array[GFS2_FAST_NAME_SIZE], *buf = array; | ||
1047 | unsigned int len = GFS2_FAST_NAME_SIZE; | ||
1048 | int error; | ||
1049 | |||
1050 | error = gfs2_readlinki(ip, &buf, &len); | ||
1051 | if (error) | ||
1052 | return error; | ||
1053 | |||
1054 | if (user_size > len - 1) | ||
1055 | user_size = len - 1; | ||
1056 | |||
1057 | if (copy_to_user(user_buf, buf, user_size)) | ||
1058 | error = -EFAULT; | ||
1059 | else | ||
1060 | error = user_size; | ||
1061 | |||
1062 | if (buf != array) | ||
1063 | kfree(buf); | ||
1064 | |||
1065 | return error; | ||
1066 | } | 1028 | } |
1067 | 1029 | ||
1068 | /** | 1030 | static void gfs2_put_link(struct dentry *dentry, struct nameidata *nd, void *p) |
1069 | * gfs2_follow_link - Follow a symbolic link | ||
1070 | * @dentry: The dentry of the link | ||
1071 | * @nd: Data that we pass to vfs_follow_link() | ||
1072 | * | ||
1073 | * This can handle symlinks of any size. It is optimised for symlinks | ||
1074 | * under GFS2_FAST_NAME_SIZE. | ||
1075 | * | ||
1076 | * Returns: 0 on success or error code | ||
1077 | */ | ||
1078 | |||
1079 | static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) | ||
1080 | { | 1031 | { |
1081 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 1032 | char *s = nd_get_link(nd); |
1082 | char array[GFS2_FAST_NAME_SIZE], *buf = array; | 1033 | if (!IS_ERR(s)) |
1083 | unsigned int len = GFS2_FAST_NAME_SIZE; | 1034 | kfree(s); |
1084 | int error; | ||
1085 | |||
1086 | error = gfs2_readlinki(ip, &buf, &len); | ||
1087 | if (!error) { | ||
1088 | error = vfs_follow_link(nd, buf); | ||
1089 | if (buf != array) | ||
1090 | kfree(buf); | ||
1091 | } else | ||
1092 | path_put(&nd->path); | ||
1093 | |||
1094 | return ERR_PTR(error); | ||
1095 | } | 1035 | } |
1096 | 1036 | ||
1097 | /** | 1037 | /** |
@@ -1426,8 +1366,9 @@ const struct inode_operations gfs2_dir_iops = { | |||
1426 | }; | 1366 | }; |
1427 | 1367 | ||
1428 | const struct inode_operations gfs2_symlink_iops = { | 1368 | const struct inode_operations gfs2_symlink_iops = { |
1429 | .readlink = gfs2_readlink, | 1369 | .readlink = generic_readlink, |
1430 | .follow_link = gfs2_follow_link, | 1370 | .follow_link = gfs2_follow_link, |
1371 | .put_link = gfs2_put_link, | ||
1431 | .permission = gfs2_permission, | 1372 | .permission = gfs2_permission, |
1432 | .setattr = gfs2_setattr, | 1373 | .setattr = gfs2_setattr, |
1433 | .getattr = gfs2_getattr, | 1374 | .getattr = gfs2_getattr, |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index e3bf6eab8750..6dbcbad6ab17 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -1083,7 +1083,7 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | |||
1083 | } | 1083 | } |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | int gfs2_quota_sync(struct super_block *sb, int type) | 1086 | int gfs2_quota_sync(struct super_block *sb, int type, int wait) |
1087 | { | 1087 | { |
1088 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1088 | struct gfs2_sbd *sdp = sb->s_fs_info; |
1089 | struct gfs2_quota_data **qda; | 1089 | struct gfs2_quota_data **qda; |
@@ -1127,6 +1127,11 @@ int gfs2_quota_sync(struct super_block *sb, int type) | |||
1127 | return error; | 1127 | return error; |
1128 | } | 1128 | } |
1129 | 1129 | ||
1130 | static int gfs2_quota_sync_timeo(struct super_block *sb, int type) | ||
1131 | { | ||
1132 | return gfs2_quota_sync(sb, type, 0); | ||
1133 | } | ||
1134 | |||
1130 | int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id) | 1135 | int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id) |
1131 | { | 1136 | { |
1132 | struct gfs2_quota_data *qd; | 1137 | struct gfs2_quota_data *qd; |
@@ -1382,7 +1387,7 @@ int gfs2_quotad(void *data) | |||
1382 | &tune->gt_statfs_quantum); | 1387 | &tune->gt_statfs_quantum); |
1383 | 1388 | ||
1384 | /* Update quota file */ | 1389 | /* Update quota file */ |
1385 | quotad_check_timeo(sdp, "sync", gfs2_quota_sync, t, | 1390 | quotad_check_timeo(sdp, "sync", gfs2_quota_sync_timeo, t, |
1386 | "ad_timeo, &tune->gt_quota_quantum); | 1391 | "ad_timeo, &tune->gt_quota_quantum); |
1387 | 1392 | ||
1388 | /* Check for & recover partially truncated inodes */ | 1393 | /* Check for & recover partially truncated inodes */ |
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h index e271fa07ad02..195f60c8bd14 100644 --- a/fs/gfs2/quota.h +++ b/fs/gfs2/quota.h | |||
@@ -25,7 +25,7 @@ extern int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid); | |||
25 | extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | 25 | extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change, |
26 | u32 uid, u32 gid); | 26 | u32 uid, u32 gid); |
27 | 27 | ||
28 | extern int gfs2_quota_sync(struct super_block *sb, int type); | 28 | extern int gfs2_quota_sync(struct super_block *sb, int type, int wait); |
29 | extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id); | 29 | extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id); |
30 | 30 | ||
31 | extern int gfs2_quota_init(struct gfs2_sbd *sdp); | 31 | extern int gfs2_quota_init(struct gfs2_sbd *sdp); |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index e5e22629da67..50aac606b990 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/crc32.h> | 22 | #include <linux/crc32.h> |
23 | #include <linux/time.h> | 23 | #include <linux/time.h> |
24 | #include <linux/wait.h> | 24 | #include <linux/wait.h> |
25 | #include <linux/writeback.h> | ||
25 | 26 | ||
26 | #include "gfs2.h" | 27 | #include "gfs2.h" |
27 | #include "incore.h" | 28 | #include "incore.h" |
@@ -711,7 +712,7 @@ void gfs2_unfreeze_fs(struct gfs2_sbd *sdp) | |||
711 | * Returns: errno | 712 | * Returns: errno |
712 | */ | 713 | */ |
713 | 714 | ||
714 | static int gfs2_write_inode(struct inode *inode, int sync) | 715 | static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) |
715 | { | 716 | { |
716 | struct gfs2_inode *ip = GFS2_I(inode); | 717 | struct gfs2_inode *ip = GFS2_I(inode); |
717 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 718 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -745,7 +746,7 @@ static int gfs2_write_inode(struct inode *inode, int sync) | |||
745 | do_unlock: | 746 | do_unlock: |
746 | gfs2_glock_dq_uninit(&gh); | 747 | gfs2_glock_dq_uninit(&gh); |
747 | do_flush: | 748 | do_flush: |
748 | if (sync != 0) | 749 | if (wbc->sync_mode == WB_SYNC_ALL) |
749 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | 750 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); |
750 | return ret; | 751 | return ret; |
751 | } | 752 | } |
@@ -763,7 +764,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | |||
763 | int error; | 764 | int error; |
764 | 765 | ||
765 | flush_workqueue(gfs2_delete_workqueue); | 766 | flush_workqueue(gfs2_delete_workqueue); |
766 | gfs2_quota_sync(sdp->sd_vfs, 0); | 767 | gfs2_quota_sync(sdp->sd_vfs, 0, 1); |
767 | gfs2_statfs_sync(sdp->sd_vfs, 0); | 768 | gfs2_statfs_sync(sdp->sd_vfs, 0); |
768 | 769 | ||
769 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, | 770 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index a0db1c94317d..b5f1a46133c8 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -167,7 +167,7 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf, | |||
167 | if (simple_strtol(buf, NULL, 0) != 1) | 167 | if (simple_strtol(buf, NULL, 0) != 1) |
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | 169 | ||
170 | gfs2_quota_sync(sdp->sd_vfs, 0); | 170 | gfs2_quota_sync(sdp->sd_vfs, 0, 1); |
171 | return len; | 171 | return len; |
172 | } | 172 | } |
173 | 173 | ||