Advertisement
stnmrshx

Patch Amiga AFFS Partition Race Condition

May 14th, 2012
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 2.98 KB | None | 0 0
  1. diff --git a/fs/affs/affs.h b/fs/affs/affs.h
  2. index 45a0ce4..fc1d4ca 100644
  3. --- a/fs/affs/affs.h
  4. +++ b/fs/affs/affs.h
  5. @@ -66,6 +66,8 @@ struct affs_inode_info {
  6.     u32  i_protect;         /* unused attribute bits */
  7.     u32  i_lastalloc;           /* last allocated block */
  8.     int  i_pa_cnt;          /* number of preallocated blocks */
  9. +   spinlock_t i_alloc;             /* Protects last 2 fields. */
  10. +
  11.     struct inode vfs_inode;
  12. };
  13.  
  14. diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c
  15. index 3e26271..3341bde 100644
  16. --- a/fs/affs/bitmap.c
  17. +++ b/fs/affs/bitmap.c
  18. @@ -151,12 +151,18 @@ affs_alloc_block(struct inode *inode, u32 goal)
  19.  
  20.     pr_debug("AFFS: balloc(inode=%lu,goal=%u): ", inode->i_ino, goal);
  21.  
  22. +   spin_lock(&AFFS_I(inode)->i_alloc);
  23. +
  24.     if (AFFS_I(inode)->i_pa_cnt) {
  25. -       pr_debug("%d\n", AFFS_I(inode)->i_lastalloc+1);
  26. +       u32 ret;
  27.         AFFS_I(inode)->i_pa_cnt--;
  28. -       return ++AFFS_I(inode)->i_lastalloc;
  29. +       ret = ++AFFS_I(inode)->i_lastalloc;
  30. +       spin_unlock(&AFFS_I(inode)->i_alloc);
  31. +       return ret;
  32.     }
  33.  
  34. +   spin_unlock(&AFFS_I(inode)->i_alloc);
  35. +
  36.     if (!goal || goal > sbi->s_partition_size) {
  37.         if (goal)
  38.             affs_warning(sb, "affs_balloc", "invalid goal %d", goal);
  39. @@ -230,16 +236,22 @@ find_bit:
  40.     bit = ffs(tmp & mask) - 1;
  41.     blk += bit + sbi->s_reserved;
  42.     mask2 = mask = 1 << (bit & 31);
  43. -   AFFS_I(inode)->i_lastalloc = blk;
  44. -
  45. -   /* prealloc as much as possible within this word */
  46. -   while ((mask2 <<= 1)) {
  47. -       if (!(tmp & mask2))
  48. -           break;
  49. -       AFFS_I(inode)->i_pa_cnt++;
  50. -       mask |= mask2;
  51. +
  52. +   spin_lock(&AFFS_I(inode)->i_alloc);
  53. +   if (!AFFS_I(inode)->i_pa_cnt) {
  54. +       AFFS_I(inode)->i_lastalloc = blk;
  55. +
  56. +       /* prealloc as much as possible within this word */
  57. +       while ((mask2 <<= 1)) {
  58. +           if (!(tmp & mask2))
  59. +               break;
  60. +           AFFS_I(inode)->i_pa_cnt++;
  61. +           mask |= mask2;
  62. +       }
  63. +       bm->bm_free -= AFFS_I(inode)->i_pa_cnt + 1;
  64.     }
  65. -   bm->bm_free -= AFFS_I(inode)->i_pa_cnt + 1;
  66. +
  67. +   spin_unlock(&AFFS_I(inode)->i_alloc);
  68.  
  69.     *data = cpu_to_be32(tmp & ~mask);
  70.  
  71. diff --git a/fs/affs/file.c b/fs/affs/file.c
  72. index 2f4c935..829e976 100644
  73. --- a/fs/affs/file.c
  74. +++ b/fs/affs/file.c
  75. @@ -795,12 +795,21 @@ void
  76. affs_free_prealloc(struct inode *inode)
  77. {
  78.     struct super_block *sb = inode->i_sb;
  79. +   u32 first, cnt;
  80.  
  81.     pr_debug("AFFS: free_prealloc(ino=%lu)\n", inode->i_ino);
  82.  
  83. -   while (AFFS_I(inode)->i_pa_cnt) {
  84. -       AFFS_I(inode)->i_pa_cnt--;
  85. -       affs_free_block(sb, ++AFFS_I(inode)->i_lastalloc);
  86. +   spin_lock(&AFFS_I(inode)->i_alloc);
  87. +   first = AFFS_I(inode)->i_lastalloc;
  88. +   cnt = AFFS_I(inode)->i_pa_cnt;
  89. +   AFFS_I(inode)->i_lastalloc += cnt;
  90. +   AFFS_I(inode)->i_pa_cnt = 0;
  91. +
  92. +   spin_unlock(&AFFS_I(inode)->i_alloc);
  93. +
  94. +   while (cnt) {
  95. +       cnt--;
  96. +       affs_free_block(sb, ++first);
  97.     }
  98. }
  99.  
  100. diff --git a/fs/affs/super.c b/fs/affs/super.c
  101. index 0782653..1df3c95 100644
  102. --- a/fs/affs/super.c
  103. +++ b/fs/affs/super.c
  104. @@ -91,6 +91,7 @@ static struct inode *affs_alloc_inode(struct super_block *sb)
  105.     i->i_lc = NULL;
  106.     i->i_ext_bh = NULL;
  107.     i->i_pa_cnt = 0;
  108. +   spin_lock_init(&i->i_alloc);
  109.  
  110.     return &i->vfs_inode;
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement