diff options
-rw-r--r-- | fs/gfs2/inode.c | 65 | ||||
-rw-r--r-- | fs/gfs2/inode.h | 3 |
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 | |||
443 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 443 | static 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 | ||
505 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 512 | static 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 | ||
654 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 662 | static 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: | |||
1140 | static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | 1150 | static 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); |
1607 | out: | 1600 | out: |
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 | ||
109 | extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 109 | extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
110 | int is_root); | 110 | int is_root); |
111 | extern struct inode *gfs2_createi(struct gfs2_holder *ghs, | ||
112 | const struct qstr *name, | ||
113 | unsigned int mode, dev_t dev); | ||
114 | extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags); | 111 | extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags); |
115 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 112 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
116 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 113 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |