aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2')
-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/*