aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2011-05-13 05:34:59 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2011-05-13 05:34:59 -0400
commit160b4026dc3e75c0693d0123eca805e88cd200b6 (patch)
tree32aa1a6e23b09be65cabdbcd6be2a8fc3d50527f
parente2d0a13bba051d7a9618b0952d91fac68175a71a (diff)
GFS2: Clean up symlink creation
This moves the symlink specific parts of inode creation into the function where we initialise the rest of the dinode. As a result we have one less place where we need to look up the inode's buffer. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/gfs2/inode.c65
-rw-r--r--fs/gfs2/inode.h3
2 files changed, 29 insertions, 39 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 4aee9dd464f7..c2a3d9cd0bc8 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -443,7 +443,8 @@ static void gfs2_init_dir(struct buffer_head *dibh, const struct gfs2_inode *par
443static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, 443static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
444 const struct gfs2_inum_host *inum, unsigned int mode, 444 const struct gfs2_inum_host *inum, unsigned int mode,
445 unsigned int uid, unsigned int gid, 445 unsigned int uid, unsigned int gid,
446 const u64 *generation, dev_t dev, struct buffer_head **bhp) 446 const u64 *generation, dev_t dev, const char *symname,
447 unsigned size, struct buffer_head **bhp)
447{ 448{
448 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 449 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
449 struct gfs2_dinode *di; 450 struct gfs2_dinode *di;
@@ -462,7 +463,7 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
462 di->di_uid = cpu_to_be32(uid); 463 di->di_uid = cpu_to_be32(uid);
463 di->di_gid = cpu_to_be32(gid); 464 di->di_gid = cpu_to_be32(gid);
464 di->di_nlink = 0; 465 di->di_nlink = 0;
465 di->di_size = 0; 466 di->di_size = cpu_to_be64(size);
466 di->di_blocks = cpu_to_be64(1); 467 di->di_blocks = cpu_to_be64(1);
467 di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec); 468 di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(tv.tv_sec);
468 di->di_major = cpu_to_be32(MAJOR(dev)); 469 di->di_major = cpu_to_be32(MAJOR(dev));
@@ -483,18 +484,24 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
483 di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec); 484 di->di_mtime_nsec = cpu_to_be32(tv.tv_nsec);
484 di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); 485 di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec);
485 memset(&di->di_reserved, 0, sizeof(di->di_reserved)); 486 memset(&di->di_reserved, 0, sizeof(di->di_reserved));
486 487
487 if (S_ISREG(mode)) { 488 switch(mode & S_IFMT) {
489 case S_IFREG:
488 if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || 490 if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) ||
489 gfs2_tune_get(sdp, gt_new_files_jdata)) 491 gfs2_tune_get(sdp, gt_new_files_jdata))
490 di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); 492 di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
491 } else if (S_ISDIR(mode)) { 493 break;
494 case S_IFDIR:
492 di->di_flags |= cpu_to_be32(dip->i_diskflags & 495 di->di_flags |= cpu_to_be32(dip->i_diskflags &
493 GFS2_DIF_INHERIT_JDATA); 496 GFS2_DIF_INHERIT_JDATA);
494 di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); 497 di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA);
495 di->di_size = cpu_to_be64(sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)); 498 di->di_size = cpu_to_be64(sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode));
496 di->di_entries = cpu_to_be32(2); 499 di->di_entries = cpu_to_be32(2);
497 gfs2_init_dir(dibh, dip); 500 gfs2_init_dir(dibh, dip);
501 break;
502 case S_IFLNK:
503 memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, size);
504 break;
498 } 505 }
499 506
500 set_buffer_uptodate(dibh); 507 set_buffer_uptodate(dibh);
@@ -504,7 +511,8 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
504 511
505static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, 512static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
506 unsigned int mode, const struct gfs2_inum_host *inum, 513 unsigned int mode, const struct gfs2_inum_host *inum,
507 const u64 *generation, dev_t dev, struct buffer_head **bhp) 514 const u64 *generation, dev_t dev, const char *symname,
515 unsigned int size, struct buffer_head **bhp)
508{ 516{
509 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 517 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
510 unsigned int uid, gid; 518 unsigned int uid, gid;
@@ -526,7 +534,7 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl,
526 if (error) 534 if (error)
527 goto out_quota; 535 goto out_quota;
528 536
529 init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, bhp); 537 init_dinode(dip, gl, inum, mode, uid, gid, generation, dev, symname, size, bhp);
530 gfs2_quota_change(dip, +1, uid, gid); 538 gfs2_quota_change(dip, +1, uid, gid);
531 gfs2_trans_end(sdp); 539 gfs2_trans_end(sdp);
532 540
@@ -651,8 +659,10 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
651 * Returns: An inode 659 * Returns: An inode
652 */ 660 */
653 661
654struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, 662static struct inode *gfs2_createi(struct gfs2_holder *ghs,
655 unsigned int mode, dev_t dev) 663 const struct qstr *name, unsigned int mode,
664 dev_t dev, const char *symname,
665 unsigned int size)
656{ 666{
657 struct inode *inode = NULL; 667 struct inode *inode = NULL;
658 struct gfs2_inode *dip = ghs->gh_gl->gl_object; 668 struct gfs2_inode *dip = ghs->gh_gl->gl_object;
@@ -685,7 +695,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
685 if (error) 695 if (error)
686 goto fail_gunlock; 696 goto fail_gunlock;
687 697
688 error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, &bh); 698 error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev, symname, size, &bh);
689 if (error) 699 if (error)
690 goto fail_gunlock2; 700 goto fail_gunlock2;
691 701
@@ -745,7 +755,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
745 gfs2_holder_init(dip->i_gl, 0, 0, ghs); 755 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
746 756
747 for (;;) { 757 for (;;) {
748 inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0); 758 inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0, NULL, 0);
749 if (!IS_ERR(inode)) { 759 if (!IS_ERR(inode)) {
750 gfs2_trans_end(sdp); 760 gfs2_trans_end(sdp);
751 if (dip->i_alloc->al_rgd) 761 if (dip->i_alloc->al_rgd)
@@ -1140,40 +1150,24 @@ out_parent:
1140static int gfs2_symlink(struct inode *dir, struct dentry *dentry, 1150static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
1141 const char *symname) 1151 const char *symname)
1142{ 1152{
1143 struct gfs2_inode *dip = GFS2_I(dir), *ip; 1153 struct gfs2_inode *dip = GFS2_I(dir);
1144 struct gfs2_sbd *sdp = GFS2_SB(dir); 1154 struct gfs2_sbd *sdp = GFS2_SB(dir);
1145 struct gfs2_holder ghs[2]; 1155 struct gfs2_holder ghs[2];
1146 struct inode *inode; 1156 struct inode *inode;
1147 struct buffer_head *dibh; 1157 unsigned int size;
1148 int size;
1149 int error;
1150 1158
1151 /* Must be stuffed with a null terminator for gfs2_follow_link() */
1152 size = strlen(symname); 1159 size = strlen(symname);
1153 if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1) 1160 if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1)
1154 return -ENAMETOOLONG; 1161 return -ENAMETOOLONG;
1155 1162
1156 gfs2_holder_init(dip->i_gl, 0, 0, ghs); 1163 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
1157 1164
1158 inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0); 1165 inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0, symname, size);
1159 if (IS_ERR(inode)) { 1166 if (IS_ERR(inode)) {
1160 gfs2_holder_uninit(ghs); 1167 gfs2_holder_uninit(ghs);
1161 return PTR_ERR(inode); 1168 return PTR_ERR(inode);
1162 } 1169 }
1163 1170
1164 ip = ghs[1].gh_gl->gl_object;
1165
1166 i_size_write(inode, size);
1167
1168 error = gfs2_meta_inode_buffer(ip, &dibh);
1169
1170 if (!gfs2_assert_withdraw(sdp, !error)) {
1171 gfs2_dinode_out(ip, dibh->b_data);
1172 memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname,
1173 size);
1174 brelse(dibh);
1175 }
1176
1177 gfs2_trans_end(sdp); 1171 gfs2_trans_end(sdp);
1178 if (dip->i_alloc->al_rgd) 1172 if (dip->i_alloc->al_rgd)
1179 gfs2_inplace_release(dip); 1173 gfs2_inplace_release(dip);
@@ -1206,7 +1200,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1206 1200
1207 gfs2_holder_init(dip->i_gl, 0, 0, ghs); 1201 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
1208 1202
1209 inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0); 1203 inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0, NULL, 0);
1210 if (IS_ERR(inode)) { 1204 if (IS_ERR(inode)) {
1211 gfs2_holder_uninit(ghs); 1205 gfs2_holder_uninit(ghs);
1212 return PTR_ERR(inode); 1206 return PTR_ERR(inode);
@@ -1245,7 +1239,7 @@ static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
1245 1239
1246 gfs2_holder_init(dip->i_gl, 0, 0, ghs); 1240 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
1247 1241
1248 inode = gfs2_createi(ghs, &dentry->d_name, mode, dev); 1242 inode = gfs2_createi(ghs, &dentry->d_name, mode, dev, NULL, 0);
1249 if (IS_ERR(inode)) { 1243 if (IS_ERR(inode)) {
1250 gfs2_holder_uninit(ghs); 1244 gfs2_holder_uninit(ghs);
1251 return PTR_ERR(inode); 1245 return PTR_ERR(inode);
@@ -1572,7 +1566,7 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
1572 struct gfs2_inode *ip = GFS2_I(dentry->d_inode); 1566 struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
1573 struct gfs2_holder i_gh; 1567 struct gfs2_holder i_gh;
1574 struct buffer_head *dibh; 1568 struct buffer_head *dibh;
1575 unsigned int x, size; 1569 unsigned int size;
1576 char *buf; 1570 char *buf;
1577 int error; 1571 int error;
1578 1572
@@ -1597,12 +1591,11 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
1597 goto out; 1591 goto out;
1598 } 1592 }
1599 1593
1600 x = size + 1; 1594 buf = kzalloc(size + 1, GFP_NOFS);
1601 buf = kmalloc(x, GFP_NOFS);
1602 if (!buf) 1595 if (!buf)
1603 buf = ERR_PTR(-ENOMEM); 1596 buf = ERR_PTR(-ENOMEM);
1604 else 1597 else
1605 memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), x); 1598 memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), size);
1606 brelse(dibh); 1599 brelse(dibh);
1607out: 1600out:
1608 gfs2_glock_dq_uninit(&i_gh); 1601 gfs2_glock_dq_uninit(&i_gh);
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index 7ed60aa1b61f..31606076f701 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -108,9 +108,6 @@ extern int gfs2_inode_refresh(struct gfs2_inode *ip);
108 108
109extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, 109extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
110 int is_root); 110 int is_root);
111extern struct inode *gfs2_createi(struct gfs2_holder *ghs,
112 const struct qstr *name,
113 unsigned int mode, dev_t dev);
114extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags); 111extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags);
115extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); 112extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr);
116extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); 113extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name);