diff options
Diffstat (limited to 'fs/jfs')
-rw-r--r-- | fs/jfs/acl.c | 24 | ||||
-rw-r--r-- | fs/jfs/inode.c | 24 | ||||
-rw-r--r-- | fs/jfs/jfs_acl.h | 12 | ||||
-rw-r--r-- | fs/jfs/jfs_dmap.c | 344 | ||||
-rw-r--r-- | fs/jfs/jfs_dtree.c | 212 | ||||
-rw-r--r-- | fs/jfs/jfs_dtree.h | 7 | ||||
-rw-r--r-- | fs/jfs/jfs_filsys.h | 3 | ||||
-rw-r--r-- | fs/jfs/jfs_imap.c | 105 | ||||
-rw-r--r-- | fs/jfs/jfs_logmgr.c | 39 | ||||
-rw-r--r-- | fs/jfs/jfs_logmgr.h | 2 | ||||
-rw-r--r-- | fs/jfs/jfs_metapage.c | 11 | ||||
-rw-r--r-- | fs/jfs/jfs_txnmgr.c | 12 | ||||
-rw-r--r-- | fs/jfs/jfs_unicode.c | 7 | ||||
-rw-r--r-- | fs/jfs/jfs_xattr.h | 14 | ||||
-rw-r--r-- | fs/jfs/jfs_xtree.c | 340 | ||||
-rw-r--r-- | fs/jfs/jfs_xtree.h | 6 | ||||
-rw-r--r-- | fs/jfs/namei.c | 90 | ||||
-rw-r--r-- | fs/jfs/super.c | 52 | ||||
-rw-r--r-- | fs/jfs/symlink.c | 4 | ||||
-rw-r--r-- | fs/jfs/xattr.c | 100 |
20 files changed, 334 insertions, 1074 deletions
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index e892dab40c..461e4934ca 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/quotaops.h> | 23 | #include <linux/quotaops.h> |
24 | #include <linux/posix_acl_xattr.h> | 24 | #include <linux/posix_acl_xattr.h> |
25 | #include "jfs_incore.h" | 25 | #include "jfs_incore.h" |
26 | #include "jfs_txnmgr.h" | ||
26 | #include "jfs_xattr.h" | 27 | #include "jfs_xattr.h" |
27 | #include "jfs_acl.h" | 28 | #include "jfs_acl.h" |
28 | 29 | ||
@@ -75,7 +76,8 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type) | |||
75 | return acl; | 76 | return acl; |
76 | } | 77 | } |
77 | 78 | ||
78 | static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | 79 | static int jfs_set_acl(tid_t tid, struct inode *inode, int type, |
80 | struct posix_acl *acl) | ||
79 | { | 81 | { |
80 | char *ea_name; | 82 | char *ea_name; |
81 | struct jfs_inode_info *ji = JFS_IP(inode); | 83 | struct jfs_inode_info *ji = JFS_IP(inode); |
@@ -110,7 +112,7 @@ static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
110 | if (rc < 0) | 112 | if (rc < 0) |
111 | goto out; | 113 | goto out; |
112 | } | 114 | } |
113 | rc = __jfs_setxattr(inode, ea_name, value, size, 0); | 115 | rc = __jfs_setxattr(tid, inode, ea_name, value, size, 0); |
114 | out: | 116 | out: |
115 | kfree(value); | 117 | kfree(value); |
116 | 118 | ||
@@ -143,7 +145,7 @@ int jfs_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
143 | return generic_permission(inode, mask, jfs_check_acl); | 145 | return generic_permission(inode, mask, jfs_check_acl); |
144 | } | 146 | } |
145 | 147 | ||
146 | int jfs_init_acl(struct inode *inode, struct inode *dir) | 148 | int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) |
147 | { | 149 | { |
148 | struct posix_acl *acl = NULL; | 150 | struct posix_acl *acl = NULL; |
149 | struct posix_acl *clone; | 151 | struct posix_acl *clone; |
@@ -159,7 +161,7 @@ int jfs_init_acl(struct inode *inode, struct inode *dir) | |||
159 | 161 | ||
160 | if (acl) { | 162 | if (acl) { |
161 | if (S_ISDIR(inode->i_mode)) { | 163 | if (S_ISDIR(inode->i_mode)) { |
162 | rc = jfs_set_acl(inode, ACL_TYPE_DEFAULT, acl); | 164 | rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl); |
163 | if (rc) | 165 | if (rc) |
164 | goto cleanup; | 166 | goto cleanup; |
165 | } | 167 | } |
@@ -173,7 +175,8 @@ int jfs_init_acl(struct inode *inode, struct inode *dir) | |||
173 | if (rc >= 0) { | 175 | if (rc >= 0) { |
174 | inode->i_mode = mode; | 176 | inode->i_mode = mode; |
175 | if (rc > 0) | 177 | if (rc > 0) |
176 | rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone); | 178 | rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, |
179 | clone); | ||
177 | } | 180 | } |
178 | posix_acl_release(clone); | 181 | posix_acl_release(clone); |
179 | cleanup: | 182 | cleanup: |
@@ -202,8 +205,15 @@ static int jfs_acl_chmod(struct inode *inode) | |||
202 | return -ENOMEM; | 205 | return -ENOMEM; |
203 | 206 | ||
204 | rc = posix_acl_chmod_masq(clone, inode->i_mode); | 207 | rc = posix_acl_chmod_masq(clone, inode->i_mode); |
205 | if (!rc) | 208 | if (!rc) { |
206 | rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone); | 209 | tid_t tid = txBegin(inode->i_sb, 0); |
210 | down(&JFS_IP(inode)->commit_sem); | ||
211 | rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone); | ||
212 | if (!rc) | ||
213 | rc = txCommit(tid, 1, &inode, 0); | ||
214 | txEnd(tid); | ||
215 | up(&JFS_IP(inode)->commit_sem); | ||
216 | } | ||
207 | 217 | ||
208 | posix_acl_release(clone); | 218 | posix_acl_release(clone); |
209 | return rc; | 219 | return rc; |
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 2137138c59..0ec62d5310 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c | |||
@@ -128,17 +128,23 @@ void jfs_delete_inode(struct inode *inode) | |||
128 | { | 128 | { |
129 | jfs_info("In jfs_delete_inode, inode = 0x%p", inode); | 129 | jfs_info("In jfs_delete_inode, inode = 0x%p", inode); |
130 | 130 | ||
131 | if (test_cflag(COMMIT_Freewmap, inode)) | 131 | if (!is_bad_inode(inode) && |
132 | jfs_free_zero_link(inode); | 132 | (JFS_IP(inode)->fileset == cpu_to_le32(FILESYSTEM_I))) { |
133 | 133 | ||
134 | diFree(inode); | 134 | truncate_inode_pages(&inode->i_data, 0); |
135 | 135 | ||
136 | /* | 136 | if (test_cflag(COMMIT_Freewmap, inode)) |
137 | * Free the inode from the quota allocation. | 137 | jfs_free_zero_link(inode); |
138 | */ | 138 | |
139 | DQUOT_INIT(inode); | 139 | diFree(inode); |
140 | DQUOT_FREE_INODE(inode); | 140 | |
141 | DQUOT_DROP(inode); | 141 | /* |
142 | * Free the inode from the quota allocation. | ||
143 | */ | ||
144 | DQUOT_INIT(inode); | ||
145 | DQUOT_FREE_INODE(inode); | ||
146 | DQUOT_DROP(inode); | ||
147 | } | ||
142 | 148 | ||
143 | clear_inode(inode); | 149 | clear_inode(inode); |
144 | } | 150 | } |
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h index a3acd3eec0..a76293767c 100644 --- a/fs/jfs/jfs_acl.h +++ b/fs/jfs/jfs_acl.h | |||
@@ -21,8 +21,16 @@ | |||
21 | #ifdef CONFIG_JFS_POSIX_ACL | 21 | #ifdef CONFIG_JFS_POSIX_ACL |
22 | 22 | ||
23 | int jfs_permission(struct inode *, int, struct nameidata *); | 23 | int jfs_permission(struct inode *, int, struct nameidata *); |
24 | int jfs_init_acl(struct inode *, struct inode *); | 24 | int jfs_init_acl(tid_t, struct inode *, struct inode *); |
25 | int jfs_setattr(struct dentry *, struct iattr *); | 25 | int jfs_setattr(struct dentry *, struct iattr *); |
26 | 26 | ||
27 | #endif /* CONFIG_JFS_POSIX_ACL */ | 27 | #else |
28 | |||
29 | static inline int jfs_init_acl(tid_t tid, struct inode *inode, | ||
30 | struct inode *dir) | ||
31 | { | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | #endif | ||
28 | #endif /* _H_JFS_ACL */ | 36 | #endif /* _H_JFS_ACL */ |
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index cced2fed9d..c739626f5b 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c | |||
@@ -26,36 +26,6 @@ | |||
26 | #include "jfs_debug.h" | 26 | #include "jfs_debug.h" |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * Debug code for double-checking block map | ||
30 | */ | ||
31 | /* #define _JFS_DEBUG_DMAP 1 */ | ||
32 | |||
33 | #ifdef _JFS_DEBUG_DMAP | ||
34 | #define DBINITMAP(size,ipbmap,results) \ | ||
35 | DBinitmap(size,ipbmap,results) | ||
36 | #define DBALLOC(dbmap,mapsize,blkno,nblocks) \ | ||
37 | DBAlloc(dbmap,mapsize,blkno,nblocks) | ||
38 | #define DBFREE(dbmap,mapsize,blkno,nblocks) \ | ||
39 | DBFree(dbmap,mapsize,blkno,nblocks) | ||
40 | #define DBALLOCCK(dbmap,mapsize,blkno,nblocks) \ | ||
41 | DBAllocCK(dbmap,mapsize,blkno,nblocks) | ||
42 | #define DBFREECK(dbmap,mapsize,blkno,nblocks) \ | ||
43 | DBFreeCK(dbmap,mapsize,blkno,nblocks) | ||
44 | |||
45 | static void DBinitmap(s64, struct inode *, u32 **); | ||
46 | static void DBAlloc(uint *, s64, s64, s64); | ||
47 | static void DBFree(uint *, s64, s64, s64); | ||
48 | static void DBAllocCK(uint *, s64, s64, s64); | ||
49 | static void DBFreeCK(uint *, s64, s64, s64); | ||
50 | #else | ||
51 | #define DBINITMAP(size,ipbmap,results) | ||
52 | #define DBALLOC(dbmap, mapsize, blkno, nblocks) | ||
53 | #define DBFREE(dbmap, mapsize, blkno, nblocks) | ||
54 | #define DBALLOCCK(dbmap, mapsize, blkno, nblocks) | ||
55 | #define DBFREECK(dbmap, mapsize, blkno, nblocks) | ||
56 | #endif /* _JFS_DEBUG_DMAP */ | ||
57 | |||
58 | /* | ||
59 | * SERIALIZATION of the Block Allocation Map. | 29 | * SERIALIZATION of the Block Allocation Map. |
60 | * | 30 | * |
61 | * the working state of the block allocation map is accessed in | 31 | * the working state of the block allocation map is accessed in |
@@ -105,7 +75,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
105 | int nblocks); | 75 | int nblocks); |
106 | static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); | 76 | static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); |
107 | static void dbBackSplit(dmtree_t * tp, int leafno); | 77 | static void dbBackSplit(dmtree_t * tp, int leafno); |
108 | static void dbJoin(dmtree_t * tp, int leafno, int newval); | 78 | static int dbJoin(dmtree_t * tp, int leafno, int newval); |
109 | static void dbAdjTree(dmtree_t * tp, int leafno, int newval); | 79 | static void dbAdjTree(dmtree_t * tp, int leafno, int newval); |
110 | static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, | 80 | static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, |
111 | int level); | 81 | int level); |
@@ -128,8 +98,8 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks); | |||
128 | static int dbFindBits(u32 word, int l2nb); | 98 | static int dbFindBits(u32 word, int l2nb); |
129 | static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); | 99 | static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); |
130 | static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); | 100 | static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); |
131 | static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | 101 | static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, |
132 | int nblocks); | 102 | int nblocks); |
133 | static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, | 103 | static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, |
134 | int nblocks); | 104 | int nblocks); |
135 | static int dbMaxBud(u8 * cp); | 105 | static int dbMaxBud(u8 * cp); |
@@ -242,7 +212,6 @@ int dbMount(struct inode *ipbmap) | |||
242 | JFS_SBI(ipbmap->i_sb)->bmap = bmp; | 212 | JFS_SBI(ipbmap->i_sb)->bmap = bmp; |
243 | 213 | ||
244 | memset(bmp->db_active, 0, sizeof(bmp->db_active)); | 214 | memset(bmp->db_active, 0, sizeof(bmp->db_active)); |
245 | DBINITMAP(bmp->db_mapsize, ipbmap, &bmp->db_DBmap); | ||
246 | 215 | ||
247 | /* | 216 | /* |
248 | * allocate/initialize the bmap lock | 217 | * allocate/initialize the bmap lock |
@@ -407,16 +376,13 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks) | |||
407 | */ | 376 | */ |
408 | nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1))); | 377 | nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1))); |
409 | 378 | ||
410 | DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nb); | ||
411 | |||
412 | /* free the blocks. */ | 379 | /* free the blocks. */ |
413 | if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) { | 380 | if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) { |
381 | jfs_error(ip->i_sb, "dbFree: error in block map\n"); | ||
414 | release_metapage(mp); | 382 | release_metapage(mp); |
415 | IREAD_UNLOCK(ipbmap); | 383 | IREAD_UNLOCK(ipbmap); |
416 | return (rc); | 384 | return (rc); |
417 | } | 385 | } |
418 | |||
419 | DBFREE(bmp->db_DBmap, bmp->db_mapsize, blkno, nb); | ||
420 | } | 386 | } |
421 | 387 | ||
422 | /* write the last buffer. */ | 388 | /* write the last buffer. */ |
@@ -775,10 +741,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) | |||
775 | IWRITE_LOCK(ipbmap); | 741 | IWRITE_LOCK(ipbmap); |
776 | 742 | ||
777 | rc = dbAllocAny(bmp, nblocks, l2nb, results); | 743 | rc = dbAllocAny(bmp, nblocks, l2nb, results); |
778 | if (rc == 0) { | ||
779 | DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results, | ||
780 | nblocks); | ||
781 | } | ||
782 | 744 | ||
783 | goto write_unlock; | 745 | goto write_unlock; |
784 | } | 746 | } |
@@ -836,8 +798,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) | |||
836 | != -ENOSPC) { | 798 | != -ENOSPC) { |
837 | if (rc == 0) { | 799 | if (rc == 0) { |
838 | *results = blkno; | 800 | *results = blkno; |
839 | DBALLOC(bmp->db_DBmap, bmp->db_mapsize, | ||
840 | *results, nblocks); | ||
841 | mark_metapage_dirty(mp); | 801 | mark_metapage_dirty(mp); |
842 | } | 802 | } |
843 | 803 | ||
@@ -863,11 +823,8 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) | |||
863 | if ((rc = | 823 | if ((rc = |
864 | dbAllocNear(bmp, dp, blkno, (int) nblocks, l2nb, results)) | 824 | dbAllocNear(bmp, dp, blkno, (int) nblocks, l2nb, results)) |
865 | != -ENOSPC) { | 825 | != -ENOSPC) { |
866 | if (rc == 0) { | 826 | if (rc == 0) |
867 | DBALLOC(bmp->db_DBmap, bmp->db_mapsize, | ||
868 | *results, nblocks); | ||
869 | mark_metapage_dirty(mp); | 827 | mark_metapage_dirty(mp); |
870 | } | ||
871 | 828 | ||
872 | release_metapage(mp); | 829 | release_metapage(mp); |
873 | goto read_unlock; | 830 | goto read_unlock; |
@@ -878,11 +835,8 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) | |||
878 | */ | 835 | */ |
879 | if ((rc = dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results)) | 836 | if ((rc = dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results)) |
880 | != -ENOSPC) { | 837 | != -ENOSPC) { |
881 | if (rc == 0) { | 838 | if (rc == 0) |
882 | DBALLOC(bmp->db_DBmap, bmp->db_mapsize, | ||
883 | *results, nblocks); | ||
884 | mark_metapage_dirty(mp); | 839 | mark_metapage_dirty(mp); |
885 | } | ||
886 | 840 | ||
887 | release_metapage(mp); | 841 | release_metapage(mp); |
888 | goto read_unlock; | 842 | goto read_unlock; |
@@ -896,13 +850,9 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) | |||
896 | * the same allocation group as the hint. | 850 | * the same allocation group as the hint. |
897 | */ | 851 | */ |
898 | IWRITE_LOCK(ipbmap); | 852 | IWRITE_LOCK(ipbmap); |
899 | if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) | 853 | if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) != -ENOSPC) |
900 | != -ENOSPC) { | ||
901 | if (rc == 0) | ||
902 | DBALLOC(bmp->db_DBmap, bmp->db_mapsize, | ||
903 | *results, nblocks); | ||
904 | goto write_unlock; | 854 | goto write_unlock; |
905 | } | 855 | |
906 | IWRITE_UNLOCK(ipbmap); | 856 | IWRITE_UNLOCK(ipbmap); |
907 | 857 | ||
908 | 858 | ||
@@ -918,9 +868,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results) | |||
918 | */ | 868 | */ |
919 | if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) == -ENOSPC) | 869 | if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) == -ENOSPC) |
920 | rc = dbAllocAny(bmp, nblocks, l2nb, results); | 870 | rc = dbAllocAny(bmp, nblocks, l2nb, results); |
921 | if (rc == 0) { | ||
922 | DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results, nblocks); | ||
923 | } | ||
924 | 871 | ||
925 | write_unlock: | 872 | write_unlock: |
926 | IWRITE_UNLOCK(ipbmap); | 873 | IWRITE_UNLOCK(ipbmap); |
@@ -992,10 +939,9 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks) | |||
992 | 939 | ||
993 | IREAD_UNLOCK(ipbmap); | 940 | IREAD_UNLOCK(ipbmap); |
994 | 941 | ||
995 | if (rc == 0) { | 942 | if (rc == 0) |
996 | DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks); | ||
997 | mark_metapage_dirty(mp); | 943 | mark_metapage_dirty(mp); |
998 | } | 944 | |
999 | release_metapage(mp); | 945 | release_metapage(mp); |
1000 | 946 | ||
1001 | return (rc); | 947 | return (rc); |
@@ -1144,7 +1090,6 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks) | |||
1144 | return -EIO; | 1090 | return -EIO; |
1145 | } | 1091 | } |
1146 | 1092 | ||
1147 | DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks); | ||
1148 | dp = (struct dmap *) mp->data; | 1093 | dp = (struct dmap *) mp->data; |
1149 | 1094 | ||
1150 | /* try to allocate the blocks immediately following the | 1095 | /* try to allocate the blocks immediately following the |
@@ -1155,11 +1100,9 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks) | |||
1155 | IREAD_UNLOCK(ipbmap); | 1100 | IREAD_UNLOCK(ipbmap); |
1156 | 1101 | ||
1157 | /* were we successful ? */ | 1102 | /* were we successful ? */ |
1158 | if (rc == 0) { | 1103 | if (rc == 0) |
1159 | DBALLOC(bmp->db_DBmap, bmp->db_mapsize, extblkno, | ||
1160 | addnblocks); | ||
1161 | write_metapage(mp); | 1104 | write_metapage(mp); |
1162 | } else | 1105 | else |
1163 | /* we were not successful */ | 1106 | /* we were not successful */ |
1164 | release_metapage(mp); | 1107 | release_metapage(mp); |
1165 | 1108 | ||
@@ -2078,7 +2021,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2078 | int nblocks) | 2021 | int nblocks) |
2079 | { | 2022 | { |
2080 | s8 oldroot; | 2023 | s8 oldroot; |
2081 | int rc, word; | 2024 | int rc = 0, word; |
2082 | 2025 | ||
2083 | /* save the current value of the root (i.e. maximum free string) | 2026 | /* save the current value of the root (i.e. maximum free string) |
2084 | * of the dmap tree. | 2027 | * of the dmap tree. |
@@ -2086,11 +2029,11 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2086 | oldroot = dp->tree.stree[ROOT]; | 2029 | oldroot = dp->tree.stree[ROOT]; |
2087 | 2030 | ||
2088 | /* free the specified (blocks) bits */ | 2031 | /* free the specified (blocks) bits */ |
2089 | dbFreeBits(bmp, dp, blkno, nblocks); | 2032 | rc = dbFreeBits(bmp, dp, blkno, nblocks); |
2090 | 2033 | ||
2091 | /* if the root has not changed, done. */ | 2034 | /* if error or the root has not changed, done. */ |
2092 | if (dp->tree.stree[ROOT] == oldroot) | 2035 | if (rc || (dp->tree.stree[ROOT] == oldroot)) |
2093 | return (0); | 2036 | return (rc); |
2094 | 2037 | ||
2095 | /* root changed. bubble the change up to the dmap control pages. | 2038 | /* root changed. bubble the change up to the dmap control pages. |
2096 | * if the adjustment of the upper level control pages fails, | 2039 | * if the adjustment of the upper level control pages fails, |
@@ -2279,15 +2222,16 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2279 | * blkno - starting block number of the bits to be freed. | 2222 | * blkno - starting block number of the bits to be freed. |
2280 | * nblocks - number of bits to be freed. | 2223 | * nblocks - number of bits to be freed. |
2281 | * | 2224 | * |
2282 | * RETURN VALUES: none | 2225 | * RETURN VALUES: 0 for success |
2283 | * | 2226 | * |
2284 | * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; | 2227 | * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; |
2285 | */ | 2228 | */ |
2286 | static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | 2229 | static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, |
2287 | int nblocks) | 2230 | int nblocks) |
2288 | { | 2231 | { |
2289 | int dbitno, word, rembits, nb, nwords, wbitno, nw, agno; | 2232 | int dbitno, word, rembits, nb, nwords, wbitno, nw, agno; |
2290 | dmtree_t *tp = (dmtree_t *) & dp->tree; | 2233 | dmtree_t *tp = (dmtree_t *) & dp->tree; |
2234 | int rc = 0; | ||
2291 | int size; | 2235 | int size; |
2292 | 2236 | ||
2293 | /* determine the bit number and word within the dmap of the | 2237 | /* determine the bit number and word within the dmap of the |
@@ -2336,8 +2280,10 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2336 | 2280 | ||
2337 | /* update the leaf for this dmap word. | 2281 | /* update the leaf for this dmap word. |
2338 | */ | 2282 | */ |
2339 | dbJoin(tp, word, | 2283 | rc = dbJoin(tp, word, |
2340 | dbMaxBud((u8 *) & dp->wmap[word])); | 2284 | dbMaxBud((u8 *) & dp->wmap[word])); |
2285 | if (rc) | ||
2286 | return rc; | ||
2341 | 2287 | ||
2342 | word += 1; | 2288 | word += 1; |
2343 | } else { | 2289 | } else { |
@@ -2368,7 +2314,9 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2368 | 2314 | ||
2369 | /* update the leaf. | 2315 | /* update the leaf. |
2370 | */ | 2316 | */ |
2371 | dbJoin(tp, word, size); | 2317 | rc = dbJoin(tp, word, size); |
2318 | if (rc) | ||
2319 | return rc; | ||
2372 | 2320 | ||
2373 | /* get the number of dmap words handled. | 2321 | /* get the number of dmap words handled. |
2374 | */ | 2322 | */ |
@@ -2415,6 +2363,8 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, | |||
2415 | } | 2363 | } |
2416 | 2364 | ||
2417 | BMAP_UNLOCK(bmp); | 2365 | BMAP_UNLOCK(bmp); |
2366 | |||
2367 | return 0; | ||
2418 | } | 2368 | } |
2419 | 2369 | ||
2420 | 2370 | ||
@@ -2522,7 +2472,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) | |||
2522 | } | 2472 | } |
2523 | dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); | 2473 | dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); |
2524 | } else { | 2474 | } else { |
2525 | dbJoin((dmtree_t *) dcp, leafno, newval); | 2475 | rc = dbJoin((dmtree_t *) dcp, leafno, newval); |
2476 | if (rc) | ||
2477 | return rc; | ||
2526 | } | 2478 | } |
2527 | 2479 | ||
2528 | /* check if the root of the current dmap control page changed due | 2480 | /* check if the root of the current dmap control page changed due |
@@ -2747,7 +2699,7 @@ static void dbBackSplit(dmtree_t * tp, int leafno) | |||
2747 | * | 2699 | * |
2748 | * RETURN VALUES: none | 2700 | * RETURN VALUES: none |
2749 | */ | 2701 | */ |
2750 | static void dbJoin(dmtree_t * tp, int leafno, int newval) | 2702 | static int dbJoin(dmtree_t * tp, int leafno, int newval) |
2751 | { | 2703 | { |
2752 | int budsz, buddy; | 2704 | int budsz, buddy; |
2753 | s8 *leaf; | 2705 | s8 *leaf; |
@@ -2787,7 +2739,9 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval) | |||
2787 | if (newval > leaf[buddy]) | 2739 | if (newval > leaf[buddy]) |
2788 | break; | 2740 | break; |
2789 | 2741 | ||
2790 | assert(newval == leaf[buddy]); | 2742 | /* It shouldn't be less */ |
2743 | if (newval < leaf[buddy]) | ||
2744 | return -EIO; | ||
2791 | 2745 | ||
2792 | /* check which (leafno or buddy) is the left buddy. | 2746 | /* check which (leafno or buddy) is the left buddy. |
2793 | * the left buddy gets to claim the blocks resulting | 2747 | * the left buddy gets to claim the blocks resulting |
@@ -2819,6 +2773,8 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval) | |||
2819 | /* update the leaf value. | 2773 | /* update the leaf value. |
2820 | */ | 2774 | */ |
2821 | dbAdjTree(tp, leafno, newval); | 2775 | dbAdjTree(tp, leafno, newval); |
2776 | |||
2777 | return 0; | ||
2822 | } | 2778 | } |
2823 | 2779 | ||
2824 | 2780 | ||
@@ -3185,16 +3141,12 @@ int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks) | |||
3185 | */ | 3141 | */ |
3186 | nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1))); | 3142 | nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1))); |
3187 | 3143 | ||
3188 | DBFREECK(bmp->db_DBmap, bmp->db_mapsize, blkno, nb); | ||
3189 | |||
3190 | /* allocate the blocks. */ | 3144 | /* allocate the blocks. */ |
3191 | if ((rc = dbAllocDmapBU(bmp, dp, blkno, nb))) { | 3145 | if ((rc = dbAllocDmapBU(bmp, dp, blkno, nb))) { |
3192 | release_metapage(mp); | 3146 | release_metapage(mp); |
3193 | IREAD_UNLOCK(ipbmap); | 3147 | IREAD_UNLOCK(ipbmap); |
3194 | return (rc); | 3148 | return (rc); |
3195 | } | 3149 | } |
3196 | |||
3197 | DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nb); | ||
3198 | } | 3150 | } |
3199 | 3151 | ||
3200 | /* write the last buffer. */ | 3152 | /* write the last buffer. */ |
@@ -4041,223 +3993,3 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap) | |||
4041 | 3993 | ||
4042 | return (nblocks); | 3994 | return (nblocks); |
4043 | } | 3995 | } |
4044 | |||
4045 | |||
4046 | #ifdef _JFS_DEBUG_DMAP | ||
4047 | /* | ||
4048 | * DBinitmap() | ||
4049 | */ | ||
4050 | static void DBinitmap(s64 size, struct inode *ipbmap, u32 ** results) | ||
4051 | { | ||
4052 | int npages; | ||
4053 | u32 *dbmap, *d; | ||
4054 | int n; | ||
4055 | s64 lblkno, cur_block; | ||
4056 | struct dmap *dp; | ||
4057 | struct metapage *mp; | ||
4058 | |||
4059 | npages = size / 32768; | ||
4060 | npages += (size % 32768) ? 1 : 0; | ||
4061 | |||
4062 | dbmap = (u32 *) xmalloc(npages * 4096, L2PSIZE, kernel_heap); | ||
4063 | if (dbmap == NULL) | ||
4064 | BUG(); /* Not robust since this is only unused debug code */ | ||
4065 | |||
4066 | for (n = 0, d = dbmap; n < npages; n++, d += 1024) | ||
4067 | bzero(d, 4096); | ||
4068 | |||
4069 | /* Need to initialize from disk map pages | ||
4070 | */ | ||
4071 | for (d = dbmap, cur_block = 0; cur_block < size; | ||
4072 | cur_block += BPERDMAP, d += LPERDMAP) { | ||
4073 | lblkno = BLKTODMAP(cur_block, | ||
4074 | JFS_SBI(ipbmap->i_sb)->bmap-> | ||
4075 | db_l2nbperpage); | ||
4076 | mp = read_metapage(ipbmap, lblkno, PSIZE, 0); | ||
4077 | if (mp == NULL) { | ||
4078 | jfs_error(ipbmap->i_sb, | ||
4079 | "DBinitmap: could not read disk map page"); | ||
4080 | continue; | ||
4081 | } | ||
4082 | dp = (struct dmap *) mp->data; | ||
4083 | |||
4084 | for (n = 0; n < LPERDMAP; n++) | ||
4085 | d[n] = le32_to_cpu(dp->wmap[n]); | ||
4086 | |||
4087 | release_metapage(mp); | ||
4088 | } | ||
4089 | |||
4090 | *results = dbmap; | ||
4091 | } | ||
4092 | |||
4093 | |||
4094 | /* | ||
4095 | * DBAlloc() | ||
4096 | */ | ||
4097 | void DBAlloc(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks) | ||
4098 | { | ||
4099 | int word, nb, bitno; | ||
4100 | u32 mask; | ||
4101 | |||
4102 | assert(blkno > 0 && blkno < mapsize); | ||
4103 | assert(nblocks > 0 && nblocks <= mapsize); | ||
4104 | |||
4105 | assert(blkno + nblocks <= mapsize); | ||
4106 | |||
4107 | dbmap += (blkno / 32); | ||
4108 | while (nblocks > 0) { | ||
4109 | bitno = blkno & (32 - 1); | ||
4110 | nb = min(nblocks, 32 - bitno); | ||
4111 | |||
4112 | mask = (0xffffffff << (32 - nb) >> bitno); | ||
4113 | assert((mask & *dbmap) == 0); | ||
4114 | *dbmap |= mask; | ||
4115 | |||
4116 | dbmap++; | ||
4117 | blkno += nb; | ||
4118 | nblocks -= nb; | ||
4119 | } | ||
4120 | } | ||
4121 | |||
4122 | |||
4123 | /* | ||
4124 | * DBFree() | ||
4125 | */ | ||
4126 | static void DBFree(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks) | ||
4127 | { | ||
4128 | int word, nb, bitno; | ||
4129 | u32 mask; | ||
4130 | |||
4131 | assert(blkno > 0 && blkno < mapsize); | ||
4132 | assert(nblocks > 0 && nblocks <= mapsize); | ||
4133 | |||
4134 | assert(blkno + nblocks <= mapsize); | ||
4135 | |||
4136 | dbmap += (blkno / 32); | ||
4137 | while (nblocks > 0) { | ||
4138 | bitno = blkno & (32 - 1); | ||
4139 | nb = min(nblocks, 32 - bitno); | ||
4140 | |||
4141 | mask = (0xffffffff << (32 - nb) >> bitno); | ||
4142 | assert((mask & *dbmap) == mask); | ||
4143 | *dbmap &= ~mask; | ||
4144 | |||
4145 | dbmap++; | ||
4146 | blkno += nb; | ||
4147 | nblocks -= nb; | ||
4148 | } | ||
4149 | } | ||
4150 | |||
4151 | |||
4152 | /* | ||
4153 | * DBAllocCK() | ||
4154 | */ | ||
4155 | static void DBAllocCK(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks) | ||
4156 | { | ||
4157 | int word, nb, bitno; | ||
4158 | u32 mask; | ||
4159 | |||
4160 | assert(blkno > 0 && blkno < mapsize); | ||
4161 | assert(nblocks > 0 && nblocks <= mapsize); | ||
4162 | |||
4163 | assert(blkno + nblocks <= mapsize); | ||
4164 | |||
4165 | dbmap += (blkno / 32); | ||
4166 | while (nblocks > 0) { | ||
4167 | bitno = blkno & (32 - 1); | ||
4168 | nb = min(nblocks, 32 - bitno); | ||
4169 | |||
4170 | mask = (0xffffffff << (32 - nb) >> bitno); | ||
4171 | assert((mask & *dbmap) == mask); | ||
4172 | |||
4173 | dbmap++; | ||
4174 | blkno += nb; | ||
4175 | nblocks -= nb; | ||
4176 | } | ||
4177 | } | ||
4178 | |||
4179 | |||
4180 | /* | ||
4181 | * DBFreeCK() | ||
4182 | */ | ||
4183 | static void DBFreeCK(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks) | ||
4184 | { | ||
4185 | int word, nb, bitno; | ||
4186 | u32 mask; | ||
4187 | |||
4188 | assert(blkno > 0 && blkno < mapsize); | ||
4189 | assert(nblocks > 0 && nblocks <= mapsize); | ||
4190 | |||
4191 | assert(blkno + nblocks <= mapsize); | ||
4192 | |||
4193 | dbmap += (blkno / 32); | ||
4194 | while (nblocks > 0) { | ||
4195 | bitno = blkno & (32 - 1); | ||
4196 | nb = min(nblocks, 32 - bitno); | ||
4197 | |||
4198 | mask = (0xffffffff << (32 - nb) >> bitno); | ||
4199 | assert((mask & *dbmap) == 0); | ||
4200 | |||
4201 | dbmap++; | ||
4202 | blkno += nb; | ||
4203 | nblocks -= nb; | ||
4204 | } | ||
4205 | } | ||
4206 | |||
4207 | |||
4208 | /* | ||
4209 | * dbPrtMap() | ||
4210 | */ | ||
4211 | static void dbPrtMap(struct bmap * bmp) | ||
4212 | { | ||
4213 | printk(" mapsize: %d%d\n", bmp->db_mapsize); | ||
4214 | printk(" nfree: %d%d\n", bmp->db_nfree); | ||
4215 | printk(" numag: %d\n", bmp->db_numag); | ||
4216 | printk(" agsize: %d%d\n", bmp->db_agsize); | ||
4217 | printk(" agl2size: %d\n", bmp->db_agl2size); | ||
4218 | printk(" agwidth: %d\n", bmp->db_agwidth); | ||
4219 | printk(" agstart: %d\n", bmp->db_agstart); | ||
4220 | printk(" agheigth: %d\n", bmp->db_agheigth); | ||
4221 | printk(" aglevel: %d\n", bmp->db_aglevel); | ||
4222 | printk(" maxlevel: %d\n", bmp->db_maxlevel); | ||
4223 | printk(" maxag: %d\n", bmp->db_maxag); | ||
4224 | printk(" agpref: %d\n", bmp->db_agpref); | ||
4225 | printk(" l2nbppg: %d\n", bmp->db_l2nbperpage); | ||
4226 | } | ||
4227 | |||
4228 | |||
4229 | /* | ||
4230 | * dbPrtCtl() | ||
4231 | */ | ||
4232 | static void dbPrtCtl(struct dmapctl * dcp) | ||
4233 | { | ||
4234 | int i, j, n; | ||
4235 | |||
4236 | printk(" height: %08x\n", le32_to_cpu(dcp->height)); | ||
4237 | printk(" leafidx: %08x\n", le32_to_cpu(dcp->leafidx)); | ||
4238 | printk(" budmin: %08x\n", dcp->budmin); | ||
4239 | printk(" nleafs: %08x\n", le32_to_cpu(dcp->nleafs)); | ||
4240 | printk(" l2nleafs: %08x\n", le32_to_cpu(dcp->l2nleafs)); | ||
4241 | |||
4242 | printk("\n Tree:\n"); | ||
4243 | for (i = 0; i < CTLLEAFIND; i += 8) { | ||
4244 | n = min(8, CTLLEAFIND - i); | ||
4245 | |||
4246 | for (j = 0; j < n; j++) | ||
4247 | printf(" [%03x]: %02x", i + j, | ||
4248 | (char) dcp->stree[i + j]); | ||
4249 | printf("\n"); | ||
4250 | } | ||
4251 | |||
4252 | printk("\n Tree Leaves:\n"); | ||
4253 | for (i = 0; i < LPERCTL; i += 8) { | ||
4254 | n = min(8, LPERCTL - i); | ||
4255 | |||
4256 | for (j = 0; j < n; j++) | ||
4257 | printf(" [%03x]: %02x", | ||
4258 | i + j, | ||
4259 | (char) dcp->stree[i + j + CTLLEAFIND]); | ||
4260 | printf("\n"); | ||
4261 | } | ||
4262 | } | ||
4263 | #endif /* _JFS_DEBUG_DMAP */ | ||
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index 8676aee3ae..404f33eae5 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c | |||
@@ -381,9 +381,12 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) | |||
381 | * It's time to move the inline table to an external | 381 | * It's time to move the inline table to an external |
382 | * page and begin to build the xtree | 382 | * page and begin to build the xtree |
383 | */ | 383 | */ |
384 | if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage) || | 384 | if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage)) |
385 | dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) | 385 | goto clean_up; |
386 | goto clean_up; /* No space */ | 386 | if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) { |
387 | DQUOT_FREE_BLOCK(ip, sbi->nbperpage); | ||
388 | goto clean_up; | ||
389 | } | ||
387 | 390 | ||
388 | /* | 391 | /* |
389 | * Save the table, we're going to overwrite it with the | 392 | * Save the table, we're going to overwrite it with the |
@@ -397,13 +400,15 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) | |||
397 | xtInitRoot(tid, ip); | 400 | xtInitRoot(tid, ip); |
398 | 401 | ||
399 | /* | 402 | /* |
400 | * Allocate the first block & add it to the xtree | 403 | * Add the first block to the xtree |
401 | */ | 404 | */ |
402 | if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) { | 405 | if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) { |
403 | /* This really shouldn't fail */ | 406 | /* This really shouldn't fail */ |
404 | jfs_warn("add_index: xtInsert failed!"); | 407 | jfs_warn("add_index: xtInsert failed!"); |
405 | memcpy(&jfs_ip->i_dirtable, temp_table, | 408 | memcpy(&jfs_ip->i_dirtable, temp_table, |
406 | sizeof (temp_table)); | 409 | sizeof (temp_table)); |
410 | dbFree(ip, xaddr, sbi->nbperpage); | ||
411 | DQUOT_FREE_BLOCK(ip, sbi->nbperpage); | ||
407 | goto clean_up; | 412 | goto clean_up; |
408 | } | 413 | } |
409 | ip->i_size = PSIZE; | 414 | ip->i_size = PSIZE; |
@@ -4554,202 +4559,3 @@ int dtModify(tid_t tid, struct inode *ip, | |||
4554 | 4559 | ||
4555 | return 0; | 4560 | return 0; |
4556 | } | 4561 | } |
4557 | |||
4558 | #ifdef _JFS_DEBUG_DTREE | ||
4559 | /* | ||
4560 | * dtDisplayTree() | ||
4561 | * | ||
4562 | * function: traverse forward | ||
4563 | */ | ||
4564 | int dtDisplayTree(struct inode *ip) | ||
4565 | { | ||
4566 | int rc; | ||
4567 | struct metapage *mp; | ||
4568 | dtpage_t *p; | ||
4569 | s64 bn, pbn; | ||
4570 | int index, lastindex, v, h; | ||
4571 | pxd_t *xd; | ||
4572 | struct btstack btstack; | ||
4573 | struct btframe *btsp; | ||
4574 | struct btframe *parent; | ||
4575 | u8 *stbl; | ||
4576 | int psize = 256; | ||
4577 | |||
4578 | printk("display B+-tree.\n"); | ||
4579 | |||
4580 | /* clear stack */ | ||
4581 | btsp = btstack.stack; | ||
4582 | |||
4583 | /* | ||
4584 | * start with root | ||
4585 | * | ||
4586 | * root resides in the inode | ||
4587 | */ | ||
4588 | bn = 0; | ||
4589 | v = h = 0; | ||
4590 | |||
4591 | /* | ||
4592 | * first access of each page: | ||
4593 | */ | ||
4594 | newPage: | ||
4595 | DT_GETPAGE(ip, bn, mp, psize, p, rc); | ||
4596 | if (rc) | ||
4597 | return rc; | ||
4598 | |||
4599 | /* process entries forward from first index */ | ||
4600 | index = 0; | ||
4601 | lastindex = p->header.nextindex - 1; | ||
4602 | |||
4603 | if (p->header.flag & BT_INTERNAL) { | ||
4604 | /* | ||
4605 | * first access of each internal page | ||
4606 | */ | ||
4607 | printf("internal page "); | ||
4608 | dtDisplayPage(ip, bn, p); | ||
4609 | |||
4610 | goto getChild; | ||
4611 | } else { /* (p->header.flag & BT_LEAF) */ | ||
4612 | |||
4613 | /* | ||
4614 | * first access of each leaf page | ||
4615 | */ | ||
4616 | printf("leaf page "); | ||
4617 | dtDisplayPage(ip, bn, p); | ||
4618 | |||
4619 | /* | ||
4620 | * process leaf page entries | ||
4621 | * | ||
4622 | for ( ; index <= lastindex; index++) | ||
4623 | { | ||
4624 | } | ||
4625 | */ | ||
4626 | |||
4627 | /* unpin the leaf page */ | ||
4628 | DT_PUTPAGE(mp); | ||
4629 | } | ||
4630 | |||
4631 | /* | ||
4632 | * go back up to the parent page | ||
4633 | */ | ||
4634 | getParent: | ||
4635 | /* pop/restore parent entry for the current child page */ | ||
4636 | if ((parent = (btsp == btstack.stack ? NULL : --btsp)) == NULL) | ||
4637 | /* current page must have been root */ | ||
4638 | return; | ||
4639 | |||
4640 | /* | ||
4641 | * parent page scan completed | ||
4642 | */ | ||
4643 | if ((index = parent->index) == (lastindex = parent->lastindex)) { | ||
4644 | /* go back up to the parent page */ | ||
4645 | goto getParent; | ||
4646 | } | ||
4647 | |||
4648 | /* | ||
4649 | * parent page has entries remaining | ||
4650 | */ | ||
4651 | /* get back the parent page */ | ||
4652 | bn = parent->bn; | ||
4653 | /* v = parent->level; */ | ||
4654 | DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); | ||
4655 | if (rc) | ||
4656 | return rc; | ||
4657 | |||
4658 | /* get next parent entry */ | ||
4659 | index++; | ||
4660 | |||
4661 | /* | ||
4662 | * internal page: go down to child page of current entry | ||
4663 | */ | ||
4664 | getChild: | ||
4665 | /* push/save current parent entry for the child page */ | ||
4666 | btsp->bn = pbn = bn; | ||
4667 | btsp->index = index; | ||
4668 | btsp->lastindex = lastindex; | ||
4669 | /* btsp->level = v; */ | ||
4670 | /* btsp->node = h; */ | ||
4671 | ++btsp; | ||
4672 | |||
4673 | /* get current entry for the child page */ | ||
4674 | stbl = DT_GETSTBL(p); | ||
4675 | xd = (pxd_t *) & p->slot[stbl[index]]; | ||
4676 | |||
4677 | /* | ||
4678 | * first access of each internal entry: | ||
4679 | */ | ||
4680 | |||
4681 | /* get child page */ | ||
4682 | bn = addressPXD(xd); | ||
4683 | psize = lengthPXD(xd) << ip->i_ipmnt->i_l2bsize; | ||
4684 | |||
4685 | printk("traverse down 0x%Lx[%d]->0x%Lx\n", pbn, index, bn); | ||
4686 | v++; | ||
4687 | h = index; | ||
4688 | |||
4689 | /* release parent page */ | ||
4690 | DT_PUTPAGE(mp); | ||
4691 | |||
4692 | /* process the child page */ | ||
4693 | goto newPage; | ||
4694 | } | ||
4695 | |||
4696 | |||
4697 | /* | ||
4698 | * dtDisplayPage() | ||
4699 | * | ||
4700 | * function: display page | ||
4701 | */ | ||
4702 | int dtDisplayPage(struct inode *ip, s64 bn, dtpage_t * p) | ||
4703 | { | ||
4704 | int rc; | ||
4705 | struct metapage *mp; | ||
4706 | struct ldtentry *lh; | ||
4707 | struct idtentry *ih; | ||
4708 | pxd_t *xd; | ||
4709 | int i, j; | ||
4710 | u8 *stbl; | ||
4711 | wchar_t name[JFS_NAME_MAX + 1]; | ||
4712 | struct component_name key = { 0, name }; | ||
4713 | int freepage = 0; | ||
4714 | |||
4715 | if (p == NULL) { | ||
4716 | freepage = 1; | ||
4717 | DT_GETPAGE(ip, bn, mp, PSIZE, p, rc); | ||
4718 | if (rc) | ||
4719 | return rc; | ||
4720 | } | ||
4721 | |||
4722 | /* display page control */ | ||
4723 | printk("bn:0x%Lx flag:0x%08x nextindex:%d\n", | ||
4724 | bn, p->header.flag, p->header.nextindex); | ||
4725 | |||
4726 | /* display entries */ | ||
4727 | stbl = DT_GETSTBL(p); | ||
4728 | for (i = 0, j = 1; i < p->header.nextindex; i++, j++) { | ||
4729 | dtGetKey(p, i, &key, JFS_SBI(ip->i_sb)->mntflag); | ||
4730 | key.name[key.namlen] = '\0'; | ||
4731 | if (p->header.flag & BT_LEAF) { | ||
4732 | lh = (struct ldtentry *) & p->slot[stbl[i]]; | ||
4733 | printf("\t[%d] %s:%d", i, key.name, | ||
4734 | le32_to_cpu(lh->inumber)); | ||
4735 | } else { | ||
4736 | ih = (struct idtentry *) & p->slot[stbl[i]]; | ||
4737 | xd = (pxd_t *) ih; | ||
4738 | bn = addressPXD(xd); | ||
4739 | printf("\t[%d] %s:0x%Lx", i, key.name, bn); | ||
4740 | } | ||
4741 | |||
4742 | if (j == 4) { | ||
4743 | printf("\n"); | ||
4744 | j = 0; | ||
4745 | } | ||
4746 | } | ||
4747 | |||
4748 | printf("\n"); | ||
4749 | |||
4750 | if (freepage) | ||
4751 | DT_PUTPAGE(mp); | ||
4752 | |||
4753 | return 0; | ||
4754 | } | ||
4755 | #endif /* _JFS_DEBUG_DTREE */ | ||
diff --git a/fs/jfs/jfs_dtree.h b/fs/jfs/jfs_dtree.h index 273a80130c..13e4fdf077 100644 --- a/fs/jfs/jfs_dtree.h +++ b/fs/jfs/jfs_dtree.h | |||
@@ -269,11 +269,4 @@ extern int dtModify(tid_t tid, struct inode *ip, struct component_name * key, | |||
269 | ino_t * orig_ino, ino_t new_ino, int flag); | 269 | ino_t * orig_ino, ino_t new_ino, int flag); |
270 | 270 | ||
271 | extern int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir); | 271 | extern int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir); |
272 | |||
273 | #ifdef _JFS_DEBUG_DTREE | ||
274 | extern int dtDisplayTree(struct inode *ip); | ||
275 | |||
276 | extern int dtDisplayPage(struct inode *ip, s64 bn, dtpage_t * p); | ||
277 | #endif /* _JFS_DEBUG_DTREE */ | ||
278 | |||
279 | #endif /* !_H_JFS_DTREE */ | 272 | #endif /* !_H_JFS_DTREE */ |
diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h index 86ccac80f0..72a5588fae 100644 --- a/fs/jfs/jfs_filsys.h +++ b/fs/jfs/jfs_filsys.h | |||
@@ -37,6 +37,9 @@ | |||
37 | #define JFS_ERR_CONTINUE 0x00000004 /* continue */ | 37 | #define JFS_ERR_CONTINUE 0x00000004 /* continue */ |
38 | #define JFS_ERR_PANIC 0x00000008 /* panic */ | 38 | #define JFS_ERR_PANIC 0x00000008 /* panic */ |
39 | 39 | ||
40 | #define JFS_USRQUOTA 0x00000010 | ||
41 | #define JFS_GRPQUOTA 0x00000020 | ||
42 | |||
40 | /* platform option (conditional compilation) */ | 43 | /* platform option (conditional compilation) */ |
41 | #define JFS_AIX 0x80000000 /* AIX support */ | 44 | #define JFS_AIX 0x80000000 /* AIX support */ |
42 | /* POSIX name/directory support */ | 45 | /* POSIX name/directory support */ |
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 971af2977e..4021d46da7 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
@@ -87,25 +87,6 @@ static int copy_from_dinode(struct dinode *, struct inode *); | |||
87 | static void copy_to_dinode(struct dinode *, struct inode *); | 87 | static void copy_to_dinode(struct dinode *, struct inode *); |
88 | 88 | ||
89 | /* | 89 | /* |
90 | * debug code for double-checking inode map | ||
91 | */ | ||
92 | /* #define _JFS_DEBUG_IMAP 1 */ | ||
93 | |||
94 | #ifdef _JFS_DEBUG_IMAP | ||
95 | #define DBG_DIINIT(imap) DBGdiInit(imap) | ||
96 | #define DBG_DIALLOC(imap, ino) DBGdiAlloc(imap, ino) | ||
97 | #define DBG_DIFREE(imap, ino) DBGdiFree(imap, ino) | ||
98 | |||
99 | static void *DBGdiInit(struct inomap * imap); | ||
100 | static void DBGdiAlloc(struct inomap * imap, ino_t ino); | ||
101 | static void DBGdiFree(struct inomap * imap, ino_t ino); | ||
102 | #else | ||
103 | #define DBG_DIINIT(imap) | ||
104 | #define DBG_DIALLOC(imap, ino) | ||
105 | #define DBG_DIFREE(imap, ino) | ||
106 | #endif /* _JFS_DEBUG_IMAP */ | ||
107 | |||
108 | /* | ||
109 | * NAME: diMount() | 90 | * NAME: diMount() |
110 | * | 91 | * |
111 | * FUNCTION: initialize the incore inode map control structures for | 92 | * FUNCTION: initialize the incore inode map control structures for |
@@ -188,8 +169,6 @@ int diMount(struct inode *ipimap) | |||
188 | imap->im_ipimap = ipimap; | 169 | imap->im_ipimap = ipimap; |
189 | JFS_IP(ipimap)->i_imap = imap; | 170 | JFS_IP(ipimap)->i_imap = imap; |
190 | 171 | ||
191 | // DBG_DIINIT(imap); | ||
192 | |||
193 | return (0); | 172 | return (0); |
194 | } | 173 | } |
195 | 174 | ||
@@ -1043,7 +1022,6 @@ int diFree(struct inode *ip) | |||
1043 | /* update the bitmap. | 1022 | /* update the bitmap. |
1044 | */ | 1023 | */ |
1045 | iagp->wmap[extno] = cpu_to_le32(bitmap); | 1024 | iagp->wmap[extno] = cpu_to_le32(bitmap); |
1046 | DBG_DIFREE(imap, inum); | ||
1047 | 1025 | ||
1048 | /* update the free inode counts at the iag, ag and | 1026 | /* update the free inode counts at the iag, ag and |
1049 | * map level. | 1027 | * map level. |
@@ -1231,7 +1209,6 @@ int diFree(struct inode *ip) | |||
1231 | jfs_error(ip->i_sb, "diFree: the pmap does not show inode free"); | 1209 | jfs_error(ip->i_sb, "diFree: the pmap does not show inode free"); |
1232 | } | 1210 | } |
1233 | iagp->wmap[extno] = 0; | 1211 | iagp->wmap[extno] = 0; |
1234 | DBG_DIFREE(imap, inum); | ||
1235 | PXDlength(&iagp->inoext[extno], 0); | 1212 | PXDlength(&iagp->inoext[extno], 0); |
1236 | PXDaddress(&iagp->inoext[extno], 0); | 1213 | PXDaddress(&iagp->inoext[extno], 0); |
1237 | 1214 | ||
@@ -1350,7 +1327,6 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) | |||
1350 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); | 1327 | struct jfs_inode_info *jfs_ip = JFS_IP(ip); |
1351 | 1328 | ||
1352 | ip->i_ino = (iagno << L2INOSPERIAG) + ino; | 1329 | ip->i_ino = (iagno << L2INOSPERIAG) + ino; |
1353 | DBG_DIALLOC(JFS_IP(ipimap)->i_imap, ip->i_ino); | ||
1354 | jfs_ip->ixpxd = iagp->inoext[extno]; | 1330 | jfs_ip->ixpxd = iagp->inoext[extno]; |
1355 | jfs_ip->agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); | 1331 | jfs_ip->agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); |
1356 | jfs_ip->active_ag = -1; | 1332 | jfs_ip->active_ag = -1; |
@@ -3185,84 +3161,3 @@ static void copy_to_dinode(struct dinode * dip, struct inode *ip) | |||
3185 | if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) | 3161 | if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode)) |
3186 | dip->di_rdev = cpu_to_le32(jfs_ip->dev); | 3162 | dip->di_rdev = cpu_to_le32(jfs_ip->dev); |
3187 | } | 3163 | } |
3188 | |||
3189 | #ifdef _JFS_DEBUG_IMAP | ||
3190 | /* | ||
3191 | * DBGdiInit() | ||
3192 | */ | ||
3193 | static void *DBGdiInit(struct inomap * imap) | ||
3194 | { | ||
3195 | u32 *dimap; | ||
3196 | int size; | ||
3197 | size = 64 * 1024; | ||
3198 | if ((dimap = (u32 *) xmalloc(size, L2PSIZE, kernel_heap)) == NULL) | ||
3199 | assert(0); | ||
3200 | bzero((void *) dimap, size); | ||
3201 | imap->im_DBGdimap = dimap; | ||
3202 | } | ||
3203 | |||
3204 | /* | ||
3205 | * DBGdiAlloc() | ||
3206 | */ | ||
3207 | static void DBGdiAlloc(struct inomap * imap, ino_t ino) | ||
3208 | { | ||
3209 | u32 *dimap = imap->im_DBGdimap; | ||
3210 | int w, b; | ||
3211 | u32 m; | ||
3212 | w = ino >> 5; | ||
3213 | b = ino & 31; | ||
3214 | m = 0x80000000 >> b; | ||
3215 | assert(w < 64 * 256); | ||
3216 | if (dimap[w] & m) { | ||
3217 | printk("DEBUG diAlloc: duplicate alloc ino:0x%x\n", ino); | ||
3218 | } | ||
3219 | dimap[w] |= m; | ||
3220 | } | ||
3221 | |||
3222 | /* | ||
3223 | * DBGdiFree() | ||
3224 | */ | ||
3225 | static void DBGdiFree(struct inomap * imap, ino_t ino) | ||
3226 | { | ||
3227 | u32 *dimap = imap->im_DBGdimap; | ||
3228 | int w, b; | ||
3229 | u32 m; | ||
3230 | w = ino >> 5; | ||
3231 | b = ino & 31; | ||
3232 | m = 0x80000000 >> b; | ||
3233 | assert(w < 64 * 256); | ||
3234 | if ((dimap[w] & m) == 0) { | ||
3235 | printk("DEBUG diFree: duplicate free ino:0x%x\n", ino); | ||
3236 | } | ||
3237 | dimap[w] &= ~m; | ||
3238 | } | ||
3239 | |||
3240 | static void dump_cp(struct inomap * ipimap, char *function, int line) | ||
3241 | { | ||
3242 | printk("\n* ********* *\nControl Page %s %d\n", function, line); | ||
3243 | printk("FreeIAG %d\tNextIAG %d\n", ipimap->im_freeiag, | ||
3244 | ipimap->im_nextiag); | ||
3245 | printk("NumInos %d\tNumFree %d\n", | ||
3246 | atomic_read(&ipimap->im_numinos), | ||
3247 | atomic_read(&ipimap->im_numfree)); | ||
3248 | printk("AG InoFree %d\tAG ExtFree %d\n", | ||
3249 | ipimap->im_agctl[0].inofree, ipimap->im_agctl[0].extfree); | ||
3250 | printk("AG NumInos %d\tAG NumFree %d\n", | ||
3251 | ipimap->im_agctl[0].numinos, ipimap->im_agctl[0].numfree); | ||
3252 | } | ||
3253 | |||
3254 | static void dump_iag(struct iag * iag, char *function, int line) | ||
3255 | { | ||
3256 | printk("\n* ********* *\nIAG %s %d\n", function, line); | ||
3257 | printk("IagNum %d\tIAG Free %d\n", le32_to_cpu(iag->iagnum), | ||
3258 | le32_to_cpu(iag->iagfree)); | ||
3259 | printk("InoFreeFwd %d\tInoFreeBack %d\n", | ||
3260 | le32_to_cpu(iag->inofreefwd), | ||
3261 | le32_to_cpu(iag->inofreeback)); | ||
3262 | printk("ExtFreeFwd %d\tExtFreeBack %d\n", | ||
3263 | le32_to_cpu(iag->extfreefwd), | ||
3264 | le32_to_cpu(iag->extfreeback)); | ||
3265 | printk("NFreeInos %d\tNFreeExts %d\n", le32_to_cpu(iag->nfreeinos), | ||
3266 | le32_to_cpu(iag->nfreeexts)); | ||
3267 | } | ||
3268 | #endif /* _JFS_DEBUG_IMAP */ | ||
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 79d07624bf..d27bac6aca 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c | |||
@@ -191,7 +191,7 @@ static int lbmIOWait(struct lbuf * bp, int flag); | |||
191 | static bio_end_io_t lbmIODone; | 191 | static bio_end_io_t lbmIODone; |
192 | static void lbmStartIO(struct lbuf * bp); | 192 | static void lbmStartIO(struct lbuf * bp); |
193 | static void lmGCwrite(struct jfs_log * log, int cant_block); | 193 | static void lmGCwrite(struct jfs_log * log, int cant_block); |
194 | static int lmLogSync(struct jfs_log * log, int nosyncwait); | 194 | static int lmLogSync(struct jfs_log * log, int hard_sync); |
195 | 195 | ||
196 | 196 | ||
197 | 197 | ||
@@ -915,19 +915,17 @@ static void lmPostGC(struct lbuf * bp) | |||
915 | * if new sync address is available | 915 | * if new sync address is available |
916 | * (normally the case if sync() is executed by back-ground | 916 | * (normally the case if sync() is executed by back-ground |
917 | * process). | 917 | * process). |
918 | * if not, explicitly run jfs_blogsync() to initiate | ||
919 | * getting of new sync address. | ||
920 | * calculate new value of i_nextsync which determines when | 918 | * calculate new value of i_nextsync which determines when |
921 | * this code is called again. | 919 | * this code is called again. |
922 | * | 920 | * |
923 | * PARAMETERS: log - log structure | 921 | * PARAMETERS: log - log structure |
924 | * nosyncwait - 1 if called asynchronously | 922 | * hard_sync - 1 to force all metadata to be written |
925 | * | 923 | * |
926 | * RETURN: 0 | 924 | * RETURN: 0 |
927 | * | 925 | * |
928 | * serialization: LOG_LOCK() held on entry/exit | 926 | * serialization: LOG_LOCK() held on entry/exit |
929 | */ | 927 | */ |
930 | static int lmLogSync(struct jfs_log * log, int nosyncwait) | 928 | static int lmLogSync(struct jfs_log * log, int hard_sync) |
931 | { | 929 | { |
932 | int logsize; | 930 | int logsize; |
933 | int written; /* written since last syncpt */ | 931 | int written; /* written since last syncpt */ |
@@ -941,11 +939,18 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) | |||
941 | unsigned long flags; | 939 | unsigned long flags; |
942 | 940 | ||
943 | /* push dirty metapages out to disk */ | 941 | /* push dirty metapages out to disk */ |
944 | list_for_each_entry(sbi, &log->sb_list, log_list) { | 942 | if (hard_sync) |
945 | filemap_flush(sbi->ipbmap->i_mapping); | 943 | list_for_each_entry(sbi, &log->sb_list, log_list) { |
946 | filemap_flush(sbi->ipimap->i_mapping); | 944 | filemap_fdatawrite(sbi->ipbmap->i_mapping); |
947 | filemap_flush(sbi->direct_inode->i_mapping); | 945 | filemap_fdatawrite(sbi->ipimap->i_mapping); |
948 | } | 946 | filemap_fdatawrite(sbi->direct_inode->i_mapping); |
947 | } | ||
948 | else | ||
949 | list_for_each_entry(sbi, &log->sb_list, log_list) { | ||
950 | filemap_flush(sbi->ipbmap->i_mapping); | ||
951 | filemap_flush(sbi->ipimap->i_mapping); | ||
952 | filemap_flush(sbi->direct_inode->i_mapping); | ||
953 | } | ||
949 | 954 | ||
950 | /* | 955 | /* |
951 | * forward syncpt | 956 | * forward syncpt |
@@ -1021,16 +1026,13 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) | |||
1021 | /* next syncpt trigger = written + more */ | 1026 | /* next syncpt trigger = written + more */ |
1022 | log->nextsync = written + more; | 1027 | log->nextsync = written + more; |
1023 | 1028 | ||
1024 | /* return if lmLogSync() from outside of transaction, e.g., sync() */ | ||
1025 | if (nosyncwait) | ||
1026 | return lsn; | ||
1027 | |||
1028 | /* if number of bytes written from last sync point is more | 1029 | /* if number of bytes written from last sync point is more |
1029 | * than 1/4 of the log size, stop new transactions from | 1030 | * than 1/4 of the log size, stop new transactions from |
1030 | * starting until all current transactions are completed | 1031 | * starting until all current transactions are completed |
1031 | * by setting syncbarrier flag. | 1032 | * by setting syncbarrier flag. |
1032 | */ | 1033 | */ |
1033 | if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) { | 1034 | if (!test_bit(log_SYNCBARRIER, &log->flag) && |
1035 | (written > LOGSYNC_BARRIER(logsize)) && log->active) { | ||
1034 | set_bit(log_SYNCBARRIER, &log->flag); | 1036 | set_bit(log_SYNCBARRIER, &log->flag); |
1035 | jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn, | 1037 | jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn, |
1036 | log->syncpt); | 1038 | log->syncpt); |
@@ -1048,11 +1050,12 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) | |||
1048 | * | 1050 | * |
1049 | * FUNCTION: write log SYNCPT record for specified log | 1051 | * FUNCTION: write log SYNCPT record for specified log |
1050 | * | 1052 | * |
1051 | * PARAMETERS: log - log structure | 1053 | * PARAMETERS: log - log structure |
1054 | * hard_sync - set to 1 to force metadata to be written | ||
1052 | */ | 1055 | */ |
1053 | void jfs_syncpt(struct jfs_log *log) | 1056 | void jfs_syncpt(struct jfs_log *log, int hard_sync) |
1054 | { LOG_LOCK(log); | 1057 | { LOG_LOCK(log); |
1055 | lmLogSync(log, 1); | 1058 | lmLogSync(log, hard_sync); |
1056 | LOG_UNLOCK(log); | 1059 | LOG_UNLOCK(log); |
1057 | } | 1060 | } |
1058 | 1061 | ||
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h index 747114cd38..e4978b5b65 100644 --- a/fs/jfs/jfs_logmgr.h +++ b/fs/jfs/jfs_logmgr.h | |||
@@ -510,6 +510,6 @@ extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize); | |||
510 | extern int lmGroupCommit(struct jfs_log *, struct tblock *); | 510 | extern int lmGroupCommit(struct jfs_log *, struct tblock *); |
511 | extern int jfsIOWait(void *); | 511 | extern int jfsIOWait(void *); |
512 | extern void jfs_flush_journal(struct jfs_log * log, int wait); | 512 | extern void jfs_flush_journal(struct jfs_log * log, int wait); |
513 | extern void jfs_syncpt(struct jfs_log *log); | 513 | extern void jfs_syncpt(struct jfs_log *log, int hard_sync); |
514 | 514 | ||
515 | #endif /* _H_JFS_LOGMGR */ | 515 | #endif /* _H_JFS_LOGMGR */ |
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 6c5485d16c..13d7e3f1fe 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c | |||
@@ -561,7 +561,6 @@ static int metapage_releasepage(struct page *page, int gfp_mask) | |||
561 | dump_mem("page", page, sizeof(struct page)); | 561 | dump_mem("page", page, sizeof(struct page)); |
562 | dump_stack(); | 562 | dump_stack(); |
563 | } | 563 | } |
564 | WARN_ON(mp->lsn); | ||
565 | if (mp->lsn) | 564 | if (mp->lsn) |
566 | remove_from_logsync(mp); | 565 | remove_from_logsync(mp); |
567 | remove_metapage(page, mp); | 566 | remove_metapage(page, mp); |
@@ -641,7 +640,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, | |||
641 | } else { | 640 | } else { |
642 | page = read_cache_page(mapping, page_index, | 641 | page = read_cache_page(mapping, page_index, |
643 | (filler_t *)mapping->a_ops->readpage, NULL); | 642 | (filler_t *)mapping->a_ops->readpage, NULL); |
644 | if (IS_ERR(page)) { | 643 | if (IS_ERR(page) || !PageUptodate(page)) { |
645 | jfs_err("read_cache_page failed!"); | 644 | jfs_err("read_cache_page failed!"); |
646 | return NULL; | 645 | return NULL; |
647 | } | 646 | } |
@@ -783,14 +782,6 @@ void release_metapage(struct metapage * mp) | |||
783 | if (test_bit(META_discard, &mp->flag) && !mp->count) { | 782 | if (test_bit(META_discard, &mp->flag) && !mp->count) { |
784 | clear_page_dirty(page); | 783 | clear_page_dirty(page); |
785 | ClearPageUptodate(page); | 784 | ClearPageUptodate(page); |
786 | #ifdef _NOT_YET | ||
787 | if (page->mapping) { | ||
788 | /* Remove from page cache and page cache reference */ | ||
789 | remove_from_page_cache(page); | ||
790 | page_cache_release(page); | ||
791 | metapage_releasepage(page, 0); | ||
792 | } | ||
793 | #endif | ||
794 | } | 785 | } |
795 | #else | 786 | #else |
796 | /* Try to keep metapages from using up too much memory */ | 787 | /* Try to keep metapages from using up too much memory */ |
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 121c981ff4..c7a92f9deb 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c | |||
@@ -552,6 +552,11 @@ void txEnd(tid_t tid) | |||
552 | * synchronize with logsync barrier | 552 | * synchronize with logsync barrier |
553 | */ | 553 | */ |
554 | if (test_bit(log_SYNCBARRIER, &log->flag)) { | 554 | if (test_bit(log_SYNCBARRIER, &log->flag)) { |
555 | TXN_UNLOCK(); | ||
556 | |||
557 | /* write dirty metadata & forward log syncpt */ | ||
558 | jfs_syncpt(log, 1); | ||
559 | |||
555 | jfs_info("log barrier off: 0x%x", log->lsn); | 560 | jfs_info("log barrier off: 0x%x", log->lsn); |
556 | 561 | ||
557 | /* enable new transactions start */ | 562 | /* enable new transactions start */ |
@@ -560,11 +565,6 @@ void txEnd(tid_t tid) | |||
560 | /* wakeup all waitors for logsync barrier */ | 565 | /* wakeup all waitors for logsync barrier */ |
561 | TXN_WAKEUP(&log->syncwait); | 566 | TXN_WAKEUP(&log->syncwait); |
562 | 567 | ||
563 | TXN_UNLOCK(); | ||
564 | |||
565 | /* forward log syncpt */ | ||
566 | jfs_syncpt(log); | ||
567 | |||
568 | goto wakeup; | 568 | goto wakeup; |
569 | } | 569 | } |
570 | } | 570 | } |
@@ -657,7 +657,9 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, | |||
657 | /* only anonymous txn. | 657 | /* only anonymous txn. |
658 | * Remove from anon_list | 658 | * Remove from anon_list |
659 | */ | 659 | */ |
660 | TXN_LOCK(); | ||
660 | list_del_init(&jfs_ip->anon_inode_list); | 661 | list_del_init(&jfs_ip->anon_inode_list); |
662 | TXN_UNLOCK(); | ||
661 | } | 663 | } |
662 | jfs_ip->atlhead = tlck->next; | 664 | jfs_ip->atlhead = tlck->next; |
663 | } else { | 665 | } else { |
diff --git a/fs/jfs/jfs_unicode.c b/fs/jfs/jfs_unicode.c index b32208aad5..f327decfb1 100644 --- a/fs/jfs/jfs_unicode.c +++ b/fs/jfs/jfs_unicode.c | |||
@@ -51,8 +51,9 @@ int jfs_strfromUCS_le(char *to, const __le16 * from, | |||
51 | } | 51 | } |
52 | } else { | 52 | } else { |
53 | for (i = 0; (i < len) && from[i]; i++) { | 53 | for (i = 0; (i < len) && from[i]; i++) { |
54 | if (le16_to_cpu(from[i]) & 0xff00) { | 54 | if (unlikely(le16_to_cpu(from[i]) & 0xff00)) { |
55 | if (warn) { | 55 | to[i] = '?'; |
56 | if (unlikely(warn)) { | ||
56 | warn--; | 57 | warn--; |
57 | warn_again--; | 58 | warn_again--; |
58 | printk(KERN_ERR | 59 | printk(KERN_ERR |
@@ -61,7 +62,7 @@ int jfs_strfromUCS_le(char *to, const __le16 * from, | |||
61 | printk(KERN_ERR | 62 | printk(KERN_ERR |
62 | "mount with iocharset=utf8 to access\n"); | 63 | "mount with iocharset=utf8 to access\n"); |
63 | } | 64 | } |
64 | to[i] = '?'; | 65 | |
65 | } | 66 | } |
66 | else | 67 | else |
67 | to[i] = (char) (le16_to_cpu(from[i])); | 68 | to[i] = (char) (le16_to_cpu(from[i])); |
diff --git a/fs/jfs/jfs_xattr.h b/fs/jfs/jfs_xattr.h index a1052f3f0b..25e9990bcc 100644 --- a/fs/jfs/jfs_xattr.h +++ b/fs/jfs/jfs_xattr.h | |||
@@ -52,8 +52,8 @@ struct jfs_ea_list { | |||
52 | #define END_EALIST(ealist) \ | 52 | #define END_EALIST(ealist) \ |
53 | ((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist))) | 53 | ((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist))) |
54 | 54 | ||
55 | extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t, | 55 | extern int __jfs_setxattr(tid_t, struct inode *, const char *, const void *, |
56 | int); | 56 | size_t, int); |
57 | extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t, | 57 | extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t, |
58 | int); | 58 | int); |
59 | extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); | 59 | extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); |
@@ -61,4 +61,14 @@ extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t); | |||
61 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); | 61 | extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); |
62 | extern int jfs_removexattr(struct dentry *, const char *); | 62 | extern int jfs_removexattr(struct dentry *, const char *); |
63 | 63 | ||
64 | #ifdef CONFIG_JFS_SECURITY | ||
65 | extern int jfs_init_security(tid_t, struct inode *, struct inode *); | ||
66 | #else | ||
67 | static inline int jfs_init_security(tid_t tid, struct inode *inode, | ||
68 | struct inode *dir) | ||
69 | { | ||
70 | return 0; | ||
71 | } | ||
72 | #endif | ||
73 | |||
64 | #endif /* H_JFS_XATTR */ | 74 | #endif /* H_JFS_XATTR */ |
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c index 31b34db451..a7fe2f2b96 100644 --- a/fs/jfs/jfs_xtree.c +++ b/fs/jfs/jfs_xtree.c | |||
@@ -135,14 +135,6 @@ static int xtSearchNode(struct inode *ip, | |||
135 | static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp); | 135 | static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp); |
136 | #endif /* _STILL_TO_PORT */ | 136 | #endif /* _STILL_TO_PORT */ |
137 | 137 | ||
138 | /* External references */ | ||
139 | |||
140 | /* | ||
141 | * debug control | ||
142 | */ | ||
143 | /* #define _JFS_DEBUG_XTREE 1 */ | ||
144 | |||
145 | |||
146 | /* | 138 | /* |
147 | * xtLookup() | 139 | * xtLookup() |
148 | * | 140 | * |
@@ -4140,338 +4132,6 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size) | |||
4140 | return 0; | 4132 | return 0; |
4141 | } | 4133 | } |
4142 | 4134 | ||
4143 | |||
4144 | #ifdef _JFS_DEBUG_XTREE | ||
4145 | /* | ||
4146 | * xtDisplayTree() | ||
4147 | * | ||
4148 | * function: traverse forward | ||
4149 | */ | ||
4150 | int xtDisplayTree(struct inode *ip) | ||
4151 | { | ||
4152 | int rc = 0; | ||
4153 | struct metapage *mp; | ||
4154 | xtpage_t *p; | ||
4155 | s64 bn, pbn; | ||
4156 | int index, lastindex, v, h; | ||
4157 | xad_t *xad; | ||
4158 | struct btstack btstack; | ||
4159 | struct btframe *btsp; | ||
4160 | struct btframe *parent; | ||
4161 | |||
4162 | printk("display B+-tree.\n"); | ||
4163 | |||
4164 | /* clear stack */ | ||
4165 | btsp = btstack.stack; | ||
4166 | |||
4167 | /* | ||
4168 | * start with root | ||
4169 | * | ||
4170 | * root resides in the inode | ||
4171 | */ | ||
4172 | bn = 0; | ||
4173 | v = h = 0; | ||
4174 | |||
4175 | /* | ||
4176 | * first access of each page: | ||
4177 | */ | ||
4178 | getPage: | ||
4179 | XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); | ||
4180 | if (rc) | ||
4181 | return rc; | ||
4182 | |||
4183 | /* process entries forward from first index */ | ||
4184 | index = XTENTRYSTART; | ||
4185 | lastindex = le16_to_cpu(p->header.nextindex) - 1; | ||
4186 | |||
4187 | if (p->header.flag & BT_INTERNAL) { | ||
4188 | /* | ||
4189 | * first access of each internal page | ||
4190 | */ | ||
4191 | goto getChild; | ||
4192 | } else { /* (p->header.flag & BT_LEAF) */ | ||
4193 | |||
4194 | /* | ||
4195 | * first access of each leaf page | ||
4196 | */ | ||
4197 | printf("leaf page "); | ||
4198 | xtDisplayPage(ip, bn, p); | ||
4199 | |||
4200 | /* unpin the leaf page */ | ||
4201 | XT_PUTPAGE(mp); | ||
4202 | } | ||
4203 | |||
4204 | /* | ||
4205 | * go back up to the parent page | ||
4206 | */ | ||
4207 | getParent: | ||
4208 | /* pop/restore parent entry for the current child page */ | ||
4209 | if ((parent = (btsp == btstack.stack ? NULL : --btsp)) == NULL) | ||
4210 | /* current page must have been root */ | ||
4211 | return; | ||
4212 | |||
4213 | /* | ||
4214 | * parent page scan completed | ||
4215 | */ | ||
4216 | if ((index = parent->index) == (lastindex = parent->lastindex)) { | ||
4217 | /* go back up to the parent page */ | ||
4218 | goto getParent; | ||
4219 | } | ||
4220 | |||
4221 | /* | ||
4222 | * parent page has entries remaining | ||
4223 | */ | ||
4224 | /* get back the parent page */ | ||
4225 | bn = parent->bn; | ||
4226 | /* v = parent->level; */ | ||
4227 | XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); | ||
4228 | if (rc) | ||
4229 | return rc; | ||
4230 | |||
4231 | /* get next parent entry */ | ||
4232 | index++; | ||
4233 | |||
4234 | /* | ||
4235 | * internal page: go down to child page of current entry | ||
4236 | */ | ||
4237 | getChild: | ||
4238 | /* push/save current parent entry for the child page */ | ||
4239 | btsp->bn = pbn = bn; | ||
4240 | btsp->index = index; | ||
4241 | btsp->lastindex = lastindex; | ||
4242 | /* btsp->level = v; */ | ||
4243 | /* btsp->node = h; */ | ||
4244 | ++btsp; | ||
4245 | |||
4246 | /* get child page */ | ||
4247 | xad = &p->xad[index]; | ||
4248 | bn = addressXAD(xad); | ||
4249 | |||
4250 | /* | ||
4251 | * first access of each internal entry: | ||
4252 | */ | ||
4253 | /* release parent page */ | ||
4254 | XT_PUTPAGE(mp); | ||
4255 | |||
4256 | printk("traverse down 0x%lx[%d]->0x%lx\n", (ulong) pbn, index, | ||
4257 | (ulong) bn); | ||
4258 | v++; | ||
4259 | h = index; | ||
4260 | |||
4261 | /* process the child page */ | ||
4262 | goto getPage; | ||
4263 | } | ||
4264 | |||
4265 | |||
4266 | /* | ||
4267 | * xtDisplayPage() | ||
4268 | * | ||
4269 | * function: display page | ||
4270 | */ | ||
4271 | int xtDisplayPage(struct inode *ip, s64 bn, xtpage_t * p) | ||
4272 | { | ||
4273 | int rc = 0; | ||
4274 | xad_t *xad; | ||
4275 | s64 xaddr, xoff; | ||
4276 | int xlen, i, j; | ||
4277 | |||
4278 | /* display page control */ | ||
4279 | printf("bn:0x%lx flag:0x%x nextindex:%d\n", | ||
4280 | (ulong) bn, p->header.flag, | ||
4281 | le16_to_cpu(p->header.nextindex)); | ||
4282 | |||
4283 | /* display entries */ | ||
4284 | xad = &p->xad[XTENTRYSTART]; | ||
4285 | for (i = XTENTRYSTART, j = 1; i < le16_to_cpu(p->header.nextindex); | ||
4286 | i++, xad++, j++) { | ||
4287 | xoff = offsetXAD(xad); | ||
4288 | xaddr = addressXAD(xad); | ||
4289 | xlen = lengthXAD(xad); | ||
4290 | printf("\t[%d] 0x%lx:0x%lx(0x%x)", i, (ulong) xoff, | ||
4291 | (ulong) xaddr, xlen); | ||
4292 | |||
4293 | if (j == 4) { | ||
4294 | printf("\n"); | ||
4295 | j = 0; | ||
4296 | } | ||
4297 | } | ||
4298 | |||
4299 | printf("\n"); | ||
4300 | } | ||
4301 | #endif /* _JFS_DEBUG_XTREE */ | ||
4302 | |||
4303 | |||
4304 | #ifdef _JFS_WIP | ||
4305 | /* | ||
4306 | * xtGather() | ||
4307 | * | ||
4308 | * function: | ||
4309 | * traverse for allocation acquiring tlock at commit time | ||
4310 | * (vs at the time of update) logging backward top down | ||
4311 | * | ||
4312 | * note: | ||
4313 | * problem - establishing that all new allocation have been | ||
4314 | * processed both for append and random write in sparse file | ||
4315 | * at the current entry at the current subtree root page | ||
4316 | * | ||
4317 | */ | ||
4318 | int xtGather(btree_t *t) | ||
4319 | { | ||
4320 | int rc = 0; | ||
4321 | xtpage_t *p; | ||
4322 | u64 bn; | ||
4323 | int index; | ||
4324 | btentry_t *e; | ||
4325 | struct btstack btstack; | ||
4326 | struct btsf *parent; | ||
4327 | |||
4328 | /* clear stack */ | ||
4329 | BT_CLR(&btstack); | ||
4330 | |||
4331 | /* | ||
4332 | * start with root | ||
4333 | * | ||
4334 | * root resides in the inode | ||
4335 | */ | ||
4336 | bn = 0; | ||
4337 | XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); | ||
4338 | if (rc) | ||
4339 | return rc; | ||
4340 | |||
4341 | /* new root is NOT pointed by a new entry | ||
4342 | if (p->header.flag & NEW) | ||
4343 | allocate new page lock; | ||
4344 | write a NEWPAGE log; | ||
4345 | */ | ||
4346 | |||
4347 | dopage: | ||
4348 | /* | ||
4349 | * first access of each page: | ||
4350 | */ | ||
4351 | /* process entries backward from last index */ | ||
4352 | index = le16_to_cpu(p->header.nextindex) - 1; | ||
4353 | |||
4354 | if (p->header.flag & BT_LEAF) { | ||
4355 | /* | ||
4356 | * first access of each leaf page | ||
4357 | */ | ||
4358 | /* process leaf page entries backward */ | ||
4359 | for (; index >= XTENTRYSTART; index--) { | ||
4360 | e = &p->xad[index]; | ||
4361 | /* | ||
4362 | * if newpage, log NEWPAGE. | ||
4363 | * | ||
4364 | if (e->flag & XAD_NEW) { | ||
4365 | nfound =+ entry->length; | ||
4366 | update current page lock for the entry; | ||
4367 | newpage(entry); | ||
4368 | * | ||
4369 | * if moved, log move. | ||
4370 | * | ||
4371 | } else if (e->flag & XAD_MOVED) { | ||
4372 | reset flag; | ||
4373 | update current page lock for the entry; | ||
4374 | } | ||
4375 | */ | ||
4376 | } | ||
4377 | |||
4378 | /* unpin the leaf page */ | ||
4379 | XT_PUTPAGE(mp); | ||
4380 | |||
4381 | /* | ||
4382 | * go back up to the parent page | ||
4383 | */ | ||
4384 | getParent: | ||
4385 | /* restore parent entry for the current child page */ | ||
4386 | if ((parent = BT_POP(&btstack)) == NULL) | ||
4387 | /* current page must have been root */ | ||
4388 | return 0; | ||
4389 | |||
4390 | if ((index = parent->index) == XTENTRYSTART) { | ||
4391 | /* | ||
4392 | * parent page scan completed | ||
4393 | */ | ||
4394 | /* go back up to the parent page */ | ||
4395 | goto getParent; | ||
4396 | } else { | ||
4397 | /* | ||
4398 | * parent page has entries remaining | ||
4399 | */ | ||
4400 | /* get back the parent page */ | ||
4401 | bn = parent->bn; | ||
4402 | XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); | ||
4403 | if (rc) | ||
4404 | return -EIO; | ||
4405 | |||
4406 | /* first subroot page which | ||
4407 | * covers all new allocated blocks | ||
4408 | * itself not new/modified. | ||
4409 | * (if modified from split of descendent, | ||
4410 | * go down path of split page) | ||
4411 | |||
4412 | if (nfound == nnew && | ||
4413 | !(p->header.flag & (NEW | MOD))) | ||
4414 | exit scan; | ||
4415 | */ | ||
4416 | |||
4417 | /* process parent page entries backward */ | ||
4418 | index--; | ||
4419 | } | ||
4420 | } else { | ||
4421 | /* | ||
4422 | * first access of each internal page | ||
4423 | */ | ||
4424 | } | ||
4425 | |||
4426 | /* | ||
4427 | * internal page: go down to child page of current entry | ||
4428 | */ | ||
4429 | |||
4430 | /* save current parent entry for the child page */ | ||
4431 | BT_PUSH(&btstack, bn, index); | ||
4432 | |||
4433 | /* get current entry for the child page */ | ||
4434 | e = &p->xad[index]; | ||
4435 | |||
4436 | /* | ||
4437 | * first access of each internal entry: | ||
4438 | */ | ||
4439 | /* | ||
4440 | * if new entry, log btree_tnewentry. | ||
4441 | * | ||
4442 | if (e->flag & XAD_NEW) | ||
4443 | update parent page lock for the entry; | ||
4444 | */ | ||
4445 | |||
4446 | /* release parent page */ | ||
4447 | XT_PUTPAGE(mp); | ||
4448 | |||
4449 | /* get child page */ | ||
4450 | bn = e->bn; | ||
4451 | XT_GETPAGE(ip, bn, mp, PSIZE, p, rc); | ||
4452 | if (rc) | ||
4453 | return rc; | ||
4454 | |||
4455 | /* | ||
4456 | * first access of each non-root page: | ||
4457 | */ | ||
4458 | /* | ||
4459 | * if new, log btree_newpage. | ||
4460 | * | ||
4461 | if (p->header.flag & NEW) | ||
4462 | allocate new page lock; | ||
4463 | write a NEWPAGE log (next, prev); | ||
4464 | */ | ||
4465 | |||
4466 | /* process the child page */ | ||
4467 | goto dopage; | ||
4468 | |||
4469 | out: | ||
4470 | return 0; | ||
4471 | } | ||
4472 | #endif /* _JFS_WIP */ | ||
4473 | |||
4474 | |||
4475 | #ifdef CONFIG_JFS_STATISTICS | 4135 | #ifdef CONFIG_JFS_STATISTICS |
4476 | int jfs_xtstat_read(char *buffer, char **start, off_t offset, int length, | 4136 | int jfs_xtstat_read(char *buffer, char **start, off_t offset, int length, |
4477 | int *eof, void *data) | 4137 | int *eof, void *data) |
diff --git a/fs/jfs/jfs_xtree.h b/fs/jfs/jfs_xtree.h index a69784254f..af668a80b4 100644 --- a/fs/jfs/jfs_xtree.h +++ b/fs/jfs/jfs_xtree.h | |||
@@ -131,10 +131,4 @@ extern int xtRelocate(tid_t tid, struct inode *ip, | |||
131 | extern int xtAppend(tid_t tid, | 131 | extern int xtAppend(tid_t tid, |
132 | struct inode *ip, int xflag, s64 xoff, int maxblocks, | 132 | struct inode *ip, int xflag, s64 xoff, int maxblocks, |
133 | int *xlenp, s64 * xaddrp, int flag); | 133 | int *xlenp, s64 * xaddrp, int flag); |
134 | |||
135 | #ifdef _JFS_DEBUG_XTREE | ||
136 | extern int xtDisplayTree(struct inode *ip); | ||
137 | extern int xtDisplayPage(struct inode *ip, s64 bn, xtpage_t * p); | ||
138 | #endif /* _JFS_DEBUG_XTREE */ | ||
139 | |||
140 | #endif /* !_H_JFS_XTREE */ | 134 | #endif /* !_H_JFS_XTREE */ |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 1cae14e741..1abe7343f9 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -39,6 +39,24 @@ struct dentry_operations jfs_ci_dentry_operations; | |||
39 | static s64 commitZeroLink(tid_t, struct inode *); | 39 | static s64 commitZeroLink(tid_t, struct inode *); |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * NAME: free_ea_wmap(inode) | ||
43 | * | ||
44 | * FUNCTION: free uncommitted extended attributes from working map | ||
45 | * | ||
46 | */ | ||
47 | static inline void free_ea_wmap(struct inode *inode) | ||
48 | { | ||
49 | dxd_t *ea = &JFS_IP(inode)->ea; | ||
50 | |||
51 | if (ea->flag & DXD_EXTENT) { | ||
52 | /* free EA pages from cache */ | ||
53 | invalidate_dxd_metapages(inode, *ea); | ||
54 | dbFree(inode, addressDXD(ea), lengthDXD(ea)); | ||
55 | } | ||
56 | ea->flag = 0; | ||
57 | } | ||
58 | |||
59 | /* | ||
42 | * NAME: jfs_create(dip, dentry, mode) | 60 | * NAME: jfs_create(dip, dentry, mode) |
43 | * | 61 | * |
44 | * FUNCTION: create a regular file in the parent directory <dip> | 62 | * FUNCTION: create a regular file in the parent directory <dip> |
@@ -89,8 +107,19 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
89 | down(&JFS_IP(dip)->commit_sem); | 107 | down(&JFS_IP(dip)->commit_sem); |
90 | down(&JFS_IP(ip)->commit_sem); | 108 | down(&JFS_IP(ip)->commit_sem); |
91 | 109 | ||
110 | rc = jfs_init_acl(tid, ip, dip); | ||
111 | if (rc) | ||
112 | goto out3; | ||
113 | |||
114 | rc = jfs_init_security(tid, ip, dip); | ||
115 | if (rc) { | ||
116 | txAbort(tid, 0); | ||
117 | goto out3; | ||
118 | } | ||
119 | |||
92 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { | 120 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { |
93 | jfs_err("jfs_create: dtSearch returned %d", rc); | 121 | jfs_err("jfs_create: dtSearch returned %d", rc); |
122 | txAbort(tid, 0); | ||
94 | goto out3; | 123 | goto out3; |
95 | } | 124 | } |
96 | 125 | ||
@@ -139,6 +168,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
139 | up(&JFS_IP(dip)->commit_sem); | 168 | up(&JFS_IP(dip)->commit_sem); |
140 | up(&JFS_IP(ip)->commit_sem); | 169 | up(&JFS_IP(ip)->commit_sem); |
141 | if (rc) { | 170 | if (rc) { |
171 | free_ea_wmap(ip); | ||
142 | ip->i_nlink = 0; | 172 | ip->i_nlink = 0; |
143 | iput(ip); | 173 | iput(ip); |
144 | } else | 174 | } else |
@@ -147,11 +177,6 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, | |||
147 | out2: | 177 | out2: |
148 | free_UCSname(&dname); | 178 | free_UCSname(&dname); |
149 | 179 | ||
150 | #ifdef CONFIG_JFS_POSIX_ACL | ||
151 | if (rc == 0) | ||
152 | jfs_init_acl(ip, dip); | ||
153 | #endif | ||
154 | |||
155 | out1: | 180 | out1: |
156 | 181 | ||
157 | jfs_info("jfs_create: rc:%d", rc); | 182 | jfs_info("jfs_create: rc:%d", rc); |
@@ -216,8 +241,19 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
216 | down(&JFS_IP(dip)->commit_sem); | 241 | down(&JFS_IP(dip)->commit_sem); |
217 | down(&JFS_IP(ip)->commit_sem); | 242 | down(&JFS_IP(ip)->commit_sem); |
218 | 243 | ||
244 | rc = jfs_init_acl(tid, ip, dip); | ||
245 | if (rc) | ||
246 | goto out3; | ||
247 | |||
248 | rc = jfs_init_security(tid, ip, dip); | ||
249 | if (rc) { | ||
250 | txAbort(tid, 0); | ||
251 | goto out3; | ||
252 | } | ||
253 | |||
219 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { | 254 | if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { |
220 | jfs_err("jfs_mkdir: dtSearch returned %d", rc); | 255 | jfs_err("jfs_mkdir: dtSearch returned %d", rc); |
256 | txAbort(tid, 0); | ||
221 | goto out3; | 257 | goto out3; |
222 | } | 258 | } |
223 | 259 | ||
@@ -267,6 +303,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
267 | up(&JFS_IP(dip)->commit_sem); | 303 | up(&JFS_IP(dip)->commit_sem); |
268 | up(&JFS_IP(ip)->commit_sem); | 304 | up(&JFS_IP(ip)->commit_sem); |
269 | if (rc) { | 305 | if (rc) { |
306 | free_ea_wmap(ip); | ||
270 | ip->i_nlink = 0; | 307 | ip->i_nlink = 0; |
271 | iput(ip); | 308 | iput(ip); |
272 | } else | 309 | } else |
@@ -275,10 +312,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) | |||
275 | out2: | 312 | out2: |
276 | free_UCSname(&dname); | 313 | free_UCSname(&dname); |
277 | 314 | ||
278 | #ifdef CONFIG_JFS_POSIX_ACL | ||
279 | if (rc == 0) | ||
280 | jfs_init_acl(ip, dip); | ||
281 | #endif | ||
282 | 315 | ||
283 | out1: | 316 | out1: |
284 | 317 | ||
@@ -885,6 +918,10 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
885 | down(&JFS_IP(dip)->commit_sem); | 918 | down(&JFS_IP(dip)->commit_sem); |
886 | down(&JFS_IP(ip)->commit_sem); | 919 | down(&JFS_IP(ip)->commit_sem); |
887 | 920 | ||
921 | rc = jfs_init_security(tid, ip, dip); | ||
922 | if (rc) | ||
923 | goto out3; | ||
924 | |||
888 | tblk = tid_to_tblock(tid); | 925 | tblk = tid_to_tblock(tid); |
889 | tblk->xflag |= COMMIT_CREATE; | 926 | tblk->xflag |= COMMIT_CREATE; |
890 | tblk->ino = ip->i_ino; | 927 | tblk->ino = ip->i_ino; |
@@ -1000,6 +1037,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
1000 | up(&JFS_IP(dip)->commit_sem); | 1037 | up(&JFS_IP(dip)->commit_sem); |
1001 | up(&JFS_IP(ip)->commit_sem); | 1038 | up(&JFS_IP(ip)->commit_sem); |
1002 | if (rc) { | 1039 | if (rc) { |
1040 | free_ea_wmap(ip); | ||
1003 | ip->i_nlink = 0; | 1041 | ip->i_nlink = 0; |
1004 | iput(ip); | 1042 | iput(ip); |
1005 | } else | 1043 | } else |
@@ -1008,11 +1046,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, | |||
1008 | out2: | 1046 | out2: |
1009 | free_UCSname(&dname); | 1047 | free_UCSname(&dname); |
1010 | 1048 | ||
1011 | #ifdef CONFIG_JFS_POSIX_ACL | ||
1012 | if (rc == 0) | ||
1013 | jfs_init_acl(ip, dip); | ||
1014 | #endif | ||
1015 | |||
1016 | out1: | 1049 | out1: |
1017 | jfs_info("jfs_symlink: rc:%d", rc); | 1050 | jfs_info("jfs_symlink: rc:%d", rc); |
1018 | return rc; | 1051 | return rc; |
@@ -1328,8 +1361,20 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1328 | down(&JFS_IP(dir)->commit_sem); | 1361 | down(&JFS_IP(dir)->commit_sem); |
1329 | down(&JFS_IP(ip)->commit_sem); | 1362 | down(&JFS_IP(ip)->commit_sem); |
1330 | 1363 | ||
1331 | if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) | 1364 | rc = jfs_init_acl(tid, ip, dir); |
1365 | if (rc) | ||
1366 | goto out3; | ||
1367 | |||
1368 | rc = jfs_init_security(tid, ip, dir); | ||
1369 | if (rc) { | ||
1370 | txAbort(tid, 0); | ||
1371 | goto out3; | ||
1372 | } | ||
1373 | |||
1374 | if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) { | ||
1375 | txAbort(tid, 0); | ||
1332 | goto out3; | 1376 | goto out3; |
1377 | } | ||
1333 | 1378 | ||
1334 | tblk = tid_to_tblock(tid); | 1379 | tblk = tid_to_tblock(tid); |
1335 | tblk->xflag |= COMMIT_CREATE; | 1380 | tblk->xflag |= COMMIT_CREATE; |
@@ -1337,8 +1382,10 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1337 | tblk->u.ixpxd = JFS_IP(ip)->ixpxd; | 1382 | tblk->u.ixpxd = JFS_IP(ip)->ixpxd; |
1338 | 1383 | ||
1339 | ino = ip->i_ino; | 1384 | ino = ip->i_ino; |
1340 | if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) | 1385 | if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) { |
1386 | txAbort(tid, 0); | ||
1341 | goto out3; | 1387 | goto out3; |
1388 | } | ||
1342 | 1389 | ||
1343 | ip->i_op = &jfs_file_inode_operations; | 1390 | ip->i_op = &jfs_file_inode_operations; |
1344 | jfs_ip->dev = new_encode_dev(rdev); | 1391 | jfs_ip->dev = new_encode_dev(rdev); |
@@ -1360,6 +1407,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1360 | up(&JFS_IP(ip)->commit_sem); | 1407 | up(&JFS_IP(ip)->commit_sem); |
1361 | up(&JFS_IP(dir)->commit_sem); | 1408 | up(&JFS_IP(dir)->commit_sem); |
1362 | if (rc) { | 1409 | if (rc) { |
1410 | free_ea_wmap(ip); | ||
1363 | ip->i_nlink = 0; | 1411 | ip->i_nlink = 0; |
1364 | iput(ip); | 1412 | iput(ip); |
1365 | } else | 1413 | } else |
@@ -1368,11 +1416,6 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, | |||
1368 | out1: | 1416 | out1: |
1369 | free_UCSname(&dname); | 1417 | free_UCSname(&dname); |
1370 | 1418 | ||
1371 | #ifdef CONFIG_JFS_POSIX_ACL | ||
1372 | if (rc == 0) | ||
1373 | jfs_init_acl(ip, dir); | ||
1374 | #endif | ||
1375 | |||
1376 | out: | 1419 | out: |
1377 | jfs_info("jfs_mknod: returning %d", rc); | 1420 | jfs_info("jfs_mknod: returning %d", rc); |
1378 | return rc; | 1421 | return rc; |
@@ -1390,6 +1433,8 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc | |||
1390 | 1433 | ||
1391 | jfs_info("jfs_lookup: name = %s", name); | 1434 | jfs_info("jfs_lookup: name = %s", name); |
1392 | 1435 | ||
1436 | if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2) | ||
1437 | dentry->d_op = &jfs_ci_dentry_operations; | ||
1393 | 1438 | ||
1394 | if ((name[0] == '.') && (len == 1)) | 1439 | if ((name[0] == '.') && (len == 1)) |
1395 | inum = dip->i_ino; | 1440 | inum = dip->i_ino; |
@@ -1417,9 +1462,6 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc | |||
1417 | return ERR_PTR(-EACCES); | 1462 | return ERR_PTR(-EACCES); |
1418 | } | 1463 | } |
1419 | 1464 | ||
1420 | if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2) | ||
1421 | dentry->d_op = &jfs_ci_dentry_operations; | ||
1422 | |||
1423 | dentry = d_splice_alias(ip, dentry); | 1465 | dentry = d_splice_alias(ip, dentry); |
1424 | 1466 | ||
1425 | if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)) | 1467 | if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)) |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index ee32211288..71bc34b96b 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -23,9 +23,11 @@ | |||
23 | #include <linux/parser.h> | 23 | #include <linux/parser.h> |
24 | #include <linux/completion.h> | 24 | #include <linux/completion.h> |
25 | #include <linux/vfs.h> | 25 | #include <linux/vfs.h> |
26 | #include <linux/mount.h> | ||
26 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
27 | #include <linux/posix_acl.h> | 28 | #include <linux/posix_acl.h> |
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
30 | #include <linux/seq_file.h> | ||
29 | 31 | ||
30 | #include "jfs_incore.h" | 32 | #include "jfs_incore.h" |
31 | #include "jfs_filsys.h" | 33 | #include "jfs_filsys.h" |
@@ -114,6 +116,8 @@ static void jfs_destroy_inode(struct inode *inode) | |||
114 | { | 116 | { |
115 | struct jfs_inode_info *ji = JFS_IP(inode); | 117 | struct jfs_inode_info *ji = JFS_IP(inode); |
116 | 118 | ||
119 | BUG_ON(!list_empty(&ji->anon_inode_list)); | ||
120 | |||
117 | spin_lock_irq(&ji->ag_lock); | 121 | spin_lock_irq(&ji->ag_lock); |
118 | if (ji->active_ag != -1) { | 122 | if (ji->active_ag != -1) { |
119 | struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap; | 123 | struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap; |
@@ -190,7 +194,8 @@ static void jfs_put_super(struct super_block *sb) | |||
190 | 194 | ||
191 | enum { | 195 | enum { |
192 | Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, | 196 | Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, |
193 | Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, | 197 | Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota, |
198 | Opt_usrquota, Opt_grpquota | ||
194 | }; | 199 | }; |
195 | 200 | ||
196 | static match_table_t tokens = { | 201 | static match_table_t tokens = { |
@@ -202,8 +207,8 @@ static match_table_t tokens = { | |||
202 | {Opt_errors, "errors=%s"}, | 207 | {Opt_errors, "errors=%s"}, |
203 | {Opt_ignore, "noquota"}, | 208 | {Opt_ignore, "noquota"}, |
204 | {Opt_ignore, "quota"}, | 209 | {Opt_ignore, "quota"}, |
205 | {Opt_ignore, "usrquota"}, | 210 | {Opt_usrquota, "usrquota"}, |
206 | {Opt_ignore, "grpquota"}, | 211 | {Opt_grpquota, "grpquota"}, |
207 | {Opt_err, NULL} | 212 | {Opt_err, NULL} |
208 | }; | 213 | }; |
209 | 214 | ||
@@ -291,6 +296,24 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, | |||
291 | } | 296 | } |
292 | break; | 297 | break; |
293 | } | 298 | } |
299 | |||
300 | #if defined(CONFIG_QUOTA) | ||
301 | case Opt_quota: | ||
302 | case Opt_usrquota: | ||
303 | *flag |= JFS_USRQUOTA; | ||
304 | break; | ||
305 | case Opt_grpquota: | ||
306 | *flag |= JFS_GRPQUOTA; | ||
307 | break; | ||
308 | #else | ||
309 | case Opt_usrquota: | ||
310 | case Opt_grpquota: | ||
311 | case Opt_quota: | ||
312 | printk(KERN_ERR | ||
313 | "JFS: quota operations not supported\n"); | ||
314 | break; | ||
315 | #endif | ||
316 | |||
294 | default: | 317 | default: |
295 | printk("jfs: Unrecognized mount option \"%s\" " | 318 | printk("jfs: Unrecognized mount option \"%s\" " |
296 | " or missing value\n", p); | 319 | " or missing value\n", p); |
@@ -531,12 +554,32 @@ static int jfs_sync_fs(struct super_block *sb, int wait) | |||
531 | /* log == NULL indicates read-only mount */ | 554 | /* log == NULL indicates read-only mount */ |
532 | if (log) { | 555 | if (log) { |
533 | jfs_flush_journal(log, wait); | 556 | jfs_flush_journal(log, wait); |
534 | jfs_syncpt(log); | 557 | jfs_syncpt(log, 0); |
535 | } | 558 | } |
536 | 559 | ||
537 | return 0; | 560 | return 0; |
538 | } | 561 | } |
539 | 562 | ||
563 | static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | ||
564 | { | ||
565 | struct jfs_sb_info *sbi = JFS_SBI(vfs->mnt_sb); | ||
566 | |||
567 | if (sbi->flag & JFS_NOINTEGRITY) | ||
568 | seq_puts(seq, ",nointegrity"); | ||
569 | else | ||
570 | seq_puts(seq, ",integrity"); | ||
571 | |||
572 | #if defined(CONFIG_QUOTA) | ||
573 | if (sbi->flag & JFS_USRQUOTA) | ||
574 | seq_puts(seq, ",usrquota"); | ||
575 | |||
576 | if (sbi->flag & JFS_GRPQUOTA) | ||
577 | seq_puts(seq, ",grpquota"); | ||
578 | #endif | ||
579 | |||
580 | return 0; | ||
581 | } | ||
582 | |||
540 | static struct super_operations jfs_super_operations = { | 583 | static struct super_operations jfs_super_operations = { |
541 | .alloc_inode = jfs_alloc_inode, | 584 | .alloc_inode = jfs_alloc_inode, |
542 | .destroy_inode = jfs_destroy_inode, | 585 | .destroy_inode = jfs_destroy_inode, |
@@ -550,6 +593,7 @@ static struct super_operations jfs_super_operations = { | |||
550 | .unlockfs = jfs_unlockfs, | 593 | .unlockfs = jfs_unlockfs, |
551 | .statfs = jfs_statfs, | 594 | .statfs = jfs_statfs, |
552 | .remount_fs = jfs_remount, | 595 | .remount_fs = jfs_remount, |
596 | .show_options = jfs_show_options | ||
553 | }; | 597 | }; |
554 | 598 | ||
555 | static struct export_operations jfs_export_operations = { | 599 | static struct export_operations jfs_export_operations = { |
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index 287d8d6c3c..16477b3835 100644 --- a/fs/jfs/symlink.c +++ b/fs/jfs/symlink.c | |||
@@ -22,11 +22,11 @@ | |||
22 | #include "jfs_inode.h" | 22 | #include "jfs_inode.h" |
23 | #include "jfs_xattr.h" | 23 | #include "jfs_xattr.h" |
24 | 24 | ||
25 | static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd) | 25 | static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd) |
26 | { | 26 | { |
27 | char *s = JFS_IP(dentry->d_inode)->i_inline; | 27 | char *s = JFS_IP(dentry->d_inode)->i_inline; |
28 | nd_set_link(nd, s); | 28 | nd_set_link(nd, s); |
29 | return 0; | 29 | return NULL; |
30 | } | 30 | } |
31 | 31 | ||
32 | struct inode_operations jfs_symlink_inode_operations = { | 32 | struct inode_operations jfs_symlink_inode_operations = { |
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index ee438d429d..23aa5066b5 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/xattr.h> | 21 | #include <linux/xattr.h> |
22 | #include <linux/posix_acl_xattr.h> | 22 | #include <linux/posix_acl_xattr.h> |
23 | #include <linux/quotaops.h> | 23 | #include <linux/quotaops.h> |
24 | #include <linux/security.h> | ||
24 | #include "jfs_incore.h" | 25 | #include "jfs_incore.h" |
25 | #include "jfs_superblock.h" | 26 | #include "jfs_superblock.h" |
26 | #include "jfs_dmap.h" | 27 | #include "jfs_dmap.h" |
@@ -633,12 +634,12 @@ static void ea_release(struct inode *inode, struct ea_buffer *ea_buf) | |||
633 | } | 634 | } |
634 | } | 635 | } |
635 | 636 | ||
636 | static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) | 637 | static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf, |
638 | int new_size) | ||
637 | { | 639 | { |
638 | struct jfs_inode_info *ji = JFS_IP(inode); | 640 | struct jfs_inode_info *ji = JFS_IP(inode); |
639 | unsigned long old_blocks, new_blocks; | 641 | unsigned long old_blocks, new_blocks; |
640 | int rc = 0; | 642 | int rc = 0; |
641 | tid_t tid; | ||
642 | 643 | ||
643 | if (new_size == 0) { | 644 | if (new_size == 0) { |
644 | ea_release(inode, ea_buf); | 645 | ea_release(inode, ea_buf); |
@@ -664,9 +665,6 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) | |||
664 | if (rc) | 665 | if (rc) |
665 | return rc; | 666 | return rc; |
666 | 667 | ||
667 | tid = txBegin(inode->i_sb, 0); | ||
668 | down(&ji->commit_sem); | ||
669 | |||
670 | old_blocks = new_blocks = 0; | 668 | old_blocks = new_blocks = 0; |
671 | 669 | ||
672 | if (ji->ea.flag & DXD_EXTENT) { | 670 | if (ji->ea.flag & DXD_EXTENT) { |
@@ -695,11 +693,8 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) | |||
695 | DQUOT_FREE_BLOCK(inode, old_blocks); | 693 | DQUOT_FREE_BLOCK(inode, old_blocks); |
696 | 694 | ||
697 | inode->i_ctime = CURRENT_TIME; | 695 | inode->i_ctime = CURRENT_TIME; |
698 | rc = txCommit(tid, 1, &inode, 0); | ||
699 | txEnd(tid); | ||
700 | up(&ji->commit_sem); | ||
701 | 696 | ||
702 | return rc; | 697 | return 0; |
703 | } | 698 | } |
704 | 699 | ||
705 | /* | 700 | /* |
@@ -781,7 +776,7 @@ static int can_set_xattr(struct inode *inode, const char *name, | |||
781 | if (IS_RDONLY(inode)) | 776 | if (IS_RDONLY(inode)) |
782 | return -EROFS; | 777 | return -EROFS; |
783 | 778 | ||
784 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode)) | 779 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
785 | return -EPERM; | 780 | return -EPERM; |
786 | 781 | ||
787 | if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0) | 782 | if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0) |
@@ -790,12 +785,12 @@ static int can_set_xattr(struct inode *inode, const char *name, | |||
790 | */ | 785 | */ |
791 | return can_set_system_xattr(inode, name, value, value_len); | 786 | return can_set_system_xattr(inode, name, value, value_len); |
792 | 787 | ||
793 | if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0) | 788 | if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) |
794 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); | 789 | return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM); |
795 | 790 | ||
796 | #ifdef CONFIG_JFS_SECURITY | 791 | #ifdef CONFIG_JFS_SECURITY |
797 | if (strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) | 792 | if (strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) |
798 | != 0) | 793 | == 0) |
799 | return 0; /* Leave it to the security module */ | 794 | return 0; /* Leave it to the security module */ |
800 | #endif | 795 | #endif |
801 | 796 | ||
@@ -810,8 +805,8 @@ static int can_set_xattr(struct inode *inode, const char *name, | |||
810 | return permission(inode, MAY_WRITE, NULL); | 805 | return permission(inode, MAY_WRITE, NULL); |
811 | } | 806 | } |
812 | 807 | ||
813 | int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | 808 | int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, |
814 | size_t value_len, int flags) | 809 | const void *value, size_t value_len, int flags) |
815 | { | 810 | { |
816 | struct jfs_ea_list *ealist; | 811 | struct jfs_ea_list *ealist; |
817 | struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL; | 812 | struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL; |
@@ -825,9 +820,6 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | |||
825 | int rc; | 820 | int rc; |
826 | int length; | 821 | int length; |
827 | 822 | ||
828 | if ((rc = can_set_xattr(inode, name, value, value_len))) | ||
829 | return rc; | ||
830 | |||
831 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { | 823 | if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { |
832 | os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, | 824 | os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, |
833 | GFP_KERNEL); | 825 | GFP_KERNEL); |
@@ -939,7 +931,7 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | |||
939 | 931 | ||
940 | ealist->size = cpu_to_le32(new_size); | 932 | ealist->size = cpu_to_le32(new_size); |
941 | 933 | ||
942 | rc = ea_put(inode, &ea_buf, new_size); | 934 | rc = ea_put(tid, inode, &ea_buf, new_size); |
943 | 935 | ||
944 | goto out; | 936 | goto out; |
945 | release: | 937 | release: |
@@ -955,12 +947,29 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, | |||
955 | int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 947 | int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
956 | size_t value_len, int flags) | 948 | size_t value_len, int flags) |
957 | { | 949 | { |
950 | struct inode *inode = dentry->d_inode; | ||
951 | struct jfs_inode_info *ji = JFS_IP(inode); | ||
952 | int rc; | ||
953 | tid_t tid; | ||
954 | |||
955 | if ((rc = can_set_xattr(inode, name, value, value_len))) | ||
956 | return rc; | ||
957 | |||
958 | if (value == NULL) { /* empty EA, do not remove */ | 958 | if (value == NULL) { /* empty EA, do not remove */ |
959 | value = ""; | 959 | value = ""; |
960 | value_len = 0; | 960 | value_len = 0; |
961 | } | 961 | } |
962 | 962 | ||
963 | return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags); | 963 | tid = txBegin(inode->i_sb, 0); |
964 | down(&ji->commit_sem); | ||
965 | rc = __jfs_setxattr(tid, dentry->d_inode, name, value, value_len, | ||
966 | flags); | ||
967 | if (!rc) | ||
968 | rc = txCommit(tid, 1, &inode, 0); | ||
969 | txEnd(tid); | ||
970 | up(&ji->commit_sem); | ||
971 | |||
972 | return rc; | ||
964 | } | 973 | } |
965 | 974 | ||
966 | static int can_get_xattr(struct inode *inode, const char *name) | 975 | static int can_get_xattr(struct inode *inode, const char *name) |
@@ -1122,5 +1131,56 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) | |||
1122 | 1131 | ||
1123 | int jfs_removexattr(struct dentry *dentry, const char *name) | 1132 | int jfs_removexattr(struct dentry *dentry, const char *name) |
1124 | { | 1133 | { |
1125 | return __jfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | 1134 | struct inode *inode = dentry->d_inode; |
1135 | struct jfs_inode_info *ji = JFS_IP(inode); | ||
1136 | int rc; | ||
1137 | tid_t tid; | ||
1138 | |||
1139 | if ((rc = can_set_xattr(inode, name, NULL, 0))) | ||
1140 | return rc; | ||
1141 | |||
1142 | tid = txBegin(inode->i_sb, 0); | ||
1143 | down(&ji->commit_sem); | ||
1144 | rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); | ||
1145 | if (!rc) | ||
1146 | rc = txCommit(tid, 1, &inode, 0); | ||
1147 | txEnd(tid); | ||
1148 | up(&ji->commit_sem); | ||
1149 | |||
1150 | return rc; | ||
1126 | } | 1151 | } |
1152 | |||
1153 | #ifdef CONFIG_JFS_SECURITY | ||
1154 | int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir) | ||
1155 | { | ||
1156 | int rc; | ||
1157 | size_t len; | ||
1158 | void *value; | ||
1159 | char *suffix; | ||
1160 | char *name; | ||
1161 | |||
1162 | rc = security_inode_init_security(inode, dir, &suffix, &value, &len); | ||
1163 | if (rc) { | ||
1164 | if (rc == -EOPNOTSUPP) | ||
1165 | return 0; | ||
1166 | return rc; | ||
1167 | } | ||
1168 | name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix), | ||
1169 | GFP_NOFS); | ||
1170 | if (!name) { | ||
1171 | rc = -ENOMEM; | ||
1172 | goto kmalloc_failed; | ||
1173 | } | ||
1174 | strcpy(name, XATTR_SECURITY_PREFIX); | ||
1175 | strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix); | ||
1176 | |||
1177 | rc = __jfs_setxattr(tid, inode, name, value, len, 0); | ||
1178 | |||
1179 | kfree(name); | ||
1180 | kmalloc_failed: | ||
1181 | kfree(suffix); | ||
1182 | kfree(value); | ||
1183 | |||
1184 | return rc; | ||
1185 | } | ||
1186 | #endif | ||