1 /* 2 * vfsv0 quota IO operations on file 3 */ 4 5 #include <linux/errno.h> 6 #include <linux/fs.h> 7 #include <linux/mount.h> 8 #include <linux/dqblk_v2.h> 9 #include <linux/kernel.h> 10 #include <linux/init.h> 11 #include <linux/module.h> 12 #include <linux/slab.h> 13 #include <linux/quotaops.h> 14 15 #include <asm/byteorder.h> 16 17 #include "quota_tree.h" 18 19 MODULE_AUTHOR("Jan Kara"); 20 MODULE_DESCRIPTION("Quota trie support"); 21 MODULE_LICENSE("GPL"); 22 23 #define __QUOTA_QT_PARANOIA 24 25 static int get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth) 26 { 27 unsigned int epb = info->dqi_usable_bs >> 2; 28 29 depth = info->dqi_qtree_depth - depth - 1; 30 while (depth--) 31 id /= epb; 32 return id % epb; 33 } 34 35 /* Number of entries in one blocks */ 36 static int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info) 37 { 38 return (info->dqi_usable_bs - sizeof(struct qt_disk_dqdbheader)) 39 / info->dqi_entry_size; 40 } 41 42 static char *getdqbuf(size_t size) 43 { 44 char *buf = kmalloc(size, GFP_NOFS); 45 if (!buf) 46 printk(KERN_WARNING 47 "VFS: Not enough memory for quota buffers.\n"); 48 return buf; 49 } 50 51 static ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) 52 { 53 struct super_block *sb = info->dqi_sb; 54 55 memset(buf, 0, info->dqi_usable_bs); 56 return sb->s_op->quota_read(sb, info->dqi_type, buf, 57 info->dqi_usable_bs, blk << info->dqi_blocksize_bits); 58 } 59 60 static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) 61 { 62 struct super_block *sb = info->dqi_sb; 63 64 return sb->s_op->quota_write(sb, info->dqi_type, buf, 65 info->dqi_usable_bs, blk << info->dqi_blocksize_bits); 66 } 67 68 /* Remove empty block from list and return it */ 69 static int get_free_dqblk(struct qtree_mem_dqinfo *info) 70 { 71 char *buf = getdqbuf(info->dqi_usable_bs); 72 struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; 73 int ret, blk; 74 75 if (!buf) 76 return -ENOMEM; 77 if (info->dqi_free_blk) { 78 blk = info->dqi_free_blk; 79 ret = read_blk(info, blk, buf); 80 if (ret < 0) 81 goto out_buf; 82 info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free); 83 } 84 else { 85 memset(buf, 0, info->dqi_usable_bs); 86 /* Assure block allocation... */ 87 ret = write_blk(info, info->dqi_blocks, buf); 88 if (ret < 0) 89 goto out_buf; 90 blk = info->dqi_blocks++; 91 } 92 mark_info_dirty(info->dqi_sb, info->dqi_type); 93 ret = blk; 94 out_buf: 95 kfree(buf); 96 return ret; 97 } 98 99 /* Insert empty block to the list */ 100 static int put_free_dqblk(struct qtree_mem_dqinfo *info, char *buf, uint blk) 101 { 102 struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; 103 int err; 104 105 dh->dqdh_next_free = cpu_to_le32(info->dqi_free_blk); 106 dh->dqdh_prev_free = cpu_to_le32(0); 107 dh->dqdh_entries = cpu_to_le16(0); 108 err = write_blk(info, blk, buf); 109 if (err < 0) 110 return err; 111 info->dqi_free_blk = blk; 112 mark_info_dirty(info->dqi_sb, info->dqi_type); 113 return 0; 114 } 115 116 /* Remove given block from the list of blocks with free entries */ 117 static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, 118 uint blk) 119 { 120 char *tmpbuf = getdqbuf(info->dqi_usable_bs); 121 struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; 122 uint nextblk = le32_to_cpu(dh->dqdh_next_free); 123 uint prevblk = le32_to_cpu(dh->dqdh_prev_free); 124 int err; 125 126 if (!tmpbuf) 127 return -ENOMEM; 128 if (nextblk) { 129 err = read_blk(info, nextblk, tmpbuf); 130 if (err < 0) 131 goto out_buf; 132 ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = 133 dh->dqdh_prev_free; 134 err = write_blk(info, nextblk, tmpbuf); 135 if (err < 0) 136 goto out_buf; 137 } 138 if (prevblk) { 139 err = read_blk(info, prevblk, tmpbuf); 140 if (err < 0) 141 goto out_buf; 142 ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_next_free = 143 dh->dqdh_next_free; 144 err = write_blk(info, prevblk, tmpbuf); 145 if (err < 0) 146 goto out_buf; 147 } else { 148 info->dqi_free_entry = nextblk; 149 mark_info_dirty(info->dqi_sb, info->dqi_type); 150 } 151 kfree(tmpbuf); 152 dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); 153 /* No matter whether write succeeds block is out of list */ 154 if (write_blk(info, blk, buf) < 0) 155 printk(KERN_ERR 156 "VFS: Can't write block (%u) with free entries.\n", 157 blk); 158 return 0; 159 out_buf: 160 kfree(tmpbuf); 161 return err; 162 } 163 164 /* Insert given block to the beginning of list with free entries */ 165 static int insert_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, 166 uint blk) 167 { 168 char *tmpbuf = getdqbuf(info->dqi_usable_bs); 169 struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; 170 int err; 171 172 if (!tmpbuf) 173 return -ENOMEM; 174 dh->dqdh_next_free = cpu_to_le32(info->dqi_free_entry); 175 dh->dqdh_prev_free = cpu_to_le32(0); 176 err = write_blk(info, blk, buf); 177 if (err < 0) 178 goto out_buf; 179 if (info->dqi_free_entry) { 180 err = read_blk(info, info->dqi_free_entry, tmpbuf); 181 if (err < 0) 182 goto out_buf; 183 ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = 184 cpu_to_le32(blk); 185 err = write_blk(info, info->dqi_free_entry, tmpbuf); 186 if (err < 0) 187 goto out_buf; 188 } 189 kfree(tmpbuf); 190 info->dqi_free_entry = blk; 191 mark_info_dirty(info->dqi_sb, info->dqi_type); 192 return 0; 193 out_buf: 194 kfree(tmpbuf); 195 return err; 196 } 197 198 /* Is the entry in the block free? */ 199 int qtree_entry_unused(struct qtree_mem_dqinfo *info, char *disk) 200 { 201 int i; 202 203 for (i = 0; i < info->dqi_entry_size; i++) 204 if (disk[i]) 205 return 0; 206 return 1; 207 } 208 EXPORT_SYMBOL(qtree_entry_unused); 209 210 /* Find space for dquot */ 211 static uint find_free_dqentry(struct qtree_mem_dqinfo *info, 212 struct dquot *dquot, int *err) 213 { 214 uint blk, i; 215 struct qt_disk_dqdbheader *dh; 216 char *buf = getdqbuf(info->dqi_usable_bs); 217 char *ddquot; 218 219 *err = 0; 220 if (!buf) { 221 *err = -ENOMEM; 222 return 0; 223 } 224 dh = (struct qt_disk_dqdbheader *)buf; 225 if (info->dqi_free_entry) { 226 blk = info->dqi_free_entry; 227 *err = read_blk(info, blk, buf); 228 if (*err < 0) 229 goto out_buf; 230 } else { 231 blk = get_free_dqblk(info); 232 if ((int)blk < 0) { 233 *err = blk; 234 kfree(buf); 235 return 0; 236 } 237 memset(buf, 0, info->dqi_usable_bs); 238 /* This is enough as the block is already zeroed and the entry 239 * list is empty... */ 240 info->dqi_free_entry = blk; 241 mark_info_dirty(dquot->dq_sb, dquot->dq_type); 242 } 243 /* Block will be full? */ 244 if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) { 245 *err = remove_free_dqentry(info, buf, blk); 246 if (*err < 0) { 247 printk(KERN_ERR "VFS: find_free_dqentry(): Can't " 248 "remove block (%u) from entry free list.\n", 249 blk); 250 goto out_buf; 251 } 252 } 253 le16_add_cpu(&dh->dqdh_entries, 1); 254 /* Find free structure in block */ 255 ddquot = buf + sizeof(struct qt_disk_dqdbheader); 256 for (i = 0; i < qtree_dqstr_in_blk(info); i++) { 257 if (qtree_entry_unused(info, ddquot)) 258 break; 259 ddquot += info->dqi_entry_size; 260 } 261 #ifdef __QUOTA_QT_PARANOIA 262 if (i == qtree_dqstr_in_blk(info)) { 263 printk(KERN_ERR "VFS: find_free_dqentry(): Data block full " 264 "but it shouldn't.\n"); 265 *err = -EIO; 266 goto out_buf; 267 } 268 #endif 269 *err = write_blk(info, blk, buf); 270 if (*err < 0) { 271 printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota " 272 "data block %u.\n", blk); 273 goto out_buf; 274 } 275 dquot->dq_off = (blk << info->dqi_blocksize_bits) + 276 sizeof(struct qt_disk_dqdbheader) + 277 i * info->dqi_entry_size; 278 kfree(buf); 279 return blk; 280 out_buf: 281 kfree(buf); 282 return 0; 283 } 284 285 /* Insert reference to structure into the trie */ 286 static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, 287 uint *treeblk, int depth) 288 { 289 char *buf = getdqbuf(info->dqi_usable_bs); 290 int ret = 0, newson = 0, newact = 0; 291 __le32 *ref; 292 uint newblk; 293 294 if (!buf) 295 return -ENOMEM; 296 if (!*treeblk) { 297 ret = get_free_dqblk(info); 298 if (ret < 0) 299 goto out_buf; 300 *treeblk = ret; 301 memset(buf, 0, info->dqi_usable_bs); 302 newact = 1; 303 } else { 304 ret = read_blk(info, *treeblk, buf); 305 if (ret < 0) { 306 printk(KERN_ERR "VFS: Can't read tree quota block " 307 "%u.\n", *treeblk); 308 goto out_buf; 309 } 310 } 311 ref = (__le32 *)buf; 312 newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); 313 if (!newblk) 314 newson = 1; 315 if (depth == info->dqi_qtree_depth - 1) { 316 #ifdef __QUOTA_QT_PARANOIA 317 if (newblk) { 318 printk(KERN_ERR "VFS: Inserting already present quota " 319 "entry (block %u).\n", 320 le32_to_cpu(ref[get_index(info, 321 dquot->dq_id, depth)])); 322 ret = -EIO; 323 goto out_buf; 324 } 325 #endif 326 newblk = find_free_dqentry(info, dquot, &ret); 327 } else { 328 ret = do_insert_tree(info, dquot, &newblk, depth+1); 329 } 330 if (newson && ret >= 0) { 331 ref[get_index(info, dquot->dq_id, depth)] = 332 cpu_to_le32(newblk); 333 ret = write_blk(info, *treeblk, buf); 334 } else if (newact && ret < 0) { 335 put_free_dqblk(info, buf, *treeblk); 336 } 337 out_buf: 338 kfree(buf); 339 return ret; 340 } 341 342 /* Wrapper for inserting quota structure into tree */ 343 static inline int dq_insert_tree(struct qtree_mem_dqinfo *info, 344 struct dquot *dquot) 345 { 346 int tmp = QT_TREEOFF; 347 return do_insert_tree(info, dquot, &tmp, 0); 348 } 349 350 /* 351 * We don't have to be afraid of deadlocks as we never have quotas on quota 352 * files... 353 */ 354 int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) 355 { 356 int type = dquot->dq_type; 357 struct super_block *sb = dquot->dq_sb; 358 ssize_t ret; 359 char *ddquot = getdqbuf(info->dqi_entry_size); 360 361 if (!ddquot) 362 return -ENOMEM; 363 364 /* dq_off is guarded by dqio_mutex */ 365 if (!dquot->dq_off) { 366 ret = dq_insert_tree(info, dquot); 367 if (ret < 0) { 368 printk(KERN_ERR "VFS: Error %zd occurred while " 369 "creating quota.\n", ret); 370 kfree(ddquot); 371 return ret; 372 } 373 } 374 spin_lock(&dq_data_lock); 375 info->dqi_ops->mem2disk_dqblk(ddquot, dquot); 376 spin_unlock(&dq_data_lock); 377 ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, 378 dquot->dq_off); 379 if (ret != info->dqi_entry_size) { 380 printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", 381 sb->s_id); 382 if (ret >= 0) 383 ret = -ENOSPC; 384 } else { 385 ret = 0; 386 } 387 dqstats.writes++; 388 kfree(ddquot); 389 390 return ret; 391 } 392 EXPORT_SYMBOL(qtree_write_dquot); 393 394 /* Free dquot entry in data block */ 395 static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, 396 uint blk) 397 { 398 struct qt_disk_dqdbheader *dh; 399 char *buf = getdqbuf(info->dqi_usable_bs); 400 int ret = 0; 401 402 if (!buf) 403 return -ENOMEM; 404 if (dquot->dq_off >> info->dqi_blocksize_bits != blk) { 405 printk(KERN_ERR "VFS: Quota structure has offset to other " 406 "block (%u) than it should (%u).\n", blk, 407 (uint)(dquot->dq_off >> info->dqi_blocksize_bits)); 408 goto out_buf; 409 } 410 ret = read_blk(info, blk, buf); 411 if (ret < 0) { 412 printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk); 413 goto out_buf; 414 } 415 dh = (struct qt_disk_dqdbheader *)buf; 416 le16_add_cpu(&dh->dqdh_entries, -1); 417 if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */ 418 ret = remove_free_dqentry(info, buf, blk); 419 if (ret >= 0) 420 ret = put_free_dqblk(info, buf, blk); 421 if (ret < 0) { 422 printk(KERN_ERR "VFS: Can't move quota data block (%u) " 423 "to free list.\n", blk); 424 goto out_buf; 425 } 426 } else { 427 memset(buf + 428 (dquot->dq_off & ((1 << info->dqi_blocksize_bits) - 1)), 429 0, info->dqi_entry_size); 430 if (le16_to_cpu(dh->dqdh_entries) == 431 qtree_dqstr_in_blk(info) - 1) { 432 /* Insert will write block itself */ 433 ret = insert_free_dqentry(info, buf, blk); 434 if (ret < 0) { 435 printk(KERN_ERR "VFS: Can't insert quota data " 436 "block (%u) to free entry list.\n", blk); 437 goto out_buf; 438 } 439 } else { 440 ret = write_blk(info, blk, buf); 441 if (ret < 0) { 442 printk(KERN_ERR "VFS: Can't write quota data " 443 "block %u\n", blk); 444 goto out_buf; 445 } 446 } 447 } 448 dquot->dq_off = 0; /* Quota is now unattached */ 449 out_buf: 450 kfree(buf); 451 return ret; 452 } 453 454 /* Remove reference to dquot from tree */ 455 static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, 456 uint *blk, int depth) 457 { 458 char *buf = getdqbuf(info->dqi_usable_bs); 459 int ret = 0; 460 uint newblk; 461 __le32 *ref = (__le32 *)buf; 462 463 if (!buf) 464 return -ENOMEM; 465 ret = read_blk(info, *blk, buf); 466 if (ret < 0) { 467 printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk); 468 goto out_buf; 469 } 470 newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); 471 if (depth == info->dqi_qtree_depth - 1) { 472 ret = free_dqentry(info, dquot, newblk); 473 newblk = 0; 474 } else { 475 ret = remove_tree(info, dquot, &newblk, depth+1); 476 } 477 if (ret >= 0 && !newblk) { 478 int i; 479 ref[get_index(info, dquot->dq_id, depth)] = cpu_to_le32(0); 480 /* Block got empty? */ 481 for (i = 0; i < (info->dqi_usable_bs >> 2) && !ref[i]; i++) 482 ; 483 /* Don't put the root block into the free block list */ 484 if (i == (info->dqi_usable_bs >> 2) 485 && *blk != QT_TREEOFF) { 486 put_free_dqblk(info, buf, *blk); 487 *blk = 0; 488 } else { 489 ret = write_blk(info, *blk, buf); 490 if (ret < 0) 491 printk(KERN_ERR "VFS: Can't write quota tree " 492 "block %u.\n", *blk); 493 } 494 } 495 out_buf: 496 kfree(buf); 497 return ret; 498 } 499 500 /* Delete dquot from tree */ 501 int qtree_delete_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) 502 { 503 uint tmp = QT_TREEOFF; 504 505 if (!dquot->dq_off) /* Even not allocated? */ 506 return 0; 507 return remove_tree(info, dquot, &tmp, 0); 508 } 509 EXPORT_SYMBOL(qtree_delete_dquot); 510 511 /* Find entry in block */ 512 static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, 513 struct dquot *dquot, uint blk) 514 { 515 char *buf = getdqbuf(info->dqi_usable_bs); 516 loff_t ret = 0; 517 int i; 518 char *ddquot; 519 520 if (!buf) 521 return -ENOMEM; 522 ret = read_blk(info, blk, buf); 523 if (ret < 0) { 524 printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); 525 goto out_buf; 526 } 527 ddquot = buf + sizeof(struct qt_disk_dqdbheader); 528 for (i = 0; i < qtree_dqstr_in_blk(info); i++) { 529 if (info->dqi_ops->is_id(ddquot, dquot)) 530 break; 531 ddquot += info->dqi_entry_size; 532 } 533 if (i == qtree_dqstr_in_blk(info)) { 534 printk(KERN_ERR "VFS: Quota for id %u referenced " 535 "but not present.\n", dquot->dq_id); 536 ret = -EIO; 537 goto out_buf; 538 } else { 539 ret = (blk << info->dqi_blocksize_bits) + sizeof(struct 540 qt_disk_dqdbheader) + i * info->dqi_entry_size; 541 } 542 out_buf: 543 kfree(buf); 544 return ret; 545 } 546 547 /* Find entry for given id in the tree */ 548 static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info, 549 struct dquot *dquot, uint blk, int depth) 550 { 551 char *buf = getdqbuf(info->dqi_usable_bs); 552 loff_t ret = 0; 553 __le32 *ref = (__le32 *)buf; 554 555 if (!buf) 556 return -ENOMEM; 557 ret = read_blk(info, blk, buf); 558 if (ret < 0) { 559 printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); 560 goto out_buf; 561 } 562 ret = 0; 563 blk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); 564 if (!blk) /* No reference? */ 565 goto out_buf; 566 if (depth < info->dqi_qtree_depth - 1) 567 ret = find_tree_dqentry(info, dquot, blk, depth+1); 568 else 569 ret = find_block_dqentry(info, dquot, blk); 570 out_buf: 571 kfree(buf); 572 return ret; 573 } 574 575 /* Find entry for given id in the tree - wrapper function */ 576 static inline loff_t find_dqentry(struct qtree_mem_dqinfo *info, 577 struct dquot *dquot) 578 { 579 return find_tree_dqentry(info, dquot, QT_TREEOFF, 0); 580 } 581 582 int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) 583 { 584 int type = dquot->dq_type; 585 struct super_block *sb = dquot->dq_sb; 586 loff_t offset; 587 char *ddquot; 588 int ret = 0; 589 590 #ifdef __QUOTA_QT_PARANOIA 591 /* Invalidated quota? */ 592 if (!sb_dqopt(dquot->dq_sb)->files[type]) { 593 printk(KERN_ERR "VFS: Quota invalidated while reading!\n"); 594 return -EIO; 595 } 596 #endif 597 /* Do we know offset of the dquot entry in the quota file? */ 598 if (!dquot->dq_off) { 599 offset = find_dqentry(info, dquot); 600 if (offset <= 0) { /* Entry not present? */ 601 if (offset < 0) 602 printk(KERN_ERR "VFS: Can't read quota " 603 "structure for id %u.\n", dquot->dq_id); 604 dquot->dq_off = 0; 605 set_bit(DQ_FAKE_B, &dquot->dq_flags); 606 memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); 607 ret = offset; 608 goto out; 609 } 610 dquot->dq_off = offset; 611 } 612 ddquot = getdqbuf(info->dqi_entry_size); 613 if (!ddquot) 614 return -ENOMEM; 615 ret = sb->s_op->quota_read(sb, type, ddquot, info->dqi_entry_size, 616 dquot->dq_off); 617 if (ret != info->dqi_entry_size) { 618 if (ret >= 0) 619 ret = -EIO; 620 printk(KERN_ERR "VFS: Error while reading quota " 621 "structure for id %u.\n", dquot->dq_id); 622 set_bit(DQ_FAKE_B, &dquot->dq_flags); 623 memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); 624 kfree(ddquot); 625 goto out; 626 } 627 spin_lock(&dq_data_lock); 628 info->dqi_ops->disk2mem_dqblk(dquot, ddquot); 629 if (!dquot->dq_dqb.dqb_bhardlimit && 630 !dquot->dq_dqb.dqb_bsoftlimit && 631 !dquot->dq_dqb.dqb_ihardlimit && 632 !dquot->dq_dqb.dqb_isoftlimit) 633 set_bit(DQ_FAKE_B, &dquot->dq_flags); 634 spin_unlock(&dq_data_lock); 635 kfree(ddquot); 636 out: 637 dqstats.reads++; 638 return ret; 639 } 640 EXPORT_SYMBOL(qtree_read_dquot); 641 642 /* Check whether dquot should not be deleted. We know we are 643 * the only one operating on dquot (thanks to dq_lock) */ 644 int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) 645 { 646 if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && 647 !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) 648 return qtree_delete_dquot(info, dquot); 649 return 0; 650 } 651 EXPORT_SYMBOL(qtree_release_dquot); 652