diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:32:11 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:32:11 -0400 |
| commit | 6c5daf012c9155aafd2c7973e4278766c30dfad0 (patch) | |
| tree | 33959d7b36d03e1610615641a2940cb2de5e8603 /fs | |
| parent | 6d39b27f0ac7e805ae3bd9efa51d7da04bec0360 (diff) | |
| parent | c08d3b0e33edce28e9cfa7b64f7fe5bdeeb29248 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
truncate: use new helpers
truncate: new helpers
fs: fix overflow in sys_mount() for in-kernel calls
fs: Make unload_nls() NULL pointer safe
freeze_bdev: grab active reference to frozen superblocks
freeze_bdev: kill bd_mount_sem
exofs: remove BKL from super operations
fs/romfs: correct error-handling code
vfs: seq_file: add helpers for data filling
vfs: remove redundant position check in do_sendfile
vfs: change sb->s_maxbytes to a loff_t
vfs: explicitly cast s_maxbytes in fiemap_check_ranges
libfs: return error code on failed attr set
seq_file: return a negative error code when seq_path_root() fails.
vfs: optimize touch_time() too
vfs: optimization for touch_atime()
vfs: split generic_forget_inode() so that hugetlbfs does not have to copy it
fs/inode.c: add dev-id and inode number for debugging in init_special_inode()
libfs: make simple_read_from_buffer conventional
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/attr.c | 46 | ||||
| -rw-r--r-- | fs/befs/linuxvfs.c | 7 | ||||
| -rw-r--r-- | fs/block_dev.c | 140 | ||||
| -rw-r--r-- | fs/buffer.c | 10 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 3 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 53 | ||||
| -rw-r--r-- | fs/compat.c | 24 | ||||
| -rw-r--r-- | fs/exofs/super.c | 6 | ||||
| -rw-r--r-- | fs/fat/inode.c | 16 | ||||
| -rw-r--r-- | fs/fuse/dir.c | 14 | ||||
| -rw-r--r-- | fs/fuse/fuse_i.h | 2 | ||||
| -rw-r--r-- | fs/fuse/inode.c | 11 | ||||
| -rw-r--r-- | fs/hfs/mdb.c | 6 | ||||
| -rw-r--r-- | fs/hfsplus/super.c | 6 | ||||
| -rw-r--r-- | fs/hugetlbfs/inode.c | 33 | ||||
| -rw-r--r-- | fs/inode.c | 89 | ||||
| -rw-r--r-- | fs/internal.h | 1 | ||||
| -rw-r--r-- | fs/ioctl.c | 9 | ||||
| -rw-r--r-- | fs/isofs/inode.c | 8 | ||||
| -rw-r--r-- | fs/jfs/super.c | 9 | ||||
| -rw-r--r-- | fs/libfs.c | 13 | ||||
| -rw-r--r-- | fs/namespace.c | 77 | ||||
| -rw-r--r-- | fs/ncpfs/inode.c | 12 | ||||
| -rw-r--r-- | fs/ncpfs/ioctl.c | 6 | ||||
| -rw-r--r-- | fs/nfs/inode.c | 54 | ||||
| -rw-r--r-- | fs/nls/nls_base.c | 3 | ||||
| -rw-r--r-- | fs/ntfs/super.c | 10 | ||||
| -rw-r--r-- | fs/ramfs/file-nommu.c | 18 | ||||
| -rw-r--r-- | fs/read_write.c | 3 | ||||
| -rw-r--r-- | fs/seq_file.c | 74 | ||||
| -rw-r--r-- | fs/smbfs/inode.c | 10 | ||||
| -rw-r--r-- | fs/super.c | 67 |
32 files changed, 415 insertions, 425 deletions
| @@ -18,7 +18,7 @@ | |||
| 18 | /* Taken over from the old code... */ | 18 | /* Taken over from the old code... */ |
| 19 | 19 | ||
| 20 | /* POSIX UID/GID verification for setting inode attributes. */ | 20 | /* POSIX UID/GID verification for setting inode attributes. */ |
| 21 | int inode_change_ok(struct inode *inode, struct iattr *attr) | 21 | int inode_change_ok(const struct inode *inode, struct iattr *attr) |
| 22 | { | 22 | { |
| 23 | int retval = -EPERM; | 23 | int retval = -EPERM; |
| 24 | unsigned int ia_valid = attr->ia_valid; | 24 | unsigned int ia_valid = attr->ia_valid; |
| @@ -60,9 +60,51 @@ fine: | |||
| 60 | error: | 60 | error: |
| 61 | return retval; | 61 | return retval; |
| 62 | } | 62 | } |
| 63 | |||
| 64 | EXPORT_SYMBOL(inode_change_ok); | 63 | EXPORT_SYMBOL(inode_change_ok); |
| 65 | 64 | ||
| 65 | /** | ||
| 66 | * inode_newsize_ok - may this inode be truncated to a given size | ||
| 67 | * @inode: the inode to be truncated | ||
| 68 | * @offset: the new size to assign to the inode | ||
| 69 | * @Returns: 0 on success, -ve errno on failure | ||
| 70 | * | ||
| 71 | * inode_newsize_ok will check filesystem limits and ulimits to check that the | ||
| 72 | * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ | ||
| 73 | * when necessary. Caller must not proceed with inode size change if failure is | ||
| 74 | * returned. @inode must be a file (not directory), with appropriate | ||
| 75 | * permissions to allow truncate (inode_newsize_ok does NOT check these | ||
| 76 | * conditions). | ||
| 77 | * | ||
| 78 | * inode_newsize_ok must be called with i_mutex held. | ||
| 79 | */ | ||
| 80 | int inode_newsize_ok(const struct inode *inode, loff_t offset) | ||
| 81 | { | ||
| 82 | if (inode->i_size < offset) { | ||
| 83 | unsigned long limit; | ||
| 84 | |||
| 85 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | ||
| 86 | if (limit != RLIM_INFINITY && offset > limit) | ||
| 87 | goto out_sig; | ||
| 88 | if (offset > inode->i_sb->s_maxbytes) | ||
| 89 | goto out_big; | ||
| 90 | } else { | ||
| 91 | /* | ||
| 92 | * truncation of in-use swapfiles is disallowed - it would | ||
| 93 | * cause subsequent swapout to scribble on the now-freed | ||
| 94 | * blocks. | ||
| 95 | */ | ||
| 96 | if (IS_SWAPFILE(inode)) | ||
| 97 | return -ETXTBSY; | ||
| 98 | } | ||
| 99 | |||
| 100 | return 0; | ||
| 101 | out_sig: | ||
| 102 | send_sig(SIGXFSZ, current, 0); | ||
| 103 | out_big: | ||
| 104 | return -EFBIG; | ||
| 105 | } | ||
| 106 | EXPORT_SYMBOL(inode_newsize_ok); | ||
| 107 | |||
| 66 | int inode_setattr(struct inode * inode, struct iattr * attr) | 108 | int inode_setattr(struct inode * inode, struct iattr * attr) |
| 67 | { | 109 | { |
| 68 | unsigned int ia_valid = attr->ia_valid; | 110 | unsigned int ia_valid = attr->ia_valid; |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index dd376c124e71..33baf27fac78 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
| @@ -737,12 +737,7 @@ befs_put_super(struct super_block *sb) | |||
| 737 | { | 737 | { |
| 738 | kfree(BEFS_SB(sb)->mount_opts.iocharset); | 738 | kfree(BEFS_SB(sb)->mount_opts.iocharset); |
| 739 | BEFS_SB(sb)->mount_opts.iocharset = NULL; | 739 | BEFS_SB(sb)->mount_opts.iocharset = NULL; |
| 740 | 740 | unload_nls(BEFS_SB(sb)->nls); | |
| 741 | if (BEFS_SB(sb)->nls) { | ||
| 742 | unload_nls(BEFS_SB(sb)->nls); | ||
| 743 | BEFS_SB(sb)->nls = NULL; | ||
| 744 | } | ||
| 745 | |||
| 746 | kfree(sb->s_fs_info); | 741 | kfree(sb->s_fs_info); |
| 747 | sb->s_fs_info = NULL; | 742 | sb->s_fs_info = NULL; |
| 748 | } | 743 | } |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 5d1ed50bd46c..9cf4b926f8e4 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -216,8 +216,6 @@ EXPORT_SYMBOL(fsync_bdev); | |||
| 216 | * freeze_bdev -- lock a filesystem and force it into a consistent state | 216 | * freeze_bdev -- lock a filesystem and force it into a consistent state |
| 217 | * @bdev: blockdevice to lock | 217 | * @bdev: blockdevice to lock |
| 218 | * | 218 | * |
| 219 | * This takes the block device bd_mount_sem to make sure no new mounts | ||
| 220 | * happen on bdev until thaw_bdev() is called. | ||
| 221 | * If a superblock is found on this device, we take the s_umount semaphore | 219 | * If a superblock is found on this device, we take the s_umount semaphore |
| 222 | * on it to make sure nobody unmounts until the snapshot creation is done. | 220 | * on it to make sure nobody unmounts until the snapshot creation is done. |
| 223 | * The reference counter (bd_fsfreeze_count) guarantees that only the last | 221 | * The reference counter (bd_fsfreeze_count) guarantees that only the last |
| @@ -232,46 +230,55 @@ struct super_block *freeze_bdev(struct block_device *bdev) | |||
| 232 | int error = 0; | 230 | int error = 0; |
| 233 | 231 | ||
| 234 | mutex_lock(&bdev->bd_fsfreeze_mutex); | 232 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
| 235 | if (bdev->bd_fsfreeze_count > 0) { | 233 | if (++bdev->bd_fsfreeze_count > 1) { |
| 236 | bdev->bd_fsfreeze_count++; | 234 | /* |
| 235 | * We don't even need to grab a reference - the first call | ||
| 236 | * to freeze_bdev grab an active reference and only the last | ||
| 237 | * thaw_bdev drops it. | ||
| 238 | */ | ||
| 237 | sb = get_super(bdev); | 239 | sb = get_super(bdev); |
| 240 | drop_super(sb); | ||
| 238 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 241 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| 239 | return sb; | 242 | return sb; |
| 240 | } | 243 | } |
| 241 | bdev->bd_fsfreeze_count++; | 244 | |
| 242 | 245 | sb = get_active_super(bdev); | |
| 243 | down(&bdev->bd_mount_sem); | 246 | if (!sb) |
| 244 | sb = get_super(bdev); | 247 | goto out; |
| 245 | if (sb && !(sb->s_flags & MS_RDONLY)) { | 248 | if (sb->s_flags & MS_RDONLY) { |
| 246 | sb->s_frozen = SB_FREEZE_WRITE; | 249 | deactivate_locked_super(sb); |
| 247 | smp_wmb(); | 250 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| 248 | 251 | return sb; | |
| 249 | sync_filesystem(sb); | 252 | } |
| 250 | 253 | ||
| 251 | sb->s_frozen = SB_FREEZE_TRANS; | 254 | sb->s_frozen = SB_FREEZE_WRITE; |
| 252 | smp_wmb(); | 255 | smp_wmb(); |
| 253 | 256 | ||
| 254 | sync_blockdev(sb->s_bdev); | 257 | sync_filesystem(sb); |
| 255 | 258 | ||
| 256 | if (sb->s_op->freeze_fs) { | 259 | sb->s_frozen = SB_FREEZE_TRANS; |
| 257 | error = sb->s_op->freeze_fs(sb); | 260 | smp_wmb(); |
| 258 | if (error) { | 261 | |
| 259 | printk(KERN_ERR | 262 | sync_blockdev(sb->s_bdev); |
| 260 | "VFS:Filesystem freeze failed\n"); | 263 | |
| 261 | sb->s_frozen = SB_UNFROZEN; | ||
