diff options
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 |
