1/* 2 Unix SMB/CIFS implementation. 3 System QUOTA function wrappers for LINUX 4 Copyright (C) Stefan (metze) Metzmacher 2003 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18*/ 19 20 21#include "includes.h" 22 23#undef DBGC_CLASS 24#define DBGC_CLASS DBGC_QUOTA 25 26#ifndef HAVE_SYS_QUOTAS 27#ifdef HAVE_QUOTACTL_LINUX 28#undef HAVE_QUOTACTL_LINUX 29#endif 30#endif 31 32#ifdef HAVE_QUOTACTL_LINUX 33 34#include "samba_linux_quota.h" 35 36/**************************************************************************** 37 Abstract out the v1 Linux quota get calls. 38****************************************************************************/ 39static int sys_get_linux_v1_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) 40{ 41 int ret = -1; 42 uint32 qflags = 0; 43 struct v1_kern_dqblk D; 44 uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE; 45 46 ZERO_STRUCT(D); 47 48 switch (qtype) { 49 case SMB_USER_QUOTA_TYPE: 50 DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", 51 path, bdev, (unsigned)id.uid)); 52 53 if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) { 54 return ret; 55 } 56 57 break; 58 case SMB_GROUP_QUOTA_TYPE: 59 DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", 60 path, bdev, (unsigned)id.gid)); 61 62 if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) { 63 return ret; 64 } 65 66 break; 67 case SMB_USER_FS_QUOTA_TYPE: 68 DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", 69 path, bdev, (unsigned)id.uid)); 70 71 if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { 72 qflags |= QUOTAS_DENY_DISK; 73 } 74 75 break; 76 case SMB_GROUP_FS_QUOTA_TYPE: 77 DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", 78 path, bdev, (unsigned)id.gid)); 79 80 if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { 81 qflags |= QUOTAS_DENY_DISK; 82 } 83 84 break; 85 default: 86 errno = ENOSYS; 87 return -1; 88 } 89 90 dp->bsize = bsize; 91 dp->softlimit = (uint64_t)D.dqb_bsoftlimit; 92 dp->hardlimit = (uint64_t)D.dqb_bhardlimit; 93 dp->ihardlimit = (uint64_t)D.dqb_ihardlimit; 94 dp->isoftlimit = (uint64_t)D.dqb_isoftlimit; 95 dp->curinodes = (uint64_t)D.dqb_curinodes; 96 dp->curblocks = (uint64_t)D.dqb_curblocks; 97 98 99 dp->qflags = qflags; 100 101 return ret; 102} 103 104/**************************************************************************** 105 Abstract out the v1 Linux quota set calls. 106****************************************************************************/ 107static int sys_set_linux_v1_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) 108{ 109 int ret = -1; 110 uint32 qflags = 0; 111 uint32 oldqflags = 0; 112 struct v1_kern_dqblk D; 113 uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE; 114 115 ZERO_STRUCT(D); 116 117 if (bsize == dp->bsize) { 118 D.dqb_bsoftlimit = dp->softlimit; 119 D.dqb_bhardlimit = dp->hardlimit; 120 D.dqb_ihardlimit = dp->ihardlimit; 121 D.dqb_isoftlimit = dp->isoftlimit; 122 } else { 123 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize; 124 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize; 125 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize; 126 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize; 127 } 128 129 qflags = dp->qflags; 130 131 switch (qtype) { 132 case SMB_USER_QUOTA_TYPE: 133 DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", 134 path, bdev, (unsigned)id.uid)); 135 136 ret = quotactl(QCMD(Q_V1_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D); 137 break; 138 case SMB_GROUP_QUOTA_TYPE: 139 DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", 140 path, bdev, (unsigned)id.gid)); 141 142 ret = quotactl(QCMD(Q_V1_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D); 143 break; 144 case SMB_USER_FS_QUOTA_TYPE: 145 DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", 146 path, bdev, (unsigned)id.uid)); 147 148 if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { 149 oldqflags |= QUOTAS_DENY_DISK; 150 } 151 152 break; 153 case SMB_GROUP_FS_QUOTA_TYPE: 154 DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", 155 path, bdev, (unsigned)id.gid)); 156 157 if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { 158 oldqflags |= QUOTAS_DENY_DISK; 159 } 160 161 break; 162 default: 163 errno = ENOSYS; 164 return -1; 165 } 166 167 return ret; 168} 169 170/**************************************************************************** 171 Abstract out the v2 Linux quota get calls. 172****************************************************************************/ 173static int sys_get_linux_v2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) 174{ 175 int ret = -1; 176 uint32 qflags = 0; 177 struct v2_kern_dqblk D; 178 uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE; 179 180 ZERO_STRUCT(D); 181 182 switch (qtype) { 183 case SMB_USER_QUOTA_TYPE: 184 DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", 185 path, bdev, (unsigned)id.uid)); 186 187 if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) { 188 return ret; 189 } 190 191 break; 192 case SMB_GROUP_QUOTA_TYPE: 193 DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", 194 path, bdev, (unsigned)id.gid)); 195 196 if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) { 197 return ret; 198 } 199 200 break; 201 case SMB_USER_FS_QUOTA_TYPE: 202 DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", 203 path, bdev, (unsigned)id.uid)); 204 205 if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { 206 qflags |= QUOTAS_DENY_DISK; 207 } 208 209 break; 210 case SMB_GROUP_FS_QUOTA_TYPE: 211 DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", 212 path, bdev, (unsigned)id.gid)); 213 214 if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { 215 qflags |= QUOTAS_DENY_DISK; 216 } 217 218 break; 219 default: 220 errno = ENOSYS; 221 return -1; 222 } 223 224 dp->bsize = bsize; 225 dp->softlimit = (uint64_t)D.dqb_bsoftlimit; 226 dp->hardlimit = (uint64_t)D.dqb_bhardlimit; 227 dp->ihardlimit = (uint64_t)D.dqb_ihardlimit; 228 dp->isoftlimit = (uint64_t)D.dqb_isoftlimit; 229 dp->curinodes = (uint64_t)D.dqb_curinodes; 230 dp->curblocks = (uint64_t)D.dqb_curspace/bsize; 231 232 233 dp->qflags = qflags; 234 235 return ret; 236} 237 238/**************************************************************************** 239 Abstract out the v2 Linux quota set calls. 240****************************************************************************/ 241static int sys_set_linux_v2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) 242{ 243 int ret = -1; 244 uint32 qflags = 0; 245 uint32 oldqflags = 0; 246 struct v2_kern_dqblk D; 247 uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE; 248 249 ZERO_STRUCT(D); 250 251 if (bsize == dp->bsize) { 252 D.dqb_bsoftlimit = dp->softlimit; 253 D.dqb_bhardlimit = dp->hardlimit; 254 D.dqb_ihardlimit = dp->ihardlimit; 255 D.dqb_isoftlimit = dp->isoftlimit; 256 } else { 257 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize; 258 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize; 259 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize; 260 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize; 261 } 262 263 qflags = dp->qflags; 264 265 switch (qtype) { 266 case SMB_USER_QUOTA_TYPE: 267 DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", 268 path, bdev, (unsigned)id.uid)); 269 270 ret = quotactl(QCMD(Q_V2_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D); 271 break; 272 case SMB_GROUP_QUOTA_TYPE: 273 DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", 274 path, bdev, (unsigned)id.gid)); 275 276 ret = quotactl(QCMD(Q_V2_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D); 277 break; 278 case SMB_USER_FS_QUOTA_TYPE: 279 DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", 280 path, bdev, (unsigned)id.uid)); 281 282 if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { 283 oldqflags |= QUOTAS_DENY_DISK; 284 } 285 286 break; 287 case SMB_GROUP_FS_QUOTA_TYPE: 288 DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", 289 path, bdev, (unsigned)id.gid)); 290 291 if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { 292 oldqflags |= QUOTAS_DENY_DISK; 293 } 294 295 break; 296 default: 297 errno = ENOSYS; 298 return -1; 299 } 300 301 return ret; 302} 303 304/**************************************************************************** 305 Abstract out the generic Linux quota get calls. 306****************************************************************************/ 307static int sys_get_linux_gen_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) 308{ 309 int ret = -1; 310 uint32 qflags = 0; 311 struct if_dqblk D; 312 uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE; 313 314 ZERO_STRUCT(D); 315 316 switch (qtype) { 317 case SMB_USER_QUOTA_TYPE: 318 DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", 319 path, bdev, (unsigned)id.uid)); 320 321 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) { 322 return ret; 323 } 324 325 break; 326 case SMB_GROUP_QUOTA_TYPE: 327 DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", 328 path, bdev, (unsigned)id.gid)); 329 330 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) { 331 return ret; 332 } 333 334 break; 335 case SMB_USER_FS_QUOTA_TYPE: 336 DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", 337 path, bdev, (unsigned)id.uid)); 338 339 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { 340 qflags |= QUOTAS_DENY_DISK; 341 } 342 343 break; 344 case SMB_GROUP_FS_QUOTA_TYPE: 345 DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", 346 path, bdev, (unsigned)id.gid)); 347 348 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { 349 qflags |= QUOTAS_DENY_DISK; 350 } 351 352 break; 353 default: 354 errno = ENOSYS; 355 return -1; 356 } 357 358 dp->bsize = bsize; 359 dp->softlimit = (uint64_t)D.dqb_bsoftlimit; 360 dp->hardlimit = (uint64_t)D.dqb_bhardlimit; 361 dp->ihardlimit = (uint64_t)D.dqb_ihardlimit; 362 dp->isoftlimit = (uint64_t)D.dqb_isoftlimit; 363 dp->curinodes = (uint64_t)D.dqb_curinodes; 364 dp->curblocks = (uint64_t)D.dqb_curspace/bsize; 365 366 367 dp->qflags = qflags; 368 369 return ret; 370} 371 372/**************************************************************************** 373 Abstract out the gen Linux quota set calls. 374****************************************************************************/ 375static int sys_set_linux_gen_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) 376{ 377 int ret = -1; 378 uint32 qflags = 0; 379 uint32 oldqflags = 0; 380 struct if_dqblk D; 381 uint64_t bsize = (uint64_t)QUOTABLOCK_SIZE; 382 383 ZERO_STRUCT(D); 384 385 if (bsize == dp->bsize) { 386 D.dqb_bsoftlimit = dp->softlimit; 387 D.dqb_bhardlimit = dp->hardlimit; 388 D.dqb_ihardlimit = dp->ihardlimit; 389 D.dqb_isoftlimit = dp->isoftlimit; 390 } else { 391 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize; 392 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize; 393 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize; 394 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize; 395 } 396 D.dqb_valid = QIF_LIMITS; 397 398 qflags = dp->qflags; 399 400 switch (qtype) { 401 case SMB_USER_QUOTA_TYPE: 402 DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n", 403 path, bdev, (unsigned)id.uid)); 404 405 ret = quotactl(QCMD(Q_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D); 406 break; 407 case SMB_GROUP_QUOTA_TYPE: 408 DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n", 409 path, bdev, (unsigned)id.gid)); 410 411 ret = quotactl(QCMD(Q_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D); 412 break; 413 case SMB_USER_FS_QUOTA_TYPE: 414 DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n", 415 path, bdev, (unsigned)id.uid)); 416 417 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) { 418 oldqflags |= QUOTAS_DENY_DISK; 419 } 420 421 break; 422 case SMB_GROUP_FS_QUOTA_TYPE: 423 DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n", 424 path, bdev, (unsigned)id.gid)); 425 426 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) { 427 oldqflags |= QUOTAS_DENY_DISK; 428 } 429 430 break; 431 default: 432 errno = ENOSYS; 433 return -1; 434 } 435 436 return ret; 437} 438 439/**************************************************************************** 440 Abstract out the Linux quota get calls. 441****************************************************************************/ 442int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) 443{ 444 int ret = -1; 445 446 if (!path||!bdev||!dp) 447 smb_panic("sys_set_vfs_quota: called with NULL pointer"); 448 449 ZERO_STRUCT(*dp); 450 dp->qtype = qtype; 451 452 switch (qtype) { 453 case SMB_USER_QUOTA_TYPE: 454 case SMB_GROUP_QUOTA_TYPE: 455 if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { 456 if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { 457 if ((ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { 458 return ret; 459 } 460 } 461 } 462 463 if ((dp->curblocks==0)&& 464 (dp->softlimit==0)&& 465 (dp->hardlimit==0)) { 466 /* the upper layer functions don't want empty quota records...*/ 467 return -1; 468 } 469 470 break; 471 case SMB_USER_FS_QUOTA_TYPE: 472 id.uid = getuid(); 473 474 if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { 475 if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { 476 ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp); 477 } 478 } 479 480 ret = 0; 481 break; 482 case SMB_GROUP_FS_QUOTA_TYPE: 483 id.gid = getgid(); 484 485 if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { 486 if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) { 487 ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp); 488 } 489 } 490 491 ret = 0; 492 break; 493 default: 494 errno = ENOSYS; 495 return -1; 496 } 497 498 return ret; 499} 500 501/**************************************************************************** 502 Abstract out the Linux quota set calls. 503****************************************************************************/ 504int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp) 505{ 506 int ret = -1; 507 uint32 oldqflags = 0; 508 509 if (!path||!bdev||!dp) 510 smb_panic("sys_set_vfs_quota: called with NULL pointer"); 511 512 oldqflags = dp->qflags; 513 514 switch (qtype) { 515 case SMB_USER_QUOTA_TYPE: 516 case SMB_GROUP_QUOTA_TYPE: 517 if ((ret=sys_set_linux_gen_quota(path, bdev, qtype, id, dp))) { 518 if ((ret=sys_set_linux_v2_quota(path, bdev, qtype, id, dp))) { 519 if ((ret=sys_set_linux_v1_quota(path, bdev, qtype, id, dp))) { 520 return ret; 521 } 522 } 523 } 524 break; 525 case SMB_USER_FS_QUOTA_TYPE: 526 id.uid = getuid(); 527 528 if ((ret=sys_set_linux_gen_quota(path, bdev, qtype, id, dp))) { 529 if ((ret=sys_set_linux_v2_quota(path, bdev, qtype, id, dp))) { 530 ret=sys_set_linux_v1_quota(path, bdev, qtype, id, dp); 531 } 532 } 533 534 if (oldqflags == dp->qflags) { 535 ret = 0; 536 } else { 537 ret = -1; 538 } 539 break; 540 case SMB_GROUP_FS_QUOTA_TYPE: 541 id.gid = getgid(); 542 543 if ((ret=sys_set_linux_gen_quota(path, bdev, qtype, id, dp))) { 544 if ((ret=sys_set_linux_v2_quota(path, bdev, qtype, id, dp))) { 545 ret=sys_set_linux_v1_quota(path, bdev, qtype, id, dp); 546 } 547 } 548 549 if (oldqflags == dp->qflags) { 550 ret = 0; 551 } else { 552 ret = -1; 553 } 554 555 break; 556 default: 557 errno = ENOSYS; 558 return -1; 559 } 560 561 return ret; 562} 563 564#else /* HAVE_QUOTACTL_LINUX */ 565 void dummy_sysquotas_linux(void); 566 567 void dummy_sysquotas_linux(void){} 568#endif /* HAVE_QUOTACTL_LINUX */ 569