diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2011-05-13 04:55:55 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2011-05-13 04:55:55 -0400 |
commit | e2d0a13bba051d7a9618b0952d91fac68175a71a (patch) | |
tree | f1a28237be9b253da551bb20911ef5e7d256e7cf /fs/gfs2/inode.c | |
parent | 32e471ef1057e812856739d26b4a87d929fb8aa1 (diff) |
GFS2: Clean up mkdir
This moves the initialisation of the directory into the inode
creation functions to avoid having to duplicate the lookup
of the inode's buffer.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 77 |
1 files changed, 33 insertions, 44 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index a783a7a8c0ca..4aee9dd464f7 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -413,6 +413,22 @@ out: | |||
413 | return error; | 413 | return error; |
414 | } | 414 | } |
415 | 415 | ||
416 | static void gfs2_init_dir(struct buffer_head *dibh, const struct gfs2_inode *parent) | ||
417 | { | ||
418 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; | ||
419 | struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); | ||
420 | |||
421 | gfs2_qstr2dirent(&gfs2_qdot, GFS2_DIRENT_SIZE(gfs2_qdot.len), dent); | ||
422 | dent->de_inum = di->di_num; /* already GFS2 endian */ | ||
423 | dent->de_type = cpu_to_be16(DT_DIR); | ||
424 | |||
425 | dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); | ||
426 | gfs2_qstr2dirent(&gfs2_qdotdot, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); | ||
427 | gfs2_inum_out(parent, dent); | ||
428 | dent->de_type = cpu_to_be16(DT_DIR); | ||
429 | |||
430 | } | ||
431 | |||
416 | /** | 432 | /** |
417 | * init_dinode - Fill in a new dinode structure | 433 | * init_dinode - Fill in a new dinode structure |
418 | * @dip: the directory this inode is being created in | 434 | * @dip: the directory this inode is being created in |
@@ -454,16 +470,6 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
454 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 470 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); |
455 | di->di_generation = cpu_to_be64(*generation); | 471 | di->di_generation = cpu_to_be64(*generation); |
456 | di->di_flags = 0; | 472 | di->di_flags = 0; |
457 | |||
458 | if (S_ISREG(mode)) { | ||
459 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | ||
460 | gfs2_tune_get(sdp, gt_new_files_jdata)) | ||
461 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | ||
462 | } else if (S_ISDIR(mode)) { | ||
463 | di->di_flags |= cpu_to_be32(dip->i_diskflags & | ||
464 | GFS2_DIF_INHERIT_JDATA); | ||
465 | } | ||
466 | |||
467 | di->__pad1 = 0; | 473 | di->__pad1 = 0; |
468 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); | 474 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); |
469 | di->di_height = 0; | 475 | di->di_height = 0; |
@@ -478,6 +484,19 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
478 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); | 484 | di->di_ctime_nsec = cpu_to_be32(tv.tv_nsec); |
479 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 485 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
480 | 486 | ||
487 | if (S_ISREG(mode)) { | ||
488 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || | ||
489 | gfs2_tune_get(sdp, gt_new_files_jdata)) | ||
490 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | ||
491 | } else if (S_ISDIR(mode)) { | ||
492 | di->di_flags |= cpu_to_be32(dip->i_diskflags & | ||
493 | GFS2_DIF_INHERIT_JDATA); | ||
494 | 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)); | ||
496 | di->di_entries = cpu_to_be32(2); | ||
497 | gfs2_init_dir(dibh, dip); | ||
498 | } | ||
499 | |||
481 | set_buffer_uptodate(dibh); | 500 | set_buffer_uptodate(dibh); |
482 | 501 | ||
483 | *bhp = dibh; | 502 | *bhp = dibh; |
@@ -568,7 +587,9 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
568 | error = gfs2_meta_inode_buffer(ip, &dibh); | 587 | error = gfs2_meta_inode_buffer(ip, &dibh); |
569 | if (error) | 588 | if (error) |
570 | goto fail_end_trans; | 589 | goto fail_end_trans; |
571 | ip->i_inode.i_nlink = 1; | 590 | inc_nlink(&ip->i_inode); |
591 | if (S_ISDIR(ip->i_inode.i_mode)) | ||
592 | inc_nlink(&ip->i_inode); | ||
572 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 593 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
573 | gfs2_dinode_out(ip, dibh->b_data); | 594 | gfs2_dinode_out(ip, dibh->b_data); |
574 | brelse(dibh); | 595 | brelse(dibh); |
@@ -1178,12 +1199,10 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
1178 | 1199 | ||
1179 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | 1200 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) |
1180 | { | 1201 | { |
1181 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | 1202 | struct gfs2_inode *dip = GFS2_I(dir); |
1182 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 1203 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
1183 | struct gfs2_holder ghs[2]; | 1204 | struct gfs2_holder ghs[2]; |
1184 | struct inode *inode; | 1205 | struct inode *inode; |
1185 | struct buffer_head *dibh; | ||
1186 | int error; | ||
1187 | 1206 | ||
1188 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 1207 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
1189 | 1208 | ||
@@ -1193,36 +1212,6 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1193 | return PTR_ERR(inode); | 1212 | return PTR_ERR(inode); |
1194 | } | 1213 | } |
1195 | 1214 | ||
1196 | ip = ghs[1].gh_gl->gl_object; | ||
1197 | |||
1198 | ip->i_inode.i_nlink = 2; | ||
1199 | i_size_write(inode, sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)); | ||
1200 | ip->i_diskflags |= GFS2_DIF_JDATA; | ||
1201 | ip->i_entries = 2; | ||
1202 | |||
1203 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
1204 | |||
1205 | if (!gfs2_assert_withdraw(sdp, !error)) { | ||
1206 | struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; | ||
1207 | struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); | ||
1208 | |||
1209 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
1210 | gfs2_qstr2dirent(&gfs2_qdot, GFS2_DIRENT_SIZE(gfs2_qdot.len), dent); | ||
1211 | dent->de_inum = di->di_num; /* already GFS2 endian */ | ||
1212 | dent->de_type = cpu_to_be16(DT_DIR); | ||
1213 | di->di_entries = cpu_to_be32(1); | ||
1214 | |||
1215 | dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1)); | ||
1216 | gfs2_qstr2dirent(&gfs2_qdotdot, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent); | ||
1217 | |||
1218 | gfs2_inum_out(dip, dent); | ||
1219 | dent->de_type = cpu_to_be16(DT_DIR); | ||
1220 | |||
1221 | gfs2_dinode_out(ip, di); | ||
1222 | |||
1223 | brelse(dibh); | ||
1224 | } | ||
1225 | |||
1226 | gfs2_trans_end(sdp); | 1215 | gfs2_trans_end(sdp); |
1227 | if (dip->i_alloc->al_rgd) | 1216 | if (dip->i_alloc->al_rgd) |
1228 | gfs2_inplace_release(dip); | 1217 | gfs2_inplace_release(dip); |