aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jfs
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-09-14 08:01:25 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-14 08:01:25 -0400
commitd7f6884ae0ae6e406ec3500fcde16e8f51642460 (patch)
treeefceb246a4fa12921b7dbd3946a88fa257684405 /fs/jfs
parentcd28ab6a4e50a7601d22752aa7ce0c8197b10bdf (diff)
parent2f4ba45a75d6383b4a1201169a808ffea416ffa0 (diff)
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'fs/jfs')
-rw-r--r--fs/jfs/acl.c24
-rw-r--r--fs/jfs/inode.c24
-rw-r--r--fs/jfs/jfs_acl.h12
-rw-r--r--fs/jfs/jfs_filsys.h3
-rw-r--r--fs/jfs/jfs_logmgr.c36
-rw-r--r--fs/jfs/jfs_logmgr.h2
-rw-r--r--fs/jfs/jfs_txnmgr.c12
-rw-r--r--fs/jfs/jfs_xattr.h14
-rw-r--r--fs/jfs/namei.c90
-rw-r--r--fs/jfs/super.c52
-rw-r--r--fs/jfs/symlink.c4
-rw-r--r--fs/jfs/xattr.c94
12 files changed, 277 insertions, 90 deletions
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index e892dab40c26..461e4934ca7c 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
78static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) 79static 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);
114out: 116out:
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
146int jfs_init_acl(struct inode *inode, struct inode *dir) 148int 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);
179cleanup: 182cleanup:
@@ -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 2137138c59b0..0ec62d5310db 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 a3acd3eec059..a76293767c73 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
23int jfs_permission(struct inode *, int, struct nameidata *); 23int jfs_permission(struct inode *, int, struct nameidata *);
24int jfs_init_acl(struct inode *, struct inode *); 24int jfs_init_acl(tid_t, struct inode *, struct inode *);
25int jfs_setattr(struct dentry *, struct iattr *); 25int jfs_setattr(struct dentry *, struct iattr *);
26 26
27#endif /* CONFIG_JFS_POSIX_ACL */ 27#else
28
29static 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_filsys.h b/fs/jfs/jfs_filsys.h
index 86ccac80f0ab..72a5588faeca 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_logmgr.c b/fs/jfs/jfs_logmgr.c
index 22815e88e7cc..d27bac6acaa3 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);
191static bio_end_io_t lbmIODone; 191static bio_end_io_t lbmIODone;
192static void lbmStartIO(struct lbuf * bp); 192static void lbmStartIO(struct lbuf * bp);
193static void lmGCwrite(struct jfs_log * log, int cant_block); 193static void lmGCwrite(struct jfs_log * log, int cant_block);
194static int lmLogSync(struct jfs_log * log, int nosyncwait); 194static 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 */
930static int lmLogSync(struct jfs_log * log, int nosyncwait) 928static 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,10 +1026,6 @@ 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
@@ -1049,11 +1050,12 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
1049 * 1050 *
1050 * FUNCTION: write log SYNCPT record for specified log 1051 * FUNCTION: write log SYNCPT record for specified log
1051 * 1052 *
1052 * PARAMETERS: log - log structure 1053 * PARAMETERS: log - log structure
1054 * hard_sync - set to 1 to force metadata to be written
1053 */ 1055 */
1054void jfs_syncpt(struct jfs_log *log) 1056void jfs_syncpt(struct jfs_log *log, int hard_sync)
1055{ LOG_LOCK(log); 1057{ LOG_LOCK(log);
1056 lmLogSync(log, 1); 1058 lmLogSync(log, hard_sync);
1057 LOG_UNLOCK(log); 1059 LOG_UNLOCK(log);
1058} 1060}
1059 1061
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
index 747114cd38b8..e4978b5b65ee 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);
510extern int lmGroupCommit(struct jfs_log *, struct tblock *); 510extern int lmGroupCommit(struct jfs_log *, struct tblock *);
511extern int jfsIOWait(void *); 511extern int jfsIOWait(void *);
512extern void jfs_flush_journal(struct jfs_log * log, int wait); 512extern void jfs_flush_journal(struct jfs_log * log, int wait);
513extern void jfs_syncpt(struct jfs_log *log); 513extern 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_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 121c981ff453..c7a92f9deb2b 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_xattr.h b/fs/jfs/jfs_xattr.h
index a1052f3f0bee..25e9990bccd1 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
55extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t, 55extern int __jfs_setxattr(tid_t, struct inode *, const char *, const void *,
56 int); 56 size_t, int);
57extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t, 57extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
58 int); 58 int);
59extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); 59extern 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);
61extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); 61extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
62extern int jfs_removexattr(struct dentry *, const char *); 62extern int jfs_removexattr(struct dentry *, const char *);
63 63
64#ifdef CONFIG_JFS_SECURITY
65extern int jfs_init_security(tid_t, struct inode *, struct inode *);
66#else
67static 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/namei.c b/fs/jfs/namei.c
index 1cae14e741eb..1abe7343f920 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -39,6 +39,24 @@ struct dentry_operations jfs_ci_dentry_operations;
39static s64 commitZeroLink(tid_t, struct inode *); 39static 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 */
47static 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 ee32211288ce..71bc34b96b2b 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
191enum { 195enum {
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
196static match_table_t tokens = { 201static 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
563static 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
540static struct super_operations jfs_super_operations = { 583static 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
555static struct export_operations jfs_export_operations = { 599static struct export_operations jfs_export_operations = {
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c
index 287d8d6c3cfd..16477b3835e1 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
25static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd) 25static 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
32struct inode_operations jfs_symlink_inode_operations = { 32struct inode_operations jfs_symlink_inode_operations = {
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 554ec739e49b..23aa5066b5a4 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
636static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) 637static 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/*
@@ -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
813int __jfs_setxattr(struct inode *inode, const char *name, const void *value, 808int __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,
955int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, 947int 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
966static int can_get_xattr(struct inode *inode, const char *name) 975static 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
1123int jfs_removexattr(struct dentry *dentry, const char *name) 1132int 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;
1151}
1152
1153#ifdef CONFIG_JFS_SECURITY
1154int 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);
1180kmalloc_failed:
1181 kfree(suffix);
1182 kfree(value);
1183
1184 return rc;
1126} 1185}
1186#endif