diff options
| -rw-r--r-- | fs/quota/quota.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 7898cd688a00..fc2c4388d126 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
| @@ -292,11 +292,26 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, | |||
| 292 | } | 292 | } |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | /* Return 1 if 'cmd' will block on frozen filesystem */ | ||
| 296 | static int quotactl_cmd_write(int cmd) | ||
| 297 | { | ||
| 298 | switch (cmd) { | ||
| 299 | case Q_GETFMT: | ||
| 300 | case Q_GETINFO: | ||
| 301 | case Q_SYNC: | ||
| 302 | case Q_XGETQSTAT: | ||
| 303 | case Q_XGETQUOTA: | ||
| 304 | case Q_XQUOTASYNC: | ||
| 305 | return 0; | ||
| 306 | } | ||
| 307 | return 1; | ||
| 308 | } | ||
| 309 | |||
| 295 | /* | 310 | /* |
| 296 | * look up a superblock on which quota ops will be performed | 311 | * look up a superblock on which quota ops will be performed |
| 297 | * - use the name of a block device to find the superblock thereon | 312 | * - use the name of a block device to find the superblock thereon |
| 298 | */ | 313 | */ |
| 299 | static struct super_block *quotactl_block(const char __user *special) | 314 | static struct super_block *quotactl_block(const char __user *special, int cmd) |
| 300 | { | 315 | { |
| 301 | #ifdef CONFIG_BLOCK | 316 | #ifdef CONFIG_BLOCK |
| 302 | struct block_device *bdev; | 317 | struct block_device *bdev; |
| @@ -309,7 +324,10 @@ static struct super_block *quotactl_block(const char __user *special) | |||
| 309 | putname(tmp); | 324 | putname(tmp); |
| 310 | if (IS_ERR(bdev)) | 325 | if (IS_ERR(bdev)) |
| 311 | return ERR_CAST(bdev); | 326 | return ERR_CAST(bdev); |
| 312 | sb = get_super(bdev); | 327 | if (quotactl_cmd_write(cmd)) |
| 328 | sb = get_super_thawed(bdev); | ||
| 329 | else | ||
| 330 | sb = get_super(bdev); | ||
| 313 | bdput(bdev); | 331 | bdput(bdev); |
| 314 | if (!sb) | 332 | if (!sb) |
| 315 | return ERR_PTR(-ENODEV); | 333 | return ERR_PTR(-ENODEV); |
| @@ -361,7 +379,7 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, | |||
| 361 | pathp = &path; | 379 | pathp = &path; |
| 362 | } | 380 | } |
| 363 | 381 | ||
| 364 | sb = quotactl_block(special); | 382 | sb = quotactl_block(special, cmds); |
| 365 | if (IS_ERR(sb)) { | 383 | if (IS_ERR(sb)) { |
| 366 | ret = PTR_ERR(sb); | 384 | ret = PTR_ERR(sb); |
| 367 | goto out; | 385 | goto out; |
