aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/ops_inode.c')
-rw-r--r--fs/gfs2/ops_inode.c118
1 files changed, 31 insertions, 87 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 247436c10deb..4e64352d49de 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -748,7 +748,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
748 struct gfs2_rgrpd *nrgd; 748 struct gfs2_rgrpd *nrgd;
749 unsigned int num_gh; 749 unsigned int num_gh;
750 int dir_rename = 0; 750 int dir_rename = 0;
751 int alloc_required; 751 int alloc_required = 0;
752 unsigned int x; 752 unsigned int x;
753 int error; 753 int error;
754 754
@@ -867,7 +867,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
867 goto out_gunlock; 867 goto out_gunlock;
868 } 868 }
869 869
870 alloc_required = error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); 870 if (nip == NULL)
871 alloc_required = gfs2_diradd_alloc_required(ndir, &ndentry->d_name);
872 error = alloc_required;
871 if (error < 0) 873 if (error < 0)
872 goto out_gunlock; 874 goto out_gunlock;
873 error = 0; 875 error = 0;
@@ -974,121 +976,62 @@ out:
974} 976}
975 977
976/** 978/**
977 * gfs2_readlinki - return the contents of a symlink 979 * gfs2_follow_link - Follow a symbolic link
978 * @ip: the symlink's inode 980 * @dentry: The dentry of the link
979 * @buf: a pointer to the buffer to be filled 981 * @nd: Data that we pass to vfs_follow_link()
980 * @len: a pointer to the length of @buf
981 * 982 *
982 * If @buf is too small, a piece of memory is kmalloc()ed and needs 983 * This can handle symlinks of any size.
983 * to be freed by the caller.
984 * 984 *
985 * Returns: errno 985 * Returns: 0 on success or error code
986 */ 986 */
987 987
988static int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) 988static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
989{ 989{
990 struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
990 struct gfs2_holder i_gh; 991 struct gfs2_holder i_gh;
991 struct buffer_head *dibh; 992 struct buffer_head *dibh;
992 unsigned int x; 993 unsigned int x;
994 char *buf;
993 int error; 995 int error;
994 996
995 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);
996 error = gfs2_glock_nq(&i_gh); 998 error = gfs2_glock_nq(&i_gh);
997 if (error) { 999 if (error) {
998 gfs2_holder_uninit(&i_gh); 1000 gfs2_holder_uninit(&i_gh);
999 return error; 1001 nd_set_link(nd, ERR_PTR(error));
1002 return NULL;
1000 } 1003 }
1001 1004
1002 if (!ip->i_disksize) { 1005 if (!ip->i_disksize) {
1003 gfs2_consist_inode(ip); 1006 gfs2_consist_inode(ip);
1004 error = -EIO; 1007 buf = ERR_PTR(-EIO);
1005 goto out; 1008 goto out;
1006 } 1009 }
1007 1010
1008 error = gfs2_meta_inode_buffer(ip, &dibh); 1011 error = gfs2_meta_inode_buffer(ip, &dibh);
1009 if (error) 1012 if (error) {
1013 buf = ERR_PTR(error);
1010 goto out; 1014 goto out;
1011
1012 x = ip->i_disksize + 1;
1013 if (x > *len) {
1014 *buf = kmalloc(x, GFP_NOFS);
1015 if (!*buf) {
1016 error = -ENOMEM;
1017 goto out_brelse;
1018 }
1019 } 1015 }
1020 1016
1021 memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x); 1017 x = ip->i_disksize + 1;
1022 *len = x; 1018 buf = kmalloc(x, GFP_NOFS);
1023 1019 if (!buf)
1024out_brelse: 1020 buf = ERR_PTR(-ENOMEM);
1021 else
1022 memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), x);
1025 brelse(dibh); 1023 brelse(dibh);
1026out: 1024out:
1027 gfs2_glock_dq_uninit(&i_gh); 1025 gfs2_glock_dq_uninit(&i_gh);
1028 return error; 1026 nd_set_link(nd, buf);
1029} 1027 return NULL;
1030
1031/**
1032 * gfs2_readlink - Read the value of a symlink
1033 * @dentry: the symlink
1034 * @buf: the buffer to read the symlink data into
1035 * @size: the size of the buffer
1036 *
1037 * Returns: errno
1038 */
1039
1040static int gfs2_readlink(struct dentry *dentry, char __user *user_buf,
1041 int user_size)
1042{
1043 struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
1044 char array[GFS2_FAST_NAME_SIZE], *buf = array;
1045 unsigned int len = GFS2_FAST_NAME_SIZE;
1046 int error;
1047
1048 error = gfs2_readlinki(ip, &buf, &len);
1049 if (error)
1050 return error;
1051
1052 if (user_size > len - 1)
1053 user_size = len - 1;
1054
1055 if (copy_to_user(user_buf, buf, user_size))
1056 error = -EFAULT;
1057 else
1058 error = user_size;
1059
1060 if (buf != array)
1061 kfree(buf);
1062
1063 return error;
1064} 1028}
1065 1029
1066/** 1030static void gfs2_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
1067 * gfs2_follow_link - Follow a symbolic link
1068 * @dentry: The dentry of the link
1069 * @nd: Data that we pass to vfs_follow_link()
1070 *
1071 * This can handle symlinks of any size. It is optimised for symlinks
1072 * under GFS2_FAST_NAME_SIZE.
1073 *
1074 * Returns: 0 on success or error code
1075 */
1076
1077static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
1078{ 1031{
1079 struct gfs2_inode *ip = GFS2_I(dentry->d_inode); 1032 char *s = nd_get_link(nd);
1080 char array[GFS2_FAST_NAME_SIZE], *buf = array; 1033 if (!IS_ERR(s))
1081 unsigned int len = GFS2_FAST_NAME_SIZE; 1034 kfree(s);
1082 int error;
1083
1084 error = gfs2_readlinki(ip, &buf, &len);
1085 if (!error) {
1086 error = vfs_follow_link(nd, buf);
1087 if (buf != array)
1088 kfree(buf);
1089 }
1090
1091 return ERR_PTR(error);
1092} 1035}
1093 1036
1094/** 1037/**
@@ -1423,8 +1366,9 @@ const struct inode_operations gfs2_dir_iops = {
1423}; 1366};
1424 1367
1425const struct inode_operations gfs2_symlink_iops = { 1368const struct inode_operations gfs2_symlink_iops = {
1426 .readlink = gfs2_readlink, 1369 .readlink = generic_readlink,
1427 .follow_link = gfs2_follow_link, 1370 .follow_link = gfs2_follow_link,
1371 .put_link = gfs2_put_link,
1428 .permission = gfs2_permission, 1372 .permission = gfs2_permission,
1429 .setattr = gfs2_setattr, 1373 .setattr = gfs2_setattr,
1430 .getattr = gfs2_getattr, 1374 .getattr = gfs2_getattr,