diff options
author | Nathan Scott <nathans@bruce> | 2006-03-21 23:31:14 -0500 |
---|---|---|
committer | Nathan Scott <nathans@bruce> | 2006-03-21 23:31:14 -0500 |
commit | 4d74f423c722b8cadfabe087369200013b217b67 (patch) | |
tree | d62facddfdb0dfd89f3e61f4fc699cf2feb4b082 /fs | |
parent | bb19fba1937cb6ab2bb98ac893365f6ebf88ef1b (diff) | |
parent | e952f31bce6e9f64db01f607abc46529ba57ac9e (diff) |
Merge HEAD from ../linux-2.6
Diffstat (limited to 'fs')
40 files changed, 585 insertions, 272 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 | ||
31 | static DECLARE_MUTEX(chrdevs_lock); | 32 | static DEFINE_MUTEX(chrdevs_lock); |
32 | 33 | ||
33 | static struct char_device_struct { | 34 | static struct char_device_struct { |
34 | struct char_device_struct *next; | 35 | struct char_device_struct *next; |
@@ -88,13 +89,13 @@ out: | |||
88 | 89 | ||
89 | void *acquire_chrdev_list(void) | 90 | void *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 | ||
95 | void release_chrdev_list(void *dev) | 96 | void 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; |
191 | out: | 192 | out: |
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 | } |
252 | EXPORT_SYMBOL_GPL(debugfs_create_bool); | 252 | EXPORT_SYMBOL_GPL(debugfs_create_bool); |
253 | 253 | ||
254 | static 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 | |||
262 | static 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 | */ | ||
293 | struct 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 | } | ||
299 | EXPORT_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 | ||
1274 | out: | 1275 | out: |
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; | |
317 | success: | ||
318 | ret = 0; | ||
319 | done: | ||
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 | ||
13 | jfs-$(CONFIG_JFS_POSIX_ACL) += acl.o | 14 | jfs-$(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 | |||
21 | static 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 | |||
35 | static 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 | |||
54 | int 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 2967b7393415..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 | */ |
128 | static s8 budtab[256] = { | 128 | static 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, |
@@ -532,10 +532,10 @@ dbUpdatePMap(struct inode *ipbmap, | |||
532 | 532 | ||
533 | lastlblkno = lblkno; | 533 | lastlblkno = lblkno; |
534 | 534 | ||
535 | LOGSYNC_LOCK(log, flags); | ||
535 | if (mp->lsn != 0) { | 536 | if (mp->lsn != 0) { |
536 | /* inherit older/smaller lsn */ | 537 | /* inherit older/smaller lsn */ |
537 | logdiff(diffp, mp->lsn, log); | 538 | logdiff(diffp, mp->lsn, log); |
538 | LOGSYNC_LOCK(log, flags); | ||
539 | if (difft < diffp) { | 539 | if (difft < diffp) { |
540 | mp->lsn = lsn; | 540 | mp->lsn = lsn; |
541 | 541 | ||
@@ -548,20 +548,17 @@ dbUpdatePMap(struct inode *ipbmap, | |||
548 | logdiff(diffp, mp->clsn, log); | 548 | logdiff(diffp, mp->clsn, log); |
549 | if (difft > diffp) | 549 | if (difft > diffp) |
550 | mp->clsn = tblk->clsn; | 550 | mp->clsn = tblk->clsn; |
551 | LOGSYNC_UNLOCK(log, flags); | ||
552 | } else { | 551 | } else { |
553 | mp->log = log; | 552 | mp->log = log; |
554 | mp->lsn = lsn; | 553 | mp->lsn = lsn; |
555 | 554 | ||
556 | /* insert bp after tblock in logsync list */ | 555 | /* insert bp after tblock in logsync list */ |
557 | LOGSYNC_LOCK(log, flags); | ||
558 | |||
559 | log->count++; | 556 | log->count++; |
560 | list_add(&mp->synclist, &tblk->synclist); | 557 | list_add(&mp->synclist, &tblk->synclist); |
561 | 558 | ||
562 | mp->clsn = tblk->clsn; | 559 | mp->clsn = tblk->clsn; |
563 | LOGSYNC_UNLOCK(log, flags); | ||
564 | } | 560 | } |
561 | LOGSYNC_UNLOCK(log, flags); | ||
565 | } | 562 | } |
566 | 563 | ||
567 | /* write the last buffer. */ | 564 | /* write the last buffer. */ |
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 { | |||
243 | struct bmap { | 243 | struct 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); |
340 | exit: | 340 | exit: |
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 31b4aa13dd4b..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 | ||
@@ -2844,11 +2844,11 @@ diUpdatePMap(struct inode *ipimap, | |||
2844 | */ | 2844 | */ |
2845 | lsn = tblk->lsn; | 2845 | lsn = tblk->lsn; |
2846 | log = JFS_SBI(tblk->sb)->log; | 2846 | log = JFS_SBI(tblk->sb)->log; |
2847 | LOGSYNC_LOCK(log, flags); | ||
2847 | if (mp->lsn != 0) { | 2848 | if (mp->lsn != 0) { |
2848 | /* inherit older/smaller lsn */ | 2849 | /* inherit older/smaller lsn */ |
2849 | logdiff(difft, lsn, log); | 2850 | logdiff(difft, lsn, log); |
2850 | logdiff(diffp, mp->lsn, log); | 2851 | logdiff(diffp, mp->lsn, log); |
2851 | LOGSYNC_LOCK(log, flags); | ||
2852 | if (difft < diffp) { | 2852 | if (difft < diffp) { |
2853 | mp->lsn = lsn; | 2853 | mp->lsn = lsn; |
2854 | /* move mp after tblock in logsync list */ | 2854 | /* move mp after tblock in logsync list */ |
@@ -2860,17 +2860,15 @@ diUpdatePMap(struct inode *ipimap, | |||
2860 | logdiff(diffp, mp->clsn, log); | 2860 | logdiff(diffp, mp->clsn, log); |
2861 | if (difft > diffp) | 2861 | if (difft > diffp) |
2862 | mp->clsn = tblk->clsn; | 2862 | mp->clsn = tblk->clsn; |
2863 | LOGSYNC_UNLOCK(log, flags); | ||
2864 | } else { | 2863 | } else { |
2865 | mp->log = log; | 2864 | mp->log = log; |
2866 | mp->lsn = lsn; | 2865 | mp->lsn = lsn; |
2867 | /* insert mp after tblock in logsync list */ | 2866 | /* insert mp after tblock in logsync list */ |
2868 | LOGSYNC_LOCK(log, flags); | ||
2869 | log->count++; | 2867 | log->count++; |
2870 | list_add(&mp->synclist, &tblk->synclist); | 2868 | list_add(&mp->synclist, &tblk->synclist); |
2871 | mp->clsn = tblk->clsn; | 2869 | mp->clsn = tblk->clsn; |
2872 | LOGSYNC_UNLOCK(log, flags); | ||
2873 | } | 2870 | } |
2871 | LOGSYNC_UNLOCK(log, flags); | ||
2874 | write_metapage(mp); | 2872 | write_metapage(mp); |
2875 | return (0); | 2873 | return (0); |
2876 | } | 2874 | } |
@@ -3076,14 +3074,40 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, | |||
3076 | static int copy_from_dinode(struct dinode * dip, struct inode *ip) | 3074 | static int copy_from_dinode(struct dinode * dip, struct inode *ip) |
3077 | { | 3075 | { |
3078 | 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); | ||
3079 | 3078 | ||
3080 | jfs_ip->fileset = le32_to_cpu(dip->di_fileset); | 3079 | jfs_ip->fileset = le32_to_cpu(dip->di_fileset); |
3081 | jfs_ip->mode2 = le32_to_cpu(dip->di_mode); | 3080 | jfs_ip->mode2 = le32_to_cpu(dip->di_mode); |
3082 | 3081 | ||
3083 | 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 | } | ||
3084 | ip->i_nlink = le32_to_cpu(dip->di_nlink); | 3095 | ip->i_nlink = le32_to_cpu(dip->di_nlink); |
3085 | ip->i_uid = le32_to_cpu(dip->di_uid); | 3096 | |
3086 | 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 | |||
3087 | ip->i_size = le64_to_cpu(dip->di_size); | 3111 | ip->i_size = le64_to_cpu(dip->di_size); |
3088 | 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); |
3089 | 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); |
@@ -3134,21 +3158,33 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip) | |||
3134 | static void copy_to_dinode(struct dinode * dip, struct inode *ip) | 3158 | static void copy_to_dinode(struct dinode * dip, struct inode *ip) |
3135 | { | 3159 | { |
3136 | 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); | ||
3137 | 3162 | ||
3138 | dip->di_fileset = cpu_to_le32(jfs_ip->fileset); | 3163 | dip->di_fileset = cpu_to_le32(jfs_ip->fileset); |
3139 | dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); | 3164 | dip->di_inostamp = cpu_to_le32(sbi->inostamp); |
3140 | dip->di_number = cpu_to_le32(ip->i_ino); | 3165 | dip->di_number = cpu_to_le32(ip->i_ino); |
3141 | dip->di_gen = cpu_to_le32(ip->i_generation); | 3166 | dip->di_gen = cpu_to_le32(ip->i_generation); |
3142 | dip->di_size = cpu_to_le64(ip->i_size); | 3167 | dip->di_size = cpu_to_le64(ip->i_size); |
3143 | 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)); |
3144 | dip->di_nlink = cpu_to_le32(ip->i_nlink); | 3169 | dip->di_nlink = cpu_to_le32(ip->i_nlink); |
3145 | dip->di_uid = cpu_to_le32(ip->i_uid); | 3170 | if (sbi->uid == -1) |
3146 | 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); | ||
3147 | /* | 3178 | /* |
3148 | * mode2 is only needed for storing the higher order bits. | 3179 | * mode2 is only needed for storing the higher order bits. |
3149 | * Trust i_mode for the lower order ones | 3180 | * Trust i_mode for the lower order ones |
3150 | */ | 3181 | */ |
3151 | 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 | |||
3152 | 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); |
3153 | 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); |
3154 | 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 { | |||
140 | struct inomap { | 140 | struct 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 @@ | |||
37 | struct jfs_inode_info { | 38 | struct 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 | |||
29 | void 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 | ||
21 | extern struct inode *ialloc(struct inode *, umode_t); | 21 | extern struct inode *ialloc(struct inode *, umode_t); |
22 | extern int jfs_fsync(struct file *, struct dentry *, int); | 22 | extern int jfs_fsync(struct file *, struct dentry *, int); |
23 | extern int jfs_ioctl(struct inode *, struct file *, | ||
24 | unsigned int, unsigned long); | ||
23 | extern void jfs_read_inode(struct inode *); | 25 | extern void jfs_read_inode(struct inode *); |
24 | extern int jfs_commit_inode(struct inode *, int); | 26 | extern int jfs_commit_inode(struct inode *, int); |
25 | extern int jfs_write_inode(struct inode*, int); | 27 | extern int jfs_write_inode(struct inode*, int); |
@@ -29,6 +31,7 @@ extern void jfs_truncate(struct inode *); | |||
29 | extern void jfs_truncate_nolock(struct inode *, loff_t); | 31 | extern void jfs_truncate_nolock(struct inode *, loff_t); |
30 | extern void jfs_free_zero_link(struct inode *); | 32 | extern void jfs_free_zero_link(struct inode *); |
31 | extern struct dentry *jfs_get_parent(struct dentry *dentry); | 33 | extern struct dentry *jfs_get_parent(struct dentry *dentry); |
34 | extern void jfs_set_inode_flags(struct inode *); | ||
32 | 35 | ||
33 | extern struct address_space_operations jfs_aops; | 36 | extern struct address_space_operations jfs_aops; |
34 | extern struct inode_operations jfs_dir_inode_operations; | 37 | extern 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 | */ |
82 | static struct lbuf *log_redrive_list; | 83 | static struct lbuf *log_redrive_list; |
83 | static DEFINE_SPINLOCK(log_redrive_lock); | 84 | static DEFINE_SPINLOCK(log_redrive_lock); |
84 | DECLARE_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 *); | |||
113 | extern int jfs_mount_rw(struct super_block *, int); | 113 | extern int jfs_mount_rw(struct super_block *, int); |
114 | extern int jfs_umount(struct super_block *); | 114 | extern int jfs_umount(struct super_block *); |
115 | extern int jfs_umount_rw(struct super_block *); | 115 | extern int jfs_umount_rw(struct super_block *); |
116 | |||
117 | extern int jfs_stop_threads; | ||
118 | extern struct completion jfsIOwait; | ||
119 | extern wait_queue_head_t jfs_IO_thread_wait; | ||
120 | extern wait_queue_head_t jfs_commit_thread_wait; | ||
121 | extern wait_queue_head_t jfs_sync_thread_wait; | ||
122 | extern int jfs_extendfs(struct super_block *, s64, int); | 116 | extern int jfs_extendfs(struct super_block *, s64, int); |
123 | 117 | ||
118 | extern struct task_struct *jfsIOthread; | ||
119 | extern 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 | ||
124 | DECLARE_WAIT_QUEUE_HEAD(jfs_sync_thread_wait); | 125 | static DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait); |
125 | DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait); | ||
126 | static int jfs_commit_thread_waking; | 126 | static 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 | ||
2818 | void txLazyUnlock(struct tblock * tblk) | 2814 | void 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 | ||
1528 | static int jfs_ci_hash(struct dentry *dir, struct qstr *this) | 1529 | static 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; | |||
54 | module_param(commit_threads, int, 0); | 55 | module_param(commit_threads, int, 0); |
55 | MODULE_PARM_DESC(commit_threads, "Number of commit threads"); | 56 | MODULE_PARM_DESC(commit_threads, "Number of commit threads"); |
56 | 57 | ||
57 | int jfs_stop_threads; | 58 | static struct task_struct *jfsCommitThread[MAX_COMMIT_THREADS]; |
58 | static pid_t jfsIOthread; | 59 | struct task_struct *jfsIOthread; |
59 | static pid_t jfsCommitThread[MAX_COMMIT_THREADS]; | 60 | struct task_struct *jfsSyncThread; |
60 | static pid_t jfsSyncThread; | ||
61 | DECLARE_COMPLETION(jfsIOwait); | ||
62 | 61 | ||
63 | #ifdef CONFIG_JFS_DEBUG | 62 | #ifdef CONFIG_JFS_DEBUG |
64 | int jfsloglevel = JFS_LOGLEVEL_WARN; | 63 | int jfsloglevel = JFS_LOGLEVEL_WARN; |
@@ -195,7 +194,7 @@ static void jfs_put_super(struct super_block *sb) | |||
195 | enum { | 194 | enum { |
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 | ||
201 | static match_table_t tokens = { | 200 | static 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 | ||
702 | kill_committask: | 727 | kill_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 */ | ||
710 | end_txmngr: | 731 | end_txmngr: |
711 | txExit(); | 732 | txExit(); |
712 | free_metapage: | 733 | free_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/lockd/clntproc.c b/fs/lockd/clntproc.c index 220058d8616d..970b6a6aa337 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -662,12 +662,18 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) | |||
662 | * reclaimed while we're stuck in the unlock call. */ | 662 | * reclaimed while we're stuck in the unlock call. */ |
663 | fl->fl_u.nfs_fl.flags &= ~NFS_LCK_GRANTED; | 663 | fl->fl_u.nfs_fl.flags &= ~NFS_LCK_GRANTED; |
664 | 664 | ||
665 | /* | ||
666 | * Note: the server is supposed to either grant us the unlock | ||
667 | * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either | ||
668 | * case, we want to unlock. | ||
669 | */ | ||
670 | do_vfs_lock(fl); | ||
671 | |||
665 | if (req->a_flags & RPC_TASK_ASYNC) { | 672 | if (req->a_flags & RPC_TASK_ASYNC) { |
666 | status = nlmclnt_async_call(req, NLMPROC_UNLOCK, | 673 | status = nlmclnt_async_call(req, NLMPROC_UNLOCK, |
667 | &nlmclnt_unlock_ops); | 674 | &nlmclnt_unlock_ops); |
668 | /* Hrmf... Do the unlock early since locks_remove_posix() | 675 | /* Hrmf... Do the unlock early since locks_remove_posix() |
669 | * really expects us to free the lock synchronously */ | 676 | * really expects us to free the lock synchronously */ |
670 | do_vfs_lock(fl); | ||
671 | if (status < 0) { | 677 | if (status < 0) { |
672 | nlmclnt_release_lockargs(req); | 678 | nlmclnt_release_lockargs(req); |
673 | kfree(req); | 679 | kfree(req); |
@@ -680,7 +686,6 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) | |||
680 | if (status < 0) | 686 | if (status < 0) |
681 | return status; | 687 | return status; |
682 | 688 | ||
683 | do_vfs_lock(fl); | ||
684 | if (resp->status == NLM_LCK_GRANTED) | 689 | if (resp->status == NLM_LCK_GRANTED) |
685 | return 0; | 690 | return 0; |
686 | 691 | ||
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 | ||
1396 | out: | ||
1397 | return new_ns; | 1396 | return new_ns; |
1398 | } | 1397 | } |
1399 | 1398 | ||
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 04ab2fc360e7..4e9b3a1b36c5 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #define NFSDBG_FACILITY NFSDBG_VFS | 57 | #define NFSDBG_FACILITY NFSDBG_VFS |
58 | #define MAX_DIRECTIO_SIZE (4096UL << PAGE_SHIFT) | 58 | #define MAX_DIRECTIO_SIZE (4096UL << PAGE_SHIFT) |
59 | 59 | ||
60 | static void nfs_free_user_pages(struct page **pages, int npages, int do_dirty); | ||
60 | static kmem_cache_t *nfs_direct_cachep; | 61 | static kmem_cache_t *nfs_direct_cachep; |
61 | 62 | ||
62 | /* | 63 | /* |
@@ -107,6 +108,15 @@ nfs_get_user_pages(int rw, unsigned long user_addr, size_t size, | |||
107 | page_count, (rw == READ), 0, | 108 | page_count, (rw == READ), 0, |
108 | *pages, NULL); | 109 | *pages, NULL); |
109 | up_read(¤t->mm->mmap_sem); | 110 | up_read(¤t->mm->mmap_sem); |
111 | /* | ||
112 | * If we got fewer pages than expected from get_user_pages(), | ||
113 | * the user buffer runs off the end of a mapping; return EFAULT. | ||
114 | */ | ||
115 | if (result >= 0 && result < page_count) { | ||
116 | nfs_free_user_pages(*pages, result, 0); | ||
117 | *pages = NULL; | ||
118 | result = -EFAULT; | ||
119 | } | ||
110 | } | 120 | } |
111 | return result; | 121 | return result; |
112 | } | 122 | } |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 984ca3454d04..f8c0066e02e1 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1430,7 +1430,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, | |||
1430 | if (status == 0) | 1430 | if (status == 0) |
1431 | status = nfs4_do_fsinfo(server, fhandle, info); | 1431 | status = nfs4_do_fsinfo(server, fhandle, info); |
1432 | out: | 1432 | out: |
1433 | return status; | 1433 | return nfs4_map_errors(status); |
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) | 1436 | static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) |
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 | */ | ||
60 | int 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 | |||
53 | int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry, | 79 | int 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 | ||
307 | int sysfs_rename_dir(struct kobject * kobj, const char *new_name) | 338 | int 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 | |||
483 | EXPORT_SYMBOL_GPL(sysfs_create_dir); | ||
484 | EXPORT_SYMBOL_GPL(sysfs_remove_dir); | ||
485 | EXPORT_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) | |||
227 | void sysfs_hash_and_remove(struct dentry * dir, const char * name) | 226 | void 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); |
70 | exit2: | 71 | exit2: |
71 | kfree(sl); | 72 | kfree(sl); |
@@ -82,12 +83,13 @@ exit1: | |||
82 | int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name) | 83 | int 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; | |||
5 | extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); | 5 | extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); |
6 | extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); | 6 | extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); |
7 | 7 | ||
8 | extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *); | ||
8 | extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, | 9 | extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, |
9 | umode_t, int); | 10 | umode_t, int); |
10 | 11 | ||