#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/buffer_head.h>
+#include <linux/capability.h>
+#include <linux/quotaops.h>
/* Check validity of generic quotactl commands */
static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
if (!sb->s_qcop->get_xquota)
return -ENOSYS;
break;
+ case Q_XQUOTASYNC:
+ if (!sb->s_qcop->quota_sync)
+ return -ENOSYS;
+ break;
default:
return -EINVAL;
}
(type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
!capable(CAP_SYS_ADMIN))
return -EPERM;
- } else if (cmd != Q_XGETQSTAT) {
+ } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
}
sync_blockdev(sb->s_bdev);
/* Now when everything is written we can discard the pagecache so
- * that userspace sees the changes. We need i_sem and so we could
+ * that userspace sees the changes. We need i_mutex and so we could
* not do it inside dqonoff_sem. Moreover we need to be carefull
* about races with quotaoff() (that is the reason why we have own
* reference to inode). */
up(&sb_dqopt(sb)->dqonoff_sem);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (discard[cnt]) {
- down(&discard[cnt]->i_sem);
+ mutex_lock(&discard[cnt]->i_mutex);
truncate_inode_pages(&discard[cnt]->i_data, 0);
- up(&discard[cnt]->i_sem);
+ mutex_unlock(&discard[cnt]->i_mutex);
iput(discard[cnt]);
}
}
return -EFAULT;
return 0;
}
+ case Q_XQUOTASYNC:
+ return sb->s_qcop->quota_sync(sb, type);
/* We never reach here unless validity check is broken */
default:
BUG();