diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/inode.c | 184 |
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 | ||
416 | static void gfs2_init_dir(struct buffer_head *dibh, const struct gfs2_inode *parent) | 416 | static 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 | ||
662 | static struct inode *gfs2_createi(struct gfs2_holder *ghs, | 664 | static 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 | ||
727 | fail_gunlock2: | 737 | fail_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); |
731 | fail_gunlock: | 741 | fail_gunlock: |
732 | gfs2_glock_dq(ghs); | 742 | gfs2_glock_dq_uninit(ghs); |
733 | fail: | 743 | fail: |
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: | |||
747 | static int gfs2_create(struct inode *dir, struct dentry *dentry, | 758 | static 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: | |||
1150 | static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | 1140 | static 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 | ||
1194 | static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | 1162 | static 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 | ||
1232 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, | 1176 | static 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 | /* |