quota.c (0c49cd295d42d0032af11d55e2140dbec11dc8d0) | quota.c (14bf61ffe6ac54afcd1e888a4407fe16054483db) |
---|---|
1/* 2 * Quota code necessary even when VFS quota support is not compiled 3 * into the kernel. The interesting stuff is over in dquot.c, here 4 * we have symbols for initial quotactl(2) handling, the sysctl(2) 5 * variables, etc - things needed even when quota support disabled. 6 */ 7 8#include <linux/fs.h> --- 104 unchanged lines hidden (view full) --- 113 114 if (copy_from_user(&info, addr, sizeof(info))) 115 return -EFAULT; 116 if (!sb->s_qcop->set_info) 117 return -ENOSYS; 118 return sb->s_qcop->set_info(sb, type, &info); 119} 120 | 1/* 2 * Quota code necessary even when VFS quota support is not compiled 3 * into the kernel. The interesting stuff is over in dquot.c, here 4 * we have symbols for initial quotactl(2) handling, the sysctl(2) 5 * variables, etc - things needed even when quota support disabled. 6 */ 7 8#include <linux/fs.h> --- 104 unchanged lines hidden (view full) --- 113 114 if (copy_from_user(&info, addr, sizeof(info))) 115 return -EFAULT; 116 if (!sb->s_qcop->set_info) 117 return -ENOSYS; 118 return sb->s_qcop->set_info(sb, type, &info); 119} 120 |
121static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src) | 121static inline qsize_t qbtos(qsize_t blocks) |
122{ | 122{ |
123 return blocks << QIF_DQBLKSIZE_BITS; 124} 125 126static inline qsize_t stoqb(qsize_t space) 127{ 128 return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS; 129} 130 131static void copy_to_if_dqblk(struct if_dqblk *dst, struct qc_dqblk *src) 132{ |
|
123 memset(dst, 0, sizeof(*dst)); | 133 memset(dst, 0, sizeof(*dst)); |
124 dst->dqb_bhardlimit = src->d_blk_hardlimit; 125 dst->dqb_bsoftlimit = src->d_blk_softlimit; 126 dst->dqb_curspace = src->d_bcount; | 134 dst->dqb_bhardlimit = stoqb(src->d_spc_hardlimit); 135 dst->dqb_bsoftlimit = stoqb(src->d_spc_softlimit); 136 dst->dqb_curspace = src->d_space; |
127 dst->dqb_ihardlimit = src->d_ino_hardlimit; 128 dst->dqb_isoftlimit = src->d_ino_softlimit; | 137 dst->dqb_ihardlimit = src->d_ino_hardlimit; 138 dst->dqb_isoftlimit = src->d_ino_softlimit; |
129 dst->dqb_curinodes = src->d_icount; 130 dst->dqb_btime = src->d_btimer; 131 dst->dqb_itime = src->d_itimer; | 139 dst->dqb_curinodes = src->d_ino_count; 140 dst->dqb_btime = src->d_spc_timer; 141 dst->dqb_itime = src->d_ino_timer; |
132 dst->dqb_valid = QIF_ALL; 133} 134 135static int quota_getquota(struct super_block *sb, int type, qid_t id, 136 void __user *addr) 137{ 138 struct kqid qid; | 142 dst->dqb_valid = QIF_ALL; 143} 144 145static int quota_getquota(struct super_block *sb, int type, qid_t id, 146 void __user *addr) 147{ 148 struct kqid qid; |
139 struct fs_disk_quota fdq; | 149 struct qc_dqblk fdq; |
140 struct if_dqblk idq; 141 int ret; 142 143 if (!sb->s_qcop->get_dqblk) 144 return -ENOSYS; 145 qid = make_kqid(current_user_ns(), type, id); 146 if (!qid_valid(qid)) 147 return -EINVAL; 148 ret = sb->s_qcop->get_dqblk(sb, qid, &fdq); 149 if (ret) 150 return ret; 151 copy_to_if_dqblk(&idq, &fdq); 152 if (copy_to_user(addr, &idq, sizeof(idq))) 153 return -EFAULT; 154 return 0; 155} 156 | 150 struct if_dqblk idq; 151 int ret; 152 153 if (!sb->s_qcop->get_dqblk) 154 return -ENOSYS; 155 qid = make_kqid(current_user_ns(), type, id); 156 if (!qid_valid(qid)) 157 return -EINVAL; 158 ret = sb->s_qcop->get_dqblk(sb, qid, &fdq); 159 if (ret) 160 return ret; 161 copy_to_if_dqblk(&idq, &fdq); 162 if (copy_to_user(addr, &idq, sizeof(idq))) 163 return -EFAULT; 164 return 0; 165} 166 |
157static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src) | 167static void copy_from_if_dqblk(struct qc_dqblk *dst, struct if_dqblk *src) |
158{ | 168{ |
159 dst->d_blk_hardlimit = src->dqb_bhardlimit; 160 dst->d_blk_softlimit = src->dqb_bsoftlimit; 161 dst->d_bcount = src->dqb_curspace; | 169 dst->d_spc_hardlimit = qbtos(src->dqb_bhardlimit); 170 dst->d_spc_softlimit = qbtos(src->dqb_bsoftlimit); 171 dst->d_space = src->dqb_curspace; |
162 dst->d_ino_hardlimit = src->dqb_ihardlimit; 163 dst->d_ino_softlimit = src->dqb_isoftlimit; | 172 dst->d_ino_hardlimit = src->dqb_ihardlimit; 173 dst->d_ino_softlimit = src->dqb_isoftlimit; |
164 dst->d_icount = src->dqb_curinodes; 165 dst->d_btimer = src->dqb_btime; 166 dst->d_itimer = src->dqb_itime; | 174 dst->d_ino_count = src->dqb_curinodes; 175 dst->d_spc_timer = src->dqb_btime; 176 dst->d_ino_timer = src->dqb_itime; |
167 168 dst->d_fieldmask = 0; 169 if (src->dqb_valid & QIF_BLIMITS) | 177 178 dst->d_fieldmask = 0; 179 if (src->dqb_valid & QIF_BLIMITS) |
170 dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD; | 180 dst->d_fieldmask |= QC_SPC_SOFT | QC_SPC_HARD; |
171 if (src->dqb_valid & QIF_SPACE) | 181 if (src->dqb_valid & QIF_SPACE) |
172 dst->d_fieldmask |= FS_DQ_BCOUNT; | 182 dst->d_fieldmask |= QC_SPACE; |
173 if (src->dqb_valid & QIF_ILIMITS) | 183 if (src->dqb_valid & QIF_ILIMITS) |
174 dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD; | 184 dst->d_fieldmask |= QC_INO_SOFT | QC_INO_HARD; |
175 if (src->dqb_valid & QIF_INODES) | 185 if (src->dqb_valid & QIF_INODES) |
176 dst->d_fieldmask |= FS_DQ_ICOUNT; | 186 dst->d_fieldmask |= QC_INO_COUNT; |
177 if (src->dqb_valid & QIF_BTIME) | 187 if (src->dqb_valid & QIF_BTIME) |
178 dst->d_fieldmask |= FS_DQ_BTIMER; | 188 dst->d_fieldmask |= QC_SPC_TIMER; |
179 if (src->dqb_valid & QIF_ITIME) | 189 if (src->dqb_valid & QIF_ITIME) |
180 dst->d_fieldmask |= FS_DQ_ITIMER; | 190 dst->d_fieldmask |= QC_INO_TIMER; |
181} 182 183static int quota_setquota(struct super_block *sb, int type, qid_t id, 184 void __user *addr) 185{ | 191} 192 193static int quota_setquota(struct super_block *sb, int type, qid_t id, 194 void __user *addr) 195{ |
186 struct fs_disk_quota fdq; | 196 struct qc_dqblk fdq; |
187 struct if_dqblk idq; 188 struct kqid qid; 189 190 if (copy_from_user(&idq, addr, sizeof(idq))) 191 return -EFAULT; 192 if (!sb->s_qcop->set_dqblk) 193 return -ENOSYS; 194 qid = make_kqid(current_user_ns(), type, id); --- 47 unchanged lines hidden (view full) --- 242 return -EINVAL; 243 } 244 ret = sb->s_qcop->get_xstatev(sb, &fqs); 245 if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) 246 return -EFAULT; 247 return ret; 248} 249 | 197 struct if_dqblk idq; 198 struct kqid qid; 199 200 if (copy_from_user(&idq, addr, sizeof(idq))) 201 return -EFAULT; 202 if (!sb->s_qcop->set_dqblk) 203 return -ENOSYS; 204 qid = make_kqid(current_user_ns(), type, id); --- 47 unchanged lines hidden (view full) --- 252 return -EINVAL; 253 } 254 ret = sb->s_qcop->get_xstatev(sb, &fqs); 255 if (!ret && copy_to_user(addr, &fqs, sizeof(fqs))) 256 return -EFAULT; 257 return ret; 258} 259 |
260/* 261 * XFS defines BBTOB and BTOBB macros inside fs/xfs/ and we cannot move them 262 * out of there as xfsprogs rely on definitions being in that header file. So 263 * just define same functions here for quota purposes. 264 */ 265#define XFS_BB_SHIFT 9 266 267static inline u64 quota_bbtob(u64 blocks) 268{ 269 return blocks << XFS_BB_SHIFT; 270} 271 272static inline u64 quota_btobb(u64 bytes) 273{ 274 return (bytes + (1 << XFS_BB_SHIFT) - 1) >> XFS_BB_SHIFT; 275} 276 277static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src) 278{ 279 dst->d_spc_hardlimit = quota_bbtob(src->d_blk_hardlimit); 280 dst->d_spc_softlimit = quota_bbtob(src->d_blk_softlimit); 281 dst->d_ino_hardlimit = src->d_ino_hardlimit; 282 dst->d_ino_softlimit = src->d_ino_softlimit; 283 dst->d_space = quota_bbtob(src->d_bcount); 284 dst->d_ino_count = src->d_icount; 285 dst->d_ino_timer = src->d_itimer; 286 dst->d_spc_timer = src->d_btimer; 287 dst->d_ino_warns = src->d_iwarns; 288 dst->d_spc_warns = src->d_bwarns; 289 dst->d_rt_spc_hardlimit = quota_bbtob(src->d_rtb_hardlimit); 290 dst->d_rt_spc_softlimit = quota_bbtob(src->d_rtb_softlimit); 291 dst->d_rt_space = quota_bbtob(src->d_rtbcount); 292 dst->d_rt_spc_timer = src->d_rtbtimer; 293 dst->d_rt_spc_warns = src->d_rtbwarns; 294 dst->d_fieldmask = 0; 295 if (src->d_fieldmask & FS_DQ_ISOFT) 296 dst->d_fieldmask |= QC_INO_SOFT; 297 if (src->d_fieldmask & FS_DQ_IHARD) 298 dst->d_fieldmask |= QC_INO_HARD; 299 if (src->d_fieldmask & FS_DQ_BSOFT) 300 dst->d_fieldmask |= QC_SPC_SOFT; 301 if (src->d_fieldmask & FS_DQ_BHARD) 302 dst->d_fieldmask |= QC_SPC_HARD; 303 if (src->d_fieldmask & FS_DQ_RTBSOFT) 304 dst->d_fieldmask |= QC_RT_SPC_SOFT; 305 if (src->d_fieldmask & FS_DQ_RTBHARD) 306 dst->d_fieldmask |= QC_RT_SPC_HARD; 307 if (src->d_fieldmask & FS_DQ_BTIMER) 308 dst->d_fieldmask |= QC_SPC_TIMER; 309 if (src->d_fieldmask & FS_DQ_ITIMER) 310 dst->d_fieldmask |= QC_INO_TIMER; 311 if (src->d_fieldmask & FS_DQ_RTBTIMER) 312 dst->d_fieldmask |= QC_RT_SPC_TIMER; 313 if (src->d_fieldmask & FS_DQ_BWARNS) 314 dst->d_fieldmask |= QC_SPC_WARNS; 315 if (src->d_fieldmask & FS_DQ_IWARNS) 316 dst->d_fieldmask |= QC_INO_WARNS; 317 if (src->d_fieldmask & FS_DQ_RTBWARNS) 318 dst->d_fieldmask |= QC_RT_SPC_WARNS; 319 if (src->d_fieldmask & FS_DQ_BCOUNT) 320 dst->d_fieldmask |= QC_SPACE; 321 if (src->d_fieldmask & FS_DQ_ICOUNT) 322 dst->d_fieldmask |= QC_INO_COUNT; 323 if (src->d_fieldmask & FS_DQ_RTBCOUNT) 324 dst->d_fieldmask |= QC_RT_SPACE; 325} 326 |
|
250static int quota_setxquota(struct super_block *sb, int type, qid_t id, 251 void __user *addr) 252{ 253 struct fs_disk_quota fdq; | 327static int quota_setxquota(struct super_block *sb, int type, qid_t id, 328 void __user *addr) 329{ 330 struct fs_disk_quota fdq; |
331 struct qc_dqblk qdq; |
|
254 struct kqid qid; 255 256 if (copy_from_user(&fdq, addr, sizeof(fdq))) 257 return -EFAULT; 258 if (!sb->s_qcop->set_dqblk) 259 return -ENOSYS; 260 qid = make_kqid(current_user_ns(), type, id); 261 if (!qid_valid(qid)) 262 return -EINVAL; | 332 struct kqid qid; 333 334 if (copy_from_user(&fdq, addr, sizeof(fdq))) 335 return -EFAULT; 336 if (!sb->s_qcop->set_dqblk) 337 return -ENOSYS; 338 qid = make_kqid(current_user_ns(), type, id); 339 if (!qid_valid(qid)) 340 return -EINVAL; |
263 return sb->s_qcop->set_dqblk(sb, qid, &fdq); | 341 copy_from_xfs_dqblk(&qdq, &fdq); 342 return sb->s_qcop->set_dqblk(sb, qid, &qdq); |
264} 265 | 343} 344 |
345static void copy_to_xfs_dqblk(struct fs_disk_quota *dst, struct qc_dqblk *src, 346 int type, qid_t id) 347{ 348 memset(dst, 0, sizeof(*dst)); 349 dst->d_version = FS_DQUOT_VERSION; 350 dst->d_id = id; 351 if (type == USRQUOTA) 352 dst->d_flags = FS_USER_QUOTA; 353 else if (type == PRJQUOTA) 354 dst->d_flags = FS_PROJ_QUOTA; 355 else 356 dst->d_flags = FS_GROUP_QUOTA; 357 dst->d_blk_hardlimit = quota_btobb(src->d_spc_hardlimit); 358 dst->d_blk_softlimit = quota_btobb(src->d_spc_softlimit); 359 dst->d_ino_hardlimit = src->d_ino_hardlimit; 360 dst->d_ino_softlimit = src->d_ino_softlimit; 361 dst->d_bcount = quota_btobb(src->d_space); 362 dst->d_icount = src->d_ino_count; 363 dst->d_itimer = src->d_ino_timer; 364 dst->d_btimer = src->d_spc_timer; 365 dst->d_iwarns = src->d_ino_warns; 366 dst->d_bwarns = src->d_spc_warns; 367 dst->d_rtb_hardlimit = quota_btobb(src->d_rt_spc_hardlimit); 368 dst->d_rtb_softlimit = quota_btobb(src->d_rt_spc_softlimit); 369 dst->d_rtbcount = quota_btobb(src->d_rt_space); 370 dst->d_rtbtimer = src->d_rt_spc_timer; 371 dst->d_rtbwarns = src->d_rt_spc_warns; 372} 373 |
|
266static int quota_getxquota(struct super_block *sb, int type, qid_t id, 267 void __user *addr) 268{ 269 struct fs_disk_quota fdq; | 374static int quota_getxquota(struct super_block *sb, int type, qid_t id, 375 void __user *addr) 376{ 377 struct fs_disk_quota fdq; |
378 struct qc_dqblk qdq; |
|
270 struct kqid qid; 271 int ret; 272 273 if (!sb->s_qcop->get_dqblk) 274 return -ENOSYS; 275 qid = make_kqid(current_user_ns(), type, id); 276 if (!qid_valid(qid)) 277 return -EINVAL; | 379 struct kqid qid; 380 int ret; 381 382 if (!sb->s_qcop->get_dqblk) 383 return -ENOSYS; 384 qid = make_kqid(current_user_ns(), type, id); 385 if (!qid_valid(qid)) 386 return -EINVAL; |
278 ret = sb->s_qcop->get_dqblk(sb, qid, &fdq); 279 if (!ret && copy_to_user(addr, &fdq, sizeof(fdq))) | 387 ret = sb->s_qcop->get_dqblk(sb, qid, &qdq); 388 if (ret) 389 return ret; 390 copy_to_xfs_dqblk(&fdq, &qdq, type, id); 391 if (copy_to_user(addr, &fdq, sizeof(fdq))) |
280 return -EFAULT; 281 return ret; 282} 283 284static int quota_rmxquota(struct super_block *sb, void __user *addr) 285{ 286 __u32 flags; 287 --- 178 unchanged lines hidden --- | 392 return -EFAULT; 393 return ret; 394} 395 396static int quota_rmxquota(struct super_block *sb, void __user *addr) 397{ 398 __u32 flags; 399 --- 178 unchanged lines hidden --- |