aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/dir.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-06-14 15:32:57 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-06-14 15:32:57 -0400
commitfeaa7bba026c181ce071d5a4884f7f9dd26207a1 (patch)
treec858deb225917265cb07820730e9764674d133e8 /fs/gfs2/dir.c
parent22da645fd6675b7abc55cf937ddf6132f343e5b9 (diff)
[GFS2] Fix unlinked file handling
This patch fixes the way we have been dealing with unlinked, but still open files. It removes all limits (other than memory for inodes, as per every other filesystem) on numbers of these which we can support on GFS2. It also means that (like other fs) its the responsibility of the last process to close the file to deallocate the storage, rather than the person who did the unlinking. Note that with GFS2, those two events might take place on different nodes. Also there are a number of other changes: o We use the Linux inode subsystem as it was intended to be used, wrt allocating GFS2 inodes o The Linux inode cache is now the point which we use for local enforcement of only holding one copy of the inode in core at once (previous to this we used the glock layer). o We no longer use the unlinked "special" file. We just ignore it completely. This makes unlinking more efficient. o We now use the 4th block allocation state. The previously unused state is used to track unlinked but still open inodes. o gfs2_inoded is no longer needed o Several fields are now no longer needed (and removed) from the in core struct gfs2_inode o Several fields are no longer needed (and removed) from the in core superblock There are a number of future possible optimisations and clean ups which have been made possible by this patch. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r--fs/gfs2/dir.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 6918a58261e..b0353884dd7 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -113,7 +113,7 @@ static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, uint64_t block,
113 error = gfs2_meta_read(ip->i_gl, block, DIO_START | DIO_WAIT, &bh); 113 error = gfs2_meta_read(ip->i_gl, block, DIO_START | DIO_WAIT, &bh);
114 if (error) 114 if (error)
115 return error; 115 return error;
116 if (gfs2_metatype_check(ip->i_sbd, bh, GFS2_METATYPE_JD)) { 116 if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) {
117 brelse(bh); 117 brelse(bh);
118 return -EIO; 118 return -EIO;
119 } 119 }
@@ -158,7 +158,7 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf,
158static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf, 158static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
159 uint64_t offset, unsigned int size) 159 uint64_t offset, unsigned int size)
160{ 160{
161 struct gfs2_sbd *sdp = ip->i_sbd; 161 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
162 struct buffer_head *dibh; 162 struct buffer_head *dibh;
163 uint64_t lblock, dblock; 163 uint64_t lblock, dblock;
164 uint32_t extlen = 0; 164 uint32_t extlen = 0;
@@ -197,7 +197,7 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
197 197
198 if (!extlen) { 198 if (!extlen) {
199 new = 1; 199 new = 1;
200 error = gfs2_extent_map(ip->i_vnode, lblock, &new, 200 error = gfs2_extent_map(&ip->i_inode, lblock, &new,
201 &dblock, &extlen); 201 &dblock, &extlen);
202 if (error) 202 if (error)
203 goto fail; 203 goto fail;
@@ -277,7 +277,7 @@ static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf,
277static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, 277static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf,
278 uint64_t offset, unsigned int size) 278 uint64_t offset, unsigned int size)
279{ 279{
280 struct gfs2_sbd *sdp = ip->i_sbd; 280 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
281 uint64_t lblock, dblock; 281 uint64_t lblock, dblock;
282 uint32_t extlen = 0; 282 uint32_t extlen = 0;
283 unsigned int o; 283 unsigned int o;
@@ -314,7 +314,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf,
314 314
315 if (!extlen) { 315 if (!extlen) {
316 new = 0; 316 new = 0;
317 error = gfs2_extent_map(ip->i_vnode, lblock, &new, 317 error = gfs2_extent_map(&ip->i_inode, lblock, &new,
318 &dblock, &extlen); 318 &dblock, &extlen);
319 if (error) 319 if (error)
320 goto fail; 320 goto fail;
@@ -534,7 +534,7 @@ static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode,
534 } 534 }
535 535
536consist_inode: 536consist_inode:
537 gfs2_consist_inode(inode->u.generic_ip); 537 gfs2_consist_inode(GFS2_I(inode));
538 return ERR_PTR(-EIO); 538 return ERR_PTR(-EIO);
539} 539}
540 540
@@ -556,13 +556,13 @@ static int dirent_first(struct gfs2_inode *dip, struct buffer_head *bh,
556 struct gfs2_meta_header *h = (struct gfs2_meta_header *)bh->b_data; 556 struct gfs2_meta_header *h = (struct gfs2_meta_header *)bh->b_data;
557 557
558 if (be32_to_cpu(h->mh_type) == GFS2_METATYPE_LF) { 558 if (be32_to_cpu(h->mh_type) == GFS2_METATYPE_LF) {
559 if (gfs2_meta_check(dip->i_sbd, bh)) 559 if (gfs2_meta_check(GFS2_SB(&dip->i_inode), bh))
560 return -EIO; 560 return -EIO;
561 *dent = (struct gfs2_dirent *)(bh->b_data + 561 *dent = (struct gfs2_dirent *)(bh->b_data +
562 sizeof(struct gfs2_leaf)); 562 sizeof(struct gfs2_leaf));
563 return IS_LEAF; 563 return IS_LEAF;
564 } else { 564 } else {
565 if (gfs2_metatype_check(dip->i_sbd, bh, GFS2_METATYPE_DI)) 565 if (gfs2_metatype_check(GFS2_SB(&dip->i_inode), bh, GFS2_METATYPE_DI))
566 return -EIO; 566 return -EIO;
567 *dent = (struct gfs2_dirent *)(bh->b_data + 567 *dent = (struct gfs2_dirent *)(bh->b_data +
568 sizeof(struct gfs2_dinode)); 568 sizeof(struct gfs2_dinode));
@@ -674,7 +674,7 @@ static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode,
674 const struct qstr *name, 674 const struct qstr *name,
675 struct buffer_head *bh) 675 struct buffer_head *bh)
676{ 676{
677 struct gfs2_inode *ip = inode->u.generic_ip; 677 struct gfs2_inode *ip = GFS2_I(inode);
678 struct gfs2_dirent *ndent; 678 struct gfs2_dirent *ndent;
679 unsigned offset = 0, totlen; 679 unsigned offset = 0, totlen;
680 680
@@ -707,8 +707,10 @@ static int get_leaf(struct gfs2_inode *dip, uint64_t leaf_no,
707 int error; 707 int error;
708 708
709 error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp); 709 error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp);
710 if (!error && gfs2_metatype_check(dip->i_sbd, *bhp, GFS2_METATYPE_LF)) 710 if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
711 /* printk(KERN_INFO "block num=%llu\n", leaf_no); */
711 error = -EIO; 712 error = -EIO;
713 }
712 714
713 return error; 715 return error;
714} 716}
@@ -759,7 +761,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
759{ 761{
760 struct buffer_head *bh; 762 struct buffer_head *bh;
761 struct gfs2_dirent *dent; 763 struct gfs2_dirent *dent;
762 struct gfs2_inode *ip = inode->u.generic_ip; 764 struct gfs2_inode *ip = GFS2_I(inode);
763 int error; 765 int error;
764 766
765 if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { 767 if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
@@ -771,7 +773,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
771 gfs2_consist_inode(ip); 773 gfs2_consist_inode(ip);
772 return ERR_PTR(-EIO); 774 return ERR_PTR(-EIO);
773 } 775 }
774 776
775 index = name->hash >> (32 - ip->i_di.di_depth); 777 index = name->hash >> (32 - ip->i_di.di_depth);
776 error = get_first_leaf(ip, index, &bh); 778 error = get_first_leaf(ip, index, &bh);
777 if (error) 779 if (error)
@@ -786,12 +788,14 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
786 brelse(bh); 788 brelse(bh);
787 if (!ln) 789 if (!ln)
788 break; 790 break;
791
789 error = get_leaf(ip, ln, &bh); 792 error = get_leaf(ip, ln, &bh);
790 } while(!error); 793 } while(!error);
791 794
792 return error ? ERR_PTR(error) : NULL; 795 return error ? ERR_PTR(error) : NULL;
793 } 796 }
794 797
798
795 error = gfs2_meta_inode_buffer(ip, &bh); 799 error = gfs2_meta_inode_buffer(ip, &bh);
796 if (error) 800 if (error)
797 return ERR_PTR(error); 801 return ERR_PTR(error);
@@ -807,7 +811,7 @@ got_dent:
807 811
808static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, u16 depth) 812static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, u16 depth)
809{ 813{
810 struct gfs2_inode *ip = inode->u.generic_ip; 814 struct gfs2_inode *ip = GFS2_I(inode);
811 u64 bn = gfs2_alloc_meta(ip); 815 u64 bn = gfs2_alloc_meta(ip);
812 struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn); 816 struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn);
813 struct gfs2_leaf *leaf; 817 struct gfs2_leaf *leaf;
@@ -815,6 +819,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
815 struct qstr name = { .name = "", .len = 0, .hash = 0 }; 819 struct qstr name = { .name = "", .len = 0, .hash = 0 };
816 if (!bh) 820 if (!bh)
817 return NULL; 821 return NULL;
822
818 gfs2_trans_add_bh(ip->i_gl, bh, 1); 823 gfs2_trans_add_bh(ip->i_gl, bh, 1);
819 gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF); 824 gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF);
820 leaf = (struct gfs2_leaf *)bh->b_data; 825 leaf = (struct gfs2_leaf *)bh->b_data;
@@ -838,8 +843,8 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
838 843
839static int dir_make_exhash(struct inode *inode) 844static int dir_make_exhash(struct inode *inode)
840{ 845{
841 struct gfs2_inode *dip = inode->u.generic_ip; 846 struct gfs2_inode *dip = GFS2_I(inode);
842 struct gfs2_sbd *sdp = dip->i_sbd; 847 struct gfs2_sbd *sdp = GFS2_SB(inode);
843 struct gfs2_dirent *dent; 848 struct gfs2_dirent *dent;
844 struct qstr args; 849 struct qstr args;
845 struct buffer_head *bh, *dibh; 850 struct buffer_head *bh, *dibh;
@@ -874,7 +879,7 @@ static int dir_make_exhash(struct inode *inode)
874 args.len = bh->b_size - sizeof(struct gfs2_dinode) + 879 args.len = bh->b_size - sizeof(struct gfs2_dinode) +
875 sizeof(struct gfs2_leaf); 880 sizeof(struct gfs2_leaf);
876 args.name = bh->b_data; 881 args.name = bh->b_data;
877 dent = gfs2_dirent_scan(dip->i_vnode, bh->b_data, bh->b_size, 882 dent = gfs2_dirent_scan(&dip->i_inode, bh->b_data, bh->b_size,
878 gfs2_dirent_last, &args, NULL); 883 gfs2_dirent_last, &args, NULL);
879 if (!dent) { 884 if (!dent) {
880 brelse(bh); 885 brelse(bh);
@@ -933,7 +938,7 @@ static int dir_make_exhash(struct inode *inode)
933 938
934static int dir_split_leaf(struct inode *inode, const struct qstr *name) 939static int dir_split_leaf(struct inode *inode, const struct qstr *name)
935{ 940{
936 struct gfs2_inode *dip = inode->u.generic_ip; 941 struct gfs2_inode *dip = GFS2_I(inode);
937 struct buffer_head *nbh, *obh, *dibh; 942 struct buffer_head *nbh, *obh, *dibh;
938 struct gfs2_leaf *nleaf, *oleaf; 943 struct gfs2_leaf *nleaf, *oleaf;
939 struct gfs2_dirent *dent, *prev = NULL, *next = NULL, *new; 944 struct gfs2_dirent *dent, *prev = NULL, *next = NULL, *new;
@@ -1044,7 +1049,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
1044 oleaf->lf_depth = nleaf->lf_depth; 1049 oleaf->lf_depth = nleaf->lf_depth;
1045 1050
1046 error = gfs2_meta_inode_buffer(dip, &dibh); 1051 error = gfs2_meta_inode_buffer(dip, &dibh);
1047 if (!gfs2_assert_withdraw(dip->i_sbd, !error)) { 1052 if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
1048 dip->i_di.di_blocks++; 1053 dip->i_di.di_blocks++;
1049 gfs2_dinode_out(&dip->i_di, dibh->b_data); 1054 gfs2_dinode_out(&dip->i_di, dibh->b_data);
1050 brelse(dibh); 1055 brelse(dibh);
@@ -1073,7 +1078,7 @@ fail_brelse:
1073 1078
1074static int dir_double_exhash(struct gfs2_inode *dip) 1079static int dir_double_exhash(struct gfs2_inode *dip)
1075{ 1080{
1076 struct gfs2_sbd *sdp = dip->i_sbd; 1081 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
1077 struct buffer_head *dibh; 1082 struct buffer_head *dibh;
1078 uint32_t hsize; 1083 uint32_t hsize;
1079 uint64_t *buf; 1084 uint64_t *buf;
@@ -1268,7 +1273,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
1268 gfs2_filldir_t filldir, int *copied, 1273 gfs2_filldir_t filldir, int *copied,
1269 unsigned *depth, u64 leaf_no) 1274 unsigned *depth, u64 leaf_no)
1270{ 1275{
1271 struct gfs2_inode *ip = inode->u.generic_ip; 1276 struct gfs2_inode *ip = GFS2_I(inode);
1272 struct buffer_head *bh; 1277 struct buffer_head *bh;
1273 struct gfs2_leaf *lf; 1278 struct gfs2_leaf *lf;
1274 unsigned entries = 0; 1279 unsigned entries = 0;
@@ -1348,8 +1353,8 @@ out:
1348static int dir_e_read(struct inode *inode, uint64_t *offset, void *opaque, 1353static int dir_e_read(struct inode *inode, uint64_t *offset, void *opaque,
1349 gfs2_filldir_t filldir) 1354 gfs2_filldir_t filldir)
1350{ 1355{
1351 struct gfs2_inode *dip = inode->u.generic_ip; 1356 struct gfs2_inode *dip = GFS2_I(inode);
1352 struct gfs2_sbd *sdp = dip->i_sbd; 1357 struct gfs2_sbd *sdp = GFS2_SB(inode);
1353 uint32_t hsize, len = 0; 1358 uint32_t hsize, len = 0;
1354 uint32_t ht_offset, lp_offset, ht_offset_cur = -1; 1359 uint32_t ht_offset, lp_offset, ht_offset_cur = -1;
1355 uint32_t hash, index; 1360 uint32_t hash, index;
@@ -1407,7 +1412,7 @@ out:
1407int gfs2_dir_read(struct inode *inode, uint64_t *offset, void *opaque, 1412int gfs2_dir_read(struct inode *inode, uint64_t *offset, void *opaque,
1408 gfs2_filldir_t filldir) 1413 gfs2_filldir_t filldir)
1409{ 1414{
1410 struct gfs2_inode *dip = inode->u.generic_ip; 1415 struct gfs2_inode *dip = GFS2_I(inode);
1411 struct dirent_gather g; 1416 struct dirent_gather g;
1412 const struct gfs2_dirent **darr, *dent; 1417 const struct gfs2_dirent **darr, *dent;
1413 struct buffer_head *dibh; 1418 struct buffer_head *dibh;
@@ -1490,7 +1495,7 @@ int gfs2_dir_search(struct inode *dir, const struct qstr *name,
1490static int dir_new_leaf(struct inode *inode, const struct qstr *name) 1495static int dir_new_leaf(struct inode *inode, const struct qstr *name)
1491{ 1496{
1492 struct buffer_head *bh, *obh; 1497 struct buffer_head *bh, *obh;
1493 struct gfs2_inode *ip = inode->u.generic_ip; 1498 struct gfs2_inode *ip = GFS2_I(inode);
1494 struct gfs2_leaf *leaf, *oleaf; 1499 struct gfs2_leaf *leaf, *oleaf;
1495 int error; 1500 int error;
1496 u32 index; 1501 u32 index;
@@ -1545,7 +1550,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
1545int gfs2_dir_add(struct inode *inode, const struct qstr *name, 1550int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1546 const struct gfs2_inum *inum, unsigned type) 1551 const struct gfs2_inum *inum, unsigned type)
1547{ 1552{
1548 struct gfs2_inode *ip = inode->u.generic_ip; 1553 struct gfs2_inode *ip = GFS2_I(inode);
1549 struct buffer_head *bh; 1554 struct buffer_head *bh;
1550 struct gfs2_dirent *dent; 1555 struct gfs2_dirent *dent;
1551 struct gfs2_leaf *leaf; 1556 struct gfs2_leaf *leaf;
@@ -1623,7 +1628,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1623 1628
1624 /* Returns _either_ the entry (if its first in block) or the 1629 /* Returns _either_ the entry (if its first in block) or the
1625 previous entry otherwise */ 1630 previous entry otherwise */
1626 dent = gfs2_dirent_search(dip->i_vnode, name, gfs2_dirent_prev, &bh); 1631 dent = gfs2_dirent_search(&dip->i_inode, name, gfs2_dirent_prev, &bh);
1627 if (!dent) { 1632 if (!dent) {
1628 gfs2_consist_inode(dip); 1633 gfs2_consist_inode(dip);
1629 return -EIO; 1634 return -EIO;
@@ -1659,6 +1664,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1659 dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); 1664 dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds();
1660 gfs2_dinode_out(&dip->i_di, bh->b_data); 1665 gfs2_dinode_out(&dip->i_di, bh->b_data);
1661 brelse(bh); 1666 brelse(bh);
1667 mark_inode_dirty(&dip->i_inode);
1662 1668
1663 return error; 1669 return error;
1664} 1670}
@@ -1683,7 +1689,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1683 struct gfs2_dirent *dent; 1689 struct gfs2_dirent *dent;
1684 int error; 1690 int error;
1685 1691
1686 dent = gfs2_dirent_search(dip->i_vnode, filename, gfs2_dirent_find, &bh); 1692 dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh);
1687 if (!dent) { 1693 if (!dent) {
1688 gfs2_consist_inode(dip); 1694 gfs2_consist_inode(dip);
1689 return -EIO; 1695 return -EIO;
@@ -1720,7 +1726,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1720 1726
1721static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) 1727static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
1722{ 1728{
1723 struct gfs2_sbd *sdp = dip->i_sbd; 1729 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
1724 struct buffer_head *bh; 1730 struct buffer_head *bh;
1725 struct gfs2_leaf *leaf; 1731 struct gfs2_leaf *leaf;
1726 uint32_t hsize, len; 1732 uint32_t hsize, len;
@@ -1800,7 +1806,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
1800static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len, 1806static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len,
1801 uint64_t leaf_no, void *data) 1807 uint64_t leaf_no, void *data)
1802{ 1808{
1803 struct gfs2_sbd *sdp = dip->i_sbd; 1809 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
1804 struct gfs2_leaf *tmp_leaf; 1810 struct gfs2_leaf *tmp_leaf;
1805 struct gfs2_rgrp_list rlist; 1811 struct gfs2_rgrp_list rlist;
1806 struct buffer_head *bh, *dibh; 1812 struct buffer_head *bh, *dibh;
@@ -1920,7 +1926,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, uint32_t index, uint32_t len,
1920 1926
1921int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip) 1927int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip)
1922{ 1928{
1923 struct gfs2_sbd *sdp = dip->i_sbd; 1929 struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
1924 struct buffer_head *bh; 1930 struct buffer_head *bh;
1925 int error; 1931 int error;
1926 1932