Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc vfs updates from Al Viro: "Assorted misc bits and pieces. There are several single-topic branches left after this (rename2 series from Miklos, current_time series from Deepa Dinamani, xattr series from Andreas, uaccess stuff from from me) and I'd prefer to send those separately" * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (39 commits) proc: switch auxv to use of __mem_open() hpfs: support FIEMAP cifs: get rid of unused arguments of CIFSSMBWrite() posix_acl: uapi header split posix_acl: xattr representation cleanups fs/aio.c: eliminate redundant loads in put_aio_ring_file fs/internal.h: add const to ns_dentry_operations declaration compat: remove compat_printk() fs/buffer.c: make __getblk_slow() static proc: unsigned file descriptors fs/file: more unsigned file descriptors fs: compat: remove redundant check of nr_segs cachefiles: Fix attempt to read i_blocks after deleting file [ver #2] cifs: don't use memcpy() to copy struct iov_iter get rid of separate multipage fault-in primitives fs: Avoid premature clearing of capabilities fs: Give dentry to inode_change_ok() instead of inode fuse: Propagate dentry down to inode_change_ok() ceph: Propagate dentry down to inode_change_ok() xfs: Propagate dentry down to inode_change_ok() ...
This commit is contained in:
commit
abb5a14fa2
136 changed files with 737 additions and 640 deletions
Documentation/filesystems
arch/parisc/kernel
drivers
gpu/drm
net/wireless/intel/iwlwifi
staging/lustre/lustre
fs
9p
adfs
affs
aio.cattr.cbtrfs
buffer.ccachefiles
ceph
cifs
compat.cecryptfs
exofs
ext2
ext4
f2fs
fat
file.cfuse
gfs2
hfs
hfsplus
hostfs
hpfs
hugetlbfs
inode.cinternal.hjffs2
jfs
kernfs
libfs.clocks.clogfs
minix
namei.cnamespace.cncpfs
nfsd
nilfs2
ntfs
ocfs2
omfs
open.corangefs
overlayfs
posix_acl.cproc
|
@ -287,8 +287,8 @@ implementing on-disk size changes. Start with a copy of the old inode_setattr
|
|||
and vmtruncate, and the reorder the vmtruncate + foofs_vmtruncate sequence to
|
||||
be in order of zeroing blocks using block_truncate_page or similar helpers,
|
||||
size update and on finally on-disk truncation which should not fail.
|
||||
inode_change_ok now includes the size checks for ATTR_SIZE and must be called
|
||||
in the beginning of ->setattr unconditionally.
|
||||
setattr_prepare (which used to be inode_change_ok) now includes the size checks
|
||||
for ATTR_SIZE and must be called in the beginning of ->setattr unconditionally.
|
||||
|
||||
[mandatory]
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ void flush_dcache_page(struct page *page)
|
|||
!= (addr & (SHM_COLOUR - 1))) {
|
||||
__flush_cache_page(mpnt, addr, page_to_phys(page));
|
||||
if (old_addr)
|
||||
printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? (char *)mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
|
||||
printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n", old_addr, addr, mpnt->vm_file);
|
||||
old_addr = addr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -387,7 +387,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
|
|||
if (!access_ok(VERIFY_READ, ptr, args->size))
|
||||
return -EFAULT;
|
||||
|
||||
ret = fault_in_multipages_readable(ptr, args->size);
|
||||
ret = fault_in_pages_readable(ptr, args->size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -104,8 +104,8 @@ int drm_debugfs_create_files(const struct drm_info_list *files, int count,
|
|||
ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO,
|
||||
root, tmp, &drm_debugfs_fops);
|
||||
if (!ent) {
|
||||
DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s/%s\n",
|
||||
root->d_name.name, files[i].name);
|
||||
DRM_ERROR("Cannot create /sys/kernel/debug/dri/%pd/%s\n",
|
||||
root, files[i].name);
|
||||
kfree(tmp);
|
||||
ret = -1;
|
||||
goto fail;
|
||||
|
|
|
@ -675,7 +675,7 @@ i915_gem_gtt_pread(struct drm_device *dev,
|
|||
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
if (likely(!i915.prefault_disable)) {
|
||||
ret = fault_in_multipages_writeable(user_data, remain);
|
||||
ret = fault_in_pages_writeable(user_data, remain);
|
||||
if (ret) {
|
||||
mutex_lock(&dev->struct_mutex);
|
||||
goto out_unpin;
|
||||
|
@ -803,7 +803,7 @@ i915_gem_shmem_pread(struct drm_device *dev,
|
|||
mutex_unlock(&dev->struct_mutex);
|
||||
|
||||
if (likely(!i915.prefault_disable) && !prefaulted) {
|
||||
ret = fault_in_multipages_writeable(user_data, remain);
|
||||
ret = fault_in_pages_writeable(user_data, remain);
|
||||
/* Userspace is tricking us, but we've already clobbered
|
||||
* its pages with the prefault and promised to write the
|
||||
* data up to the first fault. Hence ignore any errors
|
||||
|
@ -1267,7 +1267,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
|
|||
return -EFAULT;
|
||||
|
||||
if (likely(!i915.prefault_disable)) {
|
||||
ret = fault_in_multipages_readable(u64_to_user_ptr(args->data_ptr),
|
||||
ret = fault_in_pages_readable(u64_to_user_ptr(args->data_ptr),
|
||||
args->size);
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
|
|
@ -1048,7 +1048,7 @@ validate_exec_list(struct drm_device *dev,
|
|||
return -EFAULT;
|
||||
|
||||
if (likely(!i915.prefault_disable)) {
|
||||
if (fault_in_multipages_readable(ptr, length))
|
||||
if (fault_in_pages_readable(ptr, length))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -229,8 +229,8 @@ int msm_perf_debugfs_init(struct drm_minor *minor)
|
|||
perf->ent = debugfs_create_file("perf", S_IFREG | S_IRUGO,
|
||||
minor->debugfs_root, perf, &perf_debugfs_fops);
|
||||
if (!perf->ent) {
|
||||
DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s/perf\n",
|
||||
minor->debugfs_root->d_name.name);
|
||||
DRM_ERROR("Cannot create /sys/kernel/debug/dri/%pd/perf\n",
|
||||
minor->debugfs_root);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
|
@ -243,8 +243,8 @@ int msm_rd_debugfs_init(struct drm_minor *minor)
|
|||
rd->ent = debugfs_create_file("rd", S_IFREG | S_IRUGO,
|
||||
minor->debugfs_root, rd, &rd_debugfs_fops);
|
||||
if (!rd->ent) {
|
||||
DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s/rd\n",
|
||||
minor->debugfs_root->d_name.name);
|
||||
DRM_ERROR("Cannot create /sys/kernel/debug/dri/%pd/rd\n",
|
||||
minor->debugfs_root);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
|
@ -2422,14 +2422,12 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir)
|
|||
*/
|
||||
if (priv->mac80211_registered) {
|
||||
char buf[100];
|
||||
struct dentry *mac80211_dir, *dev_dir, *root_dir;
|
||||
struct dentry *mac80211_dir, *dev_dir;
|
||||
|
||||
dev_dir = dbgfs_dir->d_parent;
|
||||
root_dir = dev_dir->d_parent;
|
||||
mac80211_dir = priv->hw->wiphy->debugfsdir;
|
||||
|
||||
snprintf(buf, 100, "../../%s/%s", root_dir->d_name.name,
|
||||
dev_dir->d_name.name);
|
||||
snprintf(buf, 100, "../../%pd2", dev_dir);
|
||||
|
||||
if (!debugfs_create_symlink("iwlwifi", mac80211_dir, buf))
|
||||
goto err;
|
||||
|
|
|
@ -1571,8 +1571,8 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
|
||||
|
||||
if (!mvmvif->dbgfs_dir) {
|
||||
IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
|
||||
dbgfs_dir->d_name.name);
|
||||
IWL_ERR(mvm, "Failed to create debugfs directory under %pd\n",
|
||||
dbgfs_dir);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1627,17 +1627,15 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
* find
|
||||
* netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
|
||||
*/
|
||||
snprintf(buf, 100, "../../../%s/%s/%s/%s",
|
||||
dbgfs_dir->d_parent->d_parent->d_name.name,
|
||||
dbgfs_dir->d_parent->d_name.name,
|
||||
dbgfs_dir->d_name.name,
|
||||
mvmvif->dbgfs_dir->d_name.name);
|
||||
snprintf(buf, 100, "../../../%pd3/%pd",
|
||||
dbgfs_dir,
|
||||
mvmvif->dbgfs_dir);
|
||||
|
||||
mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
|
||||
mvm->debugfs_dir, buf);
|
||||
if (!mvmvif->dbgfs_slink)
|
||||
IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
|
||||
dbgfs_dir->d_name.name);
|
||||
IWL_ERR(mvm, "Can't create debugfs symbolic link under %pd\n",
|
||||
dbgfs_dir);
|
||||
return;
|
||||
err:
|
||||
IWL_ERR(mvm, "Can't create debugfs entity\n");
|
||||
|
|
|
@ -1748,9 +1748,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
|||
* Create a symlink with mac80211. It will be removed when mac80211
|
||||
* exists (before the opmode exists which removes the target.)
|
||||
*/
|
||||
snprintf(buf, 100, "../../%s/%s",
|
||||
dbgfs_dir->d_parent->d_parent->d_name.name,
|
||||
dbgfs_dir->d_parent->d_name.name);
|
||||
snprintf(buf, 100, "../../%pd2", dbgfs_dir->d_parent);
|
||||
if (!debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf))
|
||||
goto err;
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
#include <linux/posix_acl_xattr.h>
|
||||
|
||||
#define LUSTRE_POSIX_ACL_MAX_ENTRIES 32
|
||||
#define LUSTRE_POSIX_ACL_MAX_SIZE \
|
||||
(sizeof(posix_acl_xattr_header) + \
|
||||
LUSTRE_POSIX_ACL_MAX_ENTRIES * sizeof(posix_acl_xattr_entry))
|
||||
#define LUSTRE_POSIX_ACL_MAX_SIZE \
|
||||
(sizeof(struct posix_acl_xattr_header) + \
|
||||
LUSTRE_POSIX_ACL_MAX_ENTRIES * sizeof(struct posix_acl_xattr_entry))
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1121,8 +1121,8 @@ ll_file_io_generic(const struct lu_env *env, struct vvp_io_args *args,
|
|||
struct cl_io *io;
|
||||
ssize_t result;
|
||||
|
||||
CDEBUG(D_VFSTRACE, "file: %s, type: %d ppos: %llu, count: %zu\n",
|
||||
file->f_path.dentry->d_name.name, iot, *ppos, count);
|
||||
CDEBUG(D_VFSTRACE, "file: %pD, type: %d ppos: %llu, count: %zu\n",
|
||||
file, iot, *ppos, count);
|
||||
|
||||
restart:
|
||||
io = vvp_env_thread_io(env);
|
||||
|
|
|
@ -1459,7 +1459,7 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr, bool hsm_import)
|
|||
attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
|
||||
}
|
||||
|
||||
/* POSIX: check before ATTR_*TIME_SET set (from inode_change_ok) */
|
||||
/* POSIX: check before ATTR_*TIME_SET set (from setattr_prepare) */
|
||||
if (attr->ia_valid & TIMES_SET_FLAGS) {
|
||||
if ((!uid_eq(current_fsuid(), inode->i_uid)) &&
|
||||
!capable(CFS_CAP_FOWNER))
|
||||
|
|
|
@ -3742,32 +3742,28 @@ void lustre_assert_wire_constants(void)
|
|||
CLASSERT(FIEMAP_EXTENT_NET == 0x80000000);
|
||||
|
||||
/* Checks for type posix_acl_xattr_entry */
|
||||
LASSERTF((int)sizeof(posix_acl_xattr_entry) == 8, "found %lld\n",
|
||||
(long long)(int)sizeof(posix_acl_xattr_entry));
|
||||
LASSERTF((int)offsetof(posix_acl_xattr_entry, e_tag) == 0, "found %lld\n",
|
||||
(long long)(int)offsetof(posix_acl_xattr_entry, e_tag));
|
||||
LASSERTF((int)sizeof(((posix_acl_xattr_entry *)0)->e_tag) == 2, "found %lld\n",
|
||||
(long long)(int)sizeof(((posix_acl_xattr_entry *)0)->e_tag));
|
||||
LASSERTF((int)offsetof(posix_acl_xattr_entry, e_perm) == 2, "found %lld\n",
|
||||
(long long)(int)offsetof(posix_acl_xattr_entry, e_perm));
|
||||
LASSERTF((int)sizeof(((posix_acl_xattr_entry *)0)->e_perm) == 2, "found %lld\n",
|
||||
(long long)(int)sizeof(((posix_acl_xattr_entry *)0)->e_perm));
|
||||
LASSERTF((int)offsetof(posix_acl_xattr_entry, e_id) == 4, "found %lld\n",
|
||||
(long long)(int)offsetof(posix_acl_xattr_entry, e_id));
|
||||
LASSERTF((int)sizeof(((posix_acl_xattr_entry *)0)->e_id) == 4, "found %lld\n",
|
||||
(long long)(int)sizeof(((posix_acl_xattr_entry *)0)->e_id));
|
||||
LASSERTF((int)sizeof(struct posix_acl_xattr_entry) == 8, "found %lld\n",
|
||||
(long long)(int)sizeof(struct posix_acl_xattr_entry));
|
||||
LASSERTF((int)offsetof(struct posix_acl_xattr_entry, e_tag) == 0, "found %lld\n",
|
||||
(long long)(int)offsetof(struct posix_acl_xattr_entry, e_tag));
|
||||
LASSERTF((int)sizeof(((struct posix_acl_xattr_entry *)0)->e_tag) == 2, "found %lld\n",
|
||||
(long long)(int)sizeof(((struct posix_acl_xattr_entry *)0)->e_tag));
|
||||
LASSERTF((int)offsetof(struct posix_acl_xattr_entry, e_perm) == 2, "found %lld\n",
|
||||
(long long)(int)offsetof(struct posix_acl_xattr_entry, e_perm));
|
||||
LASSERTF((int)sizeof(((struct posix_acl_xattr_entry *)0)->e_perm) == 2, "found %lld\n",
|
||||
(long long)(int)sizeof(((struct posix_acl_xattr_entry *)0)->e_perm));
|
||||
LASSERTF((int)offsetof(struct posix_acl_xattr_entry, e_id) == 4, "found %lld\n",
|
||||
(long long)(int)offsetof(struct posix_acl_xattr_entry, e_id));
|
||||
LASSERTF((int)sizeof(((struct posix_acl_xattr_entry *)0)->e_id) == 4, "found %lld\n",
|
||||
(long long)(int)sizeof(((struct posix_acl_xattr_entry *)0)->e_id));
|
||||
|
||||
/* Checks for type posix_acl_xattr_header */
|
||||
LASSERTF((int)sizeof(posix_acl_xattr_header) == 4, "found %lld\n",
|
||||
(long long)(int)sizeof(posix_acl_xattr_header));
|
||||
LASSERTF((int)offsetof(posix_acl_xattr_header, a_version) == 0, "found %lld\n",
|
||||
(long long)(int)offsetof(posix_acl_xattr_header, a_version));
|
||||
LASSERTF((int)sizeof(((posix_acl_xattr_header *)0)->a_version) == 4, "found %lld\n",
|
||||
(long long)(int)sizeof(((posix_acl_xattr_header *)0)->a_version));
|
||||
LASSERTF((int)offsetof(posix_acl_xattr_header, a_entries) == 4, "found %lld\n",
|
||||
(long long)(int)offsetof(posix_acl_xattr_header, a_entries));
|
||||
LASSERTF((int)sizeof(((posix_acl_xattr_header *)0)->a_entries) == 0, "found %lld\n",
|
||||
(long long)(int)sizeof(((posix_acl_xattr_header *)0)->a_entries));
|
||||
LASSERTF((int)sizeof(struct posix_acl_xattr_header) == 4, "found %lld\n",
|
||||
(long long)(int)sizeof(struct posix_acl_xattr_header));
|
||||
LASSERTF((int)offsetof(struct posix_acl_xattr_header, a_version) == 0, "found %lld\n",
|
||||
(long long)(int)offsetof(struct posix_acl_xattr_header, a_version));
|
||||
LASSERTF((int)sizeof(((struct posix_acl_xattr_header *)0)->a_version) == 4, "found %lld\n",
|
||||
(long long)(int)sizeof(((struct posix_acl_xattr_header *)0)->a_version));
|
||||
|
||||
/* Checks for struct link_ea_header */
|
||||
LASSERTF((int)sizeof(struct link_ea_header) == 24, "found %lld\n",
|
||||
|
|
40
fs/9p/acl.c
40
fs/9p/acl.c
|
@ -276,32 +276,26 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
|
|||
switch (handler->flags) {
|
||||
case ACL_TYPE_ACCESS:
|
||||
if (acl) {
|
||||
umode_t mode = inode->i_mode;
|
||||
retval = posix_acl_equiv_mode(acl, &mode);
|
||||
if (retval < 0)
|
||||
struct iattr iattr;
|
||||
|
||||
retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
|
||||
if (retval)
|
||||
goto err_out;
|
||||
else {
|
||||
struct iattr iattr;
|
||||
if (retval == 0) {
|
||||
/*
|
||||
* ACL can be represented
|
||||
* by the mode bits. So don't
|
||||
* update ACL.
|
||||
*/
|
||||
acl = NULL;
|
||||
value = NULL;
|
||||
size = 0;
|
||||
}
|
||||
/* Updte the mode bits */
|
||||
iattr.ia_mode = ((mode & S_IALLUGO) |
|
||||
(inode->i_mode & ~S_IALLUGO));
|
||||
iattr.ia_valid = ATTR_MODE;
|
||||
/* FIXME should we update ctime ?
|
||||
* What is the following setxattr update the
|
||||
* mode ?
|
||||
if (!acl) {
|
||||
/*
|
||||
* ACL can be represented
|
||||
* by the mode bits. So don't
|
||||
* update ACL.
|
||||
*/
|
||||
v9fs_vfs_setattr_dotl(dentry, &iattr);
|
||||
value = NULL;
|
||||
size = 0;
|
||||
}
|
||||
iattr.ia_valid = ATTR_MODE;
|
||||
/* FIXME should we update ctime ?
|
||||
* What is the following setxattr update the
|
||||
* mode ?
|
||||
*/
|
||||
v9fs_vfs_setattr_dotl(dentry, &iattr);
|
||||
}
|
||||
break;
|
||||
case ACL_TYPE_DEFAULT:
|
||||
|
|
|
@ -1094,7 +1094,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||
struct p9_wstat wstat;
|
||||
|
||||
p9_debug(P9_DEBUG_VFS, "\n");
|
||||
retval = inode_change_ok(d_inode(dentry), iattr);
|
||||
retval = setattr_prepare(dentry, iattr);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
|
|
@ -558,7 +558,7 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
|
|||
|
||||
p9_debug(P9_DEBUG_VFS, "\n");
|
||||
|
||||
retval = inode_change_ok(inode, iattr);
|
||||
retval = setattr_prepare(dentry, iattr);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
|
|
@ -303,7 +303,7 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
|
|||
unsigned int ia_valid = attr->ia_valid;
|
||||
int error;
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
|
||||
/*
|
||||
* we can't change the UID or GID of any file -
|
||||
|
|
|
@ -219,7 +219,7 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
|
|||
|
||||
pr_debug("notify_change(%lu,0x%x)\n", inode->i_ino, attr->ia_valid);
|
||||
|
||||
error = inode_change_ok(inode,attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
|
|
9
fs/aio.c
9
fs/aio.c
|
@ -274,14 +274,17 @@ __initcall(aio_setup);
|
|||
static void put_aio_ring_file(struct kioctx *ctx)
|
||||
{
|
||||
struct file *aio_ring_file = ctx->aio_ring_file;
|
||||
struct address_space *i_mapping;
|
||||
|
||||
if (aio_ring_file) {
|
||||
truncate_setsize(aio_ring_file->f_inode, 0);
|
||||
|
||||
/* Prevent further access to the kioctx from migratepages */
|
||||
spin_lock(&aio_ring_file->f_inode->i_mapping->private_lock);
|
||||
aio_ring_file->f_inode->i_mapping->private_data = NULL;
|
||||
i_mapping = aio_ring_file->f_inode->i_mapping;
|
||||
spin_lock(&i_mapping->private_lock);
|
||||
i_mapping->private_data = NULL;
|
||||
ctx->aio_ring_file = NULL;
|
||||
spin_unlock(&aio_ring_file->f_inode->i_mapping->private_lock);
|
||||
spin_unlock(&i_mapping->private_lock);
|
||||
|
||||
fput(aio_ring_file);
|
||||
}
|
||||
|
|
50
fs/attr.c
50
fs/attr.c
|
@ -17,19 +17,22 @@
|
|||
#include <linux/ima.h>
|
||||
|
||||
/**
|
||||
* inode_change_ok - check if attribute changes to an inode are allowed
|
||||
* @inode: inode to check
|
||||
* setattr_prepare - check if attribute changes to a dentry are allowed
|
||||
* @dentry: dentry to check
|
||||
* @attr: attributes to change
|
||||
*
|
||||
* Check if we are allowed to change the attributes contained in @attr
|
||||
* in the given inode. This includes the normal unix access permission
|
||||
* checks, as well as checks for rlimits and others.
|
||||
* in the given dentry. This includes the normal unix access permission
|
||||
* checks, as well as checks for rlimits and others. The function also clears
|
||||
* SGID bit from mode if user is not allowed to set it. Also file capabilities
|
||||
* and IMA extended attributes are cleared if ATTR_KILL_PRIV is set.
|
||||
*
|
||||
* Should be called as the first thing in ->setattr implementations,
|
||||
* possibly after taking additional locks.
|
||||
*/
|
||||
int inode_change_ok(const struct inode *inode, struct iattr *attr)
|
||||
int setattr_prepare(struct dentry *dentry, struct iattr *attr)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
unsigned int ia_valid = attr->ia_valid;
|
||||
|
||||
/*
|
||||
|
@ -44,7 +47,7 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
|
|||
|
||||
/* If force is set do it anyway. */
|
||||
if (ia_valid & ATTR_FORCE)
|
||||
return 0;
|
||||
goto kill_priv;
|
||||
|
||||
/* Make sure a caller can chown. */
|
||||
if ((ia_valid & ATTR_UID) &&
|
||||
|
@ -77,9 +80,19 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
kill_priv:
|
||||
/* User has permission for the change */
|
||||
if (ia_valid & ATTR_KILL_PRIV) {
|
||||
int error;
|
||||
|
||||
error = security_inode_killpriv(dentry);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(inode_change_ok);
|
||||
EXPORT_SYMBOL(setattr_prepare);
|
||||
|
||||
/**
|
||||
* inode_newsize_ok - may this inode be truncated to a given size
|
||||
|
@ -202,6 +215,21 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
/*
|
||||
* If utimes(2) and friends are called with times == NULL (or both
|
||||
* times are UTIME_NOW), then we need to check for write permission
|
||||
*/
|
||||
if (ia_valid & ATTR_TOUCH) {
|
||||
if (IS_IMMUTABLE(inode))
|
||||
return -EPERM;
|
||||
|
||||
if (!inode_owner_or_capable(inode)) {
|
||||
error = inode_permission(inode, MAY_WRITE);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ia_valid & ATTR_MODE)) {
|
||||
umode_t amode = attr->ia_mode;
|
||||
/* Flag setting protected by i_mutex */
|
||||
|
@ -217,13 +245,11 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
|
|||
if (!(ia_valid & ATTR_MTIME_SET))
|
||||
attr->ia_mtime = now;
|
||||
if (ia_valid & ATTR_KILL_PRIV) {
|
||||
attr->ia_valid &= ~ATTR_KILL_PRIV;
|
||||
ia_valid &= ~ATTR_KILL_PRIV;
|
||||
error = security_inode_need_killpriv(dentry);
|
||||
if (error > 0)
|
||||
error = security_inode_killpriv(dentry);
|
||||
if (error)
|
||||
if (error < 0)
|
||||
return error;
|
||||
if (error == 0)
|
||||
ia_valid = attr->ia_valid &= ~ATTR_KILL_PRIV;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -79,11 +79,9 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *trans,
|
|||
case ACL_TYPE_ACCESS:
|
||||
name = XATTR_NAME_POSIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
ret = posix_acl_equiv_mode(acl, &inode->i_mode);
|
||||
if (ret < 0)
|
||||
ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (ret == 0)
|
||||
acl = NULL;
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
|
|
|
@ -3161,7 +3161,6 @@ int btrfs_prealloc_file_range_trans(struct inode *inode,
|
|||
struct btrfs_trans_handle *trans, int mode,
|
||||
u64 start, u64 num_bytes, u64 min_size,
|
||||
loff_t actual_len, u64 *alloc_hint);
|
||||
int btrfs_inode_check_errors(struct inode *inode);
|
||||
extern const struct dentry_operations btrfs_dentry_operations;
|
||||
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
|
||||
void btrfs_test_inode_set_ops(struct inode *inode);
|
||||
|
|
|
@ -2040,7 +2040,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
|
|||
* flags for any errors that might have happened while doing
|
||||
* writeback of file data.
|
||||
*/
|
||||
ret = btrfs_inode_check_errors(inode);
|
||||
ret = filemap_check_errors(inode->i_mapping);
|
||||
inode_unlock(inode);
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -5072,7 +5072,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
if (btrfs_root_readonly(root))
|
||||
return -EROFS;
|
||||
|
||||
err = inode_change_ok(inode, attr);
|
||||
err = setattr_prepare(dentry, attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -10544,21 +10544,6 @@ static int btrfs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
|
|||
|
||||
}
|
||||
|
||||
/* Inspired by filemap_check_errors() */
|
||||
int btrfs_inode_check_errors(struct inode *inode)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (test_bit(AS_ENOSPC, &inode->i_mapping->flags) &&
|
||||
test_and_clear_bit(AS_ENOSPC, &inode->i_mapping->flags))
|
||||
ret = -ENOSPC;
|
||||
if (test_bit(AS_EIO, &inode->i_mapping->flags) &&
|
||||
test_and_clear_bit(AS_EIO, &inode->i_mapping->flags))
|
||||
ret = -EIO;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct inode_operations btrfs_dir_inode_operations = {
|
||||
.getattr = btrfs_getattr,
|
||||
.lookup = btrfs_lookup,
|
||||
|
|
|
@ -4329,7 +4329,7 @@ static int __process_new_xattr(int num, struct btrfs_key *di_key,
|
|||
int ret;
|
||||
struct send_ctx *sctx = ctx;
|
||||
struct fs_path *p;
|
||||
posix_acl_xattr_header dummy_acl;
|
||||
struct posix_acl_xattr_header dummy_acl;
|
||||
|
||||
p = fs_path_alloc();
|
||||
if (!p)
|
||||
|
|
|
@ -3961,7 +3961,7 @@ static int wait_ordered_extents(struct btrfs_trans_handle *trans,
|
|||
* i_mapping flags, so that the next fsync won't get
|
||||
* an outdated io error too.
|
||||
*/
|
||||
btrfs_inode_check_errors(inode);
|
||||
filemap_check_errors(inode->i_mapping);
|
||||
*ordered_io_error = true;
|
||||
break;
|
||||
}
|
||||
|
@ -4198,7 +4198,7 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
|
|||
* without writing to the log tree and the fsync must report the
|
||||
* file data write error and not commit the current transaction.
|
||||
*/
|
||||
ret = btrfs_inode_check_errors(inode);
|
||||
ret = filemap_check_errors(inode->i_mapping);
|
||||
if (ret)
|
||||
ctx->io_err = ret;
|
||||
process:
|
||||
|
|
|
@ -1078,7 +1078,7 @@ grow_buffers(struct block_device *bdev, sector_t block, int size, gfp_t gfp)
|
|||
return grow_dev_page(bdev, block, index, size, sizebits, gfp);
|
||||
}
|
||||
|
||||
struct buffer_head *
|
||||
static struct buffer_head *
|
||||
__getblk_slow(struct block_device *bdev, sector_t block,
|
||||
unsigned size, gfp_t gfp)
|
||||
{
|
||||
|
@ -1109,7 +1109,6 @@ __getblk_slow(struct block_device *bdev, sector_t block,
|
|||
free_more_memory();
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(__getblk_slow);
|
||||
|
||||
/*
|
||||
* The relationship between dirty buffers and dirty pages:
|
||||
|
|
|
@ -253,6 +253,8 @@ static void cachefiles_drop_object(struct fscache_object *_object)
|
|||
struct cachefiles_object *object;
|
||||
struct cachefiles_cache *cache;
|
||||
const struct cred *saved_cred;
|
||||
struct inode *inode;
|
||||
blkcnt_t i_blocks = 0;
|
||||
|
||||
ASSERT(_object);
|
||||
|
||||
|
@ -279,6 +281,10 @@ static void cachefiles_drop_object(struct fscache_object *_object)
|
|||
_object != cache->cache.fsdef
|
||||
) {
|
||||
_debug("- retire object OBJ%x", object->fscache.debug_id);
|
||||
inode = d_backing_inode(object->dentry);
|
||||
if (inode)
|
||||
i_blocks = inode->i_blocks;
|
||||
|
||||
cachefiles_begin_secure(cache, &saved_cred);
|
||||
cachefiles_delete_object(cache, object);
|
||||
cachefiles_end_secure(cache, saved_cred);
|
||||
|
@ -292,7 +298,7 @@ static void cachefiles_drop_object(struct fscache_object *_object)
|
|||
|
||||
/* note that the object is now inactive */
|
||||
if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags))
|
||||
cachefiles_mark_object_inactive(cache, object);
|
||||
cachefiles_mark_object_inactive(cache, object, i_blocks);
|
||||
|
||||
dput(object->dentry);
|
||||
object->dentry = NULL;
|
||||
|
|
|
@ -160,7 +160,8 @@ extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
|
|||
* namei.c
|
||||
*/
|
||||
extern void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
|
||||
struct cachefiles_object *object);
|
||||
struct cachefiles_object *object,
|
||||
blkcnt_t i_blocks);
|
||||
extern int cachefiles_delete_object(struct cachefiles_cache *cache,
|
||||
struct cachefiles_object *object);
|
||||
extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
|
||||
|
|
|
@ -261,10 +261,9 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
|
|||
* Mark an object as being inactive.
|
||||
*/
|
||||
void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
|
||||
struct cachefiles_object *object)
|
||||
struct cachefiles_object *object,
|
||||
blkcnt_t i_blocks)
|
||||
{
|
||||
blkcnt_t i_blocks = d_backing_inode(object->dentry)->i_blocks;
|
||||
|
||||
write_lock(&cache->active_lock);
|
||||
rb_erase(&object->active_node, &cache->active_nodes);
|
||||
clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
|
||||
|
@ -707,7 +706,8 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
|
|||
|
||||
check_error:
|
||||
_debug("check error %d", ret);
|
||||
cachefiles_mark_object_inactive(cache, object);
|
||||
cachefiles_mark_object_inactive(
|
||||
cache, object, d_backing_inode(object->dentry)->i_blocks);
|
||||
release_dentry:
|
||||
dput(object->dentry);
|
||||
object->dentry = NULL;
|
||||
|
|
|
@ -95,11 +95,9 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||
case ACL_TYPE_ACCESS:
|
||||
name = XATTR_NAME_POSIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
ret = posix_acl_equiv_mode(acl, &new_mode);
|
||||
if (ret < 0)
|
||||
ret = posix_acl_update_mode(inode, &new_mode, &acl);
|
||||
if (ret)
|
||||
goto out;
|
||||
if (ret == 0)
|
||||
acl = NULL;
|
||||
}
|
||||
break;
|
||||
case ACL_TYPE_DEFAULT:
|
||||
|
@ -127,6 +125,11 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||
goto out_free;
|
||||
}
|
||||
|
||||
if (ceph_snap(inode) != CEPH_NOSNAP) {
|
||||
ret = -EROFS;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (new_mode != old_mode) {
|
||||
newattrs.ia_mode = new_mode;
|
||||
newattrs.ia_valid = ATTR_MODE;
|
||||
|
|
|
@ -1905,13 +1905,6 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|||
int inode_dirty_flags = 0;
|
||||
bool lock_snap_rwsem = false;
|
||||
|
||||
if (ceph_snap(inode) != CEPH_NOSNAP)
|
||||
return -EROFS;
|
||||
|
||||
err = inode_change_ok(inode, attr);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
prealloc_cf = ceph_alloc_cap_flush();
|
||||
if (!prealloc_cf)
|
||||
return -ENOMEM;
|
||||
|
@ -2124,7 +2117,17 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
|||
*/
|
||||
int ceph_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
{
|
||||
return __ceph_setattr(d_inode(dentry), attr);
|
||||
struct inode *inode = d_inode(dentry);
|
||||
int err;
|
||||
|
||||
if (ceph_snap(inode) != CEPH_NOSNAP)
|
||||
return -EROFS;
|
||||
|
||||
err = setattr_prepare(dentry, attr);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
return __ceph_setattr(inode, attr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -41,6 +41,16 @@ cifs_uniqueid_to_ino_t(u64 fileid)
|
|||
|
||||
}
|
||||
|
||||
static inline void cifs_set_time(struct dentry *dentry, unsigned long time)
|
||||
{
|
||||
dentry->d_fsdata = (void *) time;
|
||||
}
|
||||
|
||||
static inline unsigned long cifs_get_time(struct dentry *dentry)
|
||||
{
|
||||
return (unsigned long) dentry->d_fsdata;
|
||||
}
|
||||
|
||||
extern struct file_system_type cifs_fs_type;
|
||||
extern const struct address_space_operations cifs_addr_ops;
|
||||
extern const struct address_space_operations cifs_addr_ops_smallbuf;
|
||||
|
|
|
@ -392,8 +392,7 @@ extern int CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|||
unsigned int *nbytes, char **buf,
|
||||
int *return_buf_type);
|
||||
extern int CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
|
||||
unsigned int *nbytes, const char *buf,
|
||||
const char __user *ubuf, const int long_op);
|
||||
unsigned int *nbytes, const char *buf);
|
||||
extern int CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
|
||||
unsigned int *nbytes, struct kvec *iov, const int nvec);
|
||||
extern int CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
|
|
|
@ -1228,7 +1228,6 @@ SMBLegacyOpen(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
inc_rfc1001_len(pSMB, count);
|
||||
|
||||
pSMB->ByteCount = cpu_to_le16(count);
|
||||
/* long_op set to 1 to allow for oplock break timeouts */
|
||||
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
||||
(struct smb_hdr *)pSMBr, &bytes_returned, 0);
|
||||
cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
|
||||
|
@ -1768,8 +1767,7 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|||
|
||||
int
|
||||
CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
|
||||
unsigned int *nbytes, const char *buf,
|
||||
const char __user *ubuf, const int long_op)
|
||||
unsigned int *nbytes, const char *buf)
|
||||
{
|
||||
int rc = -EACCES;
|
||||
WRITE_REQ *pSMB = NULL;
|
||||
|
@ -1838,12 +1836,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|||
cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
|
||||
if (buf)
|
||||
memcpy(pSMB->Data, buf, bytes_sent);
|
||||
else if (ubuf) {
|
||||
if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
|
||||
cifs_buf_release(pSMB);
|
||||
return -EFAULT;
|
||||
}
|
||||
} else if (count != 0) {
|
||||
else if (count != 0) {
|
||||
/* No buffer */
|
||||
cifs_buf_release(pSMB);
|
||||
return -EINVAL;
|
||||
|
@ -1867,7 +1860,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|||
}
|
||||
|
||||
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
||||
(struct smb_hdr *) pSMBr, &bytes_returned, long_op);
|
||||
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
||||
cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
|
||||
if (rc) {
|
||||
cifs_dbg(FYI, "Send error in write = %d\n", rc);
|
||||
|
@ -3334,7 +3327,7 @@ CIFSSMB_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
#ifdef CONFIG_CIFS_POSIX
|
||||
|
||||
/*Convert an Access Control Entry from wire format to local POSIX xattr format*/
|
||||
static void cifs_convert_ace(posix_acl_xattr_entry *ace,
|
||||
static void cifs_convert_ace(struct posix_acl_xattr_entry *ace,
|
||||
struct cifs_posix_ace *cifs_ace)
|
||||
{
|
||||
/* u8 cifs fields do not need le conversion */
|
||||
|
@ -3358,7 +3351,7 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
|
|||
__u16 count;
|
||||
struct cifs_posix_ace *pACE;
|
||||
struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
|
||||
posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
|
||||
struct posix_acl_xattr_header *local_acl = (void *)trgt;
|
||||
|
||||
if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -3396,9 +3389,11 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
|
|||
} else if (size > buflen) {
|
||||
return -ERANGE;
|
||||
} else /* buffer big enough */ {
|
||||
struct posix_acl_xattr_entry *ace = (void *)(local_acl + 1);
|
||||
|
||||
local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
|
||||
for (i = 0; i < count ; i++) {
|
||||
cifs_convert_ace(&local_acl->a_entries[i], pACE);
|
||||
cifs_convert_ace(&ace[i], pACE);
|
||||
pACE++;
|
||||
}
|
||||
}
|
||||
|
@ -3406,7 +3401,7 @@ static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
|
|||
}
|
||||
|
||||
static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
|
||||
const posix_acl_xattr_entry *local_ace)
|
||||
const struct posix_acl_xattr_entry *local_ace)
|
||||
{
|
||||
__u16 rc = 0; /* 0 = ACL converted ok */
|
||||
|
||||
|
@ -3431,7 +3426,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
|
|||
{
|
||||
__u16 rc = 0;
|
||||
struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
|
||||
posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
|
||||
struct posix_acl_xattr_header *local_acl = (void *)pACL;
|
||||
int count;
|
||||
int i;
|
||||
|
||||
|
@ -3459,7 +3454,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
|
|||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
|
||||
&local_acl->a_entries[i]);
|
||||
(struct posix_acl_xattr_entry *)(local_acl + 1));
|
||||
if (rc != 0) {
|
||||
/* ACE not converted */
|
||||
break;
|
||||
|
|
|
@ -40,7 +40,7 @@ renew_parental_timestamps(struct dentry *direntry)
|
|||
/* BB check if there is a way to get the kernel to do this or if we
|
||||
really need this */
|
||||
do {
|
||||
direntry->d_time = jiffies;
|
||||
cifs_set_time(direntry, jiffies);
|
||||
direntry = direntry->d_parent;
|
||||
} while (!IS_ROOT(direntry));
|
||||
}
|
||||
|
@ -802,7 +802,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
|
||||
} else if (rc == -ENOENT) {
|
||||
rc = 0;
|
||||
direntry->d_time = jiffies;
|
||||
cifs_set_time(direntry, jiffies);
|
||||
d_add(direntry, NULL);
|
||||
/* if it was once a directory (but how can we tell?) we could do
|
||||
shrink_dcache_parent(direntry); */
|
||||
|
@ -862,7 +862,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
|
|||
if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
|
||||
return 0;
|
||||
|
||||
if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
|
||||
if (time_after(jiffies, cifs_get_time(direntry) + HZ) || !lookupCacheEnabled)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -2478,7 +2478,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
|
|||
size_t cur_len;
|
||||
unsigned long nr_pages, num_pages, i;
|
||||
struct cifs_writedata *wdata;
|
||||
struct iov_iter saved_from;
|
||||
struct iov_iter saved_from = *from;
|
||||
loff_t saved_offset = offset;
|
||||
pid_t pid;
|
||||
struct TCP_Server_Info *server;
|
||||
|
@ -2489,7 +2489,6 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
|
|||
pid = current->tgid;
|
||||
|
||||
server = tlink_tcon(open_file->tlink)->ses->server;
|
||||
memcpy(&saved_from, from, sizeof(struct iov_iter));
|
||||
|
||||
do {
|
||||
unsigned int wsize, credits;
|
||||
|
@ -2551,8 +2550,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
|
|||
kref_put(&wdata->refcount,
|
||||
cifs_uncached_writedata_release);
|
||||
if (rc == -EAGAIN) {
|
||||
memcpy(from, &saved_from,
|
||||
sizeof(struct iov_iter));
|
||||
*from = saved_from;
|
||||
iov_iter_advance(from, offset - saved_offset);
|
||||
continue;
|
||||
}
|
||||
|
@ -2576,7 +2574,7 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
|
|||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifs_writedata *wdata, *tmp;
|
||||
struct list_head wdata_list;
|
||||
struct iov_iter saved_from;
|
||||
struct iov_iter saved_from = *from;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
|
@ -2597,8 +2595,6 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
|
|||
if (!tcon->ses->server->ops->async_writev)
|
||||
return -ENOSYS;
|
||||
|
||||
memcpy(&saved_from, from, sizeof(struct iov_iter));
|
||||
|
||||
rc = cifs_write_from_iter(iocb->ki_pos, iov_iter_count(from), from,
|
||||
open_file, cifs_sb, &wdata_list);
|
||||
|
||||
|
@ -2631,13 +2627,11 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
|
|||
/* resend call if it's a retryable error */
|
||||
if (rc == -EAGAIN) {
|
||||
struct list_head tmp_list;
|
||||
struct iov_iter tmp_from;
|
||||
struct iov_iter tmp_from = saved_from;
|
||||
|
||||
INIT_LIST_HEAD(&tmp_list);
|
||||
list_del_init(&wdata->list);
|
||||
|
||||
memcpy(&tmp_from, &saved_from,
|
||||
sizeof(struct iov_iter));
|
||||
iov_iter_advance(&tmp_from,
|
||||
wdata->offset - iocb->ki_pos);
|
||||
|
||||
|
|
|
@ -1951,7 +1951,7 @@ int cifs_revalidate_dentry_attr(struct dentry *dentry)
|
|||
|
||||
cifs_dbg(FYI, "Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time %ld jiffies %ld\n",
|
||||
full_path, inode, inode->i_count.counter,
|
||||
dentry, dentry->d_time, jiffies);
|
||||
dentry, cifs_get_time(dentry), jiffies);
|
||||
|
||||
if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
|
||||
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
|
||||
|
@ -2154,7 +2154,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
|
|||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
|
||||
attrs->ia_valid |= ATTR_FORCE;
|
||||
|
||||
rc = inode_change_ok(inode, attrs);
|
||||
rc = setattr_prepare(direntry, attrs);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
||||
|
@ -2294,7 +2294,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
|||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
|
||||
attrs->ia_valid |= ATTR_FORCE;
|
||||
|
||||
rc = inode_change_ok(inode, attrs);
|
||||
rc = setattr_prepare(direntry, attrs);
|
||||
if (rc < 0) {
|
||||
free_xid(xid);
|
||||
return rc;
|
||||
|
|
|
@ -399,7 +399,7 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||
io_parms.offset = 0;
|
||||
io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
|
||||
|
||||
rc = CIFSSMBWrite(xid, &io_parms, pbytes_written, pbuf, NULL, 0);
|
||||
rc = CIFSSMBWrite(xid, &io_parms, pbytes_written, pbuf);
|
||||
CIFSSMBClose(xid, tcon, fid.netfid);
|
||||
return rc;
|
||||
}
|
||||
|
|
16
fs/compat.c
16
fs/compat.c
|
@ -54,20 +54,6 @@
|
|||
#include <asm/ioctls.h>
|
||||
#include "internal.h"
|
||||
|
||||
int compat_log = 1;
|
||||
|
||||
int compat_printk(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
if (!compat_log)
|
||||
return 0;
|
||||
va_start(ap, fmt);
|
||||
ret = vprintk(fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Not all architectures have sys_utime, so implement this in terms
|
||||
* of sys_utimes.
|
||||
|
@ -562,7 +548,7 @@ ssize_t compat_rw_copy_check_uvector(int type,
|
|||
goto out;
|
||||
|
||||
ret = -EINVAL;
|
||||
if (nr_segs > UIO_MAXIOV || nr_segs < 0)
|
||||
if (nr_segs > UIO_MAXIOV)
|
||||
goto out;
|
||||
if (nr_segs > fast_segs) {
|
||||
ret = -ENOMEM;
|
||||
|
|
|
@ -927,7 +927,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
|
|||
}
|
||||
mutex_unlock(&crypt_stat->cs_mutex);
|
||||
|
||||
rc = inode_change_ok(inode, ia);
|
||||
rc = setattr_prepare(dentry, ia);
|
||||
if (rc)
|
||||
goto out;
|
||||
if (ia->ia_valid & ATTR_SIZE) {
|
||||
|
|
|
@ -1034,7 +1034,7 @@ int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||
if (unlikely(error))
|
||||
return error;
|
||||
|
||||
error = inode_change_ok(inode, iattr);
|
||||
error = setattr_prepare(dentry, iattr);
|
||||
if (unlikely(error))
|
||||
return error;
|
||||
|
||||
|
|
|
@ -190,15 +190,11 @@ ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||
case ACL_TYPE_ACCESS:
|
||||
name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
||||
if (error < 0)
|
||||
error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
||||
if (error)
|
||||
return error;
|
||||
else {
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
mark_inode_dirty(inode);
|
||||
if (error == 0)
|
||||
acl = NULL;
|
||||
}
|
||||
inode->i_ctime = CURRENT_TIME_SEC;
|
||||
mark_inode_dirty(inode);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -1652,7 +1652,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
int error;
|
||||
|
||||
error = inode_change_ok(inode, iattr);
|
||||
error = setattr_prepare(dentry, iattr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
|
@ -193,15 +193,11 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
|
|||
case ACL_TYPE_ACCESS:
|
||||
name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
||||
if (error < 0)
|
||||
error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
||||
if (error)
|
||||
return error;
|
||||
else {
|
||||
inode->i_ctime = ext4_current_time(inode);
|
||||
ext4_mark_inode_dirty(handle, inode);
|
||||
if (error == 0)
|
||||
acl = NULL;
|
||||
}
|
||||
inode->i_ctime = ext4_current_time(inode);
|
||||
ext4_mark_inode_dirty(handle, inode);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -5078,7 +5078,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
int orphan = 0;
|
||||
const unsigned int ia_valid = attr->ia_valid;
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
|
@ -212,12 +212,10 @@ static int __f2fs_set_acl(struct inode *inode, int type,
|
|||
case ACL_TYPE_ACCESS:
|
||||
name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
error = posix_acl_equiv_mode(acl, &inode->i_mode);
|
||||
if (error < 0)
|
||||
error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
||||
if (error)
|
||||
return error;
|
||||
set_acl_inode(inode, inode->i_mode);
|
||||
if (error == 0)
|
||||
acl = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -680,7 +680,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
int err;
|
||||
|
||||
err = inode_change_ok(inode, attr);
|
||||
err = setattr_prepare(dentry, attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -1525,7 +1525,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
|
|||
{
|
||||
pgoff_t index = 0, end = ULONG_MAX;
|
||||
struct pagevec pvec;
|
||||
int ret2 = 0, ret = 0;
|
||||
int ret2, ret = 0;
|
||||
|
||||
pagevec_init(&pvec, 0);
|
||||
|
||||
|
@ -1554,10 +1554,7 @@ int wait_on_node_pages_writeback(struct f2fs_sb_info *sbi, nid_t ino)
|
|||
cond_resched();
|
||||
}
|
||||
|
||||
if (unlikely(test_and_clear_bit(AS_ENOSPC, &NODE_MAPPING(sbi)->flags)))
|
||||
ret2 = -ENOSPC;
|
||||
if (unlikely(test_and_clear_bit(AS_EIO, &NODE_MAPPING(sbi)->flags)))
|
||||
ret2 = -EIO;
|
||||
ret2 = filemap_check_errors(NODE_MAPPING(sbi));
|
||||
if (!ret)
|
||||
ret = ret2;
|
||||
return ret;
|
||||
|
|
|
@ -450,7 +450,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
attr->ia_valid &= ~TIMES_SET_FLAGS;
|
||||
}
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
attr->ia_valid = ia_valid;
|
||||
if (error) {
|
||||
if (sbi->options.quiet)
|
||||
|
|
|
@ -21,6 +21,17 @@
|
|||
#include <linux/namei.h>
|
||||
#include "fat.h"
|
||||
|
||||
static inline unsigned long vfat_d_version(struct dentry *dentry)
|
||||
{
|
||||
return (unsigned long) dentry->d_fsdata;
|
||||
}
|
||||
|
||||
static inline void vfat_d_version_set(struct dentry *dentry,
|
||||
unsigned long version)
|
||||
{
|
||||
dentry->d_fsdata = (void *) version;
|
||||
}
|
||||
|
||||
/*
|
||||
* If new entry was created in the parent, it could create the 8.3
|
||||
* alias (the shortname of logname). So, the parent may have the
|
||||
|
@ -33,7 +44,7 @@ static int vfat_revalidate_shortname(struct dentry *dentry)
|
|||
{
|
||||
int ret = 1;
|
||||
spin_lock(&dentry->d_lock);
|
||||
if (dentry->d_time != d_inode(dentry->d_parent)->i_version)
|
||||
if (vfat_d_version(dentry) != d_inode(dentry->d_parent)->i_version)
|
||||
ret = 0;
|
||||
spin_unlock(&dentry->d_lock);
|
||||
return ret;
|
||||
|
@ -759,7 +770,7 @@ static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
|
|||
out:
|
||||
mutex_unlock(&MSDOS_SB(sb)->s_lock);
|
||||
if (!inode)
|
||||
dentry->d_time = dir->i_version;
|
||||
vfat_d_version_set(dentry, dir->i_version);
|
||||
return d_splice_alias(inode, dentry);
|
||||
error:
|
||||
mutex_unlock(&MSDOS_SB(sb)->s_lock);
|
||||
|
@ -823,7 +834,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
|
|||
clear_nlink(inode);
|
||||
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
|
||||
fat_detach(inode);
|
||||
dentry->d_time = dir->i_version;
|
||||
vfat_d_version_set(dentry, dir->i_version);
|
||||
out:
|
||||
mutex_unlock(&MSDOS_SB(sb)->s_lock);
|
||||
|
||||
|
@ -849,7 +860,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry)
|
|||
clear_nlink(inode);
|
||||
inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
|
||||
fat_detach(inode);
|
||||
dentry->d_time = dir->i_version;
|
||||
vfat_d_version_set(dentry, dir->i_version);
|
||||
out:
|
||||
mutex_unlock(&MSDOS_SB(sb)->s_lock);
|
||||
|
||||
|
|
34
fs/file.c
34
fs/file.c
|
@ -23,12 +23,12 @@
|
|||
#include <linux/rcupdate.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
int sysctl_nr_open __read_mostly = 1024*1024;
|
||||
int sysctl_nr_open_min = BITS_PER_LONG;
|
||||
unsigned int sysctl_nr_open __read_mostly = 1024*1024;
|
||||
unsigned int sysctl_nr_open_min = BITS_PER_LONG;
|
||||
/* our min() is unusable in constant expressions ;-/ */
|
||||
#define __const_min(x, y) ((x) < (y) ? (x) : (y))
|
||||
int sysctl_nr_open_max = __const_min(INT_MAX, ~(size_t)0/sizeof(void *)) &
|
||||
-BITS_PER_LONG;
|
||||
unsigned int sysctl_nr_open_max =
|
||||
__const_min(INT_MAX, ~(size_t)0/sizeof(void *)) & -BITS_PER_LONG;
|
||||
|
||||
static void *alloc_fdmem(size_t size)
|
||||
{
|
||||
|
@ -163,7 +163,7 @@ static struct fdtable * alloc_fdtable(unsigned int nr)
|
|||
* Return <0 error code on error; 1 on successful completion.
|
||||
* The files->file_lock should be held on entry, and will be held on exit.
|
||||
*/
|
||||
static int expand_fdtable(struct files_struct *files, int nr)
|
||||
static int expand_fdtable(struct files_struct *files, unsigned int nr)
|
||||
__releases(files->file_lock)
|
||||
__acquires(files->file_lock)
|
||||
{
|
||||
|
@ -208,7 +208,7 @@ static int expand_fdtable(struct files_struct *files, int nr)
|
|||
* expanded and execution may have blocked.
|
||||
* The files->file_lock should be held on entry, and will be held on exit.
|
||||
*/
|
||||
static int expand_files(struct files_struct *files, int nr)
|
||||
static int expand_files(struct files_struct *files, unsigned int nr)
|
||||
__releases(files->file_lock)
|
||||
__acquires(files->file_lock)
|
||||
{
|
||||
|
@ -243,12 +243,12 @@ static int expand_files(struct files_struct *files, int nr)
|
|||
return expanded;
|
||||
}
|
||||
|
||||
static inline void __set_close_on_exec(int fd, struct fdtable *fdt)
|
||||
static inline void __set_close_on_exec(unsigned int fd, struct fdtable *fdt)
|
||||
{
|
||||
__set_bit(fd, fdt->close_on_exec);
|
||||
}
|
||||
|
||||
static inline void __clear_close_on_exec(int fd, struct fdtable *fdt)
|
||||
static inline void __clear_close_on_exec(unsigned int fd, struct fdtable *fdt)
|
||||
{
|
||||
if (test_bit(fd, fdt->close_on_exec))
|
||||
__clear_bit(fd, fdt->close_on_exec);
|
||||
|
@ -268,10 +268,10 @@ static inline void __clear_open_fd(unsigned int fd, struct fdtable *fdt)
|
|||
__clear_bit(fd / BITS_PER_LONG, fdt->full_fds_bits);
|
||||
}
|
||||
|
||||
static int count_open_files(struct fdtable *fdt)
|
||||
static unsigned int count_open_files(struct fdtable *fdt)
|
||||
{
|
||||
int size = fdt->max_fds;
|
||||
int i;
|
||||
unsigned int size = fdt->max_fds;
|
||||
unsigned int i;
|
||||
|
||||
/* Find the last open fd */
|
||||
for (i = size / BITS_PER_LONG; i > 0; ) {
|
||||
|
@ -291,7 +291,7 @@ struct files_struct *dup_fd(struct files_struct *oldf, int *errorp)
|
|||
{
|
||||
struct files_struct *newf;
|
||||
struct file **old_fds, **new_fds;
|
||||
int open_files, i;
|
||||
unsigned int open_files, i;
|
||||
struct fdtable *old_fdt, *new_fdt;
|
||||
|
||||
*errorp = -ENOMEM;
|
||||
|
@ -391,7 +391,7 @@ static struct fdtable *close_files(struct files_struct * files)
|
|||
* files structure.
|
||||
*/
|
||||
struct fdtable *fdt = rcu_dereference_raw(files->fdt);
|
||||
int i, j = 0;
|
||||
unsigned int i, j = 0;
|
||||
|
||||
for (;;) {
|
||||
unsigned long set;
|
||||
|
@ -477,11 +477,11 @@ struct files_struct init_files = {
|
|||
.file_lock = __SPIN_LOCK_UNLOCKED(init_files.file_lock),
|
||||
};
|
||||
|
||||
static unsigned long find_next_fd(struct fdtable *fdt, unsigned long start)
|
||||
static unsigned int find_next_fd(struct fdtable *fdt, unsigned int start)
|
||||
{
|
||||
unsigned long maxfd = fdt->max_fds;
|
||||
unsigned long maxbit = maxfd / BITS_PER_LONG;
|
||||
unsigned long bitbit = start / BITS_PER_LONG;
|
||||
unsigned int maxfd = fdt->max_fds;
|
||||
unsigned int maxbit = maxfd / BITS_PER_LONG;
|
||||
unsigned int bitbit = start / BITS_PER_LONG;
|
||||
|
||||
bitbit = find_next_zero_bit(fdt->full_fds_bits, maxbit, bitbit) * BITS_PER_LONG;
|
||||
if (bitbit > maxfd)
|
||||
|
|
|
@ -1604,9 +1604,10 @@ int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
|
|||
* vmtruncate() doesn't allow for this case, so do the rlimit checking
|
||||
* and the actual truncation by hand.
|
||||
*/
|
||||
int fuse_do_setattr(struct inode *inode, struct iattr *attr,
|
||||
int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
|
||||
struct file *file)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||
struct fuse_inode *fi = get_fuse_inode(inode);
|
||||
FUSE_ARGS(args);
|
||||
|
@ -1621,7 +1622,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
|
|||
if (!fc->default_permissions)
|
||||
attr->ia_valid |= ATTR_FORCE;
|
||||
|
||||
err = inode_change_ok(inode, attr);
|
||||
err = setattr_prepare(dentry, attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -1758,7 +1759,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
|
|||
if (!attr->ia_valid)
|
||||
return 0;
|
||||
|
||||
ret = fuse_do_setattr(inode, attr, file);
|
||||
ret = fuse_do_setattr(entry, attr, file);
|
||||
if (!ret) {
|
||||
/*
|
||||
* If filesystem supports acls it may have updated acl xattrs in
|
||||
|
|
|
@ -2810,7 +2810,7 @@ static void fuse_do_truncate(struct file *file)
|
|||
attr.ia_file = file;
|
||||
attr.ia_valid |= ATTR_FILE;
|
||||
|
||||
fuse_do_setattr(inode, &attr, file);
|
||||
fuse_do_setattr(file_dentry(file), &attr, file);
|
||||
}
|
||||
|
||||
static inline loff_t fuse_round_up(loff_t off)
|
||||
|
|
|
@ -961,7 +961,7 @@ bool fuse_write_update_size(struct inode *inode, loff_t pos);
|
|||
int fuse_flush_times(struct inode *inode, struct fuse_file *ff);
|
||||
int fuse_write_inode(struct inode *inode, struct writeback_control *wbc);
|
||||
|
||||
int fuse_do_setattr(struct inode *inode, struct iattr *attr,
|
||||
int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
|
||||
struct file *file);
|
||||
|
||||
void fuse_set_initialized(struct fuse_conn *fc);
|
||||
|
|
|
@ -92,17 +92,11 @@ int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||
if (type == ACL_TYPE_ACCESS) {
|
||||
umode_t mode = inode->i_mode;
|
||||
|
||||
error = posix_acl_equiv_mode(acl, &mode);
|
||||
if (error < 0)
|
||||
error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (error == 0)
|
||||
acl = NULL;
|
||||
|
||||
if (mode != inode->i_mode) {
|
||||
inode->i_mode = mode;
|
||||
if (mode != inode->i_mode)
|
||||
mark_inode_dirty(inode);
|
||||
}
|
||||
}
|
||||
|
||||
if (acl) {
|
||||
|
|
|
@ -1936,7 +1936,7 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
goto out;
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -605,7 +605,7 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
|
|||
struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
|
||||
int error;
|
||||
|
||||
error = inode_change_ok(inode, attr); /* basic permission checks */
|
||||
error = setattr_prepare(dentry, attr); /* basic permission checks */
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
int error;
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
|
@ -65,8 +65,8 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
|
|||
case ACL_TYPE_ACCESS:
|
||||
xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
err = posix_acl_equiv_mode(acl, &inode->i_mode);
|
||||
if (err < 0)
|
||||
err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
err = 0;
|
||||
|
|
|
@ -812,7 +812,7 @@ static int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
|
||||
int fd = HOSTFS_I(inode)->fd;
|
||||
|
||||
err = inode_change_ok(inode, attr);
|
||||
err = setattr_prepare(dentry, attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -189,6 +189,11 @@ static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block)
|
|||
return generic_block_bmap(mapping, block, hpfs_get_block);
|
||||
}
|
||||
|
||||
static int hpfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len)
|
||||
{
|
||||
return generic_block_fiemap(inode, fieinfo, start, len, hpfs_get_block);
|
||||
}
|
||||
|
||||
const struct address_space_operations hpfs_aops = {
|
||||
.readpage = hpfs_readpage,
|
||||
.writepage = hpfs_writepage,
|
||||
|
@ -214,4 +219,5 @@ const struct file_operations hpfs_file_ops =
|
|||
const struct inode_operations hpfs_file_iops =
|
||||
{
|
||||
.setattr = hpfs_setattr,
|
||||
.fiemap = hpfs_fiemap,
|
||||
};
|
||||
|
|
|
@ -273,7 +273,7 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size)
|
||||
goto out_unlock;
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
goto out_unlock;
|
||||
|
||||
|
|
|
@ -670,7 +670,7 @@ static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
|
||||
BUG_ON(!inode);
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
74
fs/inode.c
74
fs/inode.c
|
@ -1021,13 +1021,17 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
|
|||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, hashval);
|
||||
struct inode *inode;
|
||||
|
||||
again:
|
||||
spin_lock(&inode_hash_lock);
|
||||
inode = find_inode(sb, head, test, data);
|
||||
spin_unlock(&inode_hash_lock);
|
||||
|
||||
if (inode) {
|
||||
wait_on_inode(inode);
|
||||
if (unlikely(inode_unhashed(inode))) {
|
||||
iput(inode);
|
||||
goto again;
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
|
||||
|
@ -1064,6 +1068,10 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval,
|
|||
destroy_inode(inode);
|
||||
inode = old;
|
||||
wait_on_inode(inode);
|
||||
if (unlikely(inode_unhashed(inode))) {
|
||||
iput(inode);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
return inode;
|
||||
|
||||
|
@ -1091,12 +1099,16 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
|
|||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, ino);
|
||||
struct inode *inode;
|
||||
|
||||
again:
|
||||
spin_lock(&inode_hash_lock);
|
||||
inode = find_inode_fast(sb, head, ino);
|
||||
spin_unlock(&inode_hash_lock);
|
||||
if (inode) {
|
||||
wait_on_inode(inode);
|
||||
if (unlikely(inode_unhashed(inode))) {
|
||||
iput(inode);
|
||||
goto again;
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
|
||||
|
@ -1131,6 +1143,10 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
|
|||
destroy_inode(inode);
|
||||
inode = old;
|
||||
wait_on_inode(inode);
|
||||
if (unlikely(inode_unhashed(inode))) {
|
||||
iput(inode);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
|
@ -1266,10 +1282,16 @@ EXPORT_SYMBOL(ilookup5_nowait);
|
|||
struct inode *ilookup5(struct super_block *sb, unsigned long hashval,
|
||||
int (*test)(struct inode *, void *), void *data)
|
||||
{
|
||||
struct inode *inode = ilookup5_nowait(sb, hashval, test, data);
|
||||
|
||||
if (inode)
|
||||
struct inode *inode;
|
||||
again:
|
||||
inode = ilookup5_nowait(sb, hashval, test, data);
|
||||
if (inode) {
|
||||
wait_on_inode(inode);
|
||||
if (unlikely(inode_unhashed(inode))) {
|
||||
iput(inode);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
EXPORT_SYMBOL(ilookup5);
|
||||
|
@ -1286,13 +1308,18 @@ struct inode *ilookup(struct super_block *sb, unsigned long ino)
|
|||
{
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, ino);
|
||||
struct inode *inode;
|
||||
|
||||
again:
|
||||
spin_lock(&inode_hash_lock);
|
||||
inode = find_inode_fast(sb, head, ino);
|
||||
spin_unlock(&inode_hash_lock);
|
||||
|
||||
if (inode)
|
||||
if (inode) {
|
||||
wait_on_inode(inode);
|
||||
if (unlikely(inode_unhashed(inode))) {
|
||||
iput(inode);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
EXPORT_SYMBOL(ilookup);
|
||||
|
@ -1535,17 +1562,37 @@ sector_t bmap(struct inode *inode, sector_t block)
|
|||
}
|
||||
EXPORT_SYMBOL(bmap);
|
||||
|
||||
/*
|
||||
* Update times in overlayed inode from underlying real inode
|
||||
*/
|
||||
static void update_ovl_inode_times(struct dentry *dentry, struct inode *inode,
|
||||
bool rcu)
|
||||
{
|
||||
if (!rcu) {
|
||||
struct inode *realinode = d_real_inode(dentry);
|
||||
|
||||
if (unlikely(inode != realinode) &&
|
||||
(!timespec_equal(&inode->i_mtime, &realinode->i_mtime) ||
|
||||
!timespec_equal(&inode->i_ctime, &realinode->i_ctime))) {
|
||||
inode->i_mtime = realinode->i_mtime;
|
||||
inode->i_ctime = realinode->i_ctime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* With relative atime, only update atime if the previous atime is
|
||||
* earlier than either the ctime or mtime or if at least a day has
|
||||
* passed since the last atime update.
|
||||
*/
|
||||
static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
|
||||
struct timespec now)
|
||||
static int relatime_need_update(const struct path *path, struct inode *inode,
|
||||
struct timespec now, bool rcu)
|
||||
{
|
||||
|
||||
if (!(mnt->mnt_flags & MNT_RELATIME))
|
||||
if (!(path->mnt->mnt_flags & MNT_RELATIME))
|
||||
return 1;
|
||||
|
||||
update_ovl_inode_times(path->dentry, inode, rcu);
|
||||
/*
|
||||
* Is mtime younger than atime? If yes, update atime:
|
||||
*/
|
||||
|
@ -1612,7 +1659,8 @@ static int update_time(struct inode *inode, struct timespec *time, int flags)
|
|||
* This function automatically handles read only file systems and media,
|
||||
* as well as the "noatime" flag and inode specific "noatime" markers.
|
||||
*/
|
||||
bool atime_needs_update(const struct path *path, struct inode *inode)
|
||||
bool __atime_needs_update(const struct path *path, struct inode *inode,
|
||||
bool rcu)
|
||||
{
|
||||
struct vfsmount *mnt = path->mnt;
|
||||
struct timespec now;
|
||||
|
@ -1638,7 +1686,7 @@ bool atime_needs_update(const struct path *path, struct inode *inode)
|
|||
|
||||
now = current_fs_time(inode->i_sb);
|
||||
|
||||
if (!relatime_need_update(mnt, inode, now))
|
||||
if (!relatime_need_update(path, inode, now, rcu))
|
||||
return false;
|
||||
|
||||
if (timespec_equal(&inode->i_atime, &now))
|
||||
|
@ -1653,7 +1701,7 @@ void touch_atime(const struct path *path)
|
|||
struct inode *inode = d_inode(path->dentry);
|
||||
struct timespec now;
|
||||
|
||||
if (!atime_needs_update(path, inode))
|
||||
if (!__atime_needs_update(path, inode, false))
|
||||
return;
|
||||
|
||||
if (!sb_start_write_trylock(inode->i_sb))
|
||||
|
|
|
@ -121,6 +121,15 @@ extern long prune_icache_sb(struct super_block *sb, struct shrink_control *sc);
|
|||
extern void inode_add_lru(struct inode *inode);
|
||||
extern int dentry_needs_remove_privs(struct dentry *dentry);
|
||||
|
||||
extern bool __atime_needs_update(const struct path *, struct inode *, bool);
|
||||
static inline bool atime_needs_update_rcu(const struct path *path,
|
||||
struct inode *inode)
|
||||
{
|
||||
return __atime_needs_update(path, inode, true);
|
||||
}
|
||||
|
||||
extern bool atime_needs_update_rcu(const struct path *, struct inode *);
|
||||
|
||||
/*
|
||||
* fs-writeback.c
|
||||
*/
|
||||
|
@ -157,7 +166,7 @@ extern void mnt_pin_kill(struct mount *m);
|
|||
/*
|
||||
* fs/nsfs.c
|
||||
*/
|
||||
extern struct dentry_operations ns_dentry_operations;
|
||||
extern const struct dentry_operations ns_dentry_operations;
|
||||
|
||||
/*
|
||||
* fs/ioctl.c
|
||||
|
|
|
@ -233,9 +233,10 @@ int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||
case ACL_TYPE_ACCESS:
|
||||
xprefix = JFFS2_XPREFIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
umode_t mode = inode->i_mode;
|
||||
rc = posix_acl_equiv_mode(acl, &mode);
|
||||
if (rc < 0)
|
||||
umode_t mode;
|
||||
|
||||
rc = posix_acl_update_mode(inode, &mode, &acl);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (inode->i_mode != mode) {
|
||||
struct iattr attr;
|
||||
|
@ -247,8 +248,6 @@ int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
if (rc == 0)
|
||||
acl = NULL;
|
||||
}
|
||||
break;
|
||||
case ACL_TYPE_DEFAULT:
|
||||
|
|
|
@ -193,7 +193,7 @@ int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
int rc;
|
||||
|
||||
rc = inode_change_ok(inode, iattr);
|
||||
rc = setattr_prepare(dentry, iattr);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
|
|
@ -78,13 +78,11 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
|
|||
case ACL_TYPE_ACCESS:
|
||||
ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
rc = posix_acl_equiv_mode(acl, &inode->i_mode);
|
||||
if (rc < 0)
|
||||
rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
|
||||
if (rc)
|
||||
return rc;
|
||||
inode->i_ctime = CURRENT_TIME;
|
||||
mark_inode_dirty(inode);
|
||||
if (rc == 0)
|
||||
acl = NULL;
|
||||
}
|
||||
break;
|
||||
case ACL_TYPE_DEFAULT:
|
||||
|
|
|
@ -103,7 +103,7 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
int rc;
|
||||
|
||||
rc = inode_change_ok(inode, iattr);
|
||||
rc = setattr_prepare(dentry, iattr);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ int kernfs_iop_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&kernfs_mutex);
|
||||
error = inode_change_ok(inode, iattr);
|
||||
error = setattr_prepare(dentry, iattr);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -394,7 +394,7 @@ int simple_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
int error;
|
||||
|
||||
error = inode_change_ok(inode, iattr);
|
||||
error = setattr_prepare(dentry, iattr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
53
fs/locks.c
53
fs/locks.c
|
@ -138,6 +138,11 @@
|
|||
#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG|FL_LAYOUT))
|
||||
#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
|
||||
|
||||
static inline bool is_remote_lock(struct file *filp)
|
||||
{
|
||||
return likely(!(filp->f_path.dentry->d_sb->s_flags & MS_NOREMOTELOCK));
|
||||
}
|
||||
|
||||
static bool lease_breaking(struct file_lock *fl)
|
||||
{
|
||||
return fl->fl_flags & (FL_UNLOCK_PENDING | FL_DOWNGRADE_PENDING);
|
||||
|
@ -806,7 +811,7 @@ posix_test_lock(struct file *filp, struct file_lock *fl)
|
|||
{
|
||||
struct file_lock *cfl;
|
||||
struct file_lock_context *ctx;
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct inode *inode = locks_inode(filp);
|
||||
|
||||
ctx = smp_load_acquire(&inode->i_flctx);
|
||||
if (!ctx || list_empty_careful(&ctx->flc_posix)) {
|
||||
|
@ -1211,7 +1216,7 @@ static int posix_lock_inode(struct inode *inode, struct file_lock *request,
|
|||
int posix_lock_file(struct file *filp, struct file_lock *fl,
|
||||
struct file_lock *conflock)
|
||||
{
|
||||
return posix_lock_inode(file_inode(filp), fl, conflock);
|
||||
return posix_lock_inode(locks_inode(filp), fl, conflock);
|
||||
}
|
||||
EXPORT_SYMBOL(posix_lock_file);
|
||||
|
||||
|
@ -1251,7 +1256,7 @@ static int posix_lock_inode_wait(struct inode *inode, struct file_lock *fl)
|
|||
int locks_mandatory_locked(struct file *file)
|
||||
{
|
||||
int ret;
|
||||
struct inode *inode = file_inode(file);
|
||||
struct inode *inode = locks_inode(file);
|
||||
struct file_lock_context *ctx;
|
||||
struct file_lock *fl;
|
||||
|
||||
|
@ -1597,7 +1602,7 @@ EXPORT_SYMBOL(lease_get_mtime);
|
|||
int fcntl_getlease(struct file *filp)
|
||||
{
|
||||
struct file_lock *fl;
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct inode *inode = locks_inode(filp);
|
||||
struct file_lock_context *ctx;
|
||||
int type = F_UNLCK;
|
||||
LIST_HEAD(dispose);
|
||||
|
@ -1605,7 +1610,7 @@ int fcntl_getlease(struct file *filp)
|
|||
ctx = smp_load_acquire(&inode->i_flctx);
|
||||
if (ctx && !list_empty_careful(&ctx->flc_lease)) {
|
||||
spin_lock(&ctx->flc_lock);
|
||||
time_out_leases(file_inode(filp), &dispose);
|
||||
time_out_leases(inode, &dispose);
|
||||
list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
|
||||
if (fl->fl_file != filp)
|
||||
continue;
|
||||
|
@ -1638,7 +1643,8 @@ check_conflicting_open(const struct dentry *dentry, const long arg, int flags)
|
|||
if (flags & FL_LAYOUT)
|
||||
return 0;
|
||||
|
||||
if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
|
||||
if ((arg == F_RDLCK) &&
|
||||
(atomic_read(&d_real_inode(dentry)->i_writecount) > 0))
|
||||
return -EAGAIN;
|
||||
|
||||
if ((arg == F_WRLCK) && ((d_count(dentry) > 1) ||
|
||||
|
@ -1653,7 +1659,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
|
|||
{
|
||||
struct file_lock *fl, *my_fl = NULL, *lease;
|
||||
struct dentry *dentry = filp->f_path.dentry;
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct inode *inode = dentry->d_inode;
|
||||
struct file_lock_context *ctx;
|
||||
bool is_deleg = (*flp)->fl_flags & FL_DELEG;
|
||||
int error;
|
||||
|
@ -1769,7 +1775,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
|
|||
{
|
||||
int error = -EAGAIN;
|
||||
struct file_lock *fl, *victim = NULL;
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct inode *inode = locks_inode(filp);
|
||||
struct file_lock_context *ctx;
|
||||
LIST_HEAD(dispose);
|
||||
|
||||
|
@ -1811,7 +1817,7 @@ static int generic_delete_lease(struct file *filp, void *owner)
|
|||
int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
|
||||
void **priv)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct inode *inode = locks_inode(filp);
|
||||
int error;
|
||||
|
||||
if ((!uid_eq(current_fsuid(), inode->i_uid)) && !capable(CAP_LEASE))
|
||||
|
@ -1859,7 +1865,7 @@ EXPORT_SYMBOL(generic_setlease);
|
|||
int
|
||||
vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
|
||||
{
|
||||
if (filp->f_op->setlease)
|
||||
if (filp->f_op->setlease && is_remote_lock(filp))
|
||||
return filp->f_op->setlease(filp, arg, lease, priv);
|
||||
else
|
||||
return generic_setlease(filp, arg, lease, priv);
|
||||
|
@ -2008,7 +2014,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
|
|||
if (error)
|
||||
goto out_free;
|
||||
|
||||
if (f.file->f_op->flock)
|
||||
if (f.file->f_op->flock && is_remote_lock(f.file))
|
||||
error = f.file->f_op->flock(f.file,
|
||||
(can_sleep) ? F_SETLKW : F_SETLK,
|
||||
lock);
|
||||
|
@ -2034,7 +2040,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
|
|||
*/
|
||||
int vfs_test_lock(struct file *filp, struct file_lock *fl)
|
||||
{
|
||||
if (filp->f_op->lock)
|
||||
if (filp->f_op->lock && is_remote_lock(filp))
|
||||
return filp->f_op->lock(filp, F_GETLK, fl);
|
||||
posix_test_lock(filp, fl);
|
||||
return 0;
|
||||
|
@ -2158,7 +2164,7 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)
|
|||
*/
|
||||
int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)
|
||||
{
|
||||
if (filp->f_op->lock)
|
||||
if (filp->f_op->lock && is_remote_lock(filp))
|
||||
return filp->f_op->lock(filp, cmd, fl);
|
||||
else
|
||||
return posix_lock_file(filp, fl, conf);
|
||||
|
@ -2220,7 +2226,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,
|
|||
if (file_lock == NULL)
|
||||
return -ENOLCK;
|
||||
|
||||
inode = file_inode(filp);
|
||||
inode = locks_inode(filp);
|
||||
|
||||
/*
|
||||
* This might block, so we do it before checking the inode.
|
||||
|
@ -2372,7 +2378,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
|
|||
if (copy_from_user(&flock, l, sizeof(flock)))
|
||||
goto out;
|
||||
|
||||
inode = file_inode(filp);
|
||||
inode = locks_inode(filp);
|
||||
|
||||
/* Don't allow mandatory locks on files that may be memory mapped
|
||||
* and shared.
|
||||
|
@ -2455,6 +2461,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,
|
|||
void locks_remove_posix(struct file *filp, fl_owner_t owner)
|
||||
{
|
||||
int error;
|
||||
struct inode *inode = locks_inode(filp);
|
||||
struct file_lock lock;
|
||||
struct file_lock_context *ctx;
|
||||
|
||||
|
@ -2463,7 +2470,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
|
|||
* posix_lock_file(). Another process could be setting a lock on this
|
||||
* file at the same time, but we wouldn't remove that lock anyway.
|
||||
*/
|
||||
ctx = smp_load_acquire(&file_inode(filp)->i_flctx);
|
||||
ctx = smp_load_acquire(&inode->i_flctx);
|
||||
if (!ctx || list_empty(&ctx->flc_posix))
|
||||
return;
|
||||
|
||||
|
@ -2481,7 +2488,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
|
|||
|
||||
if (lock.fl_ops && lock.fl_ops->fl_release_private)
|
||||
lock.fl_ops->fl_release_private(&lock);
|
||||
trace_locks_remove_posix(file_inode(filp), &lock, error);
|
||||
trace_locks_remove_posix(inode, &lock, error);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(locks_remove_posix);
|
||||
|
@ -2498,12 +2505,12 @@ locks_remove_flock(struct file *filp, struct file_lock_context *flctx)
|
|||
.fl_type = F_UNLCK,
|
||||
.fl_end = OFFSET_MAX,
|
||||
};
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct inode *inode = locks_inode(filp);
|
||||
|
||||
if (list_empty(&flctx->flc_flock))
|
||||
return;
|
||||
|
||||
if (filp->f_op->flock)
|
||||
if (filp->f_op->flock && is_remote_lock(filp))
|
||||
filp->f_op->flock(filp, F_SETLKW, &fl);
|
||||
else
|
||||
flock_lock_inode(inode, &fl);
|
||||
|
@ -2537,7 +2544,7 @@ void locks_remove_file(struct file *filp)
|
|||
{
|
||||
struct file_lock_context *ctx;
|
||||
|
||||
ctx = smp_load_acquire(&file_inode(filp)->i_flctx);
|
||||
ctx = smp_load_acquire(&locks_inode(filp)->i_flctx);
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
|
@ -2581,7 +2588,7 @@ EXPORT_SYMBOL(posix_unblock_lock);
|
|||
*/
|
||||
int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
|
||||
{
|
||||
if (filp->f_op->lock)
|
||||
if (filp->f_op->lock && is_remote_lock(filp))
|
||||
return filp->f_op->lock(filp, F_CANCELLK, fl);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2620,7 +2627,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
|
|||
fl_pid = fl->fl_pid;
|
||||
|
||||
if (fl->fl_file != NULL)
|
||||
inode = file_inode(fl->fl_file);
|
||||
inode = locks_inode(fl->fl_file);
|
||||
|
||||
seq_printf(f, "%lld:%s ", id, pfx);
|
||||
if (IS_POSIX(fl)) {
|
||||
|
@ -2726,7 +2733,7 @@ static void __show_fd_locks(struct seq_file *f,
|
|||
void show_fd_locks(struct seq_file *f,
|
||||
struct file *filp, struct files_struct *files)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct inode *inode = locks_inode(filp);
|
||||
struct file_lock_context *ctx;
|
||||
int id = 0;
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ static int logfs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
int err = 0;
|
||||
|
||||
err = inode_change_ok(inode, attr);
|
||||
err = setattr_prepare(dentry, attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ static int minix_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
int error;
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
|
@ -1015,7 +1015,7 @@ const char *get_link(struct nameidata *nd)
|
|||
if (!(nd->flags & LOOKUP_RCU)) {
|
||||
touch_atime(&last->link);
|
||||
cond_resched();
|
||||
} else if (atime_needs_update(&last->link, inode)) {
|
||||
} else if (atime_needs_update_rcu(&last->link, inode)) {
|
||||
if (unlikely(unlazy_walk(nd, NULL, 0)))
|
||||
return ERR_PTR(-ECHILD);
|
||||
touch_atime(&last->link);
|
||||
|
|
|
@ -2743,7 +2743,7 @@ long do_mount(const char *dev_name, const char __user *dir_name,
|
|||
|
||||
flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
|
||||
MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
|
||||
MS_STRICTATIME);
|
||||
MS_STRICTATIME | MS_NOREMOTELOCK);
|
||||
|
||||
if (flags & MS_REMOUNT)
|
||||
retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
|
||||
|
|
|
@ -884,7 +884,7 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
|
|||
/* ageing the dentry to force validation */
|
||||
ncp_age_dentry(server, dentry);
|
||||
|
||||
result = inode_change_ok(inode, attr);
|
||||
result = setattr_prepare(dentry, attr);
|
||||
if (result < 0)
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -74,10 +74,10 @@ nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
|
|||
* which only requires access, and "set-[ac]time-to-X" which
|
||||
* requires ownership.
|
||||
* So if it looks like it might be "set both to the same time which
|
||||
* is close to now", and if inode_change_ok fails, then we
|
||||
* is close to now", and if setattr_prepare fails, then we
|
||||
* convert to "set to now" instead of "set to explicit time"
|
||||
*
|
||||
* We only call inode_change_ok as the last test as technically
|
||||
* We only call setattr_prepare as the last test as technically
|
||||
* it is not an interface that we should be using.
|
||||
*/
|
||||
#define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
|
||||
|
@ -92,17 +92,15 @@ nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp,
|
|||
* request is. We require it be within 30 minutes of now.
|
||||
*/
|
||||
time_t delta = iap->ia_atime.tv_sec - get_seconds();
|
||||
struct inode *inode;
|
||||
|
||||
nfserr = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP);
|
||||
if (nfserr)
|
||||
goto done;
|
||||
inode = d_inode(fhp->fh_dentry);
|
||||
|
||||
if (delta < 0)
|
||||
delta = -delta;
|
||||
if (delta < MAX_TOUCH_TIME_ERROR &&
|
||||
inode_change_ok(inode, iap) != 0) {
|
||||
setattr_prepare(fhp->fh_dentry, iap) != 0) {
|
||||
/*
|
||||
* Turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME.
|
||||
* This will cause notify_change to set these times
|
||||
|
|
|
@ -829,7 +829,7 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||
struct super_block *sb = inode->i_sb;
|
||||
int err;
|
||||
|
||||
err = inode_change_ok(inode, iattr);
|
||||
err = setattr_prepare(dentry, iattr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -1850,7 +1850,7 @@ static ssize_t ntfs_perform_write(struct file *file, struct iov_iter *i,
|
|||
* pages being swapped out between us bringing them into memory
|
||||
* and doing the actual copying.
|
||||
*/
|
||||
if (unlikely(iov_iter_fault_in_multipages_readable(i, bytes))) {
|
||||
if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
|
||||
status = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2893,7 +2893,7 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
int err;
|
||||
unsigned int ia_valid = attr->ia_valid;
|
||||
|
||||
err = inode_change_ok(vi, attr);
|
||||
err = setattr_prepare(dentry, attr);
|
||||
if (err)
|
||||
goto out;
|
||||
/* We do not support NTFS ACLs yet. */
|
||||
|
|
|
@ -241,13 +241,11 @@ int ocfs2_set_acl(handle_t *handle,
|
|||
case ACL_TYPE_ACCESS:
|
||||
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
umode_t mode = inode->i_mode;
|
||||
ret = posix_acl_equiv_mode(acl, &mode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
umode_t mode;
|
||||
|
||||
if (ret == 0)
|
||||
acl = NULL;
|
||||
ret = posix_acl_update_mode(inode, &mode, &acl);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ocfs2_acl_set_mode(inode, di_bh,
|
||||
handle, mode);
|
||||
|
|
|
@ -211,7 +211,7 @@ static int dlmfs_file_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
|
||||
attr->ia_valid &= ~ATTR_SIZE;
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
|
@ -1155,7 +1155,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
|
||||
return 0;
|
||||
|
||||
status = inode_change_ok(inode, attr);
|
||||
status = setattr_prepare(dentry, attr);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
|
|
@ -349,7 +349,7 @@ static int omfs_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
struct inode *inode = d_inode(dentry);
|
||||
int error;
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
|
17
fs/open.c
17
fs/open.c
|
@ -68,6 +68,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
|
|||
long vfs_truncate(const struct path *path, loff_t length)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct dentry *upperdentry;
|
||||
long error;
|
||||
|
||||
inode = path->dentry->d_inode;
|
||||
|
@ -90,7 +91,17 @@ long vfs_truncate(const struct path *path, loff_t length)
|
|||
if (IS_APPEND(inode))
|
||||
goto mnt_drop_write_and_out;
|
||||
|
||||
error = get_write_access(inode);
|
||||
/*
|
||||
* If this is an overlayfs then do as if opening the file so we get
|
||||
* write access on the upper inode, not on the overlay inode. For
|
||||
* non-overlay filesystems d_real() is an identity function.
|
||||
*/
|
||||
upperdentry = d_real(path->dentry, NULL, O_WRONLY);
|
||||
error = PTR_ERR(upperdentry);
|
||||
if (IS_ERR(upperdentry))
|
||||
goto mnt_drop_write_and_out;
|
||||
|
||||
error = get_write_access(upperdentry->d_inode);
|
||||
if (error)
|
||||
goto mnt_drop_write_and_out;
|
||||
|
||||
|
@ -109,7 +120,7 @@ long vfs_truncate(const struct path *path, loff_t length)
|
|||
error = do_truncate(path->dentry, length, 0, NULL);
|
||||
|
||||
put_write_and_out:
|
||||
put_write_access(inode);
|
||||
put_write_access(upperdentry->d_inode);
|
||||
mnt_drop_write_and_out:
|
||||
mnt_drop_write(path->mnt);
|
||||
out:
|
||||
|
@ -726,7 +737,7 @@ static int do_dentry_open(struct file *f,
|
|||
if (error)
|
||||
goto cleanup_all;
|
||||
|
||||
error = break_lease(inode, f->f_flags);
|
||||
error = break_lease(locks_inode(f), f->f_flags);
|
||||
if (error)
|
||||
goto cleanup_all;
|
||||
|
||||
|
|
|
@ -73,14 +73,11 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||
case ACL_TYPE_ACCESS:
|
||||
name = XATTR_NAME_POSIX_ACL_ACCESS;
|
||||
if (acl) {
|
||||
umode_t mode = inode->i_mode;
|
||||
/*
|
||||
* can we represent this with the traditional file
|
||||
* mode permission bits?
|
||||
*/
|
||||
error = posix_acl_equiv_mode(acl, &mode);
|
||||
if (error < 0) {
|
||||
gossip_err("%s: posix_acl_equiv_mode err: %d\n",
|
||||
umode_t mode;
|
||||
|
||||
error = posix_acl_update_mode(inode, &mode, &acl);
|
||||
if (error) {
|
||||
gossip_err("%s: posix_acl_update_mode err: %d\n",
|
||||
__func__,
|
||||
error);
|
||||
return error;
|
||||
|
@ -90,8 +87,6 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
|
|||
SetModeFlag(orangefs_inode);
|
||||
inode->i_mode = mode;
|
||||
mark_inode_dirty_sync(inode);
|
||||
if (error == 0)
|
||||
acl = NULL;
|
||||
}
|
||||
break;
|
||||
case ACL_TYPE_DEFAULT:
|
||||
|
|
|
@ -177,8 +177,8 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
|
|||
}
|
||||
|
||||
gossip_debug(GOSSIP_DIR_DEBUG,
|
||||
"orangefs_readdir called on %s (pos=%llu)\n",
|
||||
dentry->d_name.name, llu(pos));
|
||||
"orangefs_readdir called on %pd (pos=%llu)\n",
|
||||
dentry, llu(pos));
|
||||
|
||||
memset(&readdir_response, 0, sizeof(readdir_response));
|
||||
|
||||
|
|
|
@ -611,8 +611,8 @@ static int orangefs_file_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
static int orangefs_file_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
gossip_debug(GOSSIP_FILE_DEBUG,
|
||||
"orangefs_file_release: called on %s\n",
|
||||
file->f_path.dentry->d_name.name);
|
||||
"orangefs_file_release: called on %pD\n",
|
||||
file);
|
||||
|
||||
orangefs_flush_inode(inode);
|
||||
|
||||
|
|
|
@ -129,8 +129,8 @@ static ssize_t orangefs_direct_IO(struct kiocb *iocb,
|
|||
struct iov_iter *iter)
|
||||
{
|
||||
gossip_debug(GOSSIP_INODE_DEBUG,
|
||||
"orangefs_direct_IO: %s\n",
|
||||
iocb->ki_filp->f_path.dentry->d_name.name);
|
||||
"orangefs_direct_IO: %pD\n",
|
||||
iocb->ki_filp);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -216,10 +216,10 @@ int orangefs_setattr(struct dentry *dentry, struct iattr *iattr)
|
|||
struct inode *inode = dentry->d_inode;
|
||||
|
||||
gossip_debug(GOSSIP_INODE_DEBUG,
|
||||
"orangefs_setattr: called on %s\n",
|
||||
dentry->d_name.name);
|
||||
"orangefs_setattr: called on %pd\n",
|
||||
dentry);
|
||||
|
||||
ret = inode_change_ok(inode, iattr);
|
||||
ret = setattr_prepare(dentry, iattr);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@ -259,8 +259,8 @@ int orangefs_getattr(struct vfsmount *mnt,
|
|||
struct orangefs_inode_s *orangefs_inode = NULL;
|
||||
|
||||
gossip_debug(GOSSIP_INODE_DEBUG,
|
||||
"orangefs_getattr: called on %s\n",
|
||||
dentry->d_name.name);
|
||||
"orangefs_getattr: called on %pd\n",
|
||||
dentry);
|
||||
|
||||
ret = orangefs_inode_getattr(inode, 0, 0);
|
||||
if (ret == 0) {
|
||||
|
|
|
@ -24,9 +24,9 @@ static int orangefs_create(struct inode *dir,
|
|||
struct inode *inode;
|
||||
int ret;
|
||||
|
||||
gossip_debug(GOSSIP_NAME_DEBUG, "%s: %s\n",
|
||||
gossip_debug(GOSSIP_NAME_DEBUG, "%s: %pd\n",
|
||||
__func__,
|
||||
dentry->d_name.name);
|
||||
dentry);
|
||||
|
||||
new_op = op_alloc(ORANGEFS_VFS_OP_CREATE);
|
||||
if (!new_op)
|
||||
|
@ -43,9 +43,9 @@ static int orangefs_create(struct inode *dir,
|
|||
ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
|
||||
|
||||
gossip_debug(GOSSIP_NAME_DEBUG,
|
||||
"%s: %s: handle:%pU: fsid:%d: new_op:%p: ret:%d:\n",
|
||||
"%s: %pd: handle:%pU: fsid:%d: new_op:%p: ret:%d:\n",
|
||||
__func__,
|
||||
dentry->d_name.name,
|
||||
dentry,
|
||||
&new_op->downcall.resp.create.refn.khandle,
|
||||
new_op->downcall.resp.create.refn.fs_id,
|
||||
new_op,
|
||||
|
@ -57,18 +57,18 @@ static int orangefs_create(struct inode *dir,
|
|||
inode = orangefs_new_inode(dir->i_sb, dir, S_IFREG | mode, 0,
|
||||
&new_op->downcall.resp.create.refn);
|
||||
if (IS_ERR(inode)) {
|
||||
gossip_err("%s: Failed to allocate inode for file :%s:\n",
|
||||
gossip_err("%s: Failed to allocate inode for file :%pd:\n",
|
||||
__func__,
|
||||
dentry->d_name.name);
|
||||
dentry);
|
||||
ret = PTR_ERR(inode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
gossip_debug(GOSSIP_NAME_DEBUG,
|
||||
"%s: Assigned inode :%pU: for file :%s:\n",
|
||||
"%s: Assigned inode :%pU: for file :%pd:\n",
|
||||
__func__,
|
||||
get_khandle_from_ino(inode),
|
||||
dentry->d_name.name);
|
||||
dentry);
|
||||
|
||||
d_instantiate(dentry, inode);
|
||||
unlock_new_inode(inode);
|
||||
|
@ -76,9 +76,9 @@ static int orangefs_create(struct inode *dir,
|
|||
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
||||
|
||||
gossip_debug(GOSSIP_NAME_DEBUG,
|
||||
"%s: dentry instantiated for %s\n",
|
||||
"%s: dentry instantiated for %pd\n",
|
||||
__func__,
|
||||
dentry->d_name.name);
|
||||
dentry);
|
||||
|
||||
SetMtimeFlag(parent);
|
||||
dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
|
||||
|
@ -87,9 +87,9 @@ static int orangefs_create(struct inode *dir,
|
|||
out:
|
||||
op_release(new_op);
|
||||
gossip_debug(GOSSIP_NAME_DEBUG,
|
||||
"%s: %s: returning %d\n",
|
||||
"%s: %pd: returning %d\n",
|
||||
__func__,
|
||||
dentry->d_name.name,
|
||||
dentry,
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -115,8 +115,8 @@ static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry,
|
|||
* -EEXIST on O_EXCL opens, which is broken if we skip this lookup
|
||||
* in the create path)
|
||||
*/
|
||||
gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %s\n",
|
||||
__func__, dentry->d_name.name);
|
||||
gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %pd\n",
|
||||
__func__, dentry);
|
||||
|
||||
if (dentry->d_name.len > (ORANGEFS_NAME_MAX - 1))
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
@ -169,9 +169,9 @@ static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry,
|
|||
|
||||
gossip_debug(GOSSIP_NAME_DEBUG,
|
||||
"orangefs_lookup: Adding *negative* dentry "
|
||||
"%p for %s\n",
|
||||
"%p for %pd\n",
|
||||
dentry,
|
||||
dentry->d_name.name);
|
||||
dentry);
|
||||
|
||||
d_add(dentry, NULL);
|
||||
res = NULL;
|
||||
|
@ -224,10 +224,10 @@ static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
|
|||
int ret;
|
||||
|
||||
gossip_debug(GOSSIP_NAME_DEBUG,
|
||||
"%s: called on %s\n"
|
||||
"%s: called on %pd\n"
|
||||
" (inode %pU): Parent is %pU | fs_id %d\n",
|
||||
__func__,
|
||||
dentry->d_name.name,
|
||||
dentry,
|
||||
get_khandle_from_ino(inode),
|
||||
&parent->refn.khandle,
|
||||
parent->refn.fs_id);
|
||||
|
@ -326,9 +326,9 @@ static int orangefs_symlink(struct inode *dir,
|
|||
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
||||
|
||||
gossip_debug(GOSSIP_NAME_DEBUG,
|
||||
"Inode (Symlink) %pU -> %s\n",
|
||||
"Inode (Symlink) %pU -> %pd\n",
|
||||
get_khandle_from_ino(inode),
|
||||
dentry->d_name.name);
|
||||
dentry);
|
||||
|
||||
SetMtimeFlag(parent);
|
||||
dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb);
|
||||
|
@ -390,9 +390,9 @@ static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
|
|||
ORANGEFS_I(inode)->getattr_time = jiffies - 1;
|
||||
|
||||
gossip_debug(GOSSIP_NAME_DEBUG,
|
||||
"Inode (Directory) %pU -> %s\n",
|
||||
"Inode (Directory) %pU -> %pd\n",
|
||||
get_khandle_from_ino(inode),
|
||||
dentry->d_name.name);
|
||||
dentry);
|
||||
|
||||
/*
|
||||
* NOTE: we have no good way to keep nlink consistent for directories
|
||||
|
|
|
@ -428,8 +428,8 @@ static ssize_t orangefs_debug_write(struct file *file,
|
|||
struct client_debug_mask c_mask = { NULL, 0, 0 };
|
||||
|
||||
gossip_debug(GOSSIP_DEBUGFS_DEBUG,
|
||||
"orangefs_debug_write: %s\n",
|
||||
file->f_path.dentry->d_name.name);
|
||||
"orangefs_debug_write: %pD\n",
|
||||
file);
|
||||
|
||||
/*
|
||||
* Thwart users who try to jamb a ridiculous number
|
||||
|
|
|
@ -53,7 +53,7 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
* inode_newsize_ok() will always check against MAX_LFS_FILESIZE and not
|
||||
* check for a swapfile (which this won't be anyway).
|
||||
*/
|
||||
err = inode_change_ok(dentry->d_inode, attr);
|
||||
err = setattr_prepare(dentry, attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -1320,7 +1320,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
|
|||
sb->s_xattr = ovl_xattr_handlers;
|
||||
sb->s_root = root_dentry;
|
||||
sb->s_fs_info = ufs;
|
||||
sb->s_flags |= MS_POSIXACL;
|
||||
sb->s_flags |= MS_POSIXACL | MS_NOREMOTELOCK;
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -598,13 +598,14 @@ posix_acl_create(struct inode *dir, umode_t *mode,
|
|||
if (IS_ERR(p))
|
||||
return PTR_ERR(p);
|
||||
|
||||
ret = -ENOMEM;
|
||||
clone = posix_acl_clone(p, GFP_NOFS);
|
||||
if (!clone)
|
||||
goto no_mem;
|
||||
goto err_release;
|
||||
|
||||
ret = posix_acl_create_masq(clone, mode);
|
||||
if (ret < 0)
|
||||
goto no_mem_clone;
|
||||
goto err_release_clone;
|
||||
|
||||
if (ret == 0)
|
||||
posix_acl_release(clone);
|
||||
|
@ -618,14 +619,45 @@ posix_acl_create(struct inode *dir, umode_t *mode,
|
|||
|
||||
return 0;
|
||||
|
||||
no_mem_clone:
|
||||
err_release_clone:
|
||||
posix_acl_release(clone);
|
||||
no_mem:
|
||||
err_release:
|
||||
posix_acl_release(p);
|
||||
return -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(posix_acl_create);
|
||||
|
||||
/**
|
||||
* posix_acl_update_mode - update mode in set_acl
|
||||
*
|
||||
* Update the file mode when setting an ACL: compute the new file permission
|
||||
* bits based on the ACL. In addition, if the ACL is equivalent to the new
|
||||
* file mode, set *acl to NULL to indicate that no ACL should be set.
|
||||
*
|
||||
* As with chmod, clear the setgit bit if the caller is not in the owning group
|
||||
* or capable of CAP_FSETID (see inode_change_ok).
|
||||
*
|
||||
* Called from set_acl inode operations.
|
||||
*/
|
||||
int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
|
||||
struct posix_acl **acl)
|
||||
{
|
||||
umode_t mode = inode->i_mode;
|
||||
int error;
|
||||
|
||||
error = posix_acl_equiv_mode(*acl, &mode);
|
||||
if (error < 0)
|
||||
return error;
|
||||
if (error == 0)
|
||||
*acl = NULL;
|
||||
if (!in_group_p(inode->i_gid) &&
|
||||
!capable_wrt_inode_uidgid(inode, CAP_FSETID))
|
||||
mode &= ~S_ISGID;
|
||||
*mode_p = mode;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(posix_acl_update_mode);
|
||||
|
||||
/*
|
||||
* Fix up the uids and gids in posix acl extended attributes in place.
|
||||
*/
|
||||
|
@ -633,15 +665,15 @@ static void posix_acl_fix_xattr_userns(
|
|||
struct user_namespace *to, struct user_namespace *from,
|
||||
void *value, size_t size)
|
||||
{
|
||||
posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
|
||||
posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
|
||||
struct posix_acl_xattr_header *header = value;
|
||||
struct posix_acl_xattr_entry *entry = (void *)(header + 1), *end;
|
||||
int count;
|
||||
kuid_t uid;
|
||||
kgid_t gid;
|
||||
|
||||
if (!value)
|
||||
return;
|
||||
if (size < sizeof(posix_acl_xattr_header))
|
||||
if (size < sizeof(struct posix_acl_xattr_header))
|
||||
return;
|
||||
if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
|
||||
return;
|
||||
|
@ -691,15 +723,15 @@ struct posix_acl *
|
|||
posix_acl_from_xattr(struct user_namespace *user_ns,
|
||||
const void *value, size_t size)
|
||||
{
|
||||
posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
|
||||
posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
|
||||
const struct posix_acl_xattr_header *header = value;
|
||||
const struct posix_acl_xattr_entry *entry = (const void *)(header + 1), *end;
|
||||
int count;
|
||||
struct posix_acl *acl;
|
||||
struct posix_acl_entry *acl_e;
|
||||
|
||||
if (!value)
|
||||
return NULL;
|
||||
if (size < sizeof(posix_acl_xattr_header))
|
||||
if (size < sizeof(struct posix_acl_xattr_header))
|
||||
return ERR_PTR(-EINVAL);
|
||||
if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
@ -760,8 +792,8 @@ int
|
|||
posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
|
||||
void *buffer, size_t size)
|
||||
{
|
||||
posix_acl_xattr_header *ext_acl = (posix_acl_xattr_header *)buffer;
|
||||
posix_acl_xattr_entry *ext_entry;
|
||||
struct posix_acl_xattr_header *ext_acl = buffer;
|
||||
struct posix_acl_xattr_entry *ext_entry;
|
||||
int real_size, n;
|
||||
|
||||
real_size = posix_acl_xattr_size(acl->a_count);
|
||||
|
@ -770,7 +802,7 @@ posix_acl_to_xattr(struct user_namespace *user_ns, const struct posix_acl *acl,
|
|||
if (real_size > size)
|
||||
return -ERANGE;
|
||||
|
||||
ext_entry = ext_acl->a_entries;
|
||||
ext_entry = (void *)(ext_acl + 1);
|
||||
ext_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
|
||||
|
||||
for (n=0; n < acl->a_count; n++, ext_entry++) {
|
||||
|
|
|
@ -400,23 +400,6 @@ static const struct file_operations proc_pid_cmdline_ops = {
|
|||
.llseek = generic_file_llseek,
|
||||
};
|
||||
|
||||
static int proc_pid_auxv(struct seq_file *m, struct pid_namespace *ns,
|
||||
struct pid *pid, struct task_struct *task)
|
||||
{
|
||||
struct mm_struct *mm = mm_access(task, PTRACE_MODE_READ_FSCREDS);
|
||||
if (mm && !IS_ERR(mm)) {
|
||||
unsigned int nwords = 0;
|
||||
do {
|
||||
nwords += 2;
|
||||
} while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
|
||||
seq_write(m, mm->saved_auxv, nwords * sizeof(mm->saved_auxv[0]));
|
||||
mmput(mm);
|
||||
return 0;
|
||||
} else
|
||||
return PTR_ERR(mm);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
/*
|
||||
* Provides a wchan file via kallsyms in a proper one-value-per-file format.
|
||||
|
@ -709,7 +692,7 @@ int proc_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
if (attr->ia_valid & ATTR_MODE)
|
||||
return -EPERM;
|
||||
|
||||
error = inode_change_ok(inode, attr);
|
||||
error = setattr_prepare(dentry, attr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -1014,6 +997,30 @@ static const struct file_operations proc_environ_operations = {
|
|||
.release = mem_release,
|
||||
};
|
||||
|
||||
static int auxv_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return __mem_open(inode, file, PTRACE_MODE_READ_FSCREDS);
|
||||
}
|
||||
|
||||
static ssize_t auxv_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct mm_struct *mm = file->private_data;
|
||||
unsigned int nwords = 0;
|
||||
do {
|
||||
nwords += 2;
|
||||
} while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
|
||||
return simple_read_from_buffer(buf, count, ppos, mm->saved_auxv,
|
||||
nwords * sizeof(mm->saved_auxv[0]));
|
||||
}
|
||||
|
||||
static const struct file_operations proc_auxv_operations = {
|
||||
.open = auxv_open,
|
||||
.read = auxv_read,
|
||||
.llseek = generic_file_llseek,
|
||||
.release = mem_release,
|
||||
};
|
||||
|
||||
static ssize_t oom_adj_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
|
@ -2842,7 +2849,7 @@ static const struct pid_entry tgid_base_stuff[] = {
|
|||
DIR("net", S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations),
|
||||
#endif
|
||||
REG("environ", S_IRUSR, proc_environ_operations),
|
||||
ONE("auxv", S_IRUSR, proc_pid_auxv),
|
||||
REG("auxv", S_IRUSR, proc_auxv_operations),
|
||||
ONE("status", S_IRUGO, proc_pid_status),
|
||||
ONE("personality", S_IRUSR, proc_pid_personality),
|
||||
ONE("limits", S_IRUGO, proc_pid_limits),
|
||||
|
@ -3230,7 +3237,7 @@ static const struct pid_entry tid_base_stuff[] = {
|
|||
DIR("net", S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations),
|
||||
#endif
|
||||
REG("environ", S_IRUSR, proc_environ_operations),
|
||||
ONE("auxv", S_IRUSR, proc_pid_auxv),
|
||||
REG("auxv", S_IRUSR, proc_auxv_operations),
|
||||
ONE("status", S_IRUGO, proc_pid_status),
|
||||
ONE("personality", S_IRUSR, proc_pid_personality),
|
||||
ONE("limits", S_IRUGO, proc_pid_limits),
|
||||
|
|
|
@ -31,7 +31,7 @@ static int seq_show(struct seq_file *m, void *v)
|
|||
put_task_struct(task);
|
||||
|
||||
if (files) {
|
||||
int fd = proc_fd(m->private);
|
||||
unsigned int fd = proc_fd(m->private);
|
||||
|
||||
spin_lock(&files->file_lock);
|
||||
file = fcheck_files(files, fd);
|
||||
|
@ -86,7 +86,7 @@ static int tid_fd_revalidate(struct dentry *dentry, unsigned int flags)
|
|||
struct task_struct *task;
|
||||
const struct cred *cred;
|
||||
struct inode *inode;
|
||||
int fd;
|
||||
unsigned int fd;
|
||||
|
||||
if (flags & LOOKUP_RCU)
|
||||
return -ECHILD;
|
||||
|
@ -158,7 +158,7 @@ static int proc_fd_link(struct dentry *dentry, struct path *path)
|
|||
}
|
||||
|
||||
if (files) {
|
||||
int fd = proc_fd(d_inode(dentry));
|
||||
unsigned int fd = proc_fd(d_inode(dentry));
|
||||
struct file *fd_file;
|
||||
|
||||
spin_lock(&files->file_lock);
|
||||
|
@ -253,7 +253,7 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx,
|
|||
continue;
|
||||
rcu_read_unlock();
|
||||
|
||||
len = snprintf(name, sizeof(name), "%d", fd);
|
||||
len = snprintf(name, sizeof(name), "%u", fd);
|
||||
if (!proc_fill_cache(file, ctx,
|
||||
name, len, instantiate, p,
|
||||
(void *)(unsigned long)fd))
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue