diff options
author | Steve French <sfrench@us.ibm.com> | 2006-03-20 11:58:09 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-03-20 11:58:09 -0500 |
commit | fd4a0b92db6a57cba8d03efbe1cebf91f9124ce0 (patch) | |
tree | 5886a08bfa1132058b06074f4666a36dc5ddd2a1 /fs | |
parent | 88274815f7477dc7550439413ab87c5ce4c5a623 (diff) | |
parent | 7705a8792b0fc82fd7d4dd923724606bbfd9fb20 (diff) |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/9p/9p.c | 1 | ||||
-rw-r--r-- | fs/9p/trans_fd.c | 1 | ||||
-rw-r--r-- | fs/9p/vfs_dir.c | 1 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 8 | ||||
-rw-r--r-- | fs/9p/vfs_super.c | 1 | ||||
-rw-r--r-- | fs/buffer.c | 6 | ||||
-rw-r--r-- | fs/compat_ioctl.c | 2 | ||||
-rw-r--r-- | fs/dcache.c | 2 | ||||
-rw-r--r-- | fs/direct-io.c | 21 | ||||
-rw-r--r-- | fs/ext2/dir.c | 28 | ||||
-rw-r--r-- | fs/ext3/inode.c | 17 | ||||
-rw-r--r-- | fs/ext3/namei.c | 3 | ||||
-rw-r--r-- | fs/file_table.c | 87 | ||||
-rw-r--r-- | fs/jffs2/nodelist.c | 3 | ||||
-rw-r--r-- | fs/jffs2/readinode.c | 2 | ||||
-rw-r--r-- | fs/jffs2/scan.c | 2 | ||||
-rw-r--r-- | fs/jfs/jfs_dmap.c | 7 | ||||
-rw-r--r-- | fs/jfs/jfs_imap.c | 6 | ||||
-rw-r--r-- | fs/lockd/clntproc.c | 9 | ||||
-rw-r--r-- | fs/namei.c | 13 | ||||
-rw-r--r-- | fs/namespace.c | 5 | ||||
-rw-r--r-- | fs/nfs/direct.c | 10 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 2 | ||||
-rw-r--r-- | fs/nfsctl.c | 4 | ||||
-rw-r--r-- | fs/partitions/ibm.c | 16 | ||||
-rw-r--r-- | fs/pipe.c | 6 | ||||
-rw-r--r-- | fs/udf/inode.c | 16 | ||||
-rw-r--r-- | fs/udf/super.c | 18 | ||||
-rw-r--r-- | fs/udf/udf_sb.h | 4 |
29 files changed, 185 insertions, 116 deletions
diff --git a/fs/9p/9p.c b/fs/9p/9p.c index 1a6d08761f39..f86a28d1d6a6 100644 --- a/fs/9p/9p.c +++ b/fs/9p/9p.c | |||
@@ -111,7 +111,6 @@ static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc, | |||
111 | if (!rc) | 111 | if (!rc) |
112 | return; | 112 | return; |
113 | 113 | ||
114 | dprintk(DEBUG_9P, "tcall id %d rcall id %d\n", tc->id, rc->id); | ||
115 | v9ses = a; | 114 | v9ses = a; |
116 | if (rc->id == RCLUNK) | 115 | if (rc->id == RCLUNK) |
117 | v9fs_put_idpool(fid, &v9ses->fidpool); | 116 | v9fs_put_idpool(fid, &v9ses->fidpool); |
diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c index 1a28ef97a3d1..5b2ce21b10fa 100644 --- a/fs/9p/trans_fd.c +++ b/fs/9p/trans_fd.c | |||
@@ -80,6 +80,7 @@ static int v9fs_fd_send(struct v9fs_transport *trans, void *v, int len) | |||
80 | if (!trans || trans->status != Connected || !ts) | 80 | if (!trans || trans->status != Connected || !ts) |
81 | return -EIO; | 81 | return -EIO; |
82 | 82 | ||
83 | oldfs = get_fs(); | ||
83 | set_fs(get_ds()); | 84 | set_fs(get_ds()); |
84 | /* The cast to a user pointer is valid due to the set_fs() */ | 85 | /* The cast to a user pointer is valid due to the set_fs() */ |
85 | ret = vfs_write(ts->out_file, (void __user *)v, len, &ts->out_file->f_pos); | 86 | ret = vfs_write(ts->out_file, (void __user *)v, len, &ts->out_file->f_pos); |
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/9p/vfs_inode.c b/fs/9p/vfs_inode.c index dce729d42869..3ad8455f8577 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -265,8 +265,7 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, | |||
265 | fid = v9fs_get_idpool(&v9ses->fidpool); | 265 | fid = v9fs_get_idpool(&v9ses->fidpool); |
266 | if (fid < 0) { | 266 | if (fid < 0) { |
267 | eprintk(KERN_WARNING, "no free fids available\n"); | 267 | eprintk(KERN_WARNING, "no free fids available\n"); |
268 | err = -ENOSPC; | 268 | return -ENOSPC; |
269 | goto error; | ||
270 | } | 269 | } |
271 | 270 | ||
272 | err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); | 271 | err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); |
@@ -313,8 +312,7 @@ v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) | |||
313 | nfid = v9fs_get_idpool(&v9ses->fidpool); | 312 | nfid = v9fs_get_idpool(&v9ses->fidpool); |
314 | if (nfid < 0) { | 313 | if (nfid < 0) { |
315 | eprintk(KERN_WARNING, "no free fids available\n"); | 314 | eprintk(KERN_WARNING, "no free fids available\n"); |
316 | err = -ENOSPC; | 315 | return ERR_PTR(-ENOSPC); |
317 | goto error; | ||
318 | } | 316 | } |
319 | 317 | ||
320 | err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name, | 318 | err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name, |
@@ -612,7 +610,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
612 | int result = 0; | 610 | int result = 0; |
613 | 611 | ||
614 | dprintk(DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", | 612 | dprintk(DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n", |
615 | dir, dentry->d_iname, dentry, nameidata); | 613 | dir, dentry->d_name.name, dentry, nameidata); |
616 | 614 | ||
617 | sb = dir->i_sb; | 615 | sb = dir->i_sb; |
618 | v9ses = v9fs_inode2v9ses(dir); | 616 | v9ses = v9fs_inode2v9ses(dir); |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index cdf787ee08de..d05318fa684e 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -156,7 +156,6 @@ static struct super_block *v9fs_get_sb(struct file_system_type | |||
156 | stat_result = v9fs_t_stat(v9ses, newfid, &fcall); | 156 | stat_result = v9fs_t_stat(v9ses, newfid, &fcall); |
157 | if (stat_result < 0) { | 157 | if (stat_result < 0) { |
158 | dprintk(DEBUG_ERROR, "stat error\n"); | 158 | dprintk(DEBUG_ERROR, "stat error\n"); |
159 | kfree(fcall); | ||
160 | v9fs_t_clunk(v9ses, newfid); | 159 | v9fs_t_clunk(v9ses, newfid); |
161 | } else { | 160 | } else { |
162 | /* Setup the Root Inode */ | 161 | /* Setup the Root Inode */ |
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/compat_ioctl.c b/fs/compat_ioctl.c index 537ac70edfe5..c666769a875d 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -446,7 +446,7 @@ static int dev_ifconf(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
446 | ifr = ifc.ifc_req; | 446 | ifr = ifc.ifc_req; |
447 | ifr32 = compat_ptr(ifc32.ifcbuf); | 447 | ifr32 = compat_ptr(ifc32.ifcbuf); |
448 | for (i = 0, j = 0; | 448 | for (i = 0, j = 0; |
449 | i + sizeof (struct ifreq32) < ifc32.ifc_len && j < ifc.ifc_len; | 449 | i + sizeof (struct ifreq32) <= ifc32.ifc_len && j < ifc.ifc_len; |
450 | i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { | 450 | i += sizeof (struct ifreq32), j += sizeof (struct ifreq)) { |
451 | if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32))) | 451 | if (copy_in_user(ifr32, ifr, sizeof (struct ifreq32))) |
452 | return -EFAULT; | 452 | return -EFAULT; |
diff --git a/fs/dcache.c b/fs/dcache.c index a173bba32666..11dc83092d4a 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1736,7 +1736,7 @@ void __init vfs_caches_init(unsigned long mempages) | |||
1736 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | 1736 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); |
1737 | 1737 | ||
1738 | filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, | 1738 | filp_cachep = kmem_cache_create("filp", sizeof(struct file), 0, |
1739 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, filp_ctor, filp_dtor); | 1739 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); |
1740 | 1740 | ||
1741 | dcache_init(mempages); | 1741 | dcache_init(mempages); |
1742 | inode_init(mempages); | 1742 | inode_init(mempages); |
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/ext3/inode.c b/fs/ext3/inode.c index 3fc4238e9703..0384e539b88f 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1624,15 +1624,14 @@ static int ext3_block_truncate_page(handle_t *handle, struct page *page, | |||
1624 | * For "nobh" option, we can only work if we don't need to | 1624 | * For "nobh" option, we can only work if we don't need to |
1625 | * read-in the page - otherwise we create buffers to do the IO. | 1625 | * read-in the page - otherwise we create buffers to do the IO. |
1626 | */ | 1626 | */ |
1627 | if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH)) { | 1627 | if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) && |
1628 | if (PageUptodate(page)) { | 1628 | ext3_should_writeback_data(inode) && PageUptodate(page)) { |
1629 | kaddr = kmap_atomic(page, KM_USER0); | 1629 | kaddr = kmap_atomic(page, KM_USER0); |
1630 | memset(kaddr + offset, 0, length); | 1630 | memset(kaddr + offset, 0, length); |
1631 | flush_dcache_page(page); | 1631 | flush_dcache_page(page); |
1632 | kunmap_atomic(kaddr, KM_USER0); | 1632 | kunmap_atomic(kaddr, KM_USER0); |
1633 | set_page_dirty(page); | 1633 | set_page_dirty(page); |
1634 | goto unlock; | 1634 | goto unlock; |
1635 | } | ||
1636 | } | 1635 | } |
1637 | 1636 | ||
1638 | if (!page_has_buffers(page)) | 1637 | if (!page_has_buffers(page)) |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 8bd8ac077704..b8f5cd1e540d 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -2141,7 +2141,8 @@ retry: | |||
2141 | * We have a transaction open. All is sweetness. It also sets | 2141 | * We have a transaction open. All is sweetness. It also sets |
2142 | * i_size in generic_commit_write(). | 2142 | * i_size in generic_commit_write(). |
2143 | */ | 2143 | */ |
2144 | err = page_symlink(inode, symname, l); | 2144 | err = __page_symlink(inode, symname, l, |
2145 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | ||
2145 | if (err) { | 2146 | if (err) { |
2146 | ext3_dec_count(handle, inode); | 2147 | ext3_dec_count(handle, inode); |
2147 | ext3_mark_inode_dirty(handle, inode); | 2148 | ext3_mark_inode_dirty(handle, inode); |
diff --git a/fs/file_table.c b/fs/file_table.c index 768b58167543..44fabeaa9415 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) | 5 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/config.h> | ||
8 | #include <linux/string.h> | 9 | #include <linux/string.h> |
9 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
10 | #include <linux/file.h> | 11 | #include <linux/file.h> |
@@ -19,52 +20,67 @@ | |||
19 | #include <linux/capability.h> | 20 | #include <linux/capability.h> |
20 | #include <linux/cdev.h> | 21 | #include <linux/cdev.h> |
21 | #include <linux/fsnotify.h> | 22 | #include <linux/fsnotify.h> |
23 | #include <linux/sysctl.h> | ||
24 | #include <linux/percpu_counter.h> | ||
25 | |||
26 | #include <asm/atomic.h> | ||
22 | 27 | ||
23 | /* sysctl tunables... */ | 28 | /* sysctl tunables... */ |
24 | struct files_stat_struct files_stat = { | 29 | struct files_stat_struct files_stat = { |
25 | .max_files = NR_FILE | 30 | .max_files = NR_FILE |
26 | }; | 31 | }; |
27 | 32 | ||
28 | EXPORT_SYMBOL(files_stat); /* Needed by unix.o */ | ||
29 | |||
30 | /* public. Not pretty! */ | 33 | /* public. Not pretty! */ |
31 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); | 34 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(files_lock); |
32 | 35 | ||
33 | static DEFINE_SPINLOCK(filp_count_lock); | 36 | static struct percpu_counter nr_files __cacheline_aligned_in_smp; |
34 | 37 | ||
35 | /* slab constructors and destructors are called from arbitrary | 38 | static inline void file_free_rcu(struct rcu_head *head) |
36 | * context and must be fully threaded - use a local spinlock | ||
37 | * to protect files_stat.nr_files | ||
38 | */ | ||
39 | void filp_ctor(void *objp, struct kmem_cache *cachep, unsigned long cflags) | ||
40 | { | 39 | { |
41 | if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 40 | struct file *f = container_of(head, struct file, f_u.fu_rcuhead); |
42 | SLAB_CTOR_CONSTRUCTOR) { | 41 | kmem_cache_free(filp_cachep, f); |
43 | unsigned long flags; | ||
44 | spin_lock_irqsave(&filp_count_lock, flags); | ||
45 | files_stat.nr_files++; | ||
46 | spin_unlock_irqrestore(&filp_count_lock, flags); | ||
47 | } | ||
48 | } | 42 | } |
49 | 43 | ||
50 | void filp_dtor(void *objp, struct kmem_cache *cachep, unsigned long dflags) | 44 | static inline void file_free(struct file *f) |
51 | { | 45 | { |
52 | unsigned long flags; | 46 | percpu_counter_dec(&nr_files); |
53 | spin_lock_irqsave(&filp_count_lock, flags); | 47 | call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); |
54 | files_stat.nr_files--; | ||
55 | spin_unlock_irqrestore(&filp_count_lock, flags); | ||
56 | } | 48 | } |
57 | 49 | ||
58 | static inline void file_free_rcu(struct rcu_head *head) | 50 | /* |
51 | * Return the total number of open files in the system | ||
52 | */ | ||
53 | static int get_nr_files(void) | ||
59 | { | 54 | { |
60 | struct file *f = container_of(head, struct file, f_u.fu_rcuhead); | 55 | return percpu_counter_read_positive(&nr_files); |
61 | kmem_cache_free(filp_cachep, f); | ||
62 | } | 56 | } |
63 | 57 | ||
64 | static inline void file_free(struct file *f) | 58 | /* |
59 | * Return the maximum number of open files in the system | ||
60 | */ | ||
61 | int get_max_files(void) | ||
65 | { | 62 | { |
66 | call_rcu(&f->f_u.fu_rcuhead, file_free_rcu); | 63 | return files_stat.max_files; |
67 | } | 64 | } |
65 | EXPORT_SYMBOL_GPL(get_max_files); | ||
66 | |||
67 | /* | ||
68 | * Handle nr_files sysctl | ||
69 | */ | ||
70 | #if defined(CONFIG_SYSCTL) && defined(CONFIG_PROC_FS) | ||
71 | int proc_nr_files(ctl_table *table, int write, struct file *filp, | ||
72 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
73 | { | ||
74 | files_stat.nr_files = get_nr_files(); | ||
75 | return proc_dointvec(table, write, filp, buffer, lenp, ppos); | ||
76 | } | ||
77 | #else | ||
78 | int proc_nr_files(ctl_table *table, int write, struct file *filp, | ||
79 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
80 | { | ||
81 | return -ENOSYS; | ||
82 | } | ||
83 | #endif | ||
68 | 84 | ||
69 | /* Find an unused file structure and return a pointer to it. | 85 | /* Find an unused file structure and return a pointer to it. |
70 | * Returns NULL, if there are no more free file structures or | 86 | * Returns NULL, if there are no more free file structures or |
@@ -78,14 +94,20 @@ struct file *get_empty_filp(void) | |||
78 | /* | 94 | /* |
79 | * Privileged users can go above max_files | 95 | * Privileged users can go above max_files |
80 | */ | 96 | */ |
81 | if (files_stat.nr_files >= files_stat.max_files && | 97 | if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { |
82 | !capable(CAP_SYS_ADMIN)) | 98 | /* |
83 | goto over; | 99 | * percpu_counters are inaccurate. Do an expensive check before |
100 | * we go and fail. | ||
101 | */ | ||
102 | if (percpu_counter_sum(&nr_files) >= files_stat.max_files) | ||
103 | goto over; | ||
104 | } | ||
84 | 105 | ||
85 | f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); | 106 | f = kmem_cache_alloc(filp_cachep, GFP_KERNEL); |
86 | if (f == NULL) | 107 | if (f == NULL) |
87 | goto fail; | 108 | goto fail; |
88 | 109 | ||
110 | percpu_counter_inc(&nr_files); | ||
89 | memset(f, 0, sizeof(*f)); | 111 | memset(f, 0, sizeof(*f)); |
90 | if (security_file_alloc(f)) | 112 | if (security_file_alloc(f)) |
91 | goto fail_sec; | 113 | goto fail_sec; |
@@ -101,10 +123,10 @@ struct file *get_empty_filp(void) | |||
101 | 123 | ||
102 | over: | 124 | over: |
103 | /* Ran out of filps - report that */ | 125 | /* Ran out of filps - report that */ |
104 | if (files_stat.nr_files > old_max) { | 126 | if (get_nr_files() > old_max) { |
105 | printk(KERN_INFO "VFS: file-max limit %d reached\n", | 127 | printk(KERN_INFO "VFS: file-max limit %d reached\n", |
106 | files_stat.max_files); | 128 | get_max_files()); |
107 | old_max = files_stat.nr_files; | 129 | old_max = get_nr_files(); |
108 | } | 130 | } |
109 | goto fail; | 131 | goto fail; |
110 | 132 | ||
@@ -276,4 +298,5 @@ void __init files_init(unsigned long mempages) | |||
276 | if (files_stat.max_files < NR_FILE) | 298 | if (files_stat.max_files < NR_FILE) |
277 | files_stat.max_files = NR_FILE; | 299 | files_stat.max_files = NR_FILE; |
278 | files_defer_init(); | 300 | files_defer_init(); |
301 | percpu_counter_init(&nr_files); | ||
279 | } | 302 | } |
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c index b635e167a3fa..d4d0c41490cd 100644 --- a/fs/jffs2/nodelist.c +++ b/fs/jffs2/nodelist.c | |||
@@ -406,7 +406,8 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info | |||
406 | int err = 0, pointed = 0; | 406 | int err = 0, pointed = 0; |
407 | struct jffs2_eraseblock *jeb; | 407 | struct jffs2_eraseblock *jeb; |
408 | unsigned char *buffer; | 408 | unsigned char *buffer; |
409 | uint32_t crc, ofs, retlen, len; | 409 | uint32_t crc, ofs, len; |
410 | size_t retlen; | ||
410 | 411 | ||
411 | BUG_ON(tn->csize == 0); | 412 | BUG_ON(tn->csize == 0); |
412 | 413 | ||
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 5f0652df5d47..f1695642d0f7 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -112,7 +112,7 @@ static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_r | |||
112 | * negative error code on failure. | 112 | * negative error code on failure. |
113 | */ | 113 | */ |
114 | static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, | 114 | static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, |
115 | struct jffs2_raw_dirent *rd, uint32_t read, struct jffs2_full_dirent **fdp, | 115 | struct jffs2_raw_dirent *rd, size_t read, struct jffs2_full_dirent **fdp, |
116 | uint32_t *latest_mctime, uint32_t *mctime_ver) | 116 | uint32_t *latest_mctime, uint32_t *mctime_ver) |
117 | { | 117 | { |
118 | struct jffs2_full_dirent *fd; | 118 | struct jffs2_full_dirent *fd; |
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 3e51dd1da8aa..cf55b221fc2b 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -233,7 +233,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) | |||
233 | c->nextblock->dirty_size = 0; | 233 | c->nextblock->dirty_size = 0; |
234 | } | 234 | } |
235 | #ifdef CONFIG_JFFS2_FS_WRITEBUFFER | 235 | #ifdef CONFIG_JFFS2_FS_WRITEBUFFER |
236 | if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) { | 236 | if (!jffs2_can_mark_obsolete(c) && c->wbuf_pagesize && c->nextblock && (c->nextblock->free_size % c->wbuf_pagesize)) { |
237 | /* If we're going to start writing into a block which already | 237 | /* If we're going to start writing into a block which already |
238 | contains data, and the end of the data isn't page-aligned, | 238 | contains data, and the end of the data isn't page-aligned, |
239 | skip a little and align it. */ | 239 | skip a little and align it. */ |
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 2967b7393415..79b5404db100 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c | |||
@@ -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_imap.c b/fs/jfs/jfs_imap.c index 31b4aa13dd4b..4efa0d0eec39 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
@@ -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 | } |
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/namei.c b/fs/namei.c index 557dcf395ca1..8dc2b038d5d9 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2613,13 +2613,15 @@ void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) | |||
2613 | } | 2613 | } |
2614 | } | 2614 | } |
2615 | 2615 | ||
2616 | int page_symlink(struct inode *inode, const char *symname, int len) | 2616 | int __page_symlink(struct inode *inode, const char *symname, int len, |
2617 | gfp_t gfp_mask) | ||
2617 | { | 2618 | { |
2618 | struct address_space *mapping = inode->i_mapping; | 2619 | struct address_space *mapping = inode->i_mapping; |
2619 | struct page *page = grab_cache_page(mapping, 0); | 2620 | struct page *page; |
2620 | int err = -ENOMEM; | 2621 | int err = -ENOMEM; |
2621 | char *kaddr; | 2622 | char *kaddr; |
2622 | 2623 | ||
2624 | page = find_or_create_page(mapping, 0, gfp_mask); | ||
2623 | if (!page) | 2625 | if (!page) |
2624 | goto fail; | 2626 | goto fail; |
2625 | err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); | 2627 | err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); |
@@ -2654,6 +2656,12 @@ fail: | |||
2654 | return err; | 2656 | return err; |
2655 | } | 2657 | } |
2656 | 2658 | ||
2659 | int page_symlink(struct inode *inode, const char *symname, int len) | ||
2660 | { | ||
2661 | return __page_symlink(inode, symname, len, | ||
2662 | mapping_gfp_mask(inode->i_mapping)); | ||
2663 | } | ||
2664 | |||
2657 | struct inode_operations page_symlink_inode_operations = { | 2665 | struct inode_operations page_symlink_inode_operations = { |
2658 | .readlink = generic_readlink, | 2666 | .readlink = generic_readlink, |
2659 | .follow_link = page_follow_link_light, | 2667 | .follow_link = page_follow_link_light, |
@@ -2672,6 +2680,7 @@ EXPORT_SYMBOL(lookup_one_len); | |||
2672 | EXPORT_SYMBOL(page_follow_link_light); | 2680 | EXPORT_SYMBOL(page_follow_link_light); |
2673 | EXPORT_SYMBOL(page_put_link); | 2681 | EXPORT_SYMBOL(page_put_link); |
2674 | EXPORT_SYMBOL(page_readlink); | 2682 | EXPORT_SYMBOL(page_readlink); |
2683 | EXPORT_SYMBOL(__page_symlink); | ||
2675 | EXPORT_SYMBOL(page_symlink); | 2684 | EXPORT_SYMBOL(page_symlink); |
2676 | EXPORT_SYMBOL(page_symlink_inode_operations); | 2685 | EXPORT_SYMBOL(page_symlink_inode_operations); |
2677 | EXPORT_SYMBOL(path_lookup); | 2686 | EXPORT_SYMBOL(path_lookup); |
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/partitions/ibm.c b/fs/partitions/ibm.c index 78010ad60e47..1e4a93835fed 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c | |||
@@ -52,6 +52,7 @@ int | |||
52 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | 52 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) |
53 | { | 53 | { |
54 | int blocksize, offset, size; | 54 | int blocksize, offset, size; |
55 | loff_t i_size; | ||
55 | dasd_information_t *info; | 56 | dasd_information_t *info; |
56 | struct hd_geometry *geo; | 57 | struct hd_geometry *geo; |
57 | char type[5] = {0,}; | 58 | char type[5] = {0,}; |
@@ -63,6 +64,13 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
63 | unsigned char *data; | 64 | unsigned char *data; |
64 | Sector sect; | 65 | Sector sect; |
65 | 66 | ||
67 | blocksize = bdev_hardsect_size(bdev); | ||
68 | if (blocksize <= 0) | ||
69 | return 0; | ||
70 | i_size = i_size_read(bdev->bd_inode); | ||
71 | if (i_size == 0) | ||
72 | return 0; | ||
73 | |||
66 | if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) | 74 | if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) |
67 | goto out_noinfo; | 75 | goto out_noinfo; |
68 | if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) | 76 | if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) |
@@ -73,9 +81,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
73 | if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || | 81 | if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || |
74 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) | 82 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) |
75 | goto out_noioctl; | 83 | goto out_noioctl; |
76 | |||
77 | if ((blocksize = bdev_hardsect_size(bdev)) <= 0) | ||
78 | goto out_badsect; | ||
79 | 84 | ||
80 | /* | 85 | /* |
81 | * Get volume label, extract name and type. | 86 | * Get volume label, extract name and type. |
@@ -111,7 +116,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
111 | } else { | 116 | } else { |
112 | printk("CMS1/%8s:", name); | 117 | printk("CMS1/%8s:", name); |
113 | offset = (info->label_block + 1); | 118 | offset = (info->label_block + 1); |
114 | size = bdev->bd_inode->i_size >> 9; | 119 | size = i_size >> 9; |
115 | } | 120 | } |
116 | put_partition(state, 1, offset*(blocksize >> 9), | 121 | put_partition(state, 1, offset*(blocksize >> 9), |
117 | size-offset*(blocksize >> 9)); | 122 | size-offset*(blocksize >> 9)); |
@@ -168,7 +173,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
168 | else | 173 | else |
169 | printk("(nonl)/%8s:", name); | 174 | printk("(nonl)/%8s:", name); |
170 | offset = (info->label_block + 1); | 175 | offset = (info->label_block + 1); |
171 | size = (bdev->bd_inode->i_size >> 9); | 176 | size = i_size >> 9; |
172 | put_partition(state, 1, offset*(blocksize >> 9), | 177 | put_partition(state, 1, offset*(blocksize >> 9), |
173 | size-offset*(blocksize >> 9)); | 178 | size-offset*(blocksize >> 9)); |
174 | } | 179 | } |
@@ -180,7 +185,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
180 | return 1; | 185 | return 1; |
181 | 186 | ||
182 | out_readerr: | 187 | out_readerr: |
183 | out_badsect: | ||
184 | out_noioctl: | 188 | out_noioctl: |
185 | kfree(label); | 189 | kfree(label); |
186 | out_nolab: | 190 | out_nolab: |
@@ -605,7 +605,7 @@ struct file_operations rdwr_fifo_fops = { | |||
605 | .fasync = pipe_rdwr_fasync, | 605 | .fasync = pipe_rdwr_fasync, |
606 | }; | 606 | }; |
607 | 607 | ||
608 | struct file_operations read_pipe_fops = { | 608 | static struct file_operations read_pipe_fops = { |
609 | .llseek = no_llseek, | 609 | .llseek = no_llseek, |
610 | .read = pipe_read, | 610 | .read = pipe_read, |
611 | .readv = pipe_readv, | 611 | .readv = pipe_readv, |
@@ -617,7 +617,7 @@ struct file_operations read_pipe_fops = { | |||
617 | .fasync = pipe_read_fasync, | 617 | .fasync = pipe_read_fasync, |
618 | }; | 618 | }; |
619 | 619 | ||
620 | struct file_operations write_pipe_fops = { | 620 | static struct file_operations write_pipe_fops = { |
621 | .llseek = no_llseek, | 621 | .llseek = no_llseek, |
622 | .read = bad_pipe_r, | 622 | .read = bad_pipe_r, |
623 | .write = pipe_write, | 623 | .write = pipe_write, |
@@ -629,7 +629,7 @@ struct file_operations write_pipe_fops = { | |||
629 | .fasync = pipe_write_fasync, | 629 | .fasync = pipe_write_fasync, |
630 | }; | 630 | }; |
631 | 631 | ||
632 | struct file_operations rdwr_pipe_fops = { | 632 | static struct file_operations rdwr_pipe_fops = { |
633 | .llseek = no_llseek, | 633 | .llseek = no_llseek, |
634 | .read = pipe_read, | 634 | .read = pipe_read, |
635 | .readv = pipe_readv, | 635 | .readv = pipe_readv, |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 395e582ee542..d04cff2273b6 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1045,10 +1045,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | inode->i_uid = le32_to_cpu(fe->uid); | 1047 | inode->i_uid = le32_to_cpu(fe->uid); |
1048 | if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid; | 1048 | if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb, |
1049 | UDF_FLAG_UID_IGNORE)) | ||
1050 | inode->i_uid = UDF_SB(inode->i_sb)->s_uid; | ||
1049 | 1051 | ||
1050 | inode->i_gid = le32_to_cpu(fe->gid); | 1052 | inode->i_gid = le32_to_cpu(fe->gid); |
1051 | if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid; | 1053 | if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb, |
1054 | UDF_FLAG_GID_IGNORE)) | ||
1055 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; | ||
1052 | 1056 | ||
1053 | inode->i_nlink = le16_to_cpu(fe->fileLinkCount); | 1057 | inode->i_nlink = le16_to_cpu(fe->fileLinkCount); |
1054 | if (!inode->i_nlink) | 1058 | if (!inode->i_nlink) |
@@ -1335,10 +1339,14 @@ udf_update_inode(struct inode *inode, int do_sync) | |||
1335 | return err; | 1339 | return err; |
1336 | } | 1340 | } |
1337 | 1341 | ||
1338 | if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) | 1342 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) |
1343 | fe->uid = cpu_to_le32(-1); | ||
1344 | else if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) | ||
1339 | fe->uid = cpu_to_le32(inode->i_uid); | 1345 | fe->uid = cpu_to_le32(inode->i_uid); |
1340 | 1346 | ||
1341 | if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) | 1347 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) |
1348 | fe->gid = cpu_to_le32(-1); | ||
1349 | else if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) | ||
1342 | fe->gid = cpu_to_le32(inode->i_gid); | 1350 | fe->gid = cpu_to_le32(inode->i_gid); |
1343 | 1351 | ||
1344 | udfperms = ((inode->i_mode & S_IRWXO) ) | | 1352 | udfperms = ((inode->i_mode & S_IRWXO) ) | |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 4a6f49adc609..368d8f81fe54 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -269,7 +269,7 @@ enum { | |||
269 | Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock, | 269 | Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock, |
270 | Opt_anchor, Opt_volume, Opt_partition, Opt_fileset, | 270 | Opt_anchor, Opt_volume, Opt_partition, Opt_fileset, |
271 | Opt_rootdir, Opt_utf8, Opt_iocharset, | 271 | Opt_rootdir, Opt_utf8, Opt_iocharset, |
272 | Opt_err | 272 | Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore |
273 | }; | 273 | }; |
274 | 274 | ||
275 | static match_table_t tokens = { | 275 | static match_table_t tokens = { |
@@ -282,6 +282,10 @@ static match_table_t tokens = { | |||
282 | {Opt_adinicb, "adinicb"}, | 282 | {Opt_adinicb, "adinicb"}, |
283 | {Opt_shortad, "shortad"}, | 283 | {Opt_shortad, "shortad"}, |
284 | {Opt_longad, "longad"}, | 284 | {Opt_longad, "longad"}, |
285 | {Opt_uforget, "uid=forget"}, | ||
286 | {Opt_uignore, "uid=ignore"}, | ||
287 | {Opt_gforget, "gid=forget"}, | ||
288 | {Opt_gignore, "gid=ignore"}, | ||
285 | {Opt_gid, "gid=%u"}, | 289 | {Opt_gid, "gid=%u"}, |
286 | {Opt_uid, "uid=%u"}, | 290 | {Opt_uid, "uid=%u"}, |
287 | {Opt_umask, "umask=%o"}, | 291 | {Opt_umask, "umask=%o"}, |
@@ -414,6 +418,18 @@ udf_parse_options(char *options, struct udf_options *uopt) | |||
414 | uopt->flags |= (1 << UDF_FLAG_NLS_MAP); | 418 | uopt->flags |= (1 << UDF_FLAG_NLS_MAP); |
415 | break; | 419 | break; |
416 | #endif | 420 | #endif |
421 | case Opt_uignore: | ||
422 | uopt->flags |= (1 << UDF_FLAG_UID_IGNORE); | ||
423 | break; | ||
424 | case Opt_uforget: | ||
425 | uopt->flags |= (1 << UDF_FLAG_UID_FORGET); | ||
426 | break; | ||
427 | case Opt_gignore: | ||
428 | uopt->flags |= (1 << UDF_FLAG_GID_IGNORE); | ||
429 | break; | ||
430 | case Opt_gforget: | ||
431 | uopt->flags |= (1 << UDF_FLAG_GID_FORGET); | ||
432 | break; | ||
417 | default: | 433 | default: |
418 | printk(KERN_ERR "udf: bad mount option \"%s\" " | 434 | printk(KERN_ERR "udf: bad mount option \"%s\" " |
419 | "or missing value\n", p); | 435 | "or missing value\n", p); |
diff --git a/fs/udf/udf_sb.h b/fs/udf/udf_sb.h index 663669810be6..110f8d62616f 100644 --- a/fs/udf/udf_sb.h +++ b/fs/udf/udf_sb.h | |||
@@ -20,6 +20,10 @@ | |||
20 | #define UDF_FLAG_VARCONV 8 | 20 | #define UDF_FLAG_VARCONV 8 |
21 | #define UDF_FLAG_NLS_MAP 9 | 21 | #define UDF_FLAG_NLS_MAP 9 |
22 | #define UDF_FLAG_UTF8 10 | 22 | #define UDF_FLAG_UTF8 10 |
23 | #define UDF_FLAG_UID_FORGET 11 /* save -1 for uid to disk */ | ||
24 | #define UDF_FLAG_UID_IGNORE 12 /* use sb uid instead of on disk uid */ | ||
25 | #define UDF_FLAG_GID_FORGET 13 | ||
26 | #define UDF_FLAG_GID_IGNORE 14 | ||
23 | 27 | ||
24 | #define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001 | 28 | #define UDF_PART_FLAG_UNALLOC_BITMAP 0x0001 |
25 | #define UDF_PART_FLAG_UNALLOC_TABLE 0x0002 | 29 | #define UDF_PART_FLAG_UNALLOC_TABLE 0x0002 |