Commit 11fbf53d authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull misc vfs updates from Al Viro:
 "Assorted bits and pieces from various people. No common topic in this
  pile, sorry"

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  fs/affs: add rename exchange
  fs/affs: add rename2 to prepare multiple methods
  Make stat/lstat/fstatat pass AT_NO_AUTOMOUNT to vfs_statx()
  fs: don't set *REFERENCED on single use objects
  fs: compat: Remove warning from COMPATIBLE_IOCTL
  remove pointless extern of atime_need_update_rcu()
  fs: completely ignore unknown open flags
  fs: add a VALID_OPEN_FLAGS
  fs: remove _submit_bh()
  fs: constify tree_descr arrays passed to simple_fill_super()
  fs: drop duplicate header percpu-rwsem.h
  fs/affs: bugfix: Write files greater than page size on OFS
  fs/affs: bugfix: enable writes on OFS disks
  fs/affs: remove node generation check
  fs/affs: import amigaffs.h
  fs/affs: bugfix: make symbolic links work again
parents 339fbf67 6b465766
...@@ -512,7 +512,7 @@ static int qibfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -512,7 +512,7 @@ static int qibfs_fill_super(struct super_block *sb, void *data, int silent)
unsigned long flags; unsigned long flags;
int ret; int ret;
static struct tree_descr files[] = { static const struct tree_descr files[] = {
[2] = {"driver_stats", &driver_ops[0], S_IRUGO}, [2] = {"driver_stats", &driver_ops[0], S_IRUGO},
[3] = {"driver_stats_names", &driver_ops[1], S_IRUGO}, [3] = {"driver_stats_names", &driver_ops[1], S_IRUGO},
{""}, {""},
......
...@@ -44,14 +44,14 @@ static const struct file_operations capabilities_file_ops = { ...@@ -44,14 +44,14 @@ static const struct file_operations capabilities_file_ops = {
static int xenfs_fill_super(struct super_block *sb, void *data, int silent) static int xenfs_fill_super(struct super_block *sb, void *data, int silent)
{ {
static struct tree_descr xenfs_files[] = { static const struct tree_descr xenfs_files[] = {
[2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR }, [2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR },
{ "capabilities", &capabilities_file_ops, S_IRUGO }, { "capabilities", &capabilities_file_ops, S_IRUGO },
{ "privcmd", &xen_privcmd_fops, S_IRUSR|S_IWUSR }, { "privcmd", &xen_privcmd_fops, S_IRUSR|S_IWUSR },
{""}, {""},
}; };
static struct tree_descr xenfs_init_files[] = { static const struct tree_descr xenfs_init_files[] = {
[2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR }, [2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR },
{ "capabilities", &capabilities_file_ops, S_IRUGO }, { "capabilities", &capabilities_file_ops, S_IRUGO },
{ "privcmd", &xen_privcmd_fops, S_IRUSR|S_IWUSR }, { "privcmd", &xen_privcmd_fops, S_IRUSR|S_IWUSR },
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/amigaffs.h> #include "amigaffs.h"
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
...@@ -173,7 +173,7 @@ extern int affs_link(struct dentry *olddentry, struct inode *dir, ...@@ -173,7 +173,7 @@ extern int affs_link(struct dentry *olddentry, struct inode *dir,
struct dentry *dentry); struct dentry *dentry);
extern int affs_symlink(struct inode *dir, struct dentry *dentry, extern int affs_symlink(struct inode *dir, struct dentry *dentry,
const char *symname); const char *symname);
extern int affs_rename(struct inode *old_dir, struct dentry *old_dentry, extern int affs_rename2(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry, struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags); unsigned int flags);
......
...@@ -35,7 +35,7 @@ const struct inode_operations affs_dir_inode_operations = { ...@@ -35,7 +35,7 @@ const struct inode_operations affs_dir_inode_operations = {
.symlink = affs_symlink, .symlink = affs_symlink,
.mkdir = affs_mkdir, .mkdir = affs_mkdir,
.rmdir = affs_rmdir, .rmdir = affs_rmdir,
.rename = affs_rename, .rename = affs_rename2,
.setattr = affs_notify_change, .setattr = affs_notify_change,
}; };
......
...@@ -499,7 +499,7 @@ affs_getemptyblk_ino(struct inode *inode, int block) ...@@ -499,7 +499,7 @@ affs_getemptyblk_ino(struct inode *inode, int block)
} }
static int static int
affs_do_readpage_ofs(struct page *page, unsigned to) affs_do_readpage_ofs(struct page *page, unsigned to, int create)
{ {
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
...@@ -518,7 +518,7 @@ affs_do_readpage_ofs(struct page *page, unsigned to) ...@@ -518,7 +518,7 @@ affs_do_readpage_ofs(struct page *page, unsigned to)
boff = tmp % bsize; boff = tmp % bsize;
while (pos < to) { while (pos < to) {
bh = affs_bread_ino(inode, bidx, 0); bh = affs_bread_ino(inode, bidx, create);
if (IS_ERR(bh)) if (IS_ERR(bh))
return PTR_ERR(bh); return PTR_ERR(bh);
tmp = min(bsize - boff, to - pos); tmp = min(bsize - boff, to - pos);
...@@ -620,7 +620,7 @@ affs_readpage_ofs(struct file *file, struct page *page) ...@@ -620,7 +620,7 @@ affs_readpage_ofs(struct file *file, struct page *page)
memset(page_address(page) + to, 0, PAGE_SIZE - to); memset(page_address(page) + to, 0, PAGE_SIZE - to);
} }
err = affs_do_readpage_ofs(page, to); err = affs_do_readpage_ofs(page, to, 0);
if (!err) if (!err)
SetPageUptodate(page); SetPageUptodate(page);
unlock_page(page); unlock_page(page);
...@@ -657,7 +657,7 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping ...@@ -657,7 +657,7 @@ static int affs_write_begin_ofs(struct file *file, struct address_space *mapping
return 0; return 0;
/* XXX: inefficient but safe in the face of short writes */ /* XXX: inefficient but safe in the face of short writes */
err = affs_do_readpage_ofs(page, PAGE_SIZE); err = affs_do_readpage_ofs(page, PAGE_SIZE, 1);
if (err) { if (err) {
unlock_page(page); unlock_page(page);
put_page(page); put_page(page);
...@@ -679,7 +679,7 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping, ...@@ -679,7 +679,7 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
int written; int written;
from = pos & (PAGE_SIZE - 1); from = pos & (PAGE_SIZE - 1);
to = pos + len; to = from + len;
/* /*
* XXX: not sure if this can handle short copies (len < copied), but * XXX: not sure if this can handle short copies (len < copied), but
* we don't have to, because the page should always be uptodate here, * we don't have to, because the page should always be uptodate here,
......
...@@ -140,6 +140,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) ...@@ -140,6 +140,7 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
inode->i_fop = &affs_file_operations; inode->i_fop = &affs_file_operations;
break; break;
case ST_SOFTLINK: case ST_SOFTLINK:
inode->i_size = strlen((char *)AFFS_HEAD(bh)->table);
inode->i_mode |= S_IFLNK; inode->i_mode |= S_IFLNK;
inode_nohighmem(inode); inode_nohighmem(inode);
inode->i_op = &affs_symlink_inode_operations; inode->i_op = &affs_symlink_inode_operations;
......
...@@ -365,6 +365,7 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) ...@@ -365,6 +365,7 @@ affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
symname++; symname++;
} }
*p = 0; *p = 0;
inode->i_size = i + 1;
mark_buffer_dirty_inode(bh, inode); mark_buffer_dirty_inode(bh, inode);
affs_brelse(bh); affs_brelse(bh);
mark_inode_dirty(inode); mark_inode_dirty(inode);
...@@ -393,21 +394,14 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) ...@@ -393,21 +394,14 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
return affs_add_entry(dir, inode, dentry, ST_LINKFILE); return affs_add_entry(dir, inode, dentry, ST_LINKFILE);
} }
int static int
affs_rename(struct inode *old_dir, struct dentry *old_dentry, affs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry, struct inode *new_dir, struct dentry *new_dentry)
unsigned int flags)
{ {
struct super_block *sb = old_dir->i_sb; struct super_block *sb = old_dir->i_sb;
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
int retval; int retval;
if (flags & ~RENAME_NOREPLACE)
return -EINVAL;
pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__,
old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry);
retval = affs_check_name(new_dentry->d_name.name, retval = affs_check_name(new_dentry->d_name.name,
new_dentry->d_name.len, new_dentry->d_name.len,
affs_nofilenametruncate(old_dentry)); affs_nofilenametruncate(old_dentry));
...@@ -447,6 +441,76 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -447,6 +441,76 @@ affs_rename(struct inode *old_dir, struct dentry *old_dentry,
return retval; return retval;
} }
static int
affs_xrename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
struct super_block *sb = old_dir->i_sb;
struct buffer_head *bh_old = NULL;
struct buffer_head *bh_new = NULL;
int retval;
bh_old = affs_bread(sb, d_inode(old_dentry)->i_ino);
if (!bh_old)
return -EIO;
bh_new = affs_bread(sb, d_inode(new_dentry)->i_ino);
if (!bh_new)
return -EIO;
/* Remove old header from its parent directory. */
affs_lock_dir(old_dir);
retval = affs_remove_hash(old_dir, bh_old);
affs_unlock_dir(old_dir);
if (retval)
goto done;
/* Remove new header from its parent directory. */
affs_lock_dir(new_dir);
retval = affs_remove_hash(new_dir, bh_new);
affs_unlock_dir(new_dir);
if (retval)
goto done;
/* Insert old into the new directory with the new name. */
affs_copy_name(AFFS_TAIL(sb, bh_old)->name, new_dentry);
affs_fix_checksum(sb, bh_old);
affs_lock_dir(new_dir);
retval = affs_insert_hash(new_dir, bh_old);
affs_unlock_dir(new_dir);
/* Insert new into the old directory with the old name. */
affs_copy_name(AFFS_TAIL(sb, bh_new)->name, old_dentry);
affs_fix_checksum(sb, bh_new);
affs_lock_dir(old_dir);
retval = affs_insert_hash(old_dir, bh_new);
affs_unlock_dir(old_dir);
done:
mark_buffer_dirty_inode(bh_old, new_dir);
mark_buffer_dirty_inode(bh_new, old_dir);
affs_brelse(bh_old);
affs_brelse(bh_new);
return retval;
}
int affs_rename2(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
{
if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
return -EINVAL;
pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__,
old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry);
if (flags & RENAME_EXCHANGE)
return affs_xrename(old_dir, old_dentry, new_dir, new_dentry);
return affs_rename(old_dir, old_dentry, new_dir, new_dentry);
}
static struct dentry *affs_get_parent(struct dentry *child) static struct dentry *affs_get_parent(struct dentry *child)
{ {
struct inode *parent; struct inode *parent;
...@@ -477,11 +541,6 @@ static struct inode *affs_nfs_get_inode(struct super_block *sb, u64 ino, ...@@ -477,11 +541,6 @@ static struct inode *affs_nfs_get_inode(struct super_block *sb, u64 ino,
if (IS_ERR(inode)) if (IS_ERR(inode))
return ERR_CAST(inode); return ERR_CAST(inode);
if (generation && inode->i_generation != generation) {
iput(inode);
return ERR_PTR(-ESTALE);
}
return inode; return inode;
} }
......
...@@ -818,7 +818,7 @@ static const struct super_operations s_ops = { ...@@ -818,7 +818,7 @@ static const struct super_operations s_ops = {
static int bm_fill_super(struct super_block *sb, void *data, int silent) static int bm_fill_super(struct super_block *sb, void *data, int silent)
{ {
int err; int err;
static struct tree_descr bm_files[] = { static const struct tree_descr bm_files[] = {
[2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
[3] = {"register", &bm_register_operations, S_IWUSR}, [3] = {"register", &bm_register_operations, S_IWUSR},
/* last one */ {""} /* last one */ {""}
......
...@@ -49,7 +49,6 @@ ...@@ -49,7 +49,6 @@
static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
unsigned long bio_flags,
struct writeback_control *wbc); struct writeback_control *wbc);
#define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers) #define BH_ENTRY(list) list_entry((list), struct buffer_head, b_assoc_buffers)
...@@ -1830,7 +1829,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, ...@@ -1830,7 +1829,7 @@ int __block_write_full_page(struct inode *inode, struct page *page,
do { do {
struct buffer_head *next = bh->b_this_page; struct buffer_head *next = bh->b_this_page;
if (buffer_async_write(bh)) { if (buffer_async_write(bh)) {
submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, 0, wbc); submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, wbc);
nr_underway++; nr_underway++;
} }
bh = next; bh = next;
...@@ -1884,7 +1883,7 @@ int __block_write_full_page(struct inode *inode, struct page *page, ...@@ -1884,7 +1883,7 @@ int __block_write_full_page(struct inode *inode, struct page *page,
struct buffer_head *next = bh->b_this_page; struct buffer_head *next = bh->b_this_page;
if (buffer_async_write(bh)) { if (buffer_async_write(bh)) {
clear_buffer_dirty(bh); clear_buffer_dirty(bh);
submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, 0, wbc); submit_bh_wbc(REQ_OP_WRITE, write_flags, bh, wbc);
nr_underway++; nr_underway++;
} }
bh = next; bh = next;
...@@ -3092,7 +3091,7 @@ void guard_bio_eod(int op, struct bio *bio) ...@@ -3092,7 +3091,7 @@ void guard_bio_eod(int op, struct bio *bio)
} }
static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
unsigned long bio_flags, struct writeback_control *wbc) struct writeback_control *wbc)
{ {
struct bio *bio; struct bio *bio;
...@@ -3127,7 +3126,6 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, ...@@ -3127,7 +3126,6 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
bio->bi_end_io = end_bio_bh_io_sync; bio->bi_end_io = end_bio_bh_io_sync;
bio->bi_private = bh; bio->bi_private = bh;
bio->bi_flags |= bio_flags;
/* Take care of bh's that straddle the end of the device */ /* Take care of bh's that straddle the end of the device */
guard_bio_eod(op, bio); guard_bio_eod(op, bio);
...@@ -3142,16 +3140,9 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh, ...@@ -3142,16 +3140,9 @@ static int submit_bh_wbc(int op, int op_flags, struct buffer_head *bh,
return 0; return 0;
} }
int _submit_bh(int op, int op_flags, struct buffer_head *bh,
unsigned long bio_flags)
{
return submit_bh_wbc(op, op_flags, bh, bio_flags, NULL);
}
EXPORT_SYMBOL_GPL(_submit_bh);
int submit_bh(int op, int op_flags, struct buffer_head *bh) int submit_bh(int op, int op_flags, struct buffer_head *bh)
{ {
return submit_bh_wbc(op, op_flags, bh, 0, NULL); return submit_bh_wbc(op, op_flags, bh, NULL);
} }
EXPORT_SYMBOL(submit_bh); EXPORT_SYMBOL(submit_bh);
......
...@@ -833,7 +833,7 @@ static int compat_ioctl_preallocate(struct file *file, ...@@ -833,7 +833,7 @@ static int compat_ioctl_preallocate(struct file *file,
*/ */
#define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff) #define XFORM(i) (((i) ^ ((i) << 27) ^ ((i) << 17)) & 0xffffffff)
#define COMPATIBLE_IOCTL(cmd) XFORM(cmd), #define COMPATIBLE_IOCTL(cmd) XFORM((u32)cmd),
/* ioctl should not be warned about even if it's not implemented. /* ioctl should not be warned about even if it's not implemented.
Valid reasons to use this: Valid reasons to use this:
- It is implemented with ->compat_ioctl on some device, but programs - It is implemented with ->compat_ioctl on some device, but programs
......
...@@ -419,6 +419,8 @@ static void dentry_lru_add(struct dentry *dentry) ...@@ -419,6 +419,8 @@ static void dentry_lru_add(struct dentry *dentry)
{ {
if (unlikely(!(dentry->d_flags & DCACHE_LRU_LIST))) if (unlikely(!(dentry->d_flags & DCACHE_LRU_LIST)))
d_lru_add(dentry); d_lru_add(dentry);
else if (unlikely(!(dentry->d_flags & DCACHE_REFERENCED)))
dentry->d_flags |= DCACHE_REFERENCED;
} }
/** /**
...@@ -779,8 +781,6 @@ void dput(struct dentry *dentry) ...@@ -779,8 +781,6 @@ void dput(struct dentry *dentry)
goto kill_it; goto kill_it;
} }
if (!(dentry->d_flags & DCACHE_REFERENCED))
dentry->d_flags |= DCACHE_REFERENCED;
dentry_lru_add(dentry); dentry_lru_add(dentry);
dentry->d_lockref.count--; dentry->d_lockref.count--;
......
...@@ -199,7 +199,7 @@ static const struct dentry_operations debugfs_dops = { ...@@ -199,7 +199,7 @@ static const struct dentry_operations debugfs_dops = {
static int debug_fill_super(struct super_block *sb, void *data, int silent) static int debug_fill_super(struct super_block *sb, void *data, int silent)
{ {
static struct tree_descr debug_files[] = {{""}}; static const struct tree_descr debug_files[] = {{""}};
struct debugfs_fs_info *fsi; struct debugfs_fs_info *fsi;
int err; int err;
......
...@@ -899,16 +899,10 @@ static int __init fcntl_init(void) ...@@ -899,16 +899,10 @@ static int __init fcntl_init(void)
* Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
* is defined as O_NONBLOCK on some platforms and not on others. * is defined as O_NONBLOCK on some platforms and not on others.
*/ */
BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ !=
O_RDONLY | O_WRONLY | O_RDWR | HWEIGHT32(
O_CREAT | O_EXCL | O_NOCTTY | (VALID_OPEN_FLAGS & ~(O_NONBLOCK | O_NDELAY)) |
O_TRUNC | O_APPEND | /* O_NONBLOCK | */ __FMODE_EXEC | __FMODE_NONOTIFY));
__O_SYNC | O_DSYNC | FASYNC |
O_DIRECT | O_LARGEFILE | O_DIRECTORY |
O_NOFOLLOW | O_NOATIME | O_CLOEXEC |
__FMODE_EXEC | O_PATH | __O_TMPFILE |
__FMODE_NONOTIFY
));
fasync_cache = kmem_cache_create("fasync_cache", fasync_cache = kmem_cache_create("fasync_cache",
sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL); sizeof(struct fasync_struct), 0, SLAB_PANIC, NULL);
......
...@@ -292,7 +292,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc) ...@@ -292,7 +292,7 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc)
static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent) static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
{ {
struct tree_descr empty_descr = {""}; static const struct tree_descr empty_descr = {""};
struct fuse_conn *fc; struct fuse_conn *fc;
int err; int err;
......
...@@ -402,6 +402,8 @@ static void inode_lru_list_add(struct inode *inode) ...@@ -402,6 +402,8 @@ static void inode_lru_list_add(struct inode *inode)
{ {
if (list_lru_add(&inode->i_sb->s_inode_lru, &inode->i_lru)) if (list_lru_add(&inode->i_sb->s_inode_lru, &inode->i_lru))
this_cpu_inc(nr_unused); this_cpu_inc(nr_unused);
else
inode->i_state |= I_REFERENCED;
} }
/* /*
...@@ -1489,7 +1491,6 @@ static void iput_final(struct inode *inode) ...@@ -1489,7 +1491,6 @@ static void iput_final(struct inode *inode)
drop = generic_drop_inode(inode); drop = generic_drop_inode(inode);
if (!drop && (sb->s_flags & MS_ACTIVE)) { if (!drop && (sb->s_flags & MS_ACTIVE)) {
inode->i_state |= I_REFERENCED;
inode_add_lru(inode); inode_add_lru(inode);
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
return; return;
......
...@@ -126,8 +126,6 @@ static inline bool atime_needs_update_rcu(const struct path *path, ...@@ -126,8 +126,6 @@ static inline bool atime_needs_update_rcu(const struct path *path,
return __atime_needs_update(path, inode, true); return __atime_needs_update(path, inode, true);
} }
extern bool atime_needs_update_rcu(const struct path *, struct inode *);
/* /*
* fs-writeback.c * fs-writeback.c
*/ */
......
...@@ -507,7 +507,7 @@ EXPORT_SYMBOL(simple_write_end); ...@@ -507,7 +507,7 @@ EXPORT_SYMBOL(simple_write_end);
* to pass it an appropriate max_reserved value to avoid collisions. * to pass it an appropriate max_reserved value to avoid collisions.
*/ */
int simple_fill_super(struct super_block *s, unsigned long magic, int simple_fill_super(struct super_block *s, unsigned long magic,
struct tree_descr *files) const struct tree_descr *files)
{ {
struct inode *inode; struct inode *inode;
struct dentry *root; struct dentry *root;
......
...@@ -1146,7 +1146,7 @@ static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size) ...@@ -1146,7 +1146,7 @@ static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size)
static int nfsd_fill_super(struct super_block * sb, void * data, int silent) static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
{ {
static struct tree_descr nfsd_files[] = { static const struct tree_descr nfsd_files[] = {
[NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO}, [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
[NFSD_Export_features] = {"export_features", [NFSD_Export_features] = {"export_features",
&export_features_operations, S_IRUGO}, &export_features_operations, S_IRUGO},
......
...@@ -900,6 +900,12 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o ...@@ -900,6 +900,12 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
int lookup_flags = 0; int lookup_flags = 0;
int acc_mode = ACC_MODE(flags); int acc_mode = ACC_MODE(flags);
/*
* Clear out all open flags we don't know about so that we don't report
* them in fcntl(F_GETFD) or similar interfaces.
*/
flags &= VALID_OPEN_FLAGS;
if (flags & (O_CREAT | __O_TMPFILE)) if (flags & (O_CREAT | __O_TMPFILE))
op->mode = (mode & S_IALLUGO) | S_IFREG; op->mode = (mode & S_IALLUGO) | S_IFREG;
else else
......
...@@ -266,7 +266,7 @@ static const struct super_operations tracefs_super_operations = { ...@@ -266,7 +266,7 @@ static const struct super_operations tracefs_super_operations = {
static int trace_fill_super(struct super_block *sb, void *data, int silent) static int trace_fill_super(struct super_block *sb, void *data, int silent)
{ {
static struct tree_descr trace_files[] = {{""}}; static const struct tree_descr trace_files[] = {{""}};
struct tracefs_fs_info *fsi; struct tracefs_fs_info *fsi;
int err; int err;
......
...@@ -196,8 +196,6 @@ void ll_rw_block(int, int, int, struct buffer_head * bh[]); ...@@ -196,8 +196,6 @@ void ll_rw_block(int, int, int, struct buffer_head * bh[]);
int sync_dirty_buffer(struct buffer_head *bh); int sync_dirty_buffer(struct buffer_head *bh);
int __sync_dirty_buffer(struct buffer_head *bh, int op_flags); int __sync_dirty_buffer(struct buffer_head *bh, int op_flags);
void write_dirty_buffer(struct buffer_head *bh, int op_flags); void write_dirty_buffer(struct buffer_head *bh, int op_flags);
int _submit_bh(int op, int op_flags, struct buffer_head *bh,
unsigned long bio_flags);
int submit_bh(int, int, struct buffer_head *); int submit_bh(int, int, struct buffer_head *);
void write_boundary_block(struct block_device *bdev, void write_boundary_block(struct block_device *bdev,
sector_t bblock, unsigned blocksize); sector_t bblock, unsigned blocksize);
......
...@@ -3,6 +3,12 @@ ...@@ -3,6 +3,12 @@
#include <uapi/linux/fcntl.h> #include <uapi/linux/fcntl.h>
/* list of all valid flags for the open/openat flags argument: */
#define VALID_OPEN_FLAGS \
(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | \
O_APPEND | O_NDELAY | O_NONBLOCK | O_NDELAY | __O_SYNC | O_DSYNC | \
FASYNC | O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \
O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)
#ifndef force_o_largefile #ifndef force_o_largefile
#define force_o_largefile() (BITS_PER_LONG != 32) #define force_o_largefile() (BITS_PER_LONG != 32)
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
#include <linux/lockdep.h> #include <linux/lockdep.h>
#include <linux/percpu-rwsem.h> #include <linux/percpu-rwsem.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/percpu-rwsem.h>
#include <linux/delayed_call.h> #include <linux/delayed_call.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
...@@ -2925,17 +2924,19 @@ extern int vfs_statx_fd(unsigned int, struct kstat *, u32, unsigned int); ...@@ -2925,17 +2924,19 @@ extern int vfs_statx_fd(unsigned int, struct kstat *, u32, unsigned int);
static inline int vfs_stat(const char __user *filename, struct kstat *stat) static inline int vfs_stat(const char __user *filename, struct kstat *stat)
{ {
return vfs_statx(AT_FDCWD, filename, 0, stat, STATX_BASIC_STATS); return vfs_statx(AT_FDCWD, filename, AT_NO_AUTOMOUNT,
stat, STATX_BASIC_STATS);
} }
static inline int vfs_lstat(const char __user *name, struct kstat *stat) static inline int vfs_lstat(const char __user *name, struct kstat *stat)
{ {
return vfs_statx(AT_FDCWD, name, AT_SYMLINK_NOFOLLOW, return vfs_statx(AT_FDCWD, name, AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT,
stat, STATX_BASIC_STATS); stat, STATX_BASIC_STATS);
} }
static inline int vfs_fstatat(int dfd, const char __user *filename, static inline int vfs_fstatat(int dfd, const char __user *filename,
struct kstat *stat, int flags) struct kstat *stat, int flags)
{ {
return vfs_statx(dfd, filename, flags, stat, STATX_BASIC_STATS); return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
stat, STATX_BASIC_STATS);
} }
static inline int vfs_fstat(int fd, struct kstat *stat) static inline int vfs_fstat(int fd, struct kstat *stat)
{ {
...@@ -3000,9 +3001,10 @@ extern const struct file_operations simple_dir_operations; ...@@ -3000,9 +3001,10 @@ extern const struct file_operations simple_dir_operations;
extern const struct inode_operations simple_dir_inode_operations; extern const struct inode_operations simple_dir_inode_operations;
extern void make_empty_dir_inode(struct inode *inode); extern void make_empty_dir_inode(struct inode *inode);
extern bool is_empty_dir_inode(struct inode *inode); extern bool is_empty_dir_inode(struct inode *inode);
struct tree_descr { char *name; const struct file_operations *ops; int mode; }; struct tree_descr { const char *name; const struct file_operations *ops; int mode; };
struct dentry *d_alloc_name(struct dentry *, const char *); struct dentry *d_alloc_name(struct dentry *, const char *);
extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *); extern int simple_fill_super(struct super_block *, unsigned long,
const struct tree_descr *);
extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count); extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count);
extern void simple_release_fs(struct vfsmount **mount, int *count); extern void simple_release_fs(struct vfsmount **mount, int *count);
......
...@@ -429,7 +429,7 @@ static int bpf_parse_options(char *data, struct bpf_mount_opts *opts) ...@@ -429,7 +429,7 @@ static int bpf_parse_options(char *data, struct bpf_mount_opts *opts)
static int bpf_fill_super(struct super_block *sb, void *data, int silent) static int bpf_fill_super(struct super_block *sb, void *data, int silent)
{ {
static struct tree_descr bpf_rfiles[] = { { "" } }; static const struct tree_descr bpf_rfiles[] = { { "" } };
struct bpf_mount_opts opts; struct bpf_mount_opts opts;
struct inode *inode; struct inode *inode;
int ret; int ret;
......
...@@ -28,7 +28,7 @@ static int mount_count; ...@@ -28,7 +28,7 @@ static int mount_count;
static int fill_super(struct super_block *sb, void *data, int silent) static int fill_super(struct super_block *sb, void *data, int silent)
{ {
static struct tree_descr files[] = {{""}}; static const struct tree_descr files[] = {{""}};
return simple_fill_super(sb, SECURITYFS_MAGIC, files); return simple_fill_super(sb, SECURITYFS_MAGIC, files);
} }
......
...@@ -1496,7 +1496,7 @@ static const struct file_operations sel_avc_cache_stats_ops = { ...@@ -1496,7 +1496,7 @@ static const struct file_operations sel_avc_cache_stats_ops = {
static int sel_make_avc_files(struct dentry *dir) static int sel_make_avc_files(struct dentry *dir)
{ {
int i; int i;
static struct tree_descr files[] = { static const struct tree_descr files[] = {
{ "cache_threshold", { "cache_threshold",
&sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR }, &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
{ "hash_stats", &sel_avc_hash_stats_ops, S_IRUGO }, { "hash_stats", &sel_avc_hash_stats_ops, S_IRUGO },
...@@ -1805,7 +1805,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) ...@@ -1805,7 +1805,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
struct inode *inode; struct inode *inode;
struct inode_security_struct *isec; struct inode_security_struct *isec;
static struct tree_descr selinux_files[] = { static const struct tree_descr selinux_files[] = {
[SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR}, [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR},
[SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR}, [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR},
[SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO}, [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO},
......
...@@ -2855,7 +2855,7 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) ...@@ -2855,7 +2855,7 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
int rc; int rc;
struct inode *root_inode; struct inode *root_inode;
static struct tree_descr smack_files[] = { static const struct tree_descr smack_files[] = {
[SMK_LOAD] = { [SMK_LOAD] = {
"load", &smk_load_ops, S_IRUGO|S_IWUSR}, "load", &smk_load_ops, S_IRUGO|S_IWUSR},
[SMK_CIPSO] = { [SMK_CIPSO] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment