aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2011-05-13 07:11:17 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2011-05-13 07:11:17 -0400
commitf2741d9898269e565c220ec295a8f5c3756c7585 (patch)
tree36700a4cb6faee29ceae753474f0f0a9cbf899d7 /fs
parent160b4026dc3e75c0693d0123eca805e88cd200b6 (diff)
GFS2: Move all locking inside the inode creation function
Now that there are no longer any exceptions to the normal inode creation code path, we can move the parts of the locking code which were duplicated in mkdir/mknod/create/symlink into the inode create function. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/inode.c184
1 files changed, 52 insertions, 132 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index c2a3d9cd0bc8..03e0c529063e 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 2 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
3 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 3 * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
4 * 4 *
5 * This copyrighted material is made available to anyone wishing to use, 5 * This copyrighted material is made available to anyone wishing to use,
6 * modify, copy, or redistribute it subject to the terms and conditions 6 * modify, copy, or redistribute it subject to the terms and conditions
@@ -413,7 +413,8 @@ out:
413 return error; 413 return error;
414} 414}
415 415
416static void gfs2_init_dir(struct buffer_head *dibh, const struct gfs2_inode *parent) 416static void gfs2_init_dir(struct buffer_head *dibh,
417 const struct gfs2_inode *parent)
417{ 418{
418 struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data; 419 struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
419 struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1); 420 struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1);
@@ -431,12 +432,17 @@ static void gfs2_init_dir(struct buffer_head *dibh, const struct gfs2_inode *par
431 432
432/** 433/**
433 * init_dinode - Fill in a new dinode structure 434 * init_dinode - Fill in a new dinode structure
434 * @dip: the directory this inode is being created in 435 * @dip: The directory this inode is being created in
435 * @gl: The glock covering the new inode 436 * @gl: The glock covering the new inode
436 * @inum: the inode number 437 * @inum: The inode number
437 * @mode: the file permissions 438 * @mode: The file permissions
438 * @uid: 439 * @uid: The uid of the new inode
439 * @gid: 440 * @gid: The gid of the new inode
441 * @generation: The generation number of the new inode
442 * @dev: The device number (if a device node)
443 * @symname: The symlink destination (if a symlink)
444 * @size: The inode size (ignored for directories)
445 * @bhp: The buffer head (returned to caller)
440 * 446 *
441 */ 447 */
442 448
@@ -644,29 +650,25 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip,
644} 650}
645 651
646/** 652/**
647 * gfs2_createi - Create a new inode 653 * gfs2_create_inode - Create a new inode
648 * @ghs: An array of two holders 654 * @dir: The parent directory
649 * @name: The name of the new file 655 * @dentry: The new dentry
650 * @mode: the permissions on the new inode 656 * @mode: The permissions on the new inode
657 * @dev: For device nodes, this is the device number
658 * @symname: For symlinks, this is the link destination
659 * @size: The initial size of the inode (ignored for directories)
651 * 660 *
652 * @ghs[0] is an initialized holder for the directory 661 * Returns: 0 on success, or error code
653 * @ghs[1] is the holder for the inode lock
654 *
655 * If the return value is not NULL, the glocks on both the directory and the new
656 * file are held. A transaction has been started and an inplace reservation
657 * is held, as well.
658 *
659 * Returns: An inode
660 */ 662 */
661 663
662static struct inode *gfs2_createi(struct gfs2_holder *ghs, 664static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
663 const struct qstr *name, unsigned int mode, 665 unsigned int mode, dev_t dev, const char *symname,
664 dev_t dev, const char *symname, 666 unsigned int size)
665 unsigned int size)
666{ 667{
668 const struct qstr *name = &dentry->d_name;
669 struct gfs2_holder ghs[2];
667 struct inode *inode = NULL; 670 struct inode *inode = NULL;
668 struct gfs2_inode *dip = ghs->gh_gl->gl_object; 671 struct gfs2_inode *dip = GFS2_I(dir);
669 struct inode *dir = &dip->i_inode;
670 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); 672 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
671 struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 }; 673 struct gfs2_inum_host inum = { .no_addr = 0, .no_formal_ino = 0 };
672 int error; 674 int error;
@@ -674,10 +676,9 @@ static struct inode *gfs2_createi(struct gfs2_holder *ghs,
674 struct buffer_head *bh = NULL; 676 struct buffer_head *bh = NULL;
675 677
676 if (!name->len || name->len > GFS2_FNAMESIZE) 678 if (!name->len || name->len > GFS2_FNAMESIZE)
677 return ERR_PTR(-ENAMETOOLONG); 679 return -ENAMETOOLONG;
678 680
679 gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); 681 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
680 error = gfs2_glock_nq(ghs);
681 if (error) 682 if (error)
682 goto fail; 683 goto fail;
683 684
@@ -722,19 +723,29 @@ static struct inode *gfs2_createi(struct gfs2_holder *ghs,
722 723
723 if (bh) 724 if (bh)
724 brelse(bh); 725 brelse(bh);
725 return inode; 726
727 gfs2_trans_end(sdp);
728 if (dip->i_alloc->al_rgd)
729 gfs2_inplace_release(dip);
730 gfs2_quota_unlock(dip);
731 gfs2_alloc_put(dip);
732 gfs2_glock_dq_uninit_m(2, ghs);
733 mark_inode_dirty(inode);
734 d_instantiate(dentry, inode);
735 return 0;
726 736
727fail_gunlock2: 737fail_gunlock2:
728 gfs2_glock_dq_uninit(ghs + 1); 738 gfs2_glock_dq_uninit(ghs + 1);
729 if (inode && !IS_ERR(inode)) 739 if (inode && !IS_ERR(inode))
730 iput(inode); 740 iput(inode);
731fail_gunlock: 741fail_gunlock:
732 gfs2_glock_dq(ghs); 742 gfs2_glock_dq_uninit(ghs);
733fail: 743fail:
734 if (bh) 744 if (bh)
735 brelse(bh); 745 brelse(bh);
736 return ERR_PTR(error); 746 return error;
737} 747}
748
738/** 749/**
739 * gfs2_create - Create a file 750 * gfs2_create - Create a file
740 * @dir: The directory in which to create the file 751 * @dir: The directory in which to create the file
@@ -747,44 +758,23 @@ fail:
747static int gfs2_create(struct inode *dir, struct dentry *dentry, 758static int gfs2_create(struct inode *dir, struct dentry *dentry,
748 int mode, struct nameidata *nd) 759 int mode, struct nameidata *nd)
749{ 760{
750 struct gfs2_inode *dip = GFS2_I(dir);
751 struct gfs2_sbd *sdp = GFS2_SB(dir);
752 struct gfs2_holder ghs[2];
753 struct inode *inode; 761 struct inode *inode;
754 762 int ret;
755 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
756 763
757 for (;;) { 764 for (;;) {
758 inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0, NULL, 0); 765 ret = gfs2_create_inode(dir, dentry, S_IFREG | mode, 0, NULL, 0);
759 if (!IS_ERR(inode)) { 766 if (ret != -EEXIST || (nd && (nd->flags & LOOKUP_EXCL)))
760 gfs2_trans_end(sdp); 767 return ret;
761 if (dip->i_alloc->al_rgd)
762 gfs2_inplace_release(dip);
763 gfs2_quota_unlock(dip);
764 gfs2_alloc_put(dip);
765 gfs2_glock_dq_uninit_m(2, ghs);
766 mark_inode_dirty(inode);
767 break;
768 } else if (PTR_ERR(inode) != -EEXIST ||
769 (nd && nd->flags & LOOKUP_EXCL)) {
770 gfs2_holder_uninit(ghs);
771 return PTR_ERR(inode);
772 }
773 768
774 inode = gfs2_lookupi(dir, &dentry->d_name, 0); 769 inode = gfs2_lookupi(dir, &dentry->d_name, 0);
775 if (inode) { 770 if (inode) {
776 if (!IS_ERR(inode)) { 771 if (!IS_ERR(inode))
777 gfs2_holder_uninit(ghs);
778 break; 772 break;
779 } else { 773 return PTR_ERR(inode);
780 gfs2_holder_uninit(ghs);
781 return PTR_ERR(inode);
782 }
783 } 774 }
784 } 775 }
785 776
786 d_instantiate(dentry, inode); 777 d_instantiate(dentry, inode);
787
788 return 0; 778 return 0;
789} 779}
790 780
@@ -1150,36 +1140,14 @@ out_parent:
1150static int gfs2_symlink(struct inode *dir, struct dentry *dentry, 1140static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
1151 const char *symname) 1141 const char *symname)
1152{ 1142{
1153 struct gfs2_inode *dip = GFS2_I(dir);
1154 struct gfs2_sbd *sdp = GFS2_SB(dir); 1143 struct gfs2_sbd *sdp = GFS2_SB(dir);
1155 struct gfs2_holder ghs[2];
1156 struct inode *inode;
1157 unsigned int size; 1144 unsigned int size;
1158 1145
1159 size = strlen(symname); 1146 size = strlen(symname);
1160 if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1) 1147 if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1)
1161 return -ENAMETOOLONG; 1148 return -ENAMETOOLONG;
1162 1149
1163 gfs2_holder_init(dip->i_gl, 0, 0, ghs); 1150 return gfs2_create_inode(dir, dentry, S_IFLNK | S_IRWXUGO, 0, symname, size);
1164
1165 inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0, symname, size);
1166 if (IS_ERR(inode)) {
1167 gfs2_holder_uninit(ghs);
1168 return PTR_ERR(inode);
1169 }
1170
1171 gfs2_trans_end(sdp);
1172 if (dip->i_alloc->al_rgd)
1173 gfs2_inplace_release(dip);
1174 gfs2_quota_unlock(dip);
1175 gfs2_alloc_put(dip);
1176
1177 gfs2_glock_dq_uninit_m(2, ghs);
1178
1179 d_instantiate(dentry, inode);
1180 mark_inode_dirty(inode);
1181
1182 return 0;
1183} 1151}
1184 1152
1185/** 1153/**
@@ -1193,31 +1161,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
1193 1161
1194static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) 1162static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1195{ 1163{
1196 struct gfs2_inode *dip = GFS2_I(dir); 1164 return gfs2_create_inode(dir, dentry, S_IFDIR | mode, 0, NULL, 0);
1197 struct gfs2_sbd *sdp = GFS2_SB(dir);
1198 struct gfs2_holder ghs[2];
1199 struct inode *inode;
1200
1201 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
1202
1203 inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0, NULL, 0);
1204 if (IS_ERR(inode)) {
1205 gfs2_holder_uninit(ghs);
1206 return PTR_ERR(inode);
1207 }
1208
1209 gfs2_trans_end(sdp);
1210 if (dip->i_alloc->al_rgd)
1211 gfs2_inplace_release(dip);
1212 gfs2_quota_unlock(dip);
1213 gfs2_alloc_put(dip);
1214
1215 gfs2_glock_dq_uninit_m(2, ghs);
1216
1217 d_instantiate(dentry, inode);
1218 mark_inode_dirty(inode);
1219
1220 return 0;
1221} 1165}
1222 1166
1223/** 1167/**
@@ -1225,38 +1169,14 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1225 * @dir: The directory in which the special file will reside 1169 * @dir: The directory in which the special file will reside
1226 * @dentry: The dentry of the special file 1170 * @dentry: The dentry of the special file
1227 * @mode: The mode of the special file 1171 * @mode: The mode of the special file
1228 * @rdev: The device specification of the special file 1172 * @dev: The device specification of the special file
1229 * 1173 *
1230 */ 1174 */
1231 1175
1232static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, 1176static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
1233 dev_t dev) 1177 dev_t dev)
1234{ 1178{
1235 struct gfs2_inode *dip = GFS2_I(dir); 1179 return gfs2_create_inode(dir, dentry, mode, dev, NULL, 0);
1236 struct gfs2_sbd *sdp = GFS2_SB(dir);
1237 struct gfs2_holder ghs[2];
1238 struct inode *inode;
1239
1240 gfs2_holder_init(dip->i_gl, 0, 0, ghs);
1241
1242 inode = gfs2_createi(ghs, &dentry->d_name, mode, dev, NULL, 0);
1243 if (IS_ERR(inode)) {
1244 gfs2_holder_uninit(ghs);
1245 return PTR_ERR(inode);
1246 }
1247
1248 gfs2_trans_end(sdp);
1249 if (dip->i_alloc->al_rgd)
1250 gfs2_inplace_release(dip);
1251 gfs2_quota_unlock(dip);
1252 gfs2_alloc_put(dip);
1253
1254 gfs2_glock_dq_uninit_m(2, ghs);
1255
1256 d_instantiate(dentry, inode);
1257 mark_inode_dirty(inode);
1258
1259 return 0;
1260} 1180}
1261 1181
1262/* 1182/*