diff options
Diffstat (limited to 'fs')
65 files changed, 469 insertions, 784 deletions
diff --git a/fs/9p/acl.c b/fs/9p/acl.c index e98f56d3787..814be079c18 100644 --- a/fs/9p/acl.c +++ b/fs/9p/acl.c @@ -96,14 +96,11 @@ static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type) return acl; } -int v9fs_check_acl(struct inode *inode, int mask) +struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type) { struct posix_acl *acl; struct v9fs_session_info *v9ses; - if (mask & MAY_NOT_BLOCK) - return -ECHILD; - v9ses = v9fs_inode2v9ses(inode); if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) || ((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) { @@ -111,18 +108,10 @@ int v9fs_check_acl(struct inode *inode, int mask) * On access = client and acl = on mode get the acl * values from the server */ - return 0; + return NULL; } - acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); + return v9fs_get_cached_acl(inode, type); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - return -EAGAIN; } static int v9fs_set_acl(struct dentry *dentry, int type, struct posix_acl *acl) @@ -165,32 +154,32 @@ err_free_out: int v9fs_acl_chmod(struct dentry *dentry) { int retval = 0; - struct posix_acl *acl, *clone; + struct posix_acl *acl; struct inode *inode = dentry->d_inode; if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS); if (acl) { - clone = posix_acl_clone(acl, GFP_KERNEL); + retval = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (retval) + return retval; + retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, acl); posix_acl_release(acl); - if (!clone) - return -ENOMEM; - retval = posix_acl_chmod_masq(clone, inode->i_mode); - if (!retval) - retval = v9fs_set_acl(dentry, ACL_TYPE_ACCESS, clone); - posix_acl_release(clone); } return retval; } int v9fs_set_create_acl(struct dentry *dentry, - struct posix_acl *dpacl, struct posix_acl *pacl) + struct posix_acl **dpacl, struct posix_acl **pacl) { - v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, dpacl); - v9fs_set_acl(dentry, ACL_TYPE_ACCESS, pacl); - posix_acl_release(dpacl); - posix_acl_release(pacl); + if (dentry) { + v9fs_set_acl(dentry, ACL_TYPE_DEFAULT, *dpacl); + v9fs_set_acl(dentry, ACL_TYPE_ACCESS, *pacl); + } + posix_acl_release(*dpacl); + posix_acl_release(*pacl); + *dpacl = *pacl = NULL; return 0; } @@ -209,29 +198,18 @@ int v9fs_acl_mode(struct inode *dir, mode_t *modep, mode &= ~current_umask(); } if (acl) { - struct posix_acl *clone; - if (S_ISDIR(mode)) - *dpacl = acl; - clone = posix_acl_clone(acl, GFP_NOFS); - retval = -ENOMEM; - if (!clone) - goto cleanup; - - retval = posix_acl_create_masq(clone, &mode); - if (retval < 0) { - posix_acl_release(clone); - goto cleanup; - } + *dpacl = posix_acl_dup(acl); + retval = posix_acl_create(&acl, GFP_NOFS, &mode); + if (retval < 0) + return retval; if (retval > 0) - *pacl = clone; + *pacl = acl; + else + posix_acl_release(acl); } *modep = mode; return 0; -cleanup: - posix_acl_release(acl); - return retval; - } static int v9fs_remote_get_acl(struct dentry *dentry, const char *name, diff --git a/fs/9p/acl.h b/fs/9p/acl.h index 59e18c2e8c7..ddb7ae19d97 100644 --- a/fs/9p/acl.h +++ b/fs/9p/acl.h @@ -16,14 +16,14 @@ #ifdef CONFIG_9P_FS_POSIX_ACL extern int v9fs_get_acl(struct inode *, struct p9_fid *); -extern int v9fs_check_acl(struct inode *inode, int mask); +extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type); extern int v9fs_acl_chmod(struct dentry *); extern int v9fs_set_create_acl(struct dentry *, - struct posix_acl *, struct posix_acl *); + struct posix_acl **, struct posix_acl **); extern int v9fs_acl_mode(struct inode *dir, mode_t *modep, struct posix_acl **dpacl, struct posix_acl **pacl); #else -#define v9fs_check_acl NULL +#define v9fs_iop_get_acl NULL static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid) { return 0; @@ -33,8 +33,8 @@ static inline int v9fs_acl_chmod(struct dentry *dentry) return 0; } static inline int v9fs_set_create_acl(struct dentry *dentry, - struct posix_acl *dpacl, - struct posix_acl *pacl) + struct posix_acl **dpacl, + struct posix_acl **pacl) { return 0; } diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 276f4a69ecd..9a26dce5a99 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -287,7 +287,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, goto error; /* Now set the ACL based on the default value */ - v9fs_set_create_acl(dentry, dacl, pacl); + v9fs_set_create_acl(dentry, &dacl, &pacl); v9inode = V9FS_I(inode); mutex_lock(&v9inode->v_mutex); @@ -328,6 +328,7 @@ error: err_clunk_old_fid: if (ofid) p9_client_clunk(ofid); + v9fs_set_create_acl(NULL, &dacl, &pacl); return err; } @@ -421,12 +422,13 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, d_instantiate(dentry, inode); } /* Now set the ACL based on the default value */ - v9fs_set_create_acl(dentry, dacl, pacl); + v9fs_set_create_acl(dentry, &dacl, &pacl); inc_nlink(dir); v9fs_invalidate_inode_attr(dir); error: if (fid) p9_client_clunk(fid); + v9fs_set_create_acl(NULL, &dacl, &pacl); return err; } @@ -826,10 +828,11 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode, d_instantiate(dentry, inode); } /* Now set the ACL based on the default value */ - v9fs_set_create_acl(dentry, dacl, pacl); + v9fs_set_create_acl(dentry, &dacl, &pacl); error: if (fid) p9_client_clunk(fid); + v9fs_set_create_acl(NULL, &dacl, &pacl); return err; } @@ -914,7 +917,7 @@ const struct inode_operations v9fs_dir_inode_operations_dotl = { .getxattr = generic_getxattr, .removexattr = generic_removexattr, .listxattr = v9fs_listxattr, - .check_acl = v9fs_check_acl, + .get_acl = v9fs_iop_get_acl, }; const struct inode_operations v9fs_file_inode_operations_dotl = { @@ -924,7 +927,7 @@ const struct inode_operations v9fs_file_inode_operations_dotl = { .getxattr = generic_getxattr, .removexattr = generic_removexattr, .listxattr = v9fs_listxattr, - .check_acl = v9fs_check_acl, + .get_acl = v9fs_iop_get_acl, }; const struct inode_operations v9fs_symlink_inode_operations_dotl = { diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index c5567cb7843..4d433d34736 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -233,7 +233,7 @@ static int __init anon_inode_init(void) return 0; err_mntput: - mntput(anon_inode_mnt); + kern_unmount(anon_inode_mnt); err_unregister_filesystem: unregister_filesystem(&anon_inode_fs_type); err_exit: diff --git a/fs/block_dev.c b/fs/block_dev.c index 9fb0b15331d..c62fb84944d 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1448,6 +1448,8 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) int blkdev_put(struct block_device *bdev, fmode_t mode) { + mutex_lock(&bdev->bd_mutex); + if (mode & FMODE_EXCL) { bool bdev_free; @@ -1456,7 +1458,6 @@ int blkdev_put(struct block_device *bdev, fmode_t mode) * are protected with bdev_lock. bd_mutex is to * synchronize disk_holder unlinking. */ - mutex_lock(&bdev->bd_mutex); spin_lock(&bdev_lock); WARN_ON_ONCE(--bdev->bd_holders < 0); @@ -1474,17 +1475,21 @@ int blkdev_put(struct block_device *bdev, fmode_t mode) * If this was the last claim, remove holder link and * unblock evpoll if it was a write holder. */ - if (bdev_free) { - if (bdev->bd_write_holder) { - disk_unblock_events(bdev->bd_disk); - disk_check_events(bdev->bd_disk); - bdev->bd_write_holder = false; - } + if (bdev_free && bdev->bd_write_holder) { + disk_unblock_events(bdev->bd_disk); + bdev->bd_write_holder = false; } - - mutex_unlock(&bdev->bd_mutex); } + /* + * Trigger event checking and tell drivers to flush MEDIA_CHANGE + * event. This is to ensure detection of media removal commanded + * from userland - e.g. eject(1). + */ + disk_flush_events(bdev->bd_disk, DISK_EVENT_MEDIA_CHANGE); + + mutex_unlock(&bdev->bd_mutex); + return __blkdev_put(bdev, mode, 0); } EXPORT_SYMBOL(blkdev_put); diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 9f62ab2a728..65a735d8f6e 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -30,7 +30,7 @@ #ifdef CONFIG_BTRFS_FS_POSIX_ACL -static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) +struct posix_acl *btrfs_get_acl(struct inode *inode, int type) { int size; const char *name; @@ -195,27 +195,6 @@ out: return ret; } -int btrfs_check_acl(struct inode *inode, int mask) -{ - int error = -EAGAIN; - - if (mask & MAY_NOT_BLOCK) { - if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) - error = -ECHILD; - } else { - struct posix_acl *acl; - acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - } - } - - return error; -} - /* * btrfs_init_acl is already generally called under fs_mutex, so the locking * stuff has been fixed to work with that. If the locking stuff changes, we @@ -243,8 +222,7 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, } if (IS_POSIXACL(dir) && acl) { - struct posix_acl *clone; - mode_t mode; + mode_t mode = inode->i_mode; if (S_ISDIR(inode->i_mode)) { ret = btrfs_set_acl(trans, inode, acl, @@ -252,22 +230,15 @@ int btrfs_init_acl(struct btrfs_trans_handle *trans, if (ret) goto failed; } - clone = posix_acl_clone(acl, GFP_NOFS); - ret = -ENOMEM; - if (!clone) - goto failed; + ret = posix_acl_create(&acl, GFP_NOFS, &mode); + if (ret < 0) + return ret; - mode = inode->i_mode; - ret = posix_acl_create_masq(clone, &mode); - if (ret >= 0) { - inode->i_mode = mode; - if (ret > 0) { - /* we need an acl */ - ret = btrfs_set_acl(trans, inode, clone, - ACL_TYPE_ACCESS); - } + inode->i_mode = mode; + if (ret > 0) { + /* we need an acl */ + ret = btrfs_set_acl(trans, inode, acl, ACL_TYPE_ACCESS); } - posix_acl_release(clone); } failed: posix_acl_release(acl); @@ -277,7 +248,7 @@ failed: int btrfs_acl_chmod(struct inode *inode) { - struct posix_acl *acl, *clone; + struct posix_acl *acl; int ret = 0; if (S_ISLNK(inode->i_mode)) @@ -290,17 +261,11 @@ int btrfs_acl_chmod(struct inode *inode) if (IS_ERR_OR_NULL(acl)) return PTR_ERR(acl); - clone = posix_acl_clone(acl, GFP_KERNEL); + ret = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); + if (ret) + return ret; + ret = btrfs_set_acl(NULL, inode, acl, ACL_TYPE_ACCESS); posix_acl_release(acl); - if (!clone) - return -ENOMEM; - - ret = posix_acl_chmod_masq(clone, inode->i_mode); - if (!ret) - ret = btrfs_set_acl(NULL, inode, clone, ACL_TYPE_ACCESS); - - posix_acl_release(clone); - return ret; } diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 82be74efbb2..fe9287b0649 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2645,9 +2645,9 @@ do { \ /* acl.c */ #ifdef CONFIG_BTRFS_FS_POSIX_ACL -int btrfs_check_acl(struct inode *inode, int mask); +struct posix_acl *btrfs_get_acl(struct inode *inode, int type); #else -#define btrfs_check_acl NULL +#define btrfs_get_acl NULL #endif int btrfs_init_acl(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2548a04a023..e91b097e725 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7351,12 +7351,12 @@ static const struct inode_operations btrfs_dir_inode_operations = { .listxattr = btrfs_listxattr, .removexattr = btrfs_removexattr, .permission = btrfs_permission, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; static const struct inode_operations btrfs_dir_ro_inode_operations = { .lookup = btrfs_lookup, .permission = btrfs_permission, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; static const struct file_operations btrfs_dir_file_operations = { @@ -7425,7 +7425,7 @@ static const struct inode_operations btrfs_file_inode_operations = { .removexattr = btrfs_removexattr, .permission = btrfs_permission, .fiemap = btrfs_fiemap, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; static const struct inode_operations btrfs_special_inode_operations = { .getattr = btrfs_getattr, @@ -7435,7 +7435,7 @@ static const struct inode_operations btrfs_special_inode_operations = { .getxattr = btrfs_getxattr, .listxattr = btrfs_listxattr, .removexattr = btrfs_removexattr, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; static const struct inode_operations btrfs_symlink_inode_operations = { .readlink = generic_readlink, @@ -7447,7 +7447,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { .getxattr = btrfs_getxattr, .listxattr = btrfs_listxattr, .removexattr = btrfs_removexattr, - .check_acl = btrfs_check_acl, + .get_acl = btrfs_get_acl, }; const struct dentry_operations btrfs_dentry_operations = { diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 14d602f178c..499f27fc857 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -641,7 +641,7 @@ lookup_out: static int cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) { - if (nd->flags & LOOKUP_RCU) + if (nd && (nd->flags & LOOKUP_RCU)) return -ECHILD; if (direntry->d_inode) { diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 61abb638b4b..8be086e9abe 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -68,6 +68,8 @@ #ifdef CONFIG_BLOCK #include <linux/loop.h> +#include <linux/cdrom.h> +#include <linux/fd.h> #include <scsi/scsi.h> #include <scsi/scsi_ioctl.h> #include <scsi/sg.h> @@ -944,6 +946,9 @@ COMPATIBLE_IOCTL(FIOQSIZE) IGNORE_IOCTL(LOOP_CLR_FD) /* md calls this on random blockdevs */ IGNORE_IOCTL(RAID_VERSION) +/* qemu/qemu-img might call these two on plain files for probing */ +IGNORE_IOCTL(CDROM_DRIVE_STATUS) +IGNORE_IOCTL(FDGETPRM32) /* SG stuff */ COMPATIBLE_IOCTL(SG_SET_TIMEOUT) COMPATIBLE_IOCTL(SG_GET_TIMEOUT) diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 27a7fefb83e..fa8049ecdc6 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -2248,7 +2248,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes, auth_tok->token.password.session_key_encryption_key, crypt_stat->key_size); ecryptfs_printk(KERN_DEBUG, - "Cached session key " "encryption key: \n"); + "Cached session key encryption key:\n"); if (ecryptfs_verbosity > 0) ecryptfs_dump_hex(session_key_encryption_key, 16); } diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index bfe651f9ae1..52c05376394 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -128,7 +128,7 @@ fail: /* * inode->i_mutex: don't care */ -static struct posix_acl * +struct posix_acl * ext2_get_acl(struct inode *inode, int type) { int name_index; @@ -231,29 +231,6 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) return error; } -int -ext2_check_acl(struct inode *inode, int mask) -{ - struct posix_acl *acl; - - if (mask & MAY_NOT_BLOCK) { - if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) - return -ECHILD; - return -EAGAIN; - } - - acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); - if (IS_ERR(acl)) - return PTR_ERR(acl); - if (acl) { - int error = posix_acl_permission(inode, acl, mask); - posix_acl_release(acl); - return error; - } - - return -EAGAIN; -} - /* * Initialize the ACLs of a new inode. Called from ext2_new_inode. * @@ -276,29 +253,20 @@ ext2_init_acl(struct inode *inode, struct inode *dir) inode->i_mode &= ~current_umask(); } if (test_opt(inode->i_sb, POSIX_ACL) && acl) { - struct posix_acl *clone; - mode_t mode; - + mode_t mode = inode->i_mode; if (S_ISDIR(inode->i_mode)) { error = ext2_set_acl(inode, ACL_TYPE_DEFAULT, acl); if (error) goto cleanup; } - |