dquot: move dquot transfer responsibility into the filesystem
Currently notify_change calls vfs_dq_transfer directly. This means we tie the quota code into the VFS. Get rid of that and make the filesystem responsible for the transfer. Most filesystems already do this, only ufs and udf need the code added, and for jfs it needs to be enabled unconditionally instead of only when ACLs are enabled. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz>
This commit is contained in:
parent
63936ddaa1
commit
759bfee658
11
fs/attr.c
11
fs/attr.c
|
@ -12,7 +12,6 @@
|
||||||
#include <linux/capability.h>
|
#include <linux/capability.h>
|
||||||
#include <linux/fsnotify.h>
|
#include <linux/fsnotify.h>
|
||||||
#include <linux/fcntl.h>
|
#include <linux/fcntl.h>
|
||||||
#include <linux/quotaops.h>
|
|
||||||
#include <linux/security.h>
|
#include <linux/security.h>
|
||||||
|
|
||||||
/* Taken over from the old code... */
|
/* Taken over from the old code... */
|
||||||
|
@ -212,14 +211,8 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
|
||||||
error = inode->i_op->setattr(dentry, attr);
|
error = inode->i_op->setattr(dentry, attr);
|
||||||
} else {
|
} else {
|
||||||
error = inode_change_ok(inode, attr);
|
error = inode_change_ok(inode, attr);
|
||||||
if (!error) {
|
if (!error)
|
||||||
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
|
error = inode_setattr(inode, attr);
|
||||||
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
|
|
||||||
error = vfs_dq_transfer(inode, attr) ?
|
|
||||||
-EDQUOT : 0;
|
|
||||||
if (!error)
|
|
||||||
error = inode_setattr(inode, attr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ia_valid & ATTR_SIZE)
|
if (ia_valid & ATTR_SIZE)
|
||||||
|
|
26
fs/jfs/acl.c
26
fs/jfs/acl.c
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/quotaops.h>
|
|
||||||
#include <linux/posix_acl_xattr.h>
|
#include <linux/posix_acl_xattr.h>
|
||||||
#include "jfs_incore.h"
|
#include "jfs_incore.h"
|
||||||
#include "jfs_txnmgr.h"
|
#include "jfs_txnmgr.h"
|
||||||
|
@ -174,7 +173,7 @@ cleanup:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jfs_acl_chmod(struct inode *inode)
|
int jfs_acl_chmod(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct posix_acl *acl, *clone;
|
struct posix_acl *acl, *clone;
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -205,26 +204,3 @@ static int jfs_acl_chmod(struct inode *inode)
|
||||||
posix_acl_release(clone);
|
posix_acl_release(clone);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
|
||||||
{
|
|
||||||
struct inode *inode = dentry->d_inode;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = inode_change_ok(inode, iattr);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
|
|
||||||
(iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
|
|
||||||
if (vfs_dq_transfer(inode, iattr))
|
|
||||||
return -EDQUOT;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = inode_setattr(inode, iattr);
|
|
||||||
|
|
||||||
if (!rc && (iattr->ia_valid & ATTR_MODE))
|
|
||||||
rc = jfs_acl_chmod(inode);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
#include <linux/quotaops.h>
|
||||||
#include "jfs_incore.h"
|
#include "jfs_incore.h"
|
||||||
#include "jfs_inode.h"
|
#include "jfs_inode.h"
|
||||||
#include "jfs_dmap.h"
|
#include "jfs_dmap.h"
|
||||||
|
@ -88,14 +89,37 @@ static int jfs_release(struct inode *inode, struct file *file)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
||||||
|
{
|
||||||
|
struct inode *inode = dentry->d_inode;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = inode_change_ok(inode, iattr);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
|
||||||
|
(iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
|
||||||
|
if (vfs_dq_transfer(inode, iattr))
|
||||||
|
return -EDQUOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = inode_setattr(inode, iattr);
|
||||||
|
|
||||||
|
if (!rc && (iattr->ia_valid & ATTR_MODE))
|
||||||
|
rc = jfs_acl_chmod(inode);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
const struct inode_operations jfs_file_inode_operations = {
|
const struct inode_operations jfs_file_inode_operations = {
|
||||||
.truncate = jfs_truncate,
|
.truncate = jfs_truncate,
|
||||||
.setxattr = jfs_setxattr,
|
.setxattr = jfs_setxattr,
|
||||||
.getxattr = jfs_getxattr,
|
.getxattr = jfs_getxattr,
|
||||||
.listxattr = jfs_listxattr,
|
.listxattr = jfs_listxattr,
|
||||||
.removexattr = jfs_removexattr,
|
.removexattr = jfs_removexattr,
|
||||||
#ifdef CONFIG_JFS_POSIX_ACL
|
|
||||||
.setattr = jfs_setattr,
|
.setattr = jfs_setattr,
|
||||||
|
#ifdef CONFIG_JFS_POSIX_ACL
|
||||||
.check_acl = jfs_check_acl,
|
.check_acl = jfs_check_acl,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
int jfs_check_acl(struct inode *, int);
|
int jfs_check_acl(struct inode *, int);
|
||||||
int jfs_init_acl(tid_t, struct inode *, struct inode *);
|
int jfs_init_acl(tid_t, struct inode *, struct inode *);
|
||||||
int jfs_setattr(struct dentry *, struct iattr *);
|
int jfs_acl_chmod(struct inode *inode);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -32,5 +32,10 @@ static inline int jfs_init_acl(tid_t tid, struct inode *inode,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int jfs_acl_chmod(struct inode *inode)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif /* _H_JFS_ACL */
|
#endif /* _H_JFS_ACL */
|
||||||
|
|
|
@ -40,6 +40,7 @@ extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
|
||||||
int fh_len, int fh_type);
|
int fh_len, int fh_type);
|
||||||
extern void jfs_set_inode_flags(struct inode *);
|
extern void jfs_set_inode_flags(struct inode *);
|
||||||
extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
||||||
|
extern int jfs_setattr(struct dentry *, struct iattr *);
|
||||||
|
|
||||||
extern const struct address_space_operations jfs_aops;
|
extern const struct address_space_operations jfs_aops;
|
||||||
extern const struct inode_operations jfs_dir_inode_operations;
|
extern const struct inode_operations jfs_dir_inode_operations;
|
||||||
|
|
|
@ -1541,8 +1541,8 @@ const struct inode_operations jfs_dir_inode_operations = {
|
||||||
.getxattr = jfs_getxattr,
|
.getxattr = jfs_getxattr,
|
||||||
.listxattr = jfs_listxattr,
|
.listxattr = jfs_listxattr,
|
||||||
.removexattr = jfs_removexattr,
|
.removexattr = jfs_removexattr,
|
||||||
#ifdef CONFIG_JFS_POSIX_ACL
|
|
||||||
.setattr = jfs_setattr,
|
.setattr = jfs_setattr,
|
||||||
|
#ifdef CONFIG_JFS_POSIX_ACL
|
||||||
.check_acl = jfs_check_acl,
|
.check_acl = jfs_check_acl,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/smp_lock.h>
|
#include <linux/smp_lock.h>
|
||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
|
#include <linux/quotaops.h>
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/aio.h>
|
#include <linux/aio.h>
|
||||||
|
|
||||||
|
@ -217,6 +218,26 @@ const struct file_operations udf_file_operations = {
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int udf_setattr(struct dentry *dentry, struct iattr *iattr)
|
||||||
|
{
|
||||||
|
struct inode *inode = dentry->d_inode;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = inode_change_ok(inode, iattr);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
|
||||||
|
(iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
|
||||||
|
error = vfs_dq_transfer(inode, iattr) ? -EDQUOT : 0;
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return inode_setattr(inode, iattr);
|
||||||
|
}
|
||||||
|
|
||||||
const struct inode_operations udf_file_inode_operations = {
|
const struct inode_operations udf_file_inode_operations = {
|
||||||
.truncate = udf_truncate,
|
.truncate = udf_truncate,
|
||||||
|
.setattr = udf_setattr,
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include <linux/buffer_head.h>
|
#include <linux/buffer_head.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#include <linux/quotaops.h>
|
||||||
|
|
||||||
#include "ufs_fs.h"
|
#include "ufs_fs.h"
|
||||||
#include "ufs.h"
|
#include "ufs.h"
|
||||||
|
@ -517,6 +518,12 @@ static int ufs_setattr(struct dentry *dentry, struct iattr *attr)
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
|
||||||
|
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
|
||||||
|
error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
if (ia_valid & ATTR_SIZE &&
|
if (ia_valid & ATTR_SIZE &&
|
||||||
attr->ia_size != i_size_read(inode)) {
|
attr->ia_size != i_size_read(inode)) {
|
||||||
loff_t old_i_size = inode->i_size;
|
loff_t old_i_size = inode->i_size;
|
||||||
|
|
Loading…
Reference in New Issue