@@ -545,6 +545,29 @@ static int ioctl_fsthaw(struct file *filp)
return thaw_super(sb);
}
+static int ioctl_fioqsize(struct file *filp, int __user *argp)
+{
+ struct inode *inode = file_inode(filp);
+ loff_t res = 0;
+ int error = 0;
+
+ if (inode->i_op->get_qsize) {
+ res = inode->i_op->get_qsize(inode);
+ error = copy_to_user(argp, &res, sizeof(res)) ?
+ -EFAULT : 0;
+ } else {
+ if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
+ S_ISLNK(inode->i_mode)) {
+ res = inode_get_bytes(inode);
+ error = copy_to_user(argp, &res, sizeof(res)) ?
+ -EFAULT : 0;
+ } else {
+ error = -ENOTTY;
+ }
+ }
+ return error;
+}
+
/*
* When you add any new common ioctls to the switches above and below
* please update compat_sys_ioctl() too.
@@ -577,13 +600,7 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
break;
case FIOQSIZE:
- if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
- S_ISLNK(inode->i_mode)) {
- loff_t res = inode_get_bytes(inode);
- error = copy_to_user(argp, &res, sizeof(res)) ?
- -EFAULT : 0;
- } else
- error = -ENOTTY;
+ error = ioctl_fioqsize(filp, argp);
break;
case FIFREEZE:
@@ -1669,6 +1669,7 @@ struct inode_operations {
umode_t create_mode, int *opened);
int (*tmpfile) (struct inode *, struct dentry *, umode_t);
int (*set_acl)(struct inode *, struct posix_acl *, int);
+ ssize_t (*get_qsize) (struct inode *);
/* WARNING: probably going away soon, do not use! */
} ____cacheline_aligned;
get_qsize() is used to allow inode to decide how much of the quota size in itself. If file system implements the own get_qsize(), ioctl of FIOQSIZe will call it to get quota size. If not implemented, get the quota size in a generic way. Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com> --- fs/ioctl.c | 31 ++++++++++++++++++++++++------- include/linux/fs.h | 1 + 2 files changed, 25 insertions(+), 7 deletions(-)