Commit 936940a9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (23 commits)
  switch xfs to generic acl caching helpers
  helpers for acl caching + switch to those
  switch shmem to inode->i_acl
  switch reiserfs to inode->i_acl
  switch reiserfs to usual conventions for caching ACLs
  reiserfs: minimal fix for ACL caching
  switch nilfs2 to inode->i_acl
  switch btrfs to inode->i_acl
  switch jffs2 to inode->i_acl
  switch jfs to inode->i_acl
  switch ext4 to inode->i_acl
  switch ext3 to inode->i_acl
  switch ext2 to inode->i_acl
  add caching of ACLs in struct inode
  fs: Add new pre-allocation ioctls to vfs for compatibility with legacy xfs ioctls
  cleanup __writeback_single_inode
  ... and the same for vfsmount id/mount group id
  Make allocation of anon devices cheaper
  update Documentation/filesystems/Locking
  devpts: remove module-related code
  ...
parents 09ce42d3 1cbd20d8
No related merge requests found
......@@ -666,10 +666,6 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
if (!ei)
return NULL;
#ifdef CONFIG_EXT4_FS_POSIX_ACL
ei->i_acl = EXT4_ACL_NOT_CACHED;
ei->i_default_acl = EXT4_ACL_NOT_CACHED;
#endif
ei->vfs_inode.i_version = 1;
ei->vfs_inode.i_data.writeback_index = 0;
memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
......@@ -735,18 +731,6 @@ static void destroy_inodecache(void)
static void ext4_clear_inode(struct inode *inode)
{
#ifdef CONFIG_EXT4_FS_POSIX_ACL
if (EXT4_I(inode)->i_acl &&
EXT4_I(inode)->i_acl != EXT4_ACL_NOT_CACHED) {
posix_acl_release(EXT4_I(inode)->i_acl);
EXT4_I(inode)->i_acl = EXT4_ACL_NOT_CACHED;
}
if (EXT4_I(inode)->i_default_acl &&
EXT4_I(inode)->i_default_acl != EXT4_ACL_NOT_CACHED) {
posix_acl_release(EXT4_I(inode)->i_default_acl);
EXT4_I(inode)->i_default_acl = EXT4_ACL_NOT_CACHED;
}
#endif
ext4_discard_preallocations(inode);
if (EXT4_JOURNAL(inode))
jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal,
......
......@@ -278,7 +278,26 @@ int sb_has_dirty_inodes(struct super_block *sb)
EXPORT_SYMBOL(sb_has_dirty_inodes);
/*
* Write a single inode's dirty pages and inode data out to disk.
* Wait for writeback on an inode to complete.
*/
static void inode_wait_for_writeback(struct inode *inode)
{
DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC);
wait_queue_head_t *wqh;
wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
do {
spin_unlock(&inode_lock);
__wait_on_bit(wqh, &wq, inode_wait, TASK_UNINTERRUPTIBLE);
spin_lock(&inode_lock);
} while (inode->i_state & I_SYNC);
}
/*
* Write out an inode's dirty pages. Called under inode_lock. Either the
* caller has ref on the inode (either via __iget or via syscall against an fd)
* or the inode has I_WILL_FREE set (via generic_forget_inode)
*
* If `wait' is set, wait on the writeout.
*
* The whole writeout design is quite complex and fragile. We want to avoid
......@@ -288,13 +307,38 @@ EXPORT_SYMBOL(sb_has_dirty_inodes);
* Called under inode_lock.
*/
static int
__sync_single_inode(struct inode *inode, struct writeback_control *wbc)
writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
{
unsigned dirty;
struct address_space *mapping = inode->i_mapping;
int wait = wbc->sync_mode == WB_SYNC_ALL;
unsigned dirty;
int ret;
if (!atomic_read(&inode->i_count))
WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING)));
else
WARN_ON(inode->i_state & I_WILL_FREE);
if (inode->i_state & I_SYNC) {
/*
* If this inode is locked for writeback and we are not doing
* writeback-for-data-integrity, move it to s_more_io so that
* writeback can proceed with the other inodes on s_io.
*
* We'll have another go at writing back this inode when we
* completed a full scan of s_io.
*/
if (!wait) {
requeue_io(inode);
return 0;
}
/*
* It's a data-integrity sync. We must wait.
*/
inode_wait_for_writeback(inode);
}
BUG_ON(inode->i_state & I_SYNC);
/* Set I_SYNC, reset I_DIRTY */
......@@ -389,50 +433,6 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
return ret;
}
/*
* Write out an inode's dirty pages. Called under inode_lock. Either the
* caller has ref on the inode (either via __iget or via syscall against an fd)
* or the inode has I_WILL_FREE set (via generic_forget_inode)
*/
static int
__writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
{
wait_queue_head_t *wqh;
if (!atomic_read(&inode->i_count))
WARN_ON(!(inode->i_state & (I_WILL_FREE|I_FREEING)));
else
WARN_ON(inode->i_state & I_WILL_FREE);
if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_SYNC)) {
/*
* We're skipping this inode because it's locked, and we're not
* doing writeback-for-data-integrity. Move it to s_more_io so
* that writeback can proceed with the other inodes on s_io.
* We'll have another go at writing back this inode when we
* completed a full scan of s_io.
*/
requeue_io(inode);
return 0;
}
/*
* It's a data-integrity sync. We must wait.
*/
if (inode->i_state & I_SYNC) {
DEFINE_WAIT_BIT(wq, &inode->i_state, __I_SYNC);
wqh = bit_waitqueue(&inode->i_state, __I_SYNC);
do {
spin_unlock(&inode_lock);
__wait_on_bit(wqh, &wq, inode_wait,
TASK_UNINTERRUPTIBLE);
spin_lock(&inode_lock);
} while (inode->i_state & I_SYNC);
}
return __sync_single_inode(inode, wbc);
}
/*
* Write out a superblock's list of dirty inodes. A wait will be performed
* upon no inodes, all inodes or the final one, depending upon sync_mode.
......@@ -526,7 +526,7 @@ void generic_sync_sb_inodes(struct super_block *sb,
BUG_ON(inode->i_state & (I_FREEING | I_CLEAR));
__iget(inode);
pages_skipped = wbc->pages_skipped;
__writeback_single_inode(inode, wbc);
writeback_single_inode(inode, wbc);
if (current_is_pdflush())
writeback_release(bdi);
if (wbc->pages_skipped != pages_skipped) {
......@@ -708,7 +708,7 @@ int write_inode_now(struct inode *inode, int sync)
might_sleep();
spin_lock(&inode_lock);
ret = __writeback_single_inode(inode, &wbc);
ret = writeback_single_inode(inode, &wbc);
spin_unlock(&inode_lock);
if (sync)
inode_sync_wait(inode);
......@@ -732,7 +732,7 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc)
int ret;
spin_lock(&inode_lock);
ret = __writeback_single_inode(inode, wbc);
ret = writeback_single_inode(inode, wbc);
spin_unlock(&inode_lock);
return ret;
}
......
......@@ -25,6 +25,7 @@
#include <linux/fsnotify.h>
#include <linux/mount.h>
#include <linux/async.h>
#include <linux/posix_acl.h>
/*
* This is needed for the following functions:
......@@ -189,6 +190,9 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
}
inode->i_private = NULL;
inode->i_mapping = mapping;
#ifdef CONFIG_FS_POSIX_ACL
inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
#endif
#ifdef CONFIG_FSNOTIFY
inode->i_fsnotify_mask = 0;
......@@ -227,6 +231,12 @@ void destroy_inode(struct inode *inode)
ima_inode_free(inode);
security_inode_free(inode);
fsnotify_inode_delete(inode);
#ifdef CONFIG_FS_POSIX_ACL
if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED)
posix_acl_release(inode->i_acl);
if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED)
posix_acl_release(inode->i_default_acl);
#endif
if (inode->i_sb->s_op->destroy_inode)
inode->i_sb->s_op->destroy_inode(inode);
else
......
......@@ -15,6 +15,7 @@
#include <linux/uaccess.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h>
#include <linux/falloc.h>
#include <asm/ioctls.h>
......@@ -403,6 +404,37 @@ EXPORT_SYMBOL(generic_block_fiemap);
#endif /* CONFIG_BLOCK */
/*
* This provides compatibility with legacy XFS pre-allocation ioctls
* which predate the fallocate syscall.
*
* Only the l_start, l_len and l_whence fields of the 'struct space_resv'
* are used here, rest are ignored.
*/
int ioctl_preallocate(struct file *filp, void __user *argp)
{
struct inode *inode = filp->f_path.dentry->d_inode;
struct space_resv sr;
if (copy_from_user(&sr, argp, sizeof(sr)))
return -EFAULT;
switch (sr.l_whence) {
case SEEK_SET:
break;
case SEEK_CUR:
sr.l_start += filp->f_pos;
break;
case SEEK_END:
sr.l_start += i_size_read(inode);
break;
default:
return -EINVAL;
}
return do_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
}
static int file_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
......@@ -414,6 +446,9 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
return ioctl_fibmap(filp, p);
case FIONREAD:
return put_user(i_size_read(inode) - filp->f_pos, p);
case FS_IOC_RESVSP:
case FS_IOC_RESVSP64:
return ioctl_preallocate(filp, p);
}
return vfs_ioctl(filp, cmd, arg);
......
......@@ -156,48 +156,25 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size)
return ERR_PTR(-EINVAL);
}
static struct posix_acl *jffs2_iget_acl(struct inode *inode, struct posix_acl **i_acl)
{
struct posix_acl *acl = JFFS2_ACL_NOT_CACHED;
spin_lock(&inode->i_lock);
if (*i_acl != JFFS2_ACL_NOT_CACHED)
acl = posix_acl_dup(*i_acl);
spin_unlock(&inode->i_lock);
return acl;
}
static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl)
{
spin_lock(&inode->i_lock);
if (*i_acl != JFFS2_ACL_NOT_CACHED)
posix_acl_release(*i_acl);
*i_acl = posix_acl_dup(acl);
spin_unlock(&inode->i_lock);
}
static struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
{
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
struct posix_acl *acl;
char *value = NULL;
int rc, xprefix;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch (type) {
case ACL_TYPE_ACCESS:
acl = jffs2_iget_acl(inode, &f->i_acl_access);
if (acl != JFFS2_ACL_NOT_CACHED)
return acl;
xprefix = JFFS2_XPREFIX_ACL_ACCESS;
break;
case ACL_TYPE_DEFAULT:
acl = jffs2_iget_acl(inode, &f->i_acl_default);
if (acl != JFFS2_ACL_NOT_CACHED)
return acl;
xprefix = JFFS2_XPREFIX_ACL_DEFAULT;
break;
default:
return ERR_PTR(-EINVAL);
BUG();
}
rc = do_jffs2_getxattr(inode, xprefix, "", NULL, 0);
if (rc > 0) {
......@@ -215,16 +192,8 @@ static struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
}
if (value)
kfree(value);
if (!IS_ERR(acl)) {
switch (type) {
case ACL_TYPE_ACCESS:
jffs2_iset_acl(inode, &f->i_acl_access, acl);
break;
case ACL_TYPE_DEFAULT:
jffs2_iset_acl(inode, &f->i_acl_default, acl);
break;
}
}
if (!IS_ERR(acl))
set_cached_acl(inode, type, acl);
return acl;
}
......@@ -249,7 +218,6 @@ static int __jffs2_set_acl(struct inode *inode, int xprefix, struct posix_acl *a
static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
{
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
int rc, xprefix;
if (S_ISLNK(inode->i_mode))
......@@ -285,16 +253,8 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
return -EINVAL;
}
rc = __jffs2_set_acl(inode, xprefix, acl);
if (!rc) {
switch(type) {
case ACL_TYPE_ACCESS:
jffs2_iset_acl(inode, &f->i_acl_access, acl);
break;
case ACL_TYPE_DEFAULT:
jffs2_iset_acl(inode, &f->i_acl_default, acl);
break;
}
}
if (!rc)
set_cached_acl(inode, type, acl);
return rc;
}
......@@ -321,12 +281,11 @@ int jffs2_permission(struct inode *inode, int mask)
int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
{
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
struct posix_acl *acl, *clone;
int rc;
f->i_acl_default = NULL;
f->i_acl_access = NULL;
inode->i_default_acl = NULL;
inode->i_acl = NULL;
if (S_ISLNK(*i_mode))
return 0; /* Symlink always has no-ACL */
......@@ -339,7 +298,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
*i_mode &= ~current_umask();
} else {
if (S_ISDIR(*i_mode))
jffs2_iset_acl(inode, &f->i_acl_default, acl);
set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);
clone = posix_acl_clone(acl, GFP_KERNEL);
if (!clone)
......@@ -350,7 +309,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
return rc;
}
if (rc > 0)
jffs2_iset_acl(inode, &f->i_acl_access, clone);
set_cached_acl(inode, ACL_TYPE_ACCESS, clone);
posix_acl_release(clone);
}
......@@ -359,17 +318,16 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
int jffs2_init_acl_post(struct inode *inode)
{
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
int rc;
if (f->i_acl_default) {
rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, f->i_acl_default);
if (inode->i_default_acl) {
rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl);
if (rc)
return rc;
}
if (f->i_acl_access) {
rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, f->i_acl_access);
if (inode->i_acl) {
rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl);
if (rc)
return rc;
}
......@@ -377,18 +335,6 @@ int jffs2_init_acl_post(struct inode *inode)
return 0;
}
void jffs2_clear_acl(struct jffs2_inode_info *f)
{
if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) {
posix_acl_release(f->i_acl_access);
f->i_acl_access = JFFS2_ACL_NOT_CACHED;
}
if (f->i_acl_default && f->i_acl_default != JFFS2_ACL_NOT_CACHED) {
posix_acl_release(f->i_acl_default);
f->i_acl_default = JFFS2_ACL_NOT_CACHED;
}
}
int jffs2_acl_chmod(struct inode *inode)
{
struct posix_acl *acl, *clone;
......
......@@ -26,13 +26,10 @@ struct jffs2_acl_header {
#ifdef CONFIG_JFFS2_FS_POSIX_ACL
#define JFFS2_ACL_NOT_CACHED ((void *)-1)
extern int jffs2_permission(struct inode *, int);
extern int jffs2_acl_chmod(struct inode *);
extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *);
extern int jffs2_init_acl_post(struct inode *);
extern void jffs2_clear_acl(struct jffs2_inode_info *);
extern struct xattr_handler jffs2_acl_access_xattr_handler;
extern struct xattr_handler jffs2_acl_default_xattr_handler;
......@@ -43,6 +40,5 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler;
#define jffs2_acl_chmod(inode) (0)
#define jffs2_init_acl_pre(dir_i,inode,mode) (0)
#define jffs2_init_acl_post(inode) (0)
#define jffs2_clear_acl(f)
#endif /* CONFIG_JFFS2_FS_POSIX_ACL */
......@@ -50,10 +50,6 @@ struct jffs2_inode_info {
uint16_t flags;
uint8_t usercompr;
struct inode vfs_inode;
#ifdef CONFIG_JFFS2_FS_POSIX_ACL
struct posix_acl *i_acl_access;
struct posix_acl *i_acl_default;
#endif
};
#endif /* _JFFS2_FS_I */
......@@ -56,10 +56,6 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
f->target = NULL;
f->flags = 0;
f->usercompr = 0;
#ifdef CONFIG_JFFS2_FS_POSIX_ACL
f->i_acl_access = JFFS2_ACL_NOT_CACHED;
f->i_acl_default = JFFS2_ACL_NOT_CACHED;
#endif
}
......
......@@ -1424,7 +1424,6 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
struct jffs2_full_dirent *fd, *fds;
int deleted;
jffs2_clear_acl(f);
jffs2_xattr_delete_inode(c, f->inocache);
mutex_lock(&f->sem);
deleted = f->inocache && !f->inocache->pino_nlink;
......
......@@ -31,27 +31,24 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
{
struct posix_acl *acl;
char *ea_name;
struct jfs_inode_info *ji = JFS_IP(inode);
struct posix_acl **p_acl;
int size;
char *value = NULL;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch(type) {
case ACL_TYPE_ACCESS:
ea_name = POSIX_ACL_XATTR_ACCESS;
p_acl = &ji->i_acl;
break;
case ACL_TYPE_DEFAULT:
ea_name = POSIX_ACL_XATTR_DEFAULT;
p_acl = &ji->i_default_acl;
break;
default:
return ERR_PTR(-EINVAL);
}
if (*p_acl != JFS_ACL_NOT_CACHED)
return posix_acl_dup(*p_acl);
size = __jfs_getxattr(inode, ea_name, NULL, 0);
if (size > 0) {
......@@ -62,17 +59,18 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
}
if (size < 0) {
if (size == -ENODATA) {
*p_acl = NULL;
if (size == -ENODATA)
acl = NULL;
} else
else
acl = ERR_PTR(size);
} else {
acl = posix_acl_from_xattr(value, size);
if (!IS_ERR(acl))
*p_acl = posix_acl_dup(acl);
}
kfree(value);
if (!IS_ERR(acl)) {
set_cached_acl(inode, type, acl);
posix_acl_release(acl);
}
return acl;
}
......@@ -80,8 +78,6 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
struct posix_acl *acl)
{
char *ea_name;
struct jfs_inode_info *ji = JFS_IP(inode);
struct posix_acl **p_acl;
int rc;
int size = 0;
char *value = NULL;
......@@ -92,11 +88,9 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
switch(type) {
case ACL_TYPE_ACCESS:
ea_name = POSIX_ACL_XATTR_ACCESS;
p_acl = &ji->i_acl;
break;
case ACL_TYPE_DEFAULT:
ea_name = POSIX_ACL_XATTR_DEFAULT;
p_acl = &ji->i_default_acl;
if (!S_ISDIR(inode->i_mode))
return acl ? -EACCES : 0;
break;
......@@ -116,27 +110,23 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
out:
kfree(value);
if (!rc) {
if (*p_acl && (*p_acl != JFS_ACL_NOT_CACHED))
posix_acl_release(*p_acl);
*p_acl = posix_acl_dup(acl);
}
if (!rc)
set_cached_acl(inode, type, acl);
return rc;
}
static int jfs_check_acl(struct inode *inode, int mask)
{
struct jfs_inode_info *ji = JFS_IP(inode);
if (ji->i_acl == JFS_ACL_NOT_CACHED) {
if (inode->i_acl == ACL_NOT_CACHED) {
struct posix_acl *acl = jfs_get_acl(inode, ACL_TYPE_ACCESS);
if (IS_ERR(acl))
return PTR_ERR(acl);
posix_acl_release(acl);
}
if (ji->i_acl)
return posix_acl_permission(inode, ji->i_acl, mask);
if (inode->i_acl)
return posix_acl_permission(inode, inode->i_acl, mask);
return -EAGAIN;
}
......
......@@ -74,10 +74,6 @@ struct jfs_inode_info {
/* xattr_sem allows us to access the xattrs without taking i_mutex */
struct rw_semaphore xattr_sem;
lid_t xtlid; /* lid of xtree lock on directory */
#ifdef CONFIG_JFS_POSIX_ACL
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif
union {
struct {
xtpage_t _xtroot; /* 288: xtree root */
......@@ -107,8 +103,6 @@ struct jfs_inode_info {
#define i_inline u.link._inline
#define i_inline_ea u.link._inline_ea
#define JFS_ACL_NOT_CACHED ((void *)-1)
#define IREAD_LOCK(ip, subclass) \
down_read_nested(&JFS_IP(ip)->rdwrlock, subclass)
#define IREAD_UNLOCK(ip) up_read(&JFS_IP(ip)->rdwrlock)
......
......@@ -128,18 +128,6 @@ static void jfs_destroy_inode(struct inode *inode)
ji->active_ag = -1;
}
spin_unlock_irq(&ji->ag_lock);
#ifdef CONFIG_JFS_POSIX_ACL
if (ji->i_acl != JFS_ACL_NOT_CACHED) {
posix_acl_release(ji->i_acl);
ji->i_acl = JFS_ACL_NOT_CACHED;
}
if (ji->i_default_acl != JFS_ACL_NOT_CACHED) {
posix_acl_release(ji->i_default_acl);
ji->i_default_acl = JFS_ACL_NOT_CACHED;
}
#endif
kmem_cache_free(jfs_inode_cachep, ji);
}
......@@ -798,10 +786,6 @@ static void init_once(void *foo)
init_rwsem(&jfs_ip->xattr_sem);
spin_lock_init(&jfs_ip->ag_lock);
jfs_ip->active_ag = -1;
#ifdef CONFIG_JFS_POSIX_ACL
jfs_ip->i_acl = JFS_ACL_NOT_CACHED;
jfs_ip->i_default_acl = JFS_ACL_NOT_CACHED;
#endif
inode_init_once(&jfs_ip->vfs_inode);
}
......
......@@ -727,10 +727,7 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
/*
* We're changing the ACL. Get rid of the cached one
*/
acl =JFS_IP(inode)->i_acl;
if (acl != JFS_ACL_NOT_CACHED)
posix_acl_release(acl);
JFS_IP(inode)->i_acl = JFS_ACL_NOT_CACHED;
forget_cached_acl(inode, ACL_TYPE_ACCESS);
return 0;
} else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) {
......@@ -746,10 +743,7 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
/*
* We're changing the default ACL. Get rid of the cached one
*/
acl =JFS_IP(inode)->i_default_acl;
if (acl && (acl != JFS_ACL_NOT_CACHED))
posix_acl_release(acl);
JFS_IP(inode)->i_default_acl = JFS_ACL_NOT_CACHED;
forget_cached_acl(inode, ACL_TYPE_DEFAULT);
return 0;
}
......
......@@ -1698,8 +1698,11 @@ struct file *do_filp_open(int dfd, const char *pathname,
if (error)
return ERR_PTR(error);
error = path_walk(pathname, &nd);
if (error)
if (error) {
if (nd.root.mnt)
path_put(&nd.root);
return ERR_PTR(error);
}
if (unlikely(!audit_dummy_context()))
audit_inode(pathname, nd.path.dentry);
......@@ -1759,6 +1762,8 @@ struct file *do_filp_open(int dfd, const char *pathname,
}
filp = nameidata_to_filp(&nd, open_flag);
mnt_drop_write(nd.path.mnt);
if (nd.root.mnt)
path_put(&nd.root);
return filp;
}
......@@ -1819,6 +1824,8 @@ struct file *do_filp_open(int dfd, const char *pathname,
*/
if (will_write)
mnt_drop_write(nd.path.mnt);
if (nd.root.mnt)
path_put(&nd.root);
return filp;
exit_mutex_unlock:
......@@ -1859,6 +1866,8 @@ struct file *do_filp_open(int dfd, const char *pathname,
* with "intent.open".
*/
release_open_intent(&nd);
if (nd.root.mnt)
path_put(&nd.root);
return ERR_PTR(error);
}
nd.flags &= ~LOOKUP_PARENT;
......
......@@ -42,6 +42,8 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
static int event;
static DEFINE_IDA(mnt_id_ida);
static DEFINE_IDA(mnt_group_ida);
static int mnt_id_start = 0;
static int mnt_group_start = 1;
static struct list_head *mount_hashtable __read_mostly;
static struct kmem_cache *mnt_cache __read_mostly;
......@@ -69,7 +71,9 @@ static int mnt_alloc_id(struct vfsmount *mnt)
retry:
ida_pre_get(&mnt_id_ida, GFP_KERNEL);
spin_lock(&vfsmount_lock);
res = ida_get_new(&mnt_id_ida, &mnt->mnt_id);
res = ida_get_new_above(&mnt_id_ida, mnt_id_start, &mnt->mnt_id);
if (!res)
mnt_id_start = mnt->mnt_id + 1;
spin_unlock(&vfsmount_lock);
if (res == -EAGAIN)
goto retry;
......@@ -79,8 +83,11 @@ static int mnt_alloc_id(struct vfsmount *mnt)
static void mnt_free_id(struct vfsmount *mnt)
{
int id = mnt->mnt_id;
spin_lock(&vfsmount_lock);
ida_remove(&mnt_id_ida, mnt->mnt_id);
ida_remove(&mnt_id_ida, id);
if (mnt_id_start > id)
mnt_id_start = id;
spin_unlock(&vfsmount_lock);
}
......@@ -91,10 +98,18 @@ static void mnt_free_id(struct vfsmount *mnt)
*/
static int mnt_alloc_group_id(struct vfsmount *mnt)
{
int res;
if (!ida_pre_get(&mnt_group_ida, GFP_KERNEL))
return -ENOMEM;
return ida_get_new_above(&mnt_group_ida, 1, &mnt->mnt_group_id);
res = ida_get_new_above(&mnt_group_ida,
mnt_group_start,
&mnt->mnt_group_id);
if (!res)
mnt_group_start = mnt->mnt_group_id + 1;
return res;
}
/*
......@@ -102,7 +117,10 @@ static int mnt_alloc_group_id(struct vfsmount *mnt)
*/
void mnt_release_group_id(struct vfsmount *mnt)
{
ida_remove(&mnt_group_ida, mnt->mnt_group_id);
int id = mnt->mnt_group_id;
ida_remove(&mnt_group_ida, id);
if (mnt_group_start > id)
mnt_group_start = id;
mnt->mnt_group_id = 0;
}
......@@ -2222,16 +2240,9 @@ static void __init init_mount_tree(void)
mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
if (IS_ERR(mnt))
panic("Can't create rootfs");
ns = kmalloc(sizeof(*ns), GFP_KERNEL);
if (!ns)
ns = create_mnt_ns(mnt);
if (IS_ERR(ns))
panic("Can't allocate initial namespace");
atomic_set(&ns->count, 1);
INIT_LIST_HEAD(&ns->list);
init_waitqueue_head(&ns->poll);
ns->event = 0;
list_add(&mnt->mnt_list, &ns->list);
ns->root = mnt;
mnt->mnt_ns = ns;
init_task.nsproxy->mnt_ns = ns;
get_mnt_ns(ns);
......
......@@ -309,10 +309,6 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode)
/* ii->i_file_acl = 0; */
/* ii->i_dir_acl = 0; */
ii->i_dir_start_lookup = 0;
#ifdef CONFIG_NILFS_FS_POSIX_ACL
ii->i_acl = NULL;
ii->i_default_acl = NULL;
#endif
ii->i_cno = 0;
nilfs_set_inode_flags(inode);
spin_lock(&sbi->s_next_gen_lock);
......@@ -434,10 +430,6 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino,
raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh);
#ifdef CONFIG_NILFS_FS_POSIX_ACL
ii->i_acl = NILFS_ACL_NOT_CACHED;
ii->i_default_acl = NILFS_ACL_NOT_CACHED;
#endif
if (nilfs_read_inode_common(inode, raw_inode))
goto failed_unmap;
......
......@@ -57,10 +57,6 @@ struct nilfs_inode_info {
* EAs.
*/
struct rw_semaphore xattr_sem;
#endif
#ifdef CONFIG_NILFS_POSIX_ACL
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif
struct buffer_head *i_bh; /* i_bh contains a new or dirty
disk inode */
......
......@@ -189,16 +189,6 @@ static void nilfs_clear_inode(struct inode *inode)
{
struct nilfs_inode_info *ii = NILFS_I(inode);
#ifdef CONFIG_NILFS_POSIX_ACL
if (ii->i_acl && ii->i_acl != NILFS_ACL_NOT_CACHED) {
posix_acl_release(ii->i_acl);
ii->i_acl = NILFS_ACL_NOT_CACHED;
}
if (ii->i_default_acl && ii->i_default_acl != NILFS_ACL_NOT_CACHED) {
posix_acl_release(ii->i_default_acl);
ii->i_default_acl = NILFS_ACL_NOT_CACHED;
}
#endif
/*
* Free resources allocated in nilfs_read_inode(), here.
*/
......
......@@ -378,63 +378,63 @@ SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64);
#endif
#endif /* BITS_PER_LONG == 32 */
SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
{
struct file *file;
struct inode *inode;
long ret = -EINVAL;
struct inode *inode = file->f_path.dentry->d_inode;
long ret;
if (offset < 0 || len <= 0)
goto out;
return -EINVAL;
/* Return error if mode is not supported */
ret = -EOPNOTSUPP;
if (mode && !(mode & FALLOC_FL_KEEP_SIZE))
goto out;
return -EOPNOTSUPP;
ret = -EBADF;
file = fget(fd);
if (!file)
goto out;
if (!(file->f_mode & FMODE_WRITE))
goto out_fput;
return -EBADF;
/*
* Revalidate the write permissions, in case security policy has
* changed since the files were opened.
*/
ret = security_file_permission(file, MAY_WRITE);
if (ret)
goto out_fput;
return ret;
inode = file->f_path.dentry->d_inode;
ret = -ESPIPE;
if (S_ISFIFO(inode->i_mode))
goto out_fput;
return -ESPIPE;
ret = -ENODEV;
/*
* Let individual file system decide if it supports preallocation
* for directories or not.
*/
if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
goto out_fput;
return -ENODEV;
ret = -EFBIG;
/* Check for wrap through zero too */
if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0))
goto out_fput;
return -EFBIG;
if (inode->i_op->fallocate)
ret = inode->i_op->fallocate(inode, mode, offset, len);
else
ret = -EOPNOTSUPP;
if (!inode->i_op->fallocate)
return -EOPNOTSUPP;
out_fput:
fput(file);
out:
return ret;
return inode->i_op->fallocate(inode, mode, offset, len);
}
SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
{
struct file *file;
int error = -EBADF;
file = fget(fd);
if (file) {
error = do_fallocate(file, mode, offset, len);
fput(file);
}
return error;
}
#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len)
{
......
......@@ -1131,8 +1131,6 @@ static void init_inode(struct inode *inode, struct treepath *path)
REISERFS_I(inode)->i_trans_id = 0;
REISERFS_I(inode)->i_jl = NULL;
mutex_init(&(REISERFS_I(inode)->i_mmap));
reiserfs_init_acl_access(inode);
reiserfs_init_acl_default(inode);
reiserfs_init_xattr_rwsem(inode);
if (stat_data_v1(ih)) {
......@@ -1834,8 +1832,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
mutex_init(&(REISERFS_I(inode)->i_mmap));
reiserfs_init_acl_access(inode);
reiserfs_init_acl_default(inode);
reiserfs_init_xattr_rwsem(inode);
/* key to search for correct place for new stat data */
......
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