aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/vfs_dir.c1
-rw-r--r--fs/buffer.c6
-rw-r--r--fs/char_dev.c17
-rw-r--r--fs/debugfs/file.c46
-rw-r--r--fs/direct-io.c21
-rw-r--r--fs/ext2/dir.c28
-rw-r--r--fs/jfs/Makefile3
-rw-r--r--fs/jfs/acl.c7
-rw-r--r--fs/jfs/file.c1
-rw-r--r--fs/jfs/inode.c15
-rw-r--r--fs/jfs/ioctl.c107
-rw-r--r--fs/jfs/jfs_dinode.h31
-rw-r--r--fs/jfs/jfs_dmap.c8
-rw-r--r--fs/jfs/jfs_dmap.h2
-rw-r--r--fs/jfs/jfs_dtree.c13
-rw-r--r--fs/jfs/jfs_extent.c20
-rw-r--r--fs/jfs/jfs_imap.c72
-rw-r--r--fs/jfs/jfs_imap.h4
-rw-r--r--fs/jfs/jfs_incore.h10
-rw-r--r--fs/jfs/jfs_inode.c46
-rw-r--r--fs/jfs/jfs_inode.h3
-rw-r--r--fs/jfs/jfs_lock.h1
-rw-r--r--fs/jfs/jfs_logmgr.c35
-rw-r--r--fs/jfs/jfs_logmgr.h2
-rw-r--r--fs/jfs/jfs_metapage.c3
-rw-r--r--fs/jfs/jfs_superblock.h9
-rw-r--r--fs/jfs/jfs_txnmgr.c36
-rw-r--r--fs/jfs/namei.c99
-rw-r--r--fs/jfs/super.c98
-rw-r--r--fs/jfs/xattr.c8
-rw-r--r--fs/namespace.c5
-rw-r--r--fs/nfsctl.c4
-rw-r--r--fs/sysfs/dir.c37
-rw-r--r--fs/sysfs/file.c9
-rw-r--r--fs/sysfs/inode.c9
-rw-r--r--fs/sysfs/symlink.c6
-rw-r--r--fs/sysfs/sysfs.h1
37 files changed, 563 insertions, 260 deletions
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index ae6d032b9b59..cd5eeb032d64 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -202,7 +202,6 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
202 filp->private_data = NULL; 202 filp->private_data = NULL;
203 } 203 }
204 204
205 d_drop(filp->f_dentry);
206 return 0; 205 return 0;
207} 206}
208 207
diff --git a/fs/buffer.c b/fs/buffer.c
index 62cfd17dc5fe..a9b399402007 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -3060,6 +3060,7 @@ int buffer_migrate_page(struct page *newpage, struct page *page)
3060{ 3060{
3061 struct address_space *mapping = page->mapping; 3061 struct address_space *mapping = page->mapping;
3062 struct buffer_head *bh, *head; 3062 struct buffer_head *bh, *head;
3063 int rc;
3063 3064
3064 if (!mapping) 3065 if (!mapping)
3065 return -EAGAIN; 3066 return -EAGAIN;
@@ -3069,8 +3070,9 @@ int buffer_migrate_page(struct page *newpage, struct page *page)
3069 3070
3070 head = page_buffers(page); 3071 head = page_buffers(page);
3071 3072
3072 if (migrate_page_remove_references(newpage, page, 3)) 3073 rc = migrate_page_remove_references(newpage, page, 3);
3073 return -EAGAIN; 3074 if (rc)
3075 return rc;
3074 3076
3075 bh = head; 3077 bh = head;
3076 do { 3078 do {
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 21195c481637..5c36345c9bf7 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -19,6 +19,7 @@
19#include <linux/kobject.h> 19#include <linux/kobject.h>
20#include <linux/kobj_map.h> 20#include <linux/kobj_map.h>
21#include <linux/cdev.h> 21#include <linux/cdev.h>
22#include <linux/mutex.h>
22 23
23#ifdef CONFIG_KMOD 24#ifdef CONFIG_KMOD
24#include <linux/kmod.h> 25#include <linux/kmod.h>
@@ -28,7 +29,7 @@ static struct kobj_map *cdev_map;
28 29
29#define MAX_PROBE_HASH 255 /* random */ 30#define MAX_PROBE_HASH 255 /* random */
30 31
31static DECLARE_MUTEX(chrdevs_lock); 32static DEFINE_MUTEX(chrdevs_lock);
32 33
33static struct char_device_struct { 34static struct char_device_struct {
34 struct char_device_struct *next; 35 struct char_device_struct *next;
@@ -88,13 +89,13 @@ out:
88 89
89void *acquire_chrdev_list(void) 90void *acquire_chrdev_list(void)
90{ 91{
91 down(&chrdevs_lock); 92 mutex_lock(&chrdevs_lock);
92 return get_next_chrdev(NULL); 93 return get_next_chrdev(NULL);
93} 94}
94 95
95void release_chrdev_list(void *dev) 96void release_chrdev_list(void *dev)
96{ 97{
97 up(&chrdevs_lock); 98 mutex_unlock(&chrdevs_lock);
98 kfree(dev); 99 kfree(dev);
99} 100}
100 101
@@ -151,7 +152,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
151 152
152 memset(cd, 0, sizeof(struct char_device_struct)); 153 memset(cd, 0, sizeof(struct char_device_struct));
153 154
154 down(&chrdevs_lock); 155 mutex_lock(&chrdevs_lock);
155 156
156 /* temporary */ 157 /* temporary */
157 if (major == 0) { 158 if (major == 0) {
@@ -186,10 +187,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
186 } 187 }
187 cd->next = *cp; 188 cd->next = *cp;
188 *cp = cd; 189 *cp = cd;
189 up(&chrdevs_lock); 190 mutex_unlock(&chrdevs_lock);
190 return cd; 191 return cd;
191out: 192out:
192 up(&chrdevs_lock); 193 mutex_unlock(&chrdevs_lock);
193 kfree(cd); 194 kfree(cd);
194 return ERR_PTR(ret); 195 return ERR_PTR(ret);
195} 196}
@@ -200,7 +201,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
200 struct char_device_struct *cd = NULL, **cp; 201 struct char_device_struct *cd = NULL, **cp;
201 int i = major_to_index(major); 202 int i = major_to_index(major);
202 203
203 down(&chrdevs_lock); 204 mutex_lock(&chrdevs_lock);
204 for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) 205 for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
205 if ((*cp)->major == major && 206 if ((*cp)->major == major &&
206 (*cp)->baseminor == baseminor && 207 (*cp)->baseminor == baseminor &&
@@ -210,7 +211,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
210 cd = *cp; 211 cd = *cp;
211 *cp = cd->next; 212 *cp = cd->next;
212 } 213 }
213 up(&chrdevs_lock); 214 mutex_unlock(&chrdevs_lock);
214 return cd; 215 return cd;
215} 216}
216 217
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index d575452cd9f7..40c4fc973fad 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -251,3 +251,49 @@ struct dentry *debugfs_create_bool(const char *name, mode_t mode,
251} 251}
252EXPORT_SYMBOL_GPL(debugfs_create_bool); 252EXPORT_SYMBOL_GPL(debugfs_create_bool);
253 253
254static ssize_t read_file_blob(struct file *file, char __user *user_buf,
255 size_t count, loff_t *ppos)
256{
257 struct debugfs_blob_wrapper *blob = file->private_data;
258 return simple_read_from_buffer(user_buf, count, ppos, blob->data,
259 blob->size);
260}
261
262static struct file_operations fops_blob = {
263 .read = read_file_blob,
264 .open = default_open,
265};
266
267/**
268 * debugfs_create_blob - create a file in the debugfs filesystem that is
269 * used to read and write a binary blob.
270 *
271 * @name: a pointer to a string containing the name of the file to create.
272 * @mode: the permission that the file should have
273 * @parent: a pointer to the parent dentry for this file. This should be a
274 * directory dentry if set. If this paramater is NULL, then the
275 * file will be created in the root of the debugfs filesystem.
276 * @blob: a pointer to a struct debugfs_blob_wrapper which contains a pointer
277 * to the blob data and the size of the data.
278 *
279 * This function creates a file in debugfs with the given name that exports
280 * @blob->data as a binary blob. If the @mode variable is so set it can be
281 * read from. Writing is not supported.
282 *
283 * This function will return a pointer to a dentry if it succeeds. This
284 * pointer must be passed to the debugfs_remove() function when the file is
285 * to be removed (no automatic cleanup happens if your module is unloaded,
286 * you are responsible here.) If an error occurs, NULL will be returned.
287 *
288 * If debugfs is not enabled in the kernel, the value -ENODEV will be
289 * returned. It is not wise to check for this value, but rather, check for
290 * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
291 * code.
292 */
293struct dentry *debugfs_create_blob(const char *name, mode_t mode,
294 struct dentry *parent,
295 struct debugfs_blob_wrapper *blob)
296{
297 return debugfs_create_file(name, mode, parent, blob, &fops_blob);
298}
299EXPORT_SYMBOL_GPL(debugfs_create_blob);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 848044af7e16..27f3e787faca 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1155,15 +1155,16 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
1155 * For writes, i_mutex is not held on entry; it is never taken. 1155 * For writes, i_mutex is not held on entry; it is never taken.
1156 * 1156 *
1157 * DIO_LOCKING (simple locking for regular files) 1157 * DIO_LOCKING (simple locking for regular files)
1158 * For writes we are called under i_mutex and return with i_mutex held, even though 1158 * For writes we are called under i_mutex and return with i_mutex held, even
1159 * it is internally dropped. 1159 * though it is internally dropped.
1160 * For reads, i_mutex is not held on entry, but it is taken and dropped before 1160 * For reads, i_mutex is not held on entry, but it is taken and dropped before
1161 * returning. 1161 * returning.
1162 * 1162 *
1163 * DIO_OWN_LOCKING (filesystem provides synchronisation and handling of 1163 * DIO_OWN_LOCKING (filesystem provides synchronisation and handling of
1164 * uninitialised data, allowing parallel direct readers and writers) 1164 * uninitialised data, allowing parallel direct readers and writers)
1165 * For writes we are called without i_mutex, return without it, never touch it. 1165 * For writes we are called without i_mutex, return without it, never touch it.
1166 * For reads, i_mutex is held on entry and will be released before returning. 1166 * For reads we are called under i_mutex and return with i_mutex held, even
1167 * though it may be internally dropped.
1167 * 1168 *
1168 * Additional i_alloc_sem locking requirements described inline below. 1169 * Additional i_alloc_sem locking requirements described inline below.
1169 */ 1170 */
@@ -1182,7 +1183,8 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1182 ssize_t retval = -EINVAL; 1183 ssize_t retval = -EINVAL;
1183 loff_t end = offset; 1184 loff_t end = offset;
1184 struct dio *dio; 1185 struct dio *dio;
1185 int reader_with_isem = (rw == READ && dio_lock_type == DIO_OWN_LOCKING); 1186 int release_i_mutex = 0;
1187 int acquire_i_mutex = 0;
1186 1188
1187 if (rw & WRITE) 1189 if (rw & WRITE)
1188 current->flags |= PF_SYNCWRITE; 1190 current->flags |= PF_SYNCWRITE;
@@ -1225,7 +1227,6 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1225 * writers need to grab i_alloc_sem only (i_mutex is already held) 1227 * writers need to grab i_alloc_sem only (i_mutex is already held)
1226 * For regular files using DIO_OWN_LOCKING, 1228 * For regular files using DIO_OWN_LOCKING,
1227 * neither readers nor writers take any locks here 1229 * neither readers nor writers take any locks here
1228 * (i_mutex is already held and release for writers here)
1229 */ 1230 */
1230 dio->lock_type = dio_lock_type; 1231 dio->lock_type = dio_lock_type;
1231 if (dio_lock_type != DIO_NO_LOCKING) { 1232 if (dio_lock_type != DIO_NO_LOCKING) {
@@ -1236,7 +1237,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1236 mapping = iocb->ki_filp->f_mapping; 1237 mapping = iocb->ki_filp->f_mapping;
1237 if (dio_lock_type != DIO_OWN_LOCKING) { 1238 if (dio_lock_type != DIO_OWN_LOCKING) {
1238 mutex_lock(&inode->i_mutex); 1239 mutex_lock(&inode->i_mutex);
1239 reader_with_isem = 1; 1240 release_i_mutex = 1;
1240 } 1241 }
1241 1242
1242 retval = filemap_write_and_wait_range(mapping, offset, 1243 retval = filemap_write_and_wait_range(mapping, offset,
@@ -1248,7 +1249,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1248 1249
1249 if (dio_lock_type == DIO_OWN_LOCKING) { 1250 if (dio_lock_type == DIO_OWN_LOCKING) {
1250 mutex_unlock(&inode->i_mutex); 1251 mutex_unlock(&inode->i_mutex);
1251 reader_with_isem = 0; 1252 acquire_i_mutex = 1;
1252 } 1253 }
1253 } 1254 }
1254 1255
@@ -1269,11 +1270,13 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1269 nr_segs, blkbits, get_blocks, end_io, dio); 1270 nr_segs, blkbits, get_blocks, end_io, dio);
1270 1271
1271 if (rw == READ && dio_lock_type == DIO_LOCKING) 1272 if (rw == READ && dio_lock_type == DIO_LOCKING)
1272 reader_with_isem = 0; 1273 release_i_mutex = 0;
1273 1274
1274out: 1275out:
1275 if (reader_with_isem) 1276 if (release_i_mutex)
1276 mutex_unlock(&inode->i_mutex); 1277 mutex_unlock(&inode->i_mutex);
1278 else if (acquire_i_mutex)
1279 mutex_lock(&inode->i_mutex);
1277 if (rw & WRITE) 1280 if (rw & WRITE)
1278 current->flags &= ~PF_SYNCWRITE; 1281 current->flags &= ~PF_SYNCWRITE;
1279 return retval; 1282 return retval;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 7442bdd1267a..b3dbd716cd3a 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -256,11 +256,10 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
256 unsigned long npages = dir_pages(inode); 256 unsigned long npages = dir_pages(inode);
257 unsigned chunk_mask = ~(ext2_chunk_size(inode)-1); 257 unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
258 unsigned char *types = NULL; 258 unsigned char *types = NULL;
259 int need_revalidate = (filp->f_version != inode->i_version); 259 int need_revalidate = filp->f_version != inode->i_version;
260 int ret;
261 260
262 if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) 261 if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
263 goto success; 262 return 0;
264 263
265 if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE)) 264 if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
266 types = ext2_filetype_table; 265 types = ext2_filetype_table;
@@ -275,12 +274,15 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
275 "bad page in #%lu", 274 "bad page in #%lu",
276 inode->i_ino); 275 inode->i_ino);
277 filp->f_pos += PAGE_CACHE_SIZE - offset; 276 filp->f_pos += PAGE_CACHE_SIZE - offset;
278 ret = -EIO; 277 return -EIO;
279 goto done;
280 } 278 }
281 kaddr = page_address(page); 279 kaddr = page_address(page);
282 if (need_revalidate) { 280 if (unlikely(need_revalidate)) {
283 offset = ext2_validate_entry(kaddr, offset, chunk_mask); 281 if (offset) {
282 offset = ext2_validate_entry(kaddr, offset, chunk_mask);
283 filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset;
284 }
285 filp->f_version = inode->i_version;
284 need_revalidate = 0; 286 need_revalidate = 0;
285 } 287 }
286 de = (ext2_dirent *)(kaddr+offset); 288 de = (ext2_dirent *)(kaddr+offset);
@@ -289,9 +291,8 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
289 if (de->rec_len == 0) { 291 if (de->rec_len == 0) {
290 ext2_error(sb, __FUNCTION__, 292 ext2_error(sb, __FUNCTION__,
291 "zero-length directory entry"); 293 "zero-length directory entry");
292 ret = -EIO;
293 ext2_put_page(page); 294 ext2_put_page(page);
294 goto done; 295 return -EIO;
295 } 296 }
296 if (de->inode) { 297 if (de->inode) {
297 int over; 298 int over;
@@ -306,19 +307,14 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
306 le32_to_cpu(de->inode), d_type); 307 le32_to_cpu(de->inode), d_type);
307 if (over) { 308 if (over) {
308 ext2_put_page(page); 309 ext2_put_page(page);
309 goto success; 310 return 0;
310 } 311 }
311 } 312 }
312 filp->f_pos += le16_to_cpu(de->rec_len); 313 filp->f_pos += le16_to_cpu(de->rec_len);
313 } 314 }
314 ext2_put_page(page); 315 ext2_put_page(page);
315 } 316 }
316 317 return 0;
317success:
318 ret = 0;
319done:
320 filp->f_version = inode->i_version;
321 return ret;
322} 318}
323 319
324/* 320/*
diff --git a/fs/jfs/Makefile b/fs/jfs/Makefile
index 6f1e0e95587a..3adb6395e42d 100644
--- a/fs/jfs/Makefile
+++ b/fs/jfs/Makefile
@@ -8,7 +8,8 @@ jfs-y := super.o file.o inode.o namei.o jfs_mount.o jfs_umount.o \
8 jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \ 8 jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \
9 jfs_unicode.o jfs_dtree.o jfs_inode.o \ 9 jfs_unicode.o jfs_dtree.o jfs_inode.o \
10 jfs_extent.o symlink.o jfs_metapage.o \ 10 jfs_extent.o symlink.o jfs_metapage.o \
11 jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o resize.o xattr.o 11 jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o \
12 resize.o xattr.o ioctl.o
12 13
13jfs-$(CONFIG_JFS_POSIX_ACL) += acl.o 14jfs-$(CONFIG_JFS_POSIX_ACL) += acl.o
14 15
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index 461e4934ca7c..e2281300979c 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -183,6 +183,9 @@ cleanup:
183 posix_acl_release(acl); 183 posix_acl_release(acl);
184 } else 184 } else
185 inode->i_mode &= ~current->fs->umask; 185 inode->i_mode &= ~current->fs->umask;
186
187 JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
188 inode->i_mode;
186 189
187 return rc; 190 return rc;
188} 191}
@@ -207,12 +210,12 @@ static int jfs_acl_chmod(struct inode *inode)
207 rc = posix_acl_chmod_masq(clone, inode->i_mode); 210 rc = posix_acl_chmod_masq(clone, inode->i_mode);
208 if (!rc) { 211 if (!rc) {
209 tid_t tid = txBegin(inode->i_sb, 0); 212 tid_t tid = txBegin(inode->i_sb, 0);
210 down(&JFS_IP(inode)->commit_sem); 213 mutex_lock(&JFS_IP(inode)->commit_mutex);
211 rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone); 214 rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone);
212 if (!rc) 215 if (!rc)
213 rc = txCommit(tid, 1, &inode, 0); 216 rc = txCommit(tid, 1, &inode, 0);
214 txEnd(tid); 217 txEnd(tid);
215 up(&JFS_IP(inode)->commit_sem); 218 mutex_unlock(&JFS_IP(inode)->commit_mutex);
216 } 219 }
217 220
218 posix_acl_release(clone); 221 posix_acl_release(clone);
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index c2c19c9ed9a4..e1ac6e497e2b 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -113,4 +113,5 @@ struct file_operations jfs_file_operations = {
113 .sendfile = generic_file_sendfile, 113 .sendfile = generic_file_sendfile,
114 .fsync = jfs_fsync, 114 .fsync = jfs_fsync,
115 .release = jfs_release, 115 .release = jfs_release,
116 .ioctl = jfs_ioctl,
116}; 117};
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 9f942ca8e4e3..51a5fed90cca 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -55,6 +55,7 @@ void jfs_read_inode(struct inode *inode)
55 inode->i_op = &jfs_file_inode_operations; 55 inode->i_op = &jfs_file_inode_operations;
56 init_special_inode(inode, inode->i_mode, inode->i_rdev); 56 init_special_inode(inode, inode->i_mode, inode->i_rdev);
57 } 57 }
58 jfs_set_inode_flags(inode);
58} 59}
59 60
60/* 61/*
@@ -89,16 +90,16 @@ int jfs_commit_inode(struct inode *inode, int wait)
89 } 90 }
90 91
91 tid = txBegin(inode->i_sb, COMMIT_INODE); 92 tid = txBegin(inode->i_sb, COMMIT_INODE);
92 down(&JFS_IP(inode)->commit_sem); 93 mutex_lock(&JFS_IP(inode)->commit_mutex);
93 94
94 /* 95 /*
95 * Retest inode state after taking commit_sem 96 * Retest inode state after taking commit_mutex
96 */ 97 */
97 if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode)) 98 if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode))
98 rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0); 99 rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
99 100
100 txEnd(tid); 101 txEnd(tid);
101 up(&JFS_IP(inode)->commit_sem); 102 mutex_unlock(&JFS_IP(inode)->commit_mutex);
102 return rc; 103 return rc;
103} 104}
104 105
@@ -335,18 +336,18 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
335 tid = txBegin(ip->i_sb, 0); 336 tid = txBegin(ip->i_sb, 0);
336 337
337 /* 338 /*
338 * The commit_sem cannot be taken before txBegin. 339 * The commit_mutex cannot be taken before txBegin.
339 * txBegin may block and there is a chance the inode 340 * txBegin may block and there is a chance the inode
340 * could be marked dirty and need to be committed 341 * could be marked dirty and need to be committed
341 * before txBegin unblocks 342 * before txBegin unblocks
342 */ 343 */
343 down(&JFS_IP(ip)->commit_sem); 344 mutex_lock(&JFS_IP(ip)->commit_mutex);
344 345
345 newsize = xtTruncate(tid, ip, length, 346 newsize = xtTruncate(tid, ip, length,
346 COMMIT_TRUNCATE | COMMIT_PWMAP); 347 COMMIT_TRUNCATE | COMMIT_PWMAP);
347 if (newsize < 0) { 348 if (newsize < 0) {
348 txEnd(tid); 349 txEnd(tid);
349 up(&JFS_IP(ip)->commit_sem); 350 mutex_unlock(&JFS_IP(ip)->commit_mutex);
350 break; 351 break;
351 } 352 }
352 353
@@ -355,7 +356,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
355 356
356 txCommit(tid, 1, &ip, 0); 357 txCommit(tid, 1, &ip, 0);
357 txEnd(tid); 358 txEnd(tid);
358 up(&JFS_IP(ip)->commit_sem); 359 mutex_unlock(&JFS_IP(ip)->commit_mutex);
359 } while (newsize > length); /* Truncate isn't always atomic */ 360 } while (newsize > length); /* Truncate isn't always atomic */
360} 361}
361 362
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c
new file mode 100644
index 000000000000..67b3774820eb
--- /dev/null
+++ b/fs/jfs/ioctl.c
@@ -0,0 +1,107 @@
1/*
2 * linux/fs/jfs/ioctl.c
3 *
4 * Copyright (C) 2006 Herbert Poetzl
5 * adapted from Remy Card's ext2/ioctl.c
6 */
7
8#include <linux/fs.h>
9#include <linux/ext2_fs.h>
10#include <linux/ctype.h>
11#include <linux/capability.h>
12#include <linux/time.h>
13#include <asm/current.h>
14#include <asm/uaccess.h>
15
16#include "jfs_incore.h"
17#include "jfs_dinode.h"
18#include "jfs_inode.h"
19
20
21static struct {
22 long jfs_flag;
23 long ext2_flag;
24} jfs_map[] = {
25 {JFS_NOATIME_FL, EXT2_NOATIME_FL},
26 {JFS_DIRSYNC_FL, EXT2_DIRSYNC_FL},
27 {JFS_SYNC_FL, EXT2_SYNC_FL},
28 {JFS_SECRM_FL, EXT2_SECRM_FL},
29 {JFS_UNRM_FL, EXT2_UNRM_FL},
30 {JFS_APPEND_FL, EXT2_APPEND_FL},
31 {JFS_IMMUTABLE_FL, EXT2_IMMUTABLE_FL},
32 {0, 0},
33};
34
35static long jfs_map_ext2(unsigned long flags, int from)
36{
37 int index=0;
38 long mapped=0;
39
40 while (jfs_map[index].jfs_flag) {
41 if (from) {
42 if (jfs_map[index].ext2_flag & flags)
43 mapped |= jfs_map[index].jfs_flag;
44 } else {
45 if (jfs_map[index].jfs_flag & flags)
46 mapped |= jfs_map[index].ext2_flag;
47 }
48 index++;
49 }
50 return mapped;
51}
52
53
54int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
55 unsigned long arg)
56{
57 struct jfs_inode_info *jfs_inode = JFS_IP(inode);
58 unsigned int flags;
59
60 switch (cmd) {
61 case JFS_IOC_GETFLAGS:
62 flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE;
63 flags = jfs_map_ext2(flags, 0);
64 return put_user(flags, (int __user *) arg);
65 case JFS_IOC_SETFLAGS: {
66 unsigned int oldflags;
67
68 if (IS_RDONLY(inode))
69 return -EROFS;
70
71 if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
72 return -EACCES;
73
74 if (get_user(flags, (int __user *) arg))
75 return -EFAULT;
76
77 flags = jfs_map_ext2(flags, 1);
78 if (!S_ISDIR(inode->i_mode))
79 flags &= ~JFS_DIRSYNC_FL;
80
81 oldflags = jfs_inode->mode2;
82
83 /*
84 * The IMMUTABLE and APPEND_ONLY flags can only be changed by
85 * the relevant capability.
86 */
87 if ((oldflags & JFS_IMMUTABLE_FL) ||
88 ((flags ^ oldflags) &
89 (JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
90 if (!capable(CAP_LINUX_IMMUTABLE))
91 return -EPERM;
92 }
93
94 flags = flags & JFS_FL_USER_MODIFIABLE;
95 flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
96 jfs_inode->mode2 = flags;
97
98 jfs_set_inode_flags(inode);
99 inode->i_ctime = CURRENT_TIME_SEC;
100 mark_inode_dirty(inode);
101 return 0;
102 }
103 default:
104 return -ENOTTY;
105 }
106}
107
diff --git a/fs/jfs/jfs_dinode.h b/fs/jfs/jfs_dinode.h
index 580a3258449b..9f2572aea561 100644
--- a/fs/jfs/jfs_dinode.h
+++ b/fs/jfs/jfs_dinode.h
@@ -139,13 +139,36 @@ struct dinode {
139 139
140/* more extended mode bits: attributes for OS/2 */ 140/* more extended mode bits: attributes for OS/2 */
141#define IREADONLY 0x02000000 /* no write access to file */ 141#define IREADONLY 0x02000000 /* no write access to file */
142#define IARCHIVE 0x40000000 /* file archive bit */
143#define ISYSTEM 0x08000000 /* system file */
144#define IHIDDEN 0x04000000 /* hidden file */ 142#define IHIDDEN 0x04000000 /* hidden file */
145#define IRASH 0x4E000000 /* mask for changeable attributes */ 143#define ISYSTEM 0x08000000 /* system file */
146#define INEWNAME 0x80000000 /* non-8.3 filename format */ 144
147#define IDIRECTORY 0x20000000 /* directory (shadow of real bit) */ 145#define IDIRECTORY 0x20000000 /* directory (shadow of real bit) */
146#define IARCHIVE 0x40000000 /* file archive bit */
147#define INEWNAME 0x80000000 /* non-8.3 filename format */
148
149#define IRASH 0x4E000000 /* mask for changeable attributes */
148#define ATTRSHIFT 25 /* bits to shift to move attribute 150#define ATTRSHIFT 25 /* bits to shift to move attribute
149 specification to mode position */ 151 specification to mode position */
150 152
153/* extended attributes for Linux */
154
155#define JFS_NOATIME_FL 0x00080000 /* do not update atime */
156
157#define JFS_DIRSYNC_FL 0x00100000 /* dirsync behaviour */
158#define JFS_SYNC_FL 0x00200000 /* Synchronous updates */
159#define JFS_SECRM_FL 0x00400000 /* Secure deletion */
160#define JFS_UNRM_FL 0x00800000 /* allow for undelete */
161
162#define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
163#define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
164
165#define JFS_FL_USER_VISIBLE 0x03F80000
166#define JFS_FL_USER_MODIFIABLE 0x03F80000
167#define JFS_FL_INHERIT 0x03C80000
168
169/* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
170#define JFS_IOC_GETFLAGS _IOR('f', 1, long)
171#define JFS_IOC_SETFLAGS _IOW('f', 2, long)
172
173
151#endif /*_H_JFS_DINODE */ 174#endif /*_H_JFS_DINODE */
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index 79b5404db100..c161c98954e0 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -64,9 +64,9 @@
64 * to the persistent bitmaps in dmaps) is guarded by (busy) buffers. 64 * to the persistent bitmaps in dmaps) is guarded by (busy) buffers.
65 */ 65 */
66 66
67#define BMAP_LOCK_INIT(bmp) init_MUTEX(&bmp->db_bmaplock) 67#define BMAP_LOCK_INIT(bmp) mutex_init(&bmp->db_bmaplock)
68#define BMAP_LOCK(bmp) down(&bmp->db_bmaplock) 68#define BMAP_LOCK(bmp) mutex_lock(&bmp->db_bmaplock)
69#define BMAP_UNLOCK(bmp) up(&bmp->db_bmaplock) 69#define BMAP_UNLOCK(bmp) mutex_unlock(&bmp->db_bmaplock)
70 70
71/* 71/*
72 * forward references 72 * forward references
@@ -125,7 +125,7 @@ static int dbGetL2AGSize(s64 nblocks);
125 * into the table, with the table elements yielding the maximum 125 * into the table, with the table elements yielding the maximum
126 * binary buddy of free bits within the character. 126 * binary buddy of free bits within the character.
127 */ 127 */
128static s8 budtab[256] = { 128static const s8 budtab[256] = {
129 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 129 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
130 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 130 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
131 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 131 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
diff --git a/fs/jfs/jfs_dmap.h b/fs/jfs/jfs_dmap.h
index 32e25884e7e8..8b14cc8e0228 100644
--- a/fs/jfs/jfs_dmap.h
+++ b/fs/jfs/jfs_dmap.h
@@ -243,7 +243,7 @@ struct dbmap {
243struct bmap { 243struct bmap {
244 struct dbmap db_bmap; /* on-disk aggregate map descriptor */ 244 struct dbmap db_bmap; /* on-disk aggregate map descriptor */
245 struct inode *db_ipbmap; /* ptr to aggregate map incore inode */ 245 struct inode *db_ipbmap; /* ptr to aggregate map incore inode */
246 struct semaphore db_bmaplock; /* aggregate map lock */ 246 struct mutex db_bmaplock; /* aggregate map lock */
247 atomic_t db_active[MAXAG]; /* count of active, open files in AG */ 247 atomic_t db_active[MAXAG]; /* count of active, open files in AG */
248 u32 *db_DBmap; 248 u32 *db_DBmap;
249}; 249};
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index 404f33eae507..6c3f08319846 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -1005,6 +1005,9 @@ static int dtSplitUp(tid_t tid,
1005 1005
1006 DT_PUTPAGE(smp); 1006 DT_PUTPAGE(smp);
1007 1007
1008 if (!DO_INDEX(ip))
1009 ip->i_size = xlen << sbi->l2bsize;
1010
1008 goto freeKeyName; 1011 goto freeKeyName;
1009 } 1012 }
1010 1013
@@ -1055,7 +1058,9 @@ static int dtSplitUp(tid_t tid,
1055 xaddr = addressPXD(pxd) + xlen; 1058 xaddr = addressPXD(pxd) + xlen;
1056 dbFree(ip, xaddr, (s64) n); 1059 dbFree(ip, xaddr, (s64) n);
1057 } 1060 }
1058 } 1061 } else if (!DO_INDEX(ip))
1062 ip->i_size = lengthPXD(pxd) << sbi->l2bsize;
1063
1059 1064
1060 extendOut: 1065 extendOut:
1061 DT_PUTPAGE(smp); 1066 DT_PUTPAGE(smp);
@@ -1098,6 +1103,9 @@ static int dtSplitUp(tid_t tid,
1098 goto splitOut; 1103 goto splitOut;
1099 } 1104 }
1100 1105
1106 if (!DO_INDEX(ip))
1107 ip->i_size += PSIZE;
1108
1101 /* 1109 /*
1102 * propagate up the router entry for the leaf page just split 1110 * propagate up the router entry for the leaf page just split
1103 * 1111 *
@@ -2424,6 +2432,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
2424 break; 2432 break;
2425 } 2433 }
2426 2434
2435 if (!DO_INDEX(ip))
2436 ip->i_size -= PSIZE;
2437
2427 return 0; 2438 return 0;
2428} 2439}
2429 2440
diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
index 4879603daa1c..5549378358bf 100644
--- a/fs/jfs/jfs_extent.c
+++ b/fs/jfs/jfs_extent.c
@@ -94,7 +94,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
94 txBeginAnon(ip->i_sb); 94 txBeginAnon(ip->i_sb);
95 95
96 /* Avoid race with jfs_commit_inode() */ 96 /* Avoid race with jfs_commit_inode() */
97 down(&JFS_IP(ip)->commit_sem); 97 mutex_lock(&JFS_IP(ip)->commit_mutex);
98 98
99 /* validate extent length */ 99 /* validate extent length */
100 if (xlen > MAXXLEN) 100 if (xlen > MAXXLEN)
@@ -136,14 +136,14 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
136 */ 136 */
137 nxlen = xlen; 137 nxlen = xlen;
138 if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) { 138 if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
139 up(&JFS_IP(ip)->commit_sem); 139 mutex_unlock(&JFS_IP(ip)->commit_mutex);
140 return (rc); 140 return (rc);
141 } 141 }
142 142
143 /* Allocate blocks to quota. */ 143 /* Allocate blocks to quota. */
144 if (DQUOT_ALLOC_BLOCK(ip, nxlen)) { 144 if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
145 dbFree(ip, nxaddr, (s64) nxlen); 145 dbFree(ip, nxaddr, (s64) nxlen);
146 up(&JFS_IP(ip)->commit_sem); 146 mutex_unlock(&JFS_IP(ip)->commit_mutex);
147 return -EDQUOT; 147 return -EDQUOT;
148 } 148 }
149 149
@@ -165,7 +165,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
165 if (rc) { 165 if (rc) {
166 dbFree(ip, nxaddr, nxlen); 166 dbFree(ip, nxaddr, nxlen);
167 DQUOT_FREE_BLOCK(ip, nxlen); 167 DQUOT_FREE_BLOCK(ip, nxlen);
168 up(&JFS_IP(ip)->commit_sem); 168 mutex_unlock(&JFS_IP(ip)->commit_mutex);
169 return (rc); 169 return (rc);
170 } 170 }
171 171
@@ -177,7 +177,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
177 177
178 mark_inode_dirty(ip); 178 mark_inode_dirty(ip);
179 179
180 up(&JFS_IP(ip)->commit_sem); 180 mutex_unlock(&JFS_IP(ip)->commit_mutex);
181 /* 181 /*
182 * COMMIT_SyncList flags an anonymous tlock on page that is on 182 * COMMIT_SyncList flags an anonymous tlock on page that is on
183 * sync list. 183 * sync list.
@@ -222,7 +222,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
222 /* This blocks if we are low on resources */ 222 /* This blocks if we are low on resources */
223 txBeginAnon(ip->i_sb); 223 txBeginAnon(ip->i_sb);
224 224
225 down(&JFS_IP(ip)->commit_sem); 225 mutex_lock(&JFS_IP(ip)->commit_mutex);
226 /* validate extent length */ 226 /* validate extent length */
227 if (nxlen > MAXXLEN) 227 if (nxlen > MAXXLEN)
228 nxlen = MAXXLEN; 228 nxlen = MAXXLEN;
@@ -258,7 +258,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
258 /* Allocat blocks to quota. */ 258 /* Allocat blocks to quota. */
259 if (DQUOT_ALLOC_BLOCK(ip, nxlen)) { 259 if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
260 dbFree(ip, nxaddr, (s64) nxlen); 260 dbFree(ip, nxaddr, (s64) nxlen);
261 up(&JFS_IP(ip)->commit_sem); 261 mutex_unlock(&JFS_IP(ip)->commit_mutex);
262 return -EDQUOT; 262 return -EDQUOT;
263 } 263 }
264 264
@@ -338,7 +338,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
338 338
339 mark_inode_dirty(ip); 339 mark_inode_dirty(ip);
340exit: 340exit:
341 up(&JFS_IP(ip)->commit_sem); 341 mutex_unlock(&JFS_IP(ip)->commit_mutex);
342 return (rc); 342 return (rc);
343} 343}
344#endif /* _NOTYET */ 344#endif /* _NOTYET */
@@ -439,12 +439,12 @@ int extRecord(struct inode *ip, xad_t * xp)
439 439
440 txBeginAnon(ip->i_sb); 440 txBeginAnon(ip->i_sb);
441 441
442 down(&JFS_IP(ip)->commit_sem); 442 mutex_lock(&JFS_IP(ip)->commit_mutex);
443 443
444 /* update the extent */ 444 /* update the extent */
445 rc = xtUpdate(0, ip, xp); 445 rc = xtUpdate(0, ip, xp);
446 446
447 up(&JFS_IP(ip)->commit_sem); 447 mutex_unlock(&JFS_IP(ip)->commit_mutex);
448 return rc; 448 return rc;
449} 449}
450 450
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 4efa0d0eec39..ccbe60aff83d 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -66,14 +66,14 @@ static HLIST_HEAD(aggregate_hash);
66 * imap locks 66 * imap locks
67 */ 67 */
68/* iag free list lock */ 68/* iag free list lock */
69#define IAGFREE_LOCK_INIT(imap) init_MUTEX(&imap->im_freelock) 69#define IAGFREE_LOCK_INIT(imap) mutex_init(&imap->im_freelock)
70#define IAGFREE_LOCK(imap) down(&imap->im_freelock) 70#define IAGFREE_LOCK(imap) mutex_lock(&imap->im_freelock)
71#define IAGFREE_UNLOCK(imap) up(&imap->im_freelock) 71#define IAGFREE_UNLOCK(imap) mutex_unlock(&imap->im_freelock)
72 72
73/* per ag iag list locks */ 73/* per ag iag list locks */
74#define AG_LOCK_INIT(imap,index) init_MUTEX(&(imap->im_aglock[index])) 74#define AG_LOCK_INIT(imap,index) mutex_init(&(imap->im_aglock[index]))
75#define AG_LOCK(imap,agno) down(&imap->im_aglock[agno]) 75#define AG_LOCK(imap,agno) mutex_lock(&imap->im_aglock[agno])
76#define AG_UNLOCK(imap,agno) up(&imap->im_aglock[agno]) 76#define AG_UNLOCK(imap,agno) mutex_unlock(&imap->im_aglock[agno])
77 77
78/* 78/*
79 * forward references 79 * forward references
@@ -1261,7 +1261,7 @@ int diFree(struct inode *ip)
1261 * to be freed by the transaction; 1261 * to be freed by the transaction;
1262 */ 1262 */
1263 tid = txBegin(ipimap->i_sb, COMMIT_FORCE); 1263 tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
1264 down(&JFS_IP(ipimap)->commit_sem); 1264 mutex_lock(&JFS_IP(ipimap)->commit_mutex);
1265 1265
1266 /* acquire tlock of the iag page of the freed ixad 1266 /* acquire tlock of the iag page of the freed ixad
1267 * to force the page NOHOMEOK (even though no data is 1267 * to force the page NOHOMEOK (even though no data is
@@ -1294,7 +1294,7 @@ int diFree(struct inode *ip)
1294 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE); 1294 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
1295 1295
1296 txEnd(tid); 1296 txEnd(tid);
1297 up(&JFS_IP(ipimap)->commit_sem); 1297 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
1298 1298
1299 /* unlock the AG inode map information */ 1299 /* unlock the AG inode map information */
1300 AG_UNLOCK(imap, agno); 1300 AG_UNLOCK(imap, agno);
@@ -2554,13 +2554,13 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2554 * addressing structure pointing to the new iag page; 2554 * addressing structure pointing to the new iag page;
2555 */ 2555 */
2556 tid = txBegin(sb, COMMIT_FORCE); 2556 tid = txBegin(sb, COMMIT_FORCE);
2557 down(&JFS_IP(ipimap)->commit_sem); 2557 mutex_lock(&JFS_IP(ipimap)->commit_mutex);
2558 2558
2559 /* update the inode map addressing structure to point to it */ 2559 /* update the inode map addressing structure to point to it */
2560 if ((rc = 2560 if ((rc =
2561 xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) { 2561 xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
2562 txEnd(tid); 2562 txEnd(tid);
2563 up(&JFS_IP(ipimap)->commit_sem); 2563 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2564 /* Free the blocks allocated for the iag since it was 2564 /* Free the blocks allocated for the iag since it was
2565 * not successfully added to the inode map 2565 * not successfully added to the inode map
2566 */ 2566 */
@@ -2626,7 +2626,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2626 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE); 2626 rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
2627 2627
2628 txEnd(tid); 2628 txEnd(tid);
2629 up(&JFS_IP(ipimap)->commit_sem); 2629 mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
2630 2630
2631 duplicateIXtree(sb, blkno, xlen, &xaddr); 2631 duplicateIXtree(sb, blkno, xlen, &xaddr);
2632 2632
@@ -3074,14 +3074,40 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
3074static int copy_from_dinode(struct dinode * dip, struct inode *ip) 3074static int copy_from_dinode(struct dinode * dip, struct inode *ip)
3075{ 3075{
3076 struct jfs_inode_info *jfs_ip = JFS_IP(ip); 3076 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3077 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3077 3078
3078 jfs_ip->fileset = le32_to_cpu(dip->di_fileset); 3079 jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
3079 jfs_ip->mode2 = le32_to_cpu(dip->di_mode); 3080 jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
3080 3081
3081 ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; 3082 ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
3083 if (sbi->umask != -1) {
3084 ip->i_mode = (ip->i_mode & ~0777) | (0777 & ~sbi->umask);
3085 /* For directories, add x permission if r is allowed by umask */
3086 if (S_ISDIR(ip->i_mode)) {
3087 if (ip->i_mode & 0400)
3088 ip->i_mode |= 0100;
3089 if (ip->i_mode & 0040)
3090 ip->i_mode |= 0010;
3091 if (ip->i_mode & 0004)
3092 ip->i_mode |= 0001;
3093 }
3094 }
3082 ip->i_nlink = le32_to_cpu(dip->di_nlink); 3095 ip->i_nlink = le32_to_cpu(dip->di_nlink);
3083 ip->i_uid = le32_to_cpu(dip->di_uid); 3096
3084 ip->i_gid = le32_to_cpu(dip->di_gid); 3097 jfs_ip->saved_uid = le32_to_cpu(dip->di_uid);
3098 if (sbi->uid == -1)
3099 ip->i_uid = jfs_ip->saved_uid;
3100 else {
3101 ip->i_uid = sbi->uid;
3102 }
3103
3104 jfs_ip->saved_gid = le32_to_cpu(dip->di_gid);
3105 if (sbi->gid == -1)
3106 ip->i_gid = jfs_ip->saved_gid;
3107 else {
3108 ip->i_gid = sbi->gid;
3109 }
3110
3085 ip->i_size = le64_to_cpu(dip->di_size); 3111 ip->i_size = le64_to_cpu(dip->di_size);
3086 ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); 3112 ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec);
3087 ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); 3113 ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec);
@@ -3132,21 +3158,33 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip)
3132static void copy_to_dinode(struct dinode * dip, struct inode *ip) 3158static void copy_to_dinode(struct dinode * dip, struct inode *ip)
3133{ 3159{
3134 struct jfs_inode_info *jfs_ip = JFS_IP(ip); 3160 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
3161 struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
3135 3162
3136 dip->di_fileset = cpu_to_le32(jfs_ip->fileset); 3163 dip->di_fileset = cpu_to_le32(jfs_ip->fileset);
3137 dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); 3164 dip->di_inostamp = cpu_to_le32(sbi->inostamp);
3138 dip->di_number = cpu_to_le32(ip->i_ino); 3165 dip->di_number = cpu_to_le32(ip->i_ino);
3139 dip->di_gen = cpu_to_le32(ip->i_generation); 3166 dip->di_gen = cpu_to_le32(ip->i_generation);
3140 dip->di_size = cpu_to_le64(ip->i_size); 3167 dip->di_size = cpu_to_le64(ip->i_size);
3141 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); 3168 dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
3142 dip->di_nlink = cpu_to_le32(ip->i_nlink); 3169 dip->di_nlink = cpu_to_le32(ip->i_nlink);
3143 dip->di_uid = cpu_to_le32(ip->i_uid); 3170 if (sbi->uid == -1)
3144 dip->di_gid = cpu_to_le32(ip->i_gid); 3171 dip->di_uid = cpu_to_le32(ip->i_uid);
3172 else
3173 dip->di_uid = cpu_to_le32(jfs_ip->saved_uid);
3174 if (sbi->gid == -1)
3175 dip->di_gid = cpu_to_le32(ip->i_gid);
3176 else
3177 dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
3145 /* 3178 /*
3146 * mode2 is only needed for storing the higher order bits. 3179 * mode2 is only needed for storing the higher order bits.
3147 * Trust i_mode for the lower order ones 3180 * Trust i_mode for the lower order ones
3148 */ 3181 */
3149 dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | ip->i_mode); 3182 if (sbi->umask == -1)
3183 dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) |
3184 ip->i_mode);
3185 else /* Leave the original permissions alone */
3186 dip->di_mode = cpu_to_le32(jfs_ip->mode2);
3187
3150 dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec); 3188 dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec);
3151 dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec); 3189 dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec);
3152 dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec); 3190 dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec);
diff --git a/fs/jfs/jfs_imap.h b/fs/jfs/jfs_imap.h
index 6b59adec036a..6e24465f0f98 100644
--- a/fs/jfs/jfs_imap.h
+++ b/fs/jfs/jfs_imap.h
@@ -140,8 +140,8 @@ struct dinomap {
140struct inomap { 140struct inomap {
141 struct dinomap im_imap; /* 4096: inode allocation control */ 141 struct dinomap im_imap; /* 4096: inode allocation control */
142 struct inode *im_ipimap; /* 4: ptr to inode for imap */ 142 struct inode *im_ipimap; /* 4: ptr to inode for imap */
143 struct semaphore im_freelock; /* 4: iag free list lock */ 143 struct mutex im_freelock; /* 4: iag free list lock */
144 struct semaphore im_aglock[MAXAG]; /* 512: per AG locks */ 144 struct mutex im_aglock[MAXAG]; /* 512: per AG locks */
145 u32 *im_DBGdimap; 145 u32 *im_DBGdimap;
146 atomic_t im_numinos; /* num of backed inodes */ 146 atomic_t im_numinos; /* num of backed inodes */
147 atomic_t im_numfree; /* num of free backed inodes */ 147 atomic_t im_numfree; /* num of free backed inodes */
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
index dc21a5bd54d4..54d73716ca8c 100644
--- a/fs/jfs/jfs_incore.h
+++ b/fs/jfs/jfs_incore.h
@@ -19,6 +19,7 @@
19#ifndef _H_JFS_INCORE 19#ifndef _H_JFS_INCORE
20#define _H_JFS_INCORE 20#define _H_JFS_INCORE
21 21
22#include <linux/mutex.h>
22#include <linux/rwsem.h> 23#include <linux/rwsem.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
24#include <linux/bitops.h> 25#include <linux/bitops.h>
@@ -37,6 +38,8 @@
37struct jfs_inode_info { 38struct jfs_inode_info {
38 int fileset; /* fileset number (always 16)*/ 39 int fileset; /* fileset number (always 16)*/
39 uint mode2; /* jfs-specific mode */ 40 uint mode2; /* jfs-specific mode */
41 uint saved_uid; /* saved for uid mount option */
42 uint saved_gid; /* saved for gid mount option */
40 pxd_t ixpxd; /* inode extent descriptor */ 43 pxd_t ixpxd; /* inode extent descriptor */
41 dxd_t acl; /* dxd describing acl */ 44 dxd_t acl; /* dxd describing acl */
42 dxd_t ea; /* dxd describing ea */ 45 dxd_t ea; /* dxd describing ea */
@@ -62,12 +65,12 @@ struct jfs_inode_info {
62 */ 65 */
63 struct rw_semaphore rdwrlock; 66 struct rw_semaphore rdwrlock;
64 /* 67 /*
65 * commit_sem serializes transaction processing on an inode. 68 * commit_mutex serializes transaction processing on an inode.
66 * It must be taken after beginning a transaction (txBegin), since 69 * It must be taken after beginning a transaction (txBegin), since
67 * dirty inodes may be committed while a new transaction on the 70 * dirty inodes may be committed while a new transaction on the
68 * inode is blocked in txBegin or TxBeginAnon 71 * inode is blocked in txBegin or TxBeginAnon
69 */ 72 */
70 struct semaphore commit_sem; 73 struct mutex commit_mutex;
71 /* xattr_sem allows us to access the xattrs without taking i_mutex */ 74 /* xattr_sem allows us to access the xattrs without taking i_mutex */
72 struct rw_semaphore xattr_sem; 75 struct rw_semaphore xattr_sem;
73 lid_t xtlid; /* lid of xtree lock on directory */ 76 lid_t xtlid; /* lid of xtree lock on directory */
@@ -169,6 +172,9 @@ struct jfs_sb_info {
169 uint state; /* mount/recovery state */ 172 uint state; /* mount/recovery state */
170 unsigned long flag; /* mount time flags */ 173 unsigned long flag; /* mount time flags */
171 uint p_state; /* state prior to going no integrity */ 174 uint p_state; /* state prior to going no integrity */
175 uint uid; /* uid to override on-disk uid */
176 uint gid; /* gid to override on-disk gid */
177 uint umask; /* umask to override on-disk umask */
172}; 178};
173 179
174/* jfs_sb_info commit_state */ 180/* jfs_sb_info commit_state */
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
index 2af5efbfd06f..495df402916d 100644
--- a/fs/jfs/jfs_inode.c
+++ b/fs/jfs/jfs_inode.c
@@ -25,6 +25,26 @@
25#include "jfs_dinode.h" 25#include "jfs_dinode.h"
26#include "jfs_debug.h" 26#include "jfs_debug.h"
27 27
28
29void jfs_set_inode_flags(struct inode *inode)
30{
31 unsigned int flags = JFS_IP(inode)->mode2;
32
33 inode->i_flags &= ~(S_IMMUTABLE | S_APPEND |
34 S_NOATIME | S_DIRSYNC | S_SYNC);
35
36 if (flags & JFS_IMMUTABLE_FL)
37 inode->i_flags |= S_IMMUTABLE;
38 if (flags & JFS_APPEND_FL)
39 inode->i_flags |= S_APPEND;
40 if (flags & JFS_NOATIME_FL)
41 inode->i_flags |= S_NOATIME;
42 if (flags & JFS_DIRSYNC_FL)
43 inode->i_flags |= S_DIRSYNC;
44 if (flags & JFS_SYNC_FL)
45 inode->i_flags |= S_SYNC;
46}
47
28/* 48/*
29 * NAME: ialloc() 49 * NAME: ialloc()
30 * 50 *
@@ -63,6 +83,13 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
63 inode->i_gid = current->fsgid; 83 inode->i_gid = current->fsgid;
64 84
65 /* 85 /*
86 * New inodes need to save sane values on disk when
87 * uid & gid mount options are used
88 */
89 jfs_inode->saved_uid = inode->i_uid;
90 jfs_inode->saved_gid = inode->i_gid;
91
92 /*
66 * Allocate inode to quota. 93 * Allocate inode to quota.
67 */ 94 */
68 if (DQUOT_ALLOC_INODE(inode)) { 95 if (DQUOT_ALLOC_INODE(inode)) {
@@ -74,10 +101,20 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
74 } 101 }
75 102
76 inode->i_mode = mode; 103 inode->i_mode = mode;
77 if (S_ISDIR(mode)) 104 /* inherit flags from parent */
78 jfs_inode->mode2 = IDIRECTORY | mode; 105 jfs_inode->mode2 = JFS_IP(parent)->mode2 & JFS_FL_INHERIT;
79 else 106
80 jfs_inode->mode2 = INLINEEA | ISPARSE | mode; 107 if (S_ISDIR(mode)) {
108 jfs_inode->mode2 |= IDIRECTORY;
109 jfs_inode->mode2 &= ~JFS_DIRSYNC_FL;
110 }
111 else {
112 jfs_inode->mode2 |= INLINEEA | ISPARSE;
113 if (S_ISLNK(mode))
114 jfs_inode->mode2 &= ~(JFS_IMMUTABLE_FL|JFS_APPEND_FL);
115 }
116 jfs_inode->mode2 |= mode;
117
81 inode->i_blksize = sb->s_blocksize; 118 inode->i_blksize = sb->s_blocksize;
82 inode->i_blocks = 0; 119 inode->i_blocks = 0;
83 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 120 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
@@ -98,6 +135,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
98 jfs_inode->atlhead = 0; 135 jfs_inode->atlhead = 0;
99 jfs_inode->atltail = 0; 136 jfs_inode->atltail = 0;
100 jfs_inode->xtlid = 0; 137 jfs_inode->xtlid = 0;
138 jfs_set_inode_flags(inode);
101 139
102 jfs_info("ialloc returns inode = 0x%p\n", inode); 140 jfs_info("ialloc returns inode = 0x%p\n", inode);
103 141
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index b54bac576cb3..095d471b9f9a 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -20,6 +20,8 @@
20 20
21extern struct inode *ialloc(struct inode *, umode_t); 21extern struct inode *ialloc(struct inode *, umode_t);
22extern int jfs_fsync(struct file *, struct dentry *, int); 22extern int jfs_fsync(struct file *, struct dentry *, int);
23extern int jfs_ioctl(struct inode *, struct file *,
24 unsigned int, unsigned long);
23extern void jfs_read_inode(struct inode *); 25extern void jfs_read_inode(struct inode *);
24extern int jfs_commit_inode(struct inode *, int); 26extern int jfs_commit_inode(struct inode *, int);
25extern int jfs_write_inode(struct inode*, int); 27extern int jfs_write_inode(struct inode*, int);
@@ -29,6 +31,7 @@ extern void jfs_truncate(struct inode *);
29extern void jfs_truncate_nolock(struct inode *, loff_t); 31extern void jfs_truncate_nolock(struct inode *, loff_t);
30extern void jfs_free_zero_link(struct inode *); 32extern void jfs_free_zero_link(struct inode *);
31extern struct dentry *jfs_get_parent(struct dentry *dentry); 33extern struct dentry *jfs_get_parent(struct dentry *dentry);
34extern void jfs_set_inode_flags(struct inode *);
32 35
33extern struct address_space_operations jfs_aops; 36extern struct address_space_operations jfs_aops;
34extern struct inode_operations jfs_dir_inode_operations; 37extern struct inode_operations jfs_dir_inode_operations;
diff --git a/fs/jfs/jfs_lock.h b/fs/jfs/jfs_lock.h
index 10ad1d086685..70ac9f7d1e00 100644
--- a/fs/jfs/jfs_lock.h
+++ b/fs/jfs/jfs_lock.h
@@ -20,6 +20,7 @@
20#define _H_JFS_LOCK 20#define _H_JFS_LOCK
21 21
22#include <linux/spinlock.h> 22#include <linux/spinlock.h>
23#include <linux/mutex.h>
23#include <linux/sched.h> 24#include <linux/sched.h>
24 25
25/* 26/*
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index d27bac6acaa3..0b348b13b551 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -64,6 +64,7 @@
64#include <linux/interrupt.h> 64#include <linux/interrupt.h>
65#include <linux/smp_lock.h> 65#include <linux/smp_lock.h>
66#include <linux/completion.h> 66#include <linux/completion.h>
67#include <linux/kthread.h>
67#include <linux/buffer_head.h> /* for sync_blockdev() */ 68#include <linux/buffer_head.h> /* for sync_blockdev() */
68#include <linux/bio.h> 69#include <linux/bio.h>
69#include <linux/suspend.h> 70#include <linux/suspend.h>
@@ -81,15 +82,14 @@
81 */ 82 */
82static struct lbuf *log_redrive_list; 83static struct lbuf *log_redrive_list;
83static DEFINE_SPINLOCK(log_redrive_lock); 84static DEFINE_SPINLOCK(log_redrive_lock);
84DECLARE_WAIT_QUEUE_HEAD(jfs_IO_thread_wait);
85 85
86 86
87/* 87/*
88 * log read/write serialization (per log) 88 * log read/write serialization (per log)
89 */ 89 */
90#define LOG_LOCK_INIT(log) init_MUTEX(&(log)->loglock) 90#define LOG_LOCK_INIT(log) mutex_init(&(log)->loglock)
91#define LOG_LOCK(log) down(&((log)->loglock)) 91#define LOG_LOCK(log) mutex_lock(&((log)->loglock))
92#define LOG_UNLOCK(log) up(&((log)->loglock)) 92#define LOG_UNLOCK(log) mutex_unlock(&((log)->loglock))
93 93
94 94
95/* 95/*
@@ -1105,11 +1105,10 @@ int lmLogOpen(struct super_block *sb)
1105 } 1105 }
1106 } 1106 }
1107 1107
1108 if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL))) { 1108 if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL))) {
1109 up(&jfs_log_sem); 1109 up(&jfs_log_sem);
1110 return -ENOMEM; 1110 return -ENOMEM;
1111 } 1111 }
1112 memset(log, 0, sizeof(struct jfs_log));
1113 INIT_LIST_HEAD(&log->sb_list); 1112 INIT_LIST_HEAD(&log->sb_list);
1114 init_waitqueue_head(&log->syncwait); 1113 init_waitqueue_head(&log->syncwait);
1115 1114
@@ -1181,9 +1180,8 @@ static int open_inline_log(struct super_block *sb)
1181 struct jfs_log *log; 1180 struct jfs_log *log;
1182 int rc; 1181 int rc;
1183 1182
1184 if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL))) 1183 if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL)))
1185 return -ENOMEM; 1184 return -ENOMEM;
1186 memset(log, 0, sizeof(struct jfs_log));
1187 INIT_LIST_HEAD(&log->sb_list); 1185 INIT_LIST_HEAD(&log->sb_list);
1188 init_waitqueue_head(&log->syncwait); 1186 init_waitqueue_head(&log->syncwait);
1189 1187
@@ -1216,12 +1214,11 @@ static int open_dummy_log(struct super_block *sb)
1216 1214
1217 down(&jfs_log_sem); 1215 down(&jfs_log_sem);
1218 if (!dummy_log) { 1216 if (!dummy_log) {
1219 dummy_log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL); 1217 dummy_log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL);
1220 if (!dummy_log) { 1218 if (!dummy_log) {
1221 up(&jfs_log_sem); 1219 up(&jfs_log_sem);
1222 return -ENOMEM; 1220 return -ENOMEM;
1223 } 1221 }
1224 memset(dummy_log, 0, sizeof(struct jfs_log));
1225 INIT_LIST_HEAD(&dummy_log->sb_list); 1222 INIT_LIST_HEAD(&dummy_log->sb_list);
1226 init_waitqueue_head(&dummy_log->syncwait); 1223 init_waitqueue_head(&dummy_log->syncwait);
1227 dummy_log->no_integrity = 1; 1224 dummy_log->no_integrity = 1;
@@ -1980,7 +1977,7 @@ static inline void lbmRedrive(struct lbuf *bp)
1980 log_redrive_list = bp; 1977 log_redrive_list = bp;
1981 spin_unlock_irqrestore(&log_redrive_lock, flags); 1978 spin_unlock_irqrestore(&log_redrive_lock, flags);
1982 1979
1983 wake_up(&jfs_IO_thread_wait); 1980 wake_up_process(jfsIOthread);
1984} 1981}
1985 1982
1986 1983
@@ -2347,13 +2344,7 @@ int jfsIOWait(void *arg)
2347{ 2344{
2348 struct lbuf *bp; 2345 struct lbuf *bp;
2349 2346
2350 daemonize("jfsIO");
2351
2352 complete(&jfsIOwait);
2353
2354 do { 2347 do {
2355 DECLARE_WAITQUEUE(wq, current);
2356
2357 spin_lock_irq(&log_redrive_lock); 2348 spin_lock_irq(&log_redrive_lock);
2358 while ((bp = log_redrive_list) != 0) { 2349 while ((bp = log_redrive_list) != 0) {
2359 log_redrive_list = bp->l_redrive_next; 2350 log_redrive_list = bp->l_redrive_next;
@@ -2362,21 +2353,19 @@ int jfsIOWait(void *arg)
2362 lbmStartIO(bp); 2353 lbmStartIO(bp);
2363 spin_lock_irq(&log_redrive_lock); 2354 spin_lock_irq(&log_redrive_lock);
2364 } 2355 }
2356 spin_unlock_irq(&log_redrive_lock);
2357
2365 if (freezing(current)) { 2358 if (freezing(current)) {
2366 spin_unlock_irq(&log_redrive_lock);
2367 refrigerator(); 2359 refrigerator();
2368 } else { 2360 } else {
2369 add_wait_queue(&jfs_IO_thread_wait, &wq);
2370 set_current_state(TASK_INTERRUPTIBLE); 2361 set_current_state(TASK_INTERRUPTIBLE);
2371 spin_unlock_irq(&log_redrive_lock);
2372 schedule(); 2362 schedule();
2373 current->state = TASK_RUNNING; 2363 current->state = TASK_RUNNING;
2374 remove_wait_queue(&jfs_IO_thread_wait, &wq);
2375 } 2364 }
2376 } while (!jfs_stop_threads); 2365 } while (!kthread_should_stop());
2377 2366
2378 jfs_info("jfsIOWait being killed!"); 2367 jfs_info("jfsIOWait being killed!");
2379 complete_and_exit(&jfsIOwait, 0); 2368 return 0;
2380} 2369}
2381 2370
2382/* 2371/*
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
index e4978b5b65ee..8c6909b80014 100644
--- a/fs/jfs/jfs_logmgr.h
+++ b/fs/jfs/jfs_logmgr.h
@@ -389,7 +389,7 @@ struct jfs_log {
389 int eor; /* 4: eor of last record in eol page */ 389 int eor; /* 4: eor of last record in eol page */
390 struct lbuf *bp; /* 4: current log page buffer */ 390 struct lbuf *bp; /* 4: current log page buffer */
391 391
392 struct semaphore loglock; /* 4: log write serialization lock */ 392 struct mutex loglock; /* 4: log write serialization lock */
393 393
394 /* syncpt */ 394 /* syncpt */
395 int nextsync; /* 4: bytes to write before next syncpt */ 395 int nextsync; /* 4: bytes to write before next syncpt */
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 8a53981f9f27..5fbaeaadccd3 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -104,10 +104,9 @@ static inline int insert_metapage(struct page *page, struct metapage *mp)
104 if (PagePrivate(page)) 104 if (PagePrivate(page))
105 a = mp_anchor(page); 105 a = mp_anchor(page);
106 else { 106 else {
107 a = kmalloc(sizeof(struct meta_anchor), GFP_NOFS); 107 a = kzalloc(sizeof(struct meta_anchor), GFP_NOFS);
108 if (!a) 108 if (!a)
109 return -ENOMEM; 109 return -ENOMEM;
110 memset(a, 0, sizeof(struct meta_anchor));
111 set_page_private(page, (unsigned long)a); 110 set_page_private(page, (unsigned long)a);
112 SetPagePrivate(page); 111 SetPagePrivate(page);
113 kmap(page); 112 kmap(page);
diff --git a/fs/jfs/jfs_superblock.h b/fs/jfs/jfs_superblock.h
index fcf781bf31cb..682cf1a68a18 100644
--- a/fs/jfs/jfs_superblock.h
+++ b/fs/jfs/jfs_superblock.h
@@ -113,12 +113,9 @@ extern int jfs_mount(struct super_block *);
113extern int jfs_mount_rw(struct super_block *, int); 113extern int jfs_mount_rw(struct super_block *, int);
114extern int jfs_umount(struct super_block *); 114extern int jfs_umount(struct super_block *);
115extern int jfs_umount_rw(struct super_block *); 115extern int jfs_umount_rw(struct super_block *);
116
117extern int jfs_stop_threads;
118extern struct completion jfsIOwait;
119extern wait_queue_head_t jfs_IO_thread_wait;
120extern wait_queue_head_t jfs_commit_thread_wait;
121extern wait_queue_head_t jfs_sync_thread_wait;
122extern int jfs_extendfs(struct super_block *, s64, int); 116extern int jfs_extendfs(struct super_block *, s64, int);
123 117
118extern struct task_struct *jfsIOthread;
119extern struct task_struct *jfsSyncThread;
120
124#endif /*_H_JFS_SUPERBLOCK */ 121#endif /*_H_JFS_SUPERBLOCK */
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 2ddb6b892bcf..ac3d66948e8c 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -49,6 +49,7 @@
49#include <linux/suspend.h> 49#include <linux/suspend.h>
50#include <linux/module.h> 50#include <linux/module.h>
51#include <linux/moduleparam.h> 51#include <linux/moduleparam.h>
52#include <linux/kthread.h>
52#include "jfs_incore.h" 53#include "jfs_incore.h"
53#include "jfs_inode.h" 54#include "jfs_inode.h"
54#include "jfs_filsys.h" 55#include "jfs_filsys.h"
@@ -121,8 +122,7 @@ static DEFINE_SPINLOCK(jfsTxnLock);
121#define LAZY_LOCK(flags) spin_lock_irqsave(&TxAnchor.LazyLock, flags) 122#define LAZY_LOCK(flags) spin_lock_irqsave(&TxAnchor.LazyLock, flags)
122#define LAZY_UNLOCK(flags) spin_unlock_irqrestore(&TxAnchor.LazyLock, flags) 123#define LAZY_UNLOCK(flags) spin_unlock_irqrestore(&TxAnchor.LazyLock, flags)
123 124
124DECLARE_WAIT_QUEUE_HEAD(jfs_sync_thread_wait); 125static DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait);
125DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait);
126static int jfs_commit_thread_waking; 126static int jfs_commit_thread_waking;
127 127
128/* 128/*
@@ -207,7 +207,7 @@ static lid_t txLockAlloc(void)
207 if ((++TxAnchor.tlocksInUse > TxLockHWM) && (jfs_tlocks_low == 0)) { 207 if ((++TxAnchor.tlocksInUse > TxLockHWM) && (jfs_tlocks_low == 0)) {
208 jfs_info("txLockAlloc tlocks low"); 208 jfs_info("txLockAlloc tlocks low");
209 jfs_tlocks_low = 1; 209 jfs_tlocks_low = 1;
210 wake_up(&jfs_sync_thread_wait); 210 wake_up_process(jfsSyncThread);
211 } 211 }
212 212
213 return lid; 213 return lid;
@@ -2743,10 +2743,6 @@ int jfs_lazycommit(void *arg)
2743 unsigned long flags; 2743 unsigned long flags;
2744 struct jfs_sb_info *sbi; 2744 struct jfs_sb_info *sbi;
2745 2745
2746 daemonize("jfsCommit");
2747
2748 complete(&jfsIOwait);
2749
2750 do { 2746 do {
2751 LAZY_LOCK(flags); 2747 LAZY_LOCK(flags);
2752 jfs_commit_thread_waking = 0; /* OK to wake another thread */ 2748 jfs_commit_thread_waking = 0; /* OK to wake another thread */
@@ -2806,13 +2802,13 @@ int jfs_lazycommit(void *arg)
2806 current->state = TASK_RUNNING; 2802 current->state = TASK_RUNNING;
2807 remove_wait_queue(&jfs_commit_thread_wait, &wq); 2803 remove_wait_queue(&jfs_commit_thread_wait, &wq);
2808 } 2804 }
2809 } while (!jfs_stop_threads); 2805 } while (!kthread_should_stop());
2810 2806
2811 if (!list_empty(&TxAnchor.unlock_queue)) 2807 if (!list_empty(&TxAnchor.unlock_queue))
2812 jfs_err("jfs_lazycommit being killed w/pending transactions!"); 2808 jfs_err("jfs_lazycommit being killed w/pending transactions!");
2813 else 2809 else
2814 jfs_info("jfs_lazycommit being killed\n"); 2810 jfs_info("jfs_lazycommit being killed\n");
2815 complete_and_exit(&jfsIOwait, 0); 2811 return 0;
2816} 2812}
2817 2813
2818void txLazyUnlock(struct tblock * tblk) 2814void txLazyUnlock(struct tblock * tblk)
@@ -2876,10 +2872,10 @@ restart:
2876 */ 2872 */
2877 TXN_UNLOCK(); 2873 TXN_UNLOCK();
2878 tid = txBegin(ip->i_sb, COMMIT_INODE | COMMIT_FORCE); 2874 tid = txBegin(ip->i_sb, COMMIT_INODE | COMMIT_FORCE);
2879 down(&jfs_ip->commit_sem); 2875 mutex_lock(&jfs_ip->commit_mutex);
2880 txCommit(tid, 1, &ip, 0); 2876 txCommit(tid, 1, &ip, 0);
2881 txEnd(tid); 2877 txEnd(tid);
2882 up(&jfs_ip->commit_sem); 2878 mutex_unlock(&jfs_ip->commit_mutex);
2883 /* 2879 /*
2884 * Just to be safe. I don't know how 2880 * Just to be safe. I don't know how
2885 * long we can run without blocking 2881 * long we can run without blocking
@@ -2932,10 +2928,6 @@ int jfs_sync(void *arg)
2932 int rc; 2928 int rc;
2933 tid_t tid; 2929 tid_t tid;
2934 2930
2935 daemonize("jfsSync");
2936
2937 complete(&jfsIOwait);
2938
2939 do { 2931 do {
2940 /* 2932 /*
2941 * write each inode on the anonymous inode list 2933 * write each inode on the anonymous inode list
@@ -2952,7 +2944,7 @@ int jfs_sync(void *arg)
2952 * Inode is being freed 2944 * Inode is being freed
2953 */ 2945 */
2954 list_del_init(&jfs_ip->anon_inode_list); 2946 list_del_init(&jfs_ip->anon_inode_list);
2955 } else if (! down_trylock(&jfs_ip->commit_sem)) { 2947 } else if (! !mutex_trylock(&jfs_ip->commit_mutex)) {
2956 /* 2948 /*
2957 * inode will be removed from anonymous list 2949 * inode will be removed from anonymous list
2958 * when it is committed 2950 * when it is committed
@@ -2961,7 +2953,7 @@ int jfs_sync(void *arg)
2961 tid = txBegin(ip->i_sb, COMMIT_INODE); 2953 tid = txBegin(ip->i_sb, COMMIT_INODE);
2962 rc = txCommit(tid, 1, &ip, 0); 2954 rc = txCommit(tid, 1, &ip, 0);
2963 txEnd(tid); 2955 txEnd(tid);
2964 up(&jfs_ip->commit_sem); 2956 mutex_unlock(&jfs_ip->commit_mutex);
2965 2957
2966 iput(ip); 2958 iput(ip);
2967 /* 2959 /*
@@ -2971,7 +2963,7 @@ int jfs_sync(void *arg)
2971 cond_resched(); 2963 cond_resched();
2972 TXN_LOCK(); 2964 TXN_LOCK();
2973 } else { 2965 } else {
2974 /* We can't get the commit semaphore. It may 2966 /* We can't get the commit mutex. It may
2975 * be held by a thread waiting for tlock's 2967 * be held by a thread waiting for tlock's
2976 * so let's not block here. Save it to 2968 * so let's not block here. Save it to
2977 * put back on the anon_list. 2969 * put back on the anon_list.
@@ -2996,19 +2988,15 @@ int jfs_sync(void *arg)
2996 TXN_UNLOCK(); 2988 TXN_UNLOCK();
2997 refrigerator(); 2989 refrigerator();
2998 } else { 2990 } else {
2999 DECLARE_WAITQUEUE(wq, current);
3000
3001 add_wait_queue(&jfs_sync_thread_wait, &wq);
3002 set_current_state(TASK_INTERRUPTIBLE); 2991 set_current_state(TASK_INTERRUPTIBLE);
3003 TXN_UNLOCK(); 2992 TXN_UNLOCK();
3004 schedule(); 2993 schedule();
3005 current->state = TASK_RUNNING; 2994 current->state = TASK_RUNNING;
3006 remove_wait_queue(&jfs_sync_thread_wait, &wq);
3007 } 2995 }
3008 } while (!jfs_stop_threads); 2996 } while (!kthread_should_stop());
3009 2997
3010 jfs_info("jfs_sync being killed"); 2998 jfs_info("jfs_sync being killed");
3011 complete_and_exit(&jfsIOwait, 0); 2999 return 0;
3012} 3000}
3013 3001
3014#if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_DEBUG) 3002#if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_DEBUG)
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 4abbe8604302..309cee575f7d 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -104,8 +104,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
104 104
105 tid = txBegin(dip->i_sb, 0); 105 tid = txBegin(dip->i_sb, 0);
106 106
107 down(&JFS_IP(dip)->commit_sem); 107 mutex_lock(&JFS_IP(dip)->commit_mutex);
108 down(&JFS_IP(ip)->commit_sem); 108 mutex_lock(&JFS_IP(ip)->commit_mutex);
109 109
110 rc = jfs_init_acl(tid, ip, dip); 110 rc = jfs_init_acl(tid, ip, dip);
111 if (rc) 111 if (rc)
@@ -165,8 +165,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
165 165
166 out3: 166 out3:
167 txEnd(tid); 167 txEnd(tid);
168 up(&JFS_IP(dip)->commit_sem); 168 mutex_unlock(&JFS_IP(dip)->commit_mutex);
169 up(&JFS_IP(ip)->commit_sem); 169 mutex_unlock(&JFS_IP(ip)->commit_mutex);
170 if (rc) { 170 if (rc) {
171 free_ea_wmap(ip); 171 free_ea_wmap(ip);
172 ip->i_nlink = 0; 172 ip->i_nlink = 0;
@@ -238,8 +238,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
238 238
239 tid = txBegin(dip->i_sb, 0); 239 tid = txBegin(dip->i_sb, 0);
240 240
241 down(&JFS_IP(dip)->commit_sem); 241 mutex_lock(&JFS_IP(dip)->commit_mutex);
242 down(&JFS_IP(ip)->commit_sem); 242 mutex_lock(&JFS_IP(ip)->commit_mutex);
243 243
244 rc = jfs_init_acl(tid, ip, dip); 244 rc = jfs_init_acl(tid, ip, dip);
245 if (rc) 245 if (rc)
@@ -300,8 +300,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
300 300
301 out3: 301 out3:
302 txEnd(tid); 302 txEnd(tid);
303 up(&JFS_IP(dip)->commit_sem); 303 mutex_unlock(&JFS_IP(dip)->commit_mutex);
304 up(&JFS_IP(ip)->commit_sem); 304 mutex_unlock(&JFS_IP(ip)->commit_mutex);
305 if (rc) { 305 if (rc) {
306 free_ea_wmap(ip); 306 free_ea_wmap(ip);
307 ip->i_nlink = 0; 307 ip->i_nlink = 0;
@@ -365,8 +365,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
365 365
366 tid = txBegin(dip->i_sb, 0); 366 tid = txBegin(dip->i_sb, 0);
367 367
368 down(&JFS_IP(dip)->commit_sem); 368 mutex_lock(&JFS_IP(dip)->commit_mutex);
369 down(&JFS_IP(ip)->commit_sem); 369 mutex_lock(&JFS_IP(ip)->commit_mutex);
370 370
371 iplist[0] = dip; 371 iplist[0] = dip;
372 iplist[1] = ip; 372 iplist[1] = ip;
@@ -384,8 +384,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
384 if (rc == -EIO) 384 if (rc == -EIO)
385 txAbort(tid, 1); 385 txAbort(tid, 1);
386 txEnd(tid); 386 txEnd(tid);
387 up(&JFS_IP(dip)->commit_sem); 387 mutex_unlock(&JFS_IP(dip)->commit_mutex);
388 up(&JFS_IP(ip)->commit_sem); 388 mutex_unlock(&JFS_IP(ip)->commit_mutex);
389 389
390 goto out2; 390 goto out2;
391 } 391 }
@@ -422,8 +422,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
422 422
423 txEnd(tid); 423 txEnd(tid);
424 424
425 up(&JFS_IP(dip)->commit_sem); 425 mutex_unlock(&JFS_IP(dip)->commit_mutex);
426 up(&JFS_IP(ip)->commit_sem); 426 mutex_unlock(&JFS_IP(ip)->commit_mutex);
427 427
428 /* 428 /*
429 * Truncating the directory index table is not guaranteed. It 429 * Truncating the directory index table is not guaranteed. It
@@ -488,8 +488,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
488 488
489 tid = txBegin(dip->i_sb, 0); 489 tid = txBegin(dip->i_sb, 0);
490 490
491 down(&JFS_IP(dip)->commit_sem); 491 mutex_lock(&JFS_IP(dip)->commit_mutex);
492 down(&JFS_IP(ip)->commit_sem); 492 mutex_lock(&JFS_IP(ip)->commit_mutex);
493 493
494 iplist[0] = dip; 494 iplist[0] = dip;
495 iplist[1] = ip; 495 iplist[1] = ip;
@@ -503,8 +503,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
503 if (rc == -EIO) 503 if (rc == -EIO)
504 txAbort(tid, 1); /* Marks FS Dirty */ 504 txAbort(tid, 1); /* Marks FS Dirty */
505 txEnd(tid); 505 txEnd(tid);
506 up(&JFS_IP(dip)->commit_sem); 506 mutex_unlock(&JFS_IP(dip)->commit_mutex);
507 up(&JFS_IP(ip)->commit_sem); 507 mutex_unlock(&JFS_IP(ip)->commit_mutex);
508 IWRITE_UNLOCK(ip); 508 IWRITE_UNLOCK(ip);
509 goto out1; 509 goto out1;
510 } 510 }
@@ -527,8 +527,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
527 if ((new_size = commitZeroLink(tid, ip)) < 0) { 527 if ((new_size = commitZeroLink(tid, ip)) < 0) {
528 txAbort(tid, 1); /* Marks FS Dirty */ 528 txAbort(tid, 1); /* Marks FS Dirty */
529 txEnd(tid); 529 txEnd(tid);
530 up(&JFS_IP(dip)->commit_sem); 530 mutex_unlock(&JFS_IP(dip)->commit_mutex);
531 up(&JFS_IP(ip)->commit_sem); 531 mutex_unlock(&JFS_IP(ip)->commit_mutex);
532 IWRITE_UNLOCK(ip); 532 IWRITE_UNLOCK(ip);
533 rc = new_size; 533 rc = new_size;
534 goto out1; 534 goto out1;
@@ -556,13 +556,13 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
556 556
557 txEnd(tid); 557 txEnd(tid);
558 558
559 up(&JFS_IP(dip)->commit_sem); 559 mutex_unlock(&JFS_IP(dip)->commit_mutex);
560 up(&JFS_IP(ip)->commit_sem); 560 mutex_unlock(&JFS_IP(ip)->commit_mutex);
561 561
562 562
563 while (new_size && (rc == 0)) { 563 while (new_size && (rc == 0)) {
564 tid = txBegin(dip->i_sb, 0); 564 tid = txBegin(dip->i_sb, 0);
565 down(&JFS_IP(ip)->commit_sem); 565 mutex_lock(&JFS_IP(ip)->commit_mutex);
566 new_size = xtTruncate_pmap(tid, ip, new_size); 566 new_size = xtTruncate_pmap(tid, ip, new_size);
567 if (new_size < 0) { 567 if (new_size < 0) {
568 txAbort(tid, 1); /* Marks FS Dirty */ 568 txAbort(tid, 1); /* Marks FS Dirty */
@@ -570,7 +570,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
570 } else 570 } else
571 rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC); 571 rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
572 txEnd(tid); 572 txEnd(tid);
573 up(&JFS_IP(ip)->commit_sem); 573 mutex_unlock(&JFS_IP(ip)->commit_mutex);
574 } 574 }
575 575
576 if (ip->i_nlink == 0) 576 if (ip->i_nlink == 0)
@@ -805,8 +805,8 @@ static int jfs_link(struct dentry *old_dentry,
805 805
806 tid = txBegin(ip->i_sb, 0); 806 tid = txBegin(ip->i_sb, 0);
807 807
808 down(&JFS_IP(dir)->commit_sem); 808 mutex_lock(&JFS_IP(dir)->commit_mutex);
809 down(&JFS_IP(ip)->commit_sem); 809 mutex_lock(&JFS_IP(ip)->commit_mutex);
810 810
811 /* 811 /*
812 * scan parent directory for entry/freespace 812 * scan parent directory for entry/freespace
@@ -847,8 +847,8 @@ static int jfs_link(struct dentry *old_dentry,
847 out: 847 out:
848 txEnd(tid); 848 txEnd(tid);
849 849
850 up(&JFS_IP(dir)->commit_sem); 850 mutex_unlock(&JFS_IP(dir)->commit_mutex);
851 up(&JFS_IP(ip)->commit_sem); 851 mutex_unlock(&JFS_IP(ip)->commit_mutex);
852 852
853 jfs_info("jfs_link: rc:%d", rc); 853 jfs_info("jfs_link: rc:%d", rc);
854 return rc; 854 return rc;
@@ -916,8 +916,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
916 916
917 tid = txBegin(dip->i_sb, 0); 917 tid = txBegin(dip->i_sb, 0);
918 918
919 down(&JFS_IP(dip)->commit_sem); 919 mutex_lock(&JFS_IP(dip)->commit_mutex);
920 down(&JFS_IP(ip)->commit_sem); 920 mutex_lock(&JFS_IP(ip)->commit_mutex);
921 921
922 rc = jfs_init_security(tid, ip, dip); 922 rc = jfs_init_security(tid, ip, dip);
923 if (rc) 923 if (rc)
@@ -1037,8 +1037,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
1037 1037
1038 out3: 1038 out3:
1039 txEnd(tid); 1039 txEnd(tid);
1040 up(&JFS_IP(dip)->commit_sem); 1040 mutex_unlock(&JFS_IP(dip)->commit_mutex);
1041 up(&JFS_IP(ip)->commit_sem); 1041 mutex_unlock(&JFS_IP(ip)->commit_mutex);
1042 if (rc) { 1042 if (rc) {
1043 free_ea_wmap(ip); 1043 free_ea_wmap(ip);
1044 ip->i_nlink = 0; 1044 ip->i_nlink = 0;
@@ -1141,13 +1141,13 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1141 */ 1141 */
1142 tid = txBegin(new_dir->i_sb, 0); 1142 tid = txBegin(new_dir->i_sb, 0);
1143 1143
1144 down(&JFS_IP(new_dir)->commit_sem); 1144 mutex_lock(&JFS_IP(new_dir)->commit_mutex);
1145 down(&JFS_IP(old_ip)->commit_sem); 1145 mutex_lock(&JFS_IP(old_ip)->commit_mutex);
1146 if (old_dir != new_dir) 1146 if (old_dir != new_dir)
1147 down(&JFS_IP(old_dir)->commit_sem); 1147 mutex_lock(&JFS_IP(old_dir)->commit_mutex);
1148 1148
1149 if (new_ip) { 1149 if (new_ip) {
1150 down(&JFS_IP(new_ip)->commit_sem); 1150 mutex_lock(&JFS_IP(new_ip)->commit_mutex);
1151 /* 1151 /*
1152 * Change existing directory entry to new inode number 1152 * Change existing directory entry to new inode number
1153 */ 1153 */
@@ -1160,10 +1160,10 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1160 if (S_ISDIR(new_ip->i_mode)) { 1160 if (S_ISDIR(new_ip->i_mode)) {
1161 new_ip->i_nlink--; 1161 new_ip->i_nlink--;
1162 if (new_ip->i_nlink) { 1162 if (new_ip->i_nlink) {
1163 up(&JFS_IP(new_dir)->commit_sem); 1163 mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
1164 up(&JFS_IP(old_ip)->commit_sem); 1164 mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
1165 if (old_dir != new_dir) 1165 if (old_dir != new_dir)
1166 up(&JFS_IP(old_dir)->commit_sem); 1166 mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
1167 if (!S_ISDIR(old_ip->i_mode) && new_ip) 1167 if (!S_ISDIR(old_ip->i_mode) && new_ip)
1168 IWRITE_UNLOCK(new_ip); 1168 IWRITE_UNLOCK(new_ip);
1169 jfs_error(new_ip->i_sb, 1169 jfs_error(new_ip->i_sb,
@@ -1282,16 +1282,16 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1282 out4: 1282 out4:
1283 txEnd(tid); 1283 txEnd(tid);
1284 1284
1285 up(&JFS_IP(new_dir)->commit_sem); 1285 mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
1286 up(&JFS_IP(old_ip)->commit_sem); 1286 mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
1287 if (old_dir != new_dir) 1287 if (old_dir != new_dir)
1288 up(&JFS_IP(old_dir)->commit_sem); 1288 mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
1289 if (new_ip) 1289 if (new_ip)
1290 up(&JFS_IP(new_ip)->commit_sem); 1290 mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1291 1291
1292 while (new_size && (rc == 0)) { 1292 while (new_size && (rc == 0)) {
1293 tid = txBegin(new_ip->i_sb, 0); 1293 tid = txBegin(new_ip->i_sb, 0);
1294 down(&JFS_IP(new_ip)->commit_sem); 1294 mutex_lock(&JFS_IP(new_ip)->commit_mutex);
1295 new_size = xtTruncate_pmap(tid, new_ip, new_size); 1295 new_size = xtTruncate_pmap(tid, new_ip, new_size);
1296 if (new_size < 0) { 1296 if (new_size < 0) {
1297 txAbort(tid, 1); 1297 txAbort(tid, 1);
@@ -1299,7 +1299,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1299 } else 1299 } else
1300 rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC); 1300 rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
1301 txEnd(tid); 1301 txEnd(tid);
1302 up(&JFS_IP(new_ip)->commit_sem); 1302 mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
1303 } 1303 }
1304 if (new_ip && (new_ip->i_nlink == 0)) 1304 if (new_ip && (new_ip->i_nlink == 0))
1305 set_cflag(COMMIT_Nolink, new_ip); 1305 set_cflag(COMMIT_Nolink, new_ip);
@@ -1361,8 +1361,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
1361 1361
1362 tid = txBegin(dir->i_sb, 0); 1362 tid = txBegin(dir->i_sb, 0);
1363 1363
1364 down(&JFS_IP(dir)->commit_sem); 1364 mutex_lock(&JFS_IP(dir)->commit_mutex);
1365 down(&JFS_IP(ip)->commit_sem); 1365 mutex_lock(&JFS_IP(ip)->commit_mutex);
1366 1366
1367 rc = jfs_init_acl(tid, ip, dir); 1367 rc = jfs_init_acl(tid, ip, dir);
1368 if (rc) 1368 if (rc)
@@ -1407,8 +1407,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
1407 1407
1408 out3: 1408 out3:
1409 txEnd(tid); 1409 txEnd(tid);
1410 up(&JFS_IP(ip)->commit_sem); 1410 mutex_unlock(&JFS_IP(ip)->commit_mutex);
1411 up(&JFS_IP(dir)->commit_sem); 1411 mutex_unlock(&JFS_IP(dir)->commit_mutex);
1412 if (rc) { 1412 if (rc) {
1413 free_ea_wmap(ip); 1413 free_ea_wmap(ip);
1414 ip->i_nlink = 0; 1414 ip->i_nlink = 0;
@@ -1523,6 +1523,7 @@ struct file_operations jfs_dir_operations = {
1523 .read = generic_read_dir, 1523 .read = generic_read_dir,
1524 .readdir = jfs_readdir, 1524 .readdir = jfs_readdir,
1525 .fsync = jfs_fsync, 1525 .fsync = jfs_fsync,
1526 .ioctl = jfs_ioctl,
1526}; 1527};
1527 1528
1528static int jfs_ci_hash(struct dentry *dir, struct qstr *this) 1529static int jfs_ci_hash(struct dentry *dir, struct qstr *this)
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 8d31f1336431..18f69e6aa719 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -25,6 +25,7 @@
25#include <linux/vfs.h> 25#include <linux/vfs.h>
26#include <linux/mount.h> 26#include <linux/mount.h>
27#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
28#include <linux/kthread.h>
28#include <linux/posix_acl.h> 29#include <linux/posix_acl.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30#include <linux/seq_file.h> 31#include <linux/seq_file.h>
@@ -54,11 +55,9 @@ static int commit_threads = 0;
54module_param(commit_threads, int, 0); 55module_param(commit_threads, int, 0);
55MODULE_PARM_DESC(commit_threads, "Number of commit threads"); 56MODULE_PARM_DESC(commit_threads, "Number of commit threads");
56 57
57int jfs_stop_threads; 58static struct task_struct *jfsCommitThread[MAX_COMMIT_THREADS];
58static pid_t jfsIOthread; 59struct task_struct *jfsIOthread;
59static pid_t jfsCommitThread[MAX_COMMIT_THREADS]; 60struct task_struct *jfsSyncThread;
60static pid_t jfsSyncThread;
61DECLARE_COMPLETION(jfsIOwait);
62 61
63#ifdef CONFIG_JFS_DEBUG 62#ifdef CONFIG_JFS_DEBUG
64int jfsloglevel = JFS_LOGLEVEL_WARN; 63int jfsloglevel = JFS_LOGLEVEL_WARN;
@@ -195,7 +194,7 @@ static void jfs_put_super(struct super_block *sb)
195enum { 194enum {
196 Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, 195 Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
197 Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota, 196 Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
198 Opt_usrquota, Opt_grpquota 197 Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
199}; 198};
200 199
201static match_table_t tokens = { 200static match_table_t tokens = {
@@ -209,6 +208,9 @@ static match_table_t tokens = {
209 {Opt_ignore, "quota"}, 208 {Opt_ignore, "quota"},
210 {Opt_usrquota, "usrquota"}, 209 {Opt_usrquota, "usrquota"},
211 {Opt_grpquota, "grpquota"}, 210 {Opt_grpquota, "grpquota"},
211 {Opt_uid, "uid=%u"},
212 {Opt_gid, "gid=%u"},
213 {Opt_umask, "umask=%u"},
212 {Opt_err, NULL} 214 {Opt_err, NULL}
213}; 215};
214 216
@@ -313,7 +315,29 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
313 "JFS: quota operations not supported\n"); 315 "JFS: quota operations not supported\n");
314 break; 316 break;
315#endif 317#endif
316 318 case Opt_uid:
319 {
320 char *uid = args[0].from;
321 sbi->uid = simple_strtoul(uid, &uid, 0);
322 break;
323 }
324 case Opt_gid:
325 {
326 char *gid = args[0].from;
327 sbi->gid = simple_strtoul(gid, &gid, 0);
328 break;
329 }
330 case Opt_umask:
331 {
332 char *umask = args[0].from;
333 sbi->umask = simple_strtoul(umask, &umask, 8);
334 if (sbi->umask & ~0777) {
335 printk(KERN_ERR
336 "JFS: Invalid value of umask\n");
337 goto cleanup;
338 }
339 break;
340 }
317 default: 341 default:
318 printk("jfs: Unrecognized mount option \"%s\" " 342 printk("jfs: Unrecognized mount option \"%s\" "
319 " or missing value\n", p); 343 " or missing value\n", p);
@@ -396,12 +420,12 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
396 if (!new_valid_dev(sb->s_bdev->bd_dev)) 420 if (!new_valid_dev(sb->s_bdev->bd_dev))
397 return -EOVERFLOW; 421 return -EOVERFLOW;
398 422
399 sbi = kmalloc(sizeof (struct jfs_sb_info), GFP_KERNEL); 423 sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
400 if (!sbi) 424 if (!sbi)
401 return -ENOSPC; 425 return -ENOSPC;
402 memset(sbi, 0, sizeof (struct jfs_sb_info));
403 sb->s_fs_info = sbi; 426 sb->s_fs_info = sbi;
404 sbi->sb = sb; 427 sbi->sb = sb;
428 sbi->uid = sbi->gid = sbi->umask = -1;
405 429
406 /* initialize the mount flag and determine the default error handler */ 430 /* initialize the mount flag and determine the default error handler */
407 flag = JFS_ERR_REMOUNT_RO; 431 flag = JFS_ERR_REMOUNT_RO;
@@ -564,10 +588,14 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
564{ 588{
565 struct jfs_sb_info *sbi = JFS_SBI(vfs->mnt_sb); 589 struct jfs_sb_info *sbi = JFS_SBI(vfs->mnt_sb);
566 590
591 if (sbi->uid != -1)
592 seq_printf(seq, ",uid=%d", sbi->uid);
593 if (sbi->gid != -1)
594 seq_printf(seq, ",gid=%d", sbi->gid);
595 if (sbi->umask != -1)
596 seq_printf(seq, ",umask=%03o", sbi->umask);
567 if (sbi->flag & JFS_NOINTEGRITY) 597 if (sbi->flag & JFS_NOINTEGRITY)
568 seq_puts(seq, ",nointegrity"); 598 seq_puts(seq, ",nointegrity");
569 else
570 seq_puts(seq, ",integrity");
571 599
572#if defined(CONFIG_QUOTA) 600#if defined(CONFIG_QUOTA)
573 if (sbi->flag & JFS_USRQUOTA) 601 if (sbi->flag & JFS_USRQUOTA)
@@ -617,7 +645,7 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
617 memset(jfs_ip, 0, sizeof(struct jfs_inode_info)); 645 memset(jfs_ip, 0, sizeof(struct jfs_inode_info));
618 INIT_LIST_HEAD(&jfs_ip->anon_inode_list); 646 INIT_LIST_HEAD(&jfs_ip->anon_inode_list);
619 init_rwsem(&jfs_ip->rdwrlock); 647 init_rwsem(&jfs_ip->rdwrlock);
620 init_MUTEX(&jfs_ip->commit_sem); 648 mutex_init(&jfs_ip->commit_mutex);
621 init_rwsem(&jfs_ip->xattr_sem); 649 init_rwsem(&jfs_ip->xattr_sem);
622 spin_lock_init(&jfs_ip->ag_lock); 650 spin_lock_init(&jfs_ip->ag_lock);
623 jfs_ip->active_ag = -1; 651 jfs_ip->active_ag = -1;
@@ -661,12 +689,12 @@ static int __init init_jfs_fs(void)
661 /* 689 /*
662 * I/O completion thread (endio) 690 * I/O completion thread (endio)
663 */ 691 */
664 jfsIOthread = kernel_thread(jfsIOWait, NULL, CLONE_KERNEL); 692 jfsIOthread = kthread_run(jfsIOWait, NULL, "jfsIO");
665 if (jfsIOthread < 0) { 693 if (IS_ERR(jfsIOthread)) {
666 jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread); 694 rc = PTR_ERR(jfsIOthread);
695 jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
667 goto end_txmngr; 696 goto end_txmngr;
668 } 697 }
669 wait_for_completion(&jfsIOwait); /* Wait until thread starts */
670 698
671 if (commit_threads < 1) 699 if (commit_threads < 1)
672 commit_threads = num_online_cpus(); 700 commit_threads = num_online_cpus();
@@ -674,24 +702,21 @@ static int __init init_jfs_fs(void)
674 commit_threads = MAX_COMMIT_THREADS; 702 commit_threads = MAX_COMMIT_THREADS;
675 703
676 for (i = 0; i < commit_threads; i++) { 704 for (i = 0; i < commit_threads; i++) {
677 jfsCommitThread[i] = kernel_thread(jfs_lazycommit, NULL, 705 jfsCommitThread[i] = kthread_run(jfs_lazycommit, NULL, "jfsCommit");
678 CLONE_KERNEL); 706 if (IS_ERR(jfsCommitThread[i])) {
679 if (jfsCommitThread[i] < 0) { 707 rc = PTR_ERR(jfsCommitThread[i]);
680 jfs_err("init_jfs_fs: fork failed w/rc = %d", 708 jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
681 jfsCommitThread[i]);
682 commit_threads = i; 709 commit_threads = i;
683 goto kill_committask; 710 goto kill_committask;
684 } 711 }
685 /* Wait until thread starts */
686 wait_for_completion(&jfsIOwait);
687 } 712 }
688 713
689 jfsSyncThread = kernel_thread(jfs_sync, NULL, CLONE_KERNEL); 714 jfsSyncThread = kthread_run(jfs_sync, NULL, "jfsSync");
690 if (jfsSyncThread < 0) { 715 if (IS_ERR(jfsSyncThread)) {
691 jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread); 716 rc = PTR_ERR(jfsSyncThread);
717 jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
692 goto kill_committask; 718 goto kill_committask;
693 } 719 }
694 wait_for_completion(&jfsIOwait); /* Wait until thread starts */
695 720
696#ifdef PROC_FS_JFS 721#ifdef PROC_FS_JFS
697 jfs_proc_init(); 722 jfs_proc_init();
@@ -700,13 +725,9 @@ static int __init init_jfs_fs(void)
700 return register_filesystem(&jfs_fs_type); 725 return register_filesystem(&jfs_fs_type);
701 726
702kill_committask: 727kill_committask:
703 jfs_stop_threads = 1;
704 wake_up_all(&jfs_commit_thread_wait);
705 for (i = 0; i < commit_threads; i++) 728 for (i = 0; i < commit_threads; i++)
706 wait_for_completion(&jfsIOwait); 729 kthread_stop(jfsCommitThread[i]);
707 730 kthread_stop(jfsIOthread);
708 wake_up(&jfs_IO_thread_wait);
709 wait_for_completion(&jfsIOwait); /* Wait for thread exit */
710end_txmngr: 731end_txmngr:
711 txExit(); 732 txExit();
712free_metapage: 733free_metapage:
@@ -722,16 +743,13 @@ static void __exit exit_jfs_fs(void)
722 743
723 jfs_info("exit_jfs_fs called"); 744 jfs_info("exit_jfs_fs called");
724 745
725 jfs_stop_threads = 1;
726 txExit(); 746 txExit();
727 metapage_exit(); 747 metapage_exit();
728 wake_up(&jfs_IO_thread_wait); 748
729 wait_for_completion(&jfsIOwait); /* Wait until IO thread exits */ 749 kthread_stop(jfsIOthread);
730 wake_up_all(&jfs_commit_thread_wait);
731 for (i = 0; i < commit_threads; i++) 750 for (i = 0; i < commit_threads; i++)
732 wait_for_completion(&jfsIOwait); 751 kthread_stop(jfsCommitThread[i]);
733 wake_up(&jfs_sync_thread_wait); 752 kthread_stop(jfsSyncThread);
734 wait_for_completion(&jfsIOwait); /* Wait until Sync thread exits */
735#ifdef PROC_FS_JFS 753#ifdef PROC_FS_JFS
736 jfs_proc_clean(); 754 jfs_proc_clean();
737#endif 755#endif
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index f23048f9471f..9bc5b7c055ce 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -934,13 +934,13 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
934 } 934 }
935 935
936 tid = txBegin(inode->i_sb, 0); 936 tid = txBegin(inode->i_sb, 0);
937 down(&ji->commit_sem); 937 mutex_lock(&ji->commit_mutex);
938 rc = __jfs_setxattr(tid, dentry->d_inode, name, value, value_len, 938 rc = __jfs_setxattr(tid, dentry->d_inode, name, value, value_len,
939 flags); 939 flags);
940 if (!rc) 940 if (!rc)
941 rc = txCommit(tid, 1, &inode, 0); 941 rc = txCommit(tid, 1, &inode, 0);
942 txEnd(tid); 942 txEnd(tid);
943 up(&ji->commit_sem); 943 mutex_unlock(&ji->commit_mutex);
944 944
945 return rc; 945 return rc;
946} 946}
@@ -1093,12 +1093,12 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
1093 return rc; 1093 return rc;
1094 1094
1095 tid = txBegin(inode->i_sb, 0); 1095 tid = txBegin(inode->i_sb, 0);
1096 down(&ji->commit_sem); 1096 mutex_lock(&ji->commit_mutex);
1097 rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); 1097 rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
1098 if (!rc) 1098 if (!rc)
1099 rc = txCommit(tid, 1, &inode, 0); 1099 rc = txCommit(tid, 1, &inode, 0);
1100 txEnd(tid); 1100 txEnd(tid);
1101 up(&ji->commit_sem); 1101 mutex_unlock(&ji->commit_mutex);
1102 1102
1103 return rc; 1103 return rc;
1104} 1104}
diff --git a/fs/namespace.c b/fs/namespace.c
index 058a44865beb..39c81a8d6316 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1338,7 +1338,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
1338 1338
1339 new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL); 1339 new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);
1340 if (!new_ns) 1340 if (!new_ns)
1341 goto out; 1341 return NULL;
1342 1342
1343 atomic_set(&new_ns->count, 1); 1343 atomic_set(&new_ns->count, 1);
1344 INIT_LIST_HEAD(&new_ns->list); 1344 INIT_LIST_HEAD(&new_ns->list);
@@ -1352,7 +1352,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
1352 if (!new_ns->root) { 1352 if (!new_ns->root) {
1353 up_write(&namespace_sem); 1353 up_write(&namespace_sem);
1354 kfree(new_ns); 1354 kfree(new_ns);
1355 goto out; 1355 return NULL;
1356 } 1356 }
1357 spin_lock(&vfsmount_lock); 1357 spin_lock(&vfsmount_lock);
1358 list_add_tail(&new_ns->list, &new_ns->root->mnt_list); 1358 list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
@@ -1393,7 +1393,6 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)
1393 if (altrootmnt) 1393 if (altrootmnt)
1394 mntput(altrootmnt); 1394 mntput(altrootmnt);
1395 1395
1396out:
1397 return new_ns; 1396 return new_ns;
1398} 1397}
1399 1398
diff --git a/fs/nfsctl.c b/fs/nfsctl.c
index 0d4cf9486068..1c72c7f85ddc 100644
--- a/fs/nfsctl.c
+++ b/fs/nfsctl.c
@@ -98,10 +98,8 @@ asmlinkage sys_nfsservctl(int cmd, struct nfsctl_arg __user *arg, void __user *r
98 if (copy_from_user(&version, &arg->ca_version, sizeof(int))) 98 if (copy_from_user(&version, &arg->ca_version, sizeof(int)))
99 return -EFAULT; 99 return -EFAULT;
100 100
101 if (version != NFSCTL_VERSION) { 101 if (version != NFSCTL_VERSION)
102 printk(KERN_WARNING "nfsd: incompatible version in syscall.\n");
103 return -EINVAL; 102 return -EINVAL;
104 }
105 103
106 if (cmd < 0 || cmd >= sizeof(map)/sizeof(map[0]) || !map[cmd].name) 104 if (cmd < 0 || cmd >= sizeof(map)/sizeof(map[0]) || !map[cmd].name)
107 return -EINVAL; 105 return -EINVAL;
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 49bd219275db..9ee956864445 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -50,6 +50,32 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
50 return sd; 50 return sd;
51} 51}
52 52
53/**
54 *
55 * Return -EEXIST if there is already a sysfs element with the same name for
56 * the same parent.
57 *
58 * called with parent inode's i_mutex held
59 */
60int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
61 const unsigned char *new)
62{
63 struct sysfs_dirent * sd;
64
65 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
66 if (sd->s_element) {
67 const unsigned char *existing = sysfs_get_name(sd);
68 if (strcmp(existing, new))
69 continue;
70 else
71 return -EEXIST;
72 }
73 }
74
75 return 0;
76}
77
78
53int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry, 79int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
54 void * element, umode_t mode, int type) 80 void * element, umode_t mode, int type)
55{ 81{
@@ -102,7 +128,11 @@ static int create_dir(struct kobject * k, struct dentry * p,
102 mutex_lock(&p->d_inode->i_mutex); 128 mutex_lock(&p->d_inode->i_mutex);
103 *d = lookup_one_len(n, p, strlen(n)); 129 *d = lookup_one_len(n, p, strlen(n));
104 if (!IS_ERR(*d)) { 130 if (!IS_ERR(*d)) {
105 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR); 131 if (sysfs_dirent_exist(p->d_fsdata, n))
132 error = -EEXIST;
133 else
134 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
135 SYSFS_DIR);
106 if (!error) { 136 if (!error) {
107 error = sysfs_create(*d, mode, init_dir); 137 error = sysfs_create(*d, mode, init_dir);
108 if (!error) { 138 if (!error) {
@@ -302,6 +332,7 @@ void sysfs_remove_dir(struct kobject * kobj)
302 * Drop reference from dget() on entrance. 332 * Drop reference from dget() on entrance.
303 */ 333 */
304 dput(dentry); 334 dput(dentry);
335 kobj->dentry = NULL;
305} 336}
306 337
307int sysfs_rename_dir(struct kobject * kobj, const char *new_name) 338int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
@@ -479,7 +510,3 @@ struct file_operations sysfs_dir_operations = {
479 .read = generic_read_dir, 510 .read = generic_read_dir,
480 .readdir = sysfs_readdir, 511 .readdir = sysfs_readdir,
481}; 512};
482
483EXPORT_SYMBOL_GPL(sysfs_create_dir);
484EXPORT_SYMBOL_GPL(sysfs_remove_dir);
485EXPORT_SYMBOL_GPL(sysfs_rename_dir);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index d0e3d8495165..5e83e7246788 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -301,9 +301,8 @@ static int check_perm(struct inode * inode, struct file * file)
301 /* No error? Great, allocate a buffer for the file, and store it 301 /* No error? Great, allocate a buffer for the file, and store it
302 * it in file->private_data for easy access. 302 * it in file->private_data for easy access.
303 */ 303 */
304 buffer = kmalloc(sizeof(struct sysfs_buffer),GFP_KERNEL); 304 buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
305 if (buffer) { 305 if (buffer) {
306 memset(buffer,0,sizeof(struct sysfs_buffer));
307 init_MUTEX(&buffer->sem); 306 init_MUTEX(&buffer->sem);
308 buffer->needs_read_fill = 1; 307 buffer->needs_read_fill = 1;
309 buffer->ops = ops; 308 buffer->ops = ops;
@@ -362,10 +361,12 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
362{ 361{
363 struct sysfs_dirent * parent_sd = dir->d_fsdata; 362 struct sysfs_dirent * parent_sd = dir->d_fsdata;
364 umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG; 363 umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
365 int error = 0; 364 int error = -EEXIST;
366 365
367 mutex_lock(&dir->d_inode->i_mutex); 366 mutex_lock(&dir->d_inode->i_mutex);
368 error = sysfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type); 367 if (!sysfs_dirent_exist(parent_sd, attr->name))
368 error = sysfs_make_dirent(parent_sd, NULL, (void *)attr,
369 mode, type);
369 mutex_unlock(&dir->d_inode->i_mutex); 370 mutex_unlock(&dir->d_inode->i_mutex);
370 371
371 return error; 372 return error;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 689f7bcfaf30..4c29ac41ac3e 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -54,11 +54,10 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
54 54
55 if (!sd_iattr) { 55 if (!sd_iattr) {
56 /* setting attributes for the first time, allocate now */ 56 /* setting attributes for the first time, allocate now */
57 sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL); 57 sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
58 if (!sd_iattr) 58 if (!sd_iattr)
59 return -ENOMEM; 59 return -ENOMEM;
60 /* assign default attributes */ 60 /* assign default attributes */
61 memset(sd_iattr, 0, sizeof(struct iattr));
62 sd_iattr->ia_mode = sd->s_mode; 61 sd_iattr->ia_mode = sd->s_mode;
63 sd_iattr->ia_uid = 0; 62 sd_iattr->ia_uid = 0;
64 sd_iattr->ia_gid = 0; 63 sd_iattr->ia_gid = 0;
@@ -227,12 +226,16 @@ void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
227void sysfs_hash_and_remove(struct dentry * dir, const char * name) 226void sysfs_hash_and_remove(struct dentry * dir, const char * name)
228{ 227{
229 struct sysfs_dirent * sd; 228 struct sysfs_dirent * sd;
230 struct sysfs_dirent * parent_sd = dir->d_fsdata; 229 struct sysfs_dirent * parent_sd;
230
231 if (!dir)
232 return;
231 233
232 if (dir->d_inode == NULL) 234 if (dir->d_inode == NULL)
233 /* no inode means this hasn't been made visible yet */ 235 /* no inode means this hasn't been made visible yet */
234 return; 236 return;
235 237
238 parent_sd = dir->d_fsdata;
236 mutex_lock(&dir->d_inode->i_mutex); 239 mutex_lock(&dir->d_inode->i_mutex);
237 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 240 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
238 if (!sd->s_element) 241 if (!sd->s_element)
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index e38d6338a20d..d2eac3ceed5f 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -66,6 +66,7 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj
66 if (!error) 66 if (!error)
67 return 0; 67 return 0;
68 68
69 kobject_put(target);
69 kfree(sl->link_name); 70 kfree(sl->link_name);
70exit2: 71exit2:
71 kfree(sl); 72 kfree(sl);
@@ -82,12 +83,13 @@ exit1:
82int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name) 83int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
83{ 84{
84 struct dentry * dentry = kobj->dentry; 85 struct dentry * dentry = kobj->dentry;
85 int error = 0; 86 int error = -EEXIST;
86 87
87 BUG_ON(!kobj || !kobj->dentry || !name); 88 BUG_ON(!kobj || !kobj->dentry || !name);
88 89
89 mutex_lock(&dentry->d_inode->i_mutex); 90 mutex_lock(&dentry->d_inode->i_mutex);
90 error = sysfs_add_link(dentry, name, target); 91 if (!sysfs_dirent_exist(dentry->d_fsdata, name))
92 error = sysfs_add_link(dentry, name, target);
91 mutex_unlock(&dentry->d_inode->i_mutex); 93 mutex_unlock(&dentry->d_inode->i_mutex);
92 return error; 94 return error;
93} 95}
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 3f8953e0e5d0..cf11d5b789d9 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -5,6 +5,7 @@ extern kmem_cache_t *sysfs_dir_cachep;
5extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); 5extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
6extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); 6extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
7 7
8extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
8extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, 9extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
9 umode_t, int); 10 umode_t, int);
10 11