diff options
Diffstat (limited to 'fs')
93 files changed, 3714 insertions, 3064 deletions
@@ -498,11 +498,11 @@ int bio_get_nr_vecs(struct block_device *bdev) | |||
498 | struct request_queue *q = bdev_get_queue(bdev); | 498 | struct request_queue *q = bdev_get_queue(bdev); |
499 | int nr_pages; | 499 | int nr_pages; |
500 | 500 | ||
501 | nr_pages = ((q->max_sectors << 9) + PAGE_SIZE - 1) >> PAGE_SHIFT; | 501 | nr_pages = ((queue_max_sectors(q) << 9) + PAGE_SIZE - 1) >> PAGE_SHIFT; |
502 | if (nr_pages > q->max_phys_segments) | 502 | if (nr_pages > queue_max_phys_segments(q)) |
503 | nr_pages = q->max_phys_segments; | 503 | nr_pages = queue_max_phys_segments(q); |
504 | if (nr_pages > q->max_hw_segments) | 504 | if (nr_pages > queue_max_hw_segments(q)) |
505 | nr_pages = q->max_hw_segments; | 505 | nr_pages = queue_max_hw_segments(q); |
506 | 506 | ||
507 | return nr_pages; | 507 | return nr_pages; |
508 | } | 508 | } |
@@ -561,8 +561,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
561 | * make this too complex. | 561 | * make this too complex. |
562 | */ | 562 | */ |
563 | 563 | ||
564 | while (bio->bi_phys_segments >= q->max_phys_segments | 564 | while (bio->bi_phys_segments >= queue_max_phys_segments(q) |
565 | || bio->bi_phys_segments >= q->max_hw_segments) { | 565 | || bio->bi_phys_segments >= queue_max_hw_segments(q)) { |
566 | 566 | ||
567 | if (retried_segments) | 567 | if (retried_segments) |
568 | return 0; | 568 | return 0; |
@@ -633,7 +633,8 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page | |||
633 | int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, | 633 | int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, |
634 | unsigned int len, unsigned int offset) | 634 | unsigned int len, unsigned int offset) |
635 | { | 635 | { |
636 | return __bio_add_page(q, bio, page, len, offset, q->max_hw_sectors); | 636 | return __bio_add_page(q, bio, page, len, offset, |
637 | queue_max_hw_sectors(q)); | ||
637 | } | 638 | } |
638 | 639 | ||
639 | /** | 640 | /** |
@@ -653,7 +654,7 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len, | |||
653 | unsigned int offset) | 654 | unsigned int offset) |
654 | { | 655 | { |
655 | struct request_queue *q = bdev_get_queue(bio->bi_bdev); | 656 | struct request_queue *q = bdev_get_queue(bio->bi_bdev); |
656 | return __bio_add_page(q, bio, page, len, offset, q->max_sectors); | 657 | return __bio_add_page(q, bio, page, len, offset, queue_max_sectors(q)); |
657 | } | 658 | } |
658 | 659 | ||
659 | struct bio_map_data { | 660 | struct bio_map_data { |
@@ -720,7 +721,7 @@ static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs, | |||
720 | 721 | ||
721 | while (bv_len && iov_idx < iov_count) { | 722 | while (bv_len && iov_idx < iov_count) { |
722 | unsigned int bytes; | 723 | unsigned int bytes; |
723 | char *iov_addr; | 724 | char __user *iov_addr; |
724 | 725 | ||
725 | bytes = min_t(unsigned int, | 726 | bytes = min_t(unsigned int, |
726 | iov[iov_idx].iov_len - iov_off, bv_len); | 727 | iov[iov_idx].iov_len - iov_off, bv_len); |
@@ -1200,7 +1201,7 @@ static void bio_copy_kern_endio(struct bio *bio, int err) | |||
1200 | char *addr = page_address(bvec->bv_page); | 1201 | char *addr = page_address(bvec->bv_page); |
1201 | int len = bmd->iovecs[i].bv_len; | 1202 | int len = bmd->iovecs[i].bv_len; |
1202 | 1203 | ||
1203 | if (read && !err) | 1204 | if (read) |
1204 | memcpy(p, addr, len); | 1205 | memcpy(p, addr, len); |
1205 | 1206 | ||
1206 | __free_page(bvec->bv_page); | 1207 | __free_page(bvec->bv_page); |
@@ -1489,11 +1490,12 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors) | |||
1489 | sector_t bio_sector_offset(struct bio *bio, unsigned short index, | 1490 | sector_t bio_sector_offset(struct bio *bio, unsigned short index, |
1490 | unsigned int offset) | 1491 | unsigned int offset) |
1491 | { | 1492 | { |
1492 | unsigned int sector_sz = queue_hardsect_size(bio->bi_bdev->bd_disk->queue); | 1493 | unsigned int sector_sz; |
1493 | struct bio_vec *bv; | 1494 | struct bio_vec *bv; |
1494 | sector_t sectors; | 1495 | sector_t sectors; |
1495 | int i; | 1496 | int i; |
1496 | 1497 | ||
1498 | sector_sz = queue_logical_block_size(bio->bi_bdev->bd_disk->queue); | ||
1497 | sectors = 0; | 1499 | sectors = 0; |
1498 | 1500 | ||
1499 | if (index >= bio->bi_idx) | 1501 | if (index >= bio->bi_idx) |
diff --git a/fs/block_dev.c b/fs/block_dev.c index f45dbc18dd17..2dfc6cdcebbe 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -76,7 +76,7 @@ int set_blocksize(struct block_device *bdev, int size) | |||
76 | return -EINVAL; | 76 | return -EINVAL; |
77 | 77 | ||
78 | /* Size cannot be smaller than the size supported by the device */ | 78 | /* Size cannot be smaller than the size supported by the device */ |
79 | if (size < bdev_hardsect_size(bdev)) | 79 | if (size < bdev_logical_block_size(bdev)) |
80 | return -EINVAL; | 80 | return -EINVAL; |
81 | 81 | ||
82 | /* Don't change the size if it is same as current */ | 82 | /* Don't change the size if it is same as current */ |
@@ -106,7 +106,7 @@ EXPORT_SYMBOL(sb_set_blocksize); | |||
106 | 106 | ||
107 | int sb_min_blocksize(struct super_block *sb, int size) | 107 | int sb_min_blocksize(struct super_block *sb, int size) |
108 | { | 108 | { |
109 | int minsize = bdev_hardsect_size(sb->s_bdev); | 109 | int minsize = bdev_logical_block_size(sb->s_bdev); |
110 | if (size < minsize) | 110 | if (size < minsize) |
111 | size = minsize; | 111 | size = minsize; |
112 | return sb_set_blocksize(sb, size); | 112 | return sb_set_blocksize(sb, size); |
@@ -1111,7 +1111,7 @@ EXPORT_SYMBOL(check_disk_change); | |||
1111 | 1111 | ||
1112 | void bd_set_size(struct block_device *bdev, loff_t size) | 1112 | void bd_set_size(struct block_device *bdev, loff_t size) |
1113 | { | 1113 | { |
1114 | unsigned bsize = bdev_hardsect_size(bdev); | 1114 | unsigned bsize = bdev_logical_block_size(bdev); |
1115 | 1115 | ||
1116 | bdev->bd_inode->i_size = size; | 1116 | bdev->bd_inode->i_size = size; |
1117 | while (bsize < PAGE_CACHE_SIZE) { | 1117 | while (bsize < PAGE_CACHE_SIZE) { |
diff --git a/fs/buffer.c b/fs/buffer.c index 49106127a4aa..a3ef091a45bd 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -1085,12 +1085,12 @@ static struct buffer_head * | |||
1085 | __getblk_slow(struct block_device *bdev, sector_t block, int size) | 1085 | __getblk_slow(struct block_device *bdev, sector_t block, int size) |
1086 | { | 1086 | { |
1087 | /* Size must be multiple of hard sectorsize */ | 1087 | /* Size must be multiple of hard sectorsize */ |
1088 | if (unlikely(size & (bdev_hardsect_size(bdev)-1) || | 1088 | if (unlikely(size & (bdev_logical_block_size(bdev)-1) || |
1089 | (size < 512 || size > PAGE_SIZE))) { | 1089 | (size < 512 || size > PAGE_SIZE))) { |
1090 | printk(KERN_ERR "getblk(): invalid block size %d requested\n", | 1090 | printk(KERN_ERR "getblk(): invalid block size %d requested\n", |
1091 | size); | 1091 | size); |
1092 | printk(KERN_ERR "hardsect size: %d\n", | 1092 | printk(KERN_ERR "logical block size: %d\n", |
1093 | bdev_hardsect_size(bdev)); | 1093 | bdev_logical_block_size(bdev)); |
1094 | 1094 | ||
1095 | dump_stack(); | 1095 | dump_stack(); |
1096 | return NULL; | 1096 | return NULL; |
@@ -2935,6 +2935,8 @@ int submit_bh(int rw, struct buffer_head * bh) | |||
2935 | BUG_ON(!buffer_locked(bh)); | 2935 | BUG_ON(!buffer_locked(bh)); |
2936 | BUG_ON(!buffer_mapped(bh)); | 2936 | BUG_ON(!buffer_mapped(bh)); |
2937 | BUG_ON(!bh->b_end_io); | 2937 | BUG_ON(!bh->b_end_io); |
2938 | BUG_ON(buffer_delay(bh)); | ||
2939 | BUG_ON(buffer_unwritten(bh)); | ||
2938 | 2940 | ||
2939 | /* | 2941 | /* |
2940 | * Mask in barrier bit for a write (could be either a WRITE or a | 2942 | * Mask in barrier bit for a write (could be either a WRITE or a |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index f20c4069c220..b48689839428 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,3 +1,12 @@ | |||
1 | Version 1.59 | ||
2 | ------------ | ||
3 | Client uses server inode numbers (which are persistent) rather than | ||
4 | client generated ones by default (mount option "serverino" turned | ||
5 | on by default if server supports it). Add forceuid and forcegid | ||
6 | mount options (so that when negotiating unix extensions specifying | ||
7 | which uid mounted does not immediately force the server's reported | ||
8 | uids to be overridden). | ||
9 | |||
1 | Version 1.58 | 10 | Version 1.58 |
2 | ------------ | 11 | ------------ |
3 | Guard against buffer overruns in various UCS-2 to UTF-8 string conversions | 12 | Guard against buffer overruns in various UCS-2 to UTF-8 string conversions |
@@ -10,6 +19,8 @@ we converted from). Fix endianness of the vcnum field used during | |||
10 | session setup to distinguish multiple mounts to same server from different | 19 | session setup to distinguish multiple mounts to same server from different |
11 | userids. Raw NTLMSSP fixed (it requires /proc/fs/cifs/experimental | 20 | userids. Raw NTLMSSP fixed (it requires /proc/fs/cifs/experimental |
12 | flag to be set to 2, and mount must enable krb5 to turn on extended security). | 21 | flag to be set to 2, and mount must enable krb5 to turn on extended security). |
22 | Performance of file create to Samba improved (posix create on lookup | ||
23 | removes 1 of 2 network requests sent on file create) | ||
13 | 24 | ||
14 | Version 1.57 | 25 | Version 1.57 |
15 | ------------ | 26 | ------------ |
diff --git a/fs/cifs/README b/fs/cifs/README index db208ddb9899..ad92921dbde4 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -262,7 +262,8 @@ A partial list of the supported mount options follows: | |||
262 | mount. | 262 | mount. |
263 | domain Set the SMB/CIFS workgroup name prepended to the | 263 | domain Set the SMB/CIFS workgroup name prepended to the |
264 | username during CIFS session establishment | 264 | username during CIFS session establishment |
265 | uid Set the default uid for inodes. For mounts to servers | 265 | forceuid Set the default uid for inodes based on the uid |
266 | passed in. For mounts to servers | ||
266 | which do support the CIFS Unix extensions, such as a | 267 | which do support the CIFS Unix extensions, such as a |
267 | properly configured Samba server, the server provides | 268 | properly configured Samba server, the server provides |
268 | the uid, gid and mode so this parameter should not be | 269 | the uid, gid and mode so this parameter should not be |
@@ -292,6 +293,12 @@ A partial list of the supported mount options follows: | |||
292 | the client. Note that the mount.cifs helper must be | 293 | the client. Note that the mount.cifs helper must be |
293 | at version 1.10 or higher to support specifying the uid | 294 | at version 1.10 or higher to support specifying the uid |
294 | (or gid) in non-numeric form. | 295 | (or gid) in non-numeric form. |
296 | forcegid (similar to above but for the groupid instead of uid) | ||
297 | uid Set the default uid for inodes, and indicate to the | ||
298 | cifs kernel driver which local user mounted . If the server | ||
299 | supports the unix extensions the default uid is | ||
300 | not used to fill in the owner fields of inodes (files) | ||
301 | unless the "forceuid" parameter is specified. | ||
295 | gid Set the default gid for inodes (similar to above). | 302 | gid Set the default gid for inodes (similar to above). |
296 | file_mode If CIFS Unix extensions are not supported by the server | 303 | file_mode If CIFS Unix extensions are not supported by the server |
297 | this overrides the default mode for file inodes. | 304 | this overrides the default mode for file inodes. |
@@ -388,8 +395,13 @@ A partial list of the supported mount options follows: | |||
388 | or the CIFS Unix Extensions equivalent and for those | 395 | or the CIFS Unix Extensions equivalent and for those |
389 | this mount option will have no effect. Exporting cifs mounts | 396 | this mount option will have no effect. Exporting cifs mounts |
390 | under nfsd requires this mount option on the cifs mount. | 397 | under nfsd requires this mount option on the cifs mount. |
398 | This is now the default if server supports the | ||
399 | required network operation. | ||
391 | noserverino Client generates inode numbers (rather than using the actual one | 400 | noserverino Client generates inode numbers (rather than using the actual one |
392 | from the server) by default. | 401 | from the server). These inode numbers will vary after |
402 | unmount or reboot which can confuse some applications, | ||
403 | but not all server filesystems support unique inode | ||
404 | numbers. | ||
393 | setuids If the CIFS Unix extensions are negotiated with the server | 405 | setuids If the CIFS Unix extensions are negotiated with the server |
394 | the client will attempt to set the effective uid and gid of | 406 | the client will attempt to set the effective uid and gid of |
395 | the local process on newly created files, directories, and | 407 | the local process on newly created files, directories, and |
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index 67bf93a40d2e..4a4581cb2b5e 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/string.h> | 23 | #include <linux/string.h> |
24 | #include <keys/user-type.h> | 24 | #include <keys/user-type.h> |
25 | #include <linux/key-type.h> | 25 | #include <linux/key-type.h> |
26 | #include <linux/inet.h> | ||
26 | #include "cifsglob.h" | 27 | #include "cifsglob.h" |
27 | #include "cifs_spnego.h" | 28 | #include "cifs_spnego.h" |
28 | #include "cifs_debug.h" | 29 | #include "cifs_debug.h" |
@@ -73,9 +74,6 @@ struct key_type cifs_spnego_key_type = { | |||
73 | * strlen(";sec=ntlmsspi") */ | 74 | * strlen(";sec=ntlmsspi") */ |
74 | #define MAX_MECH_STR_LEN 13 | 75 | #define MAX_MECH_STR_LEN 13 |
75 | 76 | ||
76 | /* max possible addr len eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/128 */ | ||
77 | #define MAX_IPV6_ADDR_LEN 43 | ||
78 | |||
79 | /* strlen of "host=" */ | 77 | /* strlen of "host=" */ |
80 | #define HOST_KEY_LEN 5 | 78 | #define HOST_KEY_LEN 5 |
81 | 79 | ||
@@ -102,7 +100,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo) | |||
102 | host=hostname sec=mechanism uid=0xFF user=username */ | 100 | host=hostname sec=mechanism uid=0xFF user=username */ |
103 | desc_len = MAX_VER_STR_LEN + | 101 | desc_len = MAX_VER_STR_LEN + |
104 | HOST_KEY_LEN + strlen(hostname) + | 102 | HOST_KEY_LEN + strlen(hostname) + |
105 | IP_KEY_LEN + MAX_IPV6_ADDR_LEN + | 103 | IP_KEY_LEN + INET6_ADDRSTRLEN + |
106 | MAX_MECH_STR_LEN + | 104 | MAX_MECH_STR_LEN + |
107 | UID_KEY_LEN + (sizeof(uid_t) * 2) + | 105 | UID_KEY_LEN + (sizeof(uid_t) * 2) + |
108 | USER_KEY_LEN + strlen(sesInfo->userName) + 1; | 106 | USER_KEY_LEN + strlen(sesInfo->userName) + 1; |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 57ecdc83c26f..1403b5d86a73 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -552,130 +552,138 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
552 | return rc; | 552 | return rc; |
553 | } | 553 | } |
554 | 554 | ||
555 | 555 | static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, | |
556 | /* Retrieve an ACL from the server */ | 556 | __u16 fid, u32 *pacllen) |
557 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | ||
558 | const char *path, const __u16 *pfid) | ||
559 | { | 557 | { |
560 | struct cifsFileInfo *open_file = NULL; | ||
561 | bool unlock_file = false; | ||
562 | int xid; | ||
563 | int rc = -EIO; | ||
564 | __u16 fid; | ||
565 | struct super_block *sb; | ||
566 | struct cifs_sb_info *cifs_sb; | ||
567 | struct cifs_ntsd *pntsd = NULL; | 558 | struct cifs_ntsd *pntsd = NULL; |
559 | int xid, rc; | ||
560 | |||
561 | xid = GetXid(); | ||
562 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); | ||
563 | FreeXid(xid); | ||
568 | 564 | ||
569 | cFYI(1, ("get mode from ACL for %s", path)); | ||
570 | 565 | ||
571 | if (inode == NULL) | 566 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); |
572 | return NULL; | 567 | return pntsd; |
568 | } | ||
569 | |||
570 | static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, | ||
571 | const char *path, u32 *pacllen) | ||
572 | { | ||
573 | struct cifs_ntsd *pntsd = NULL; | ||
574 | int oplock = 0; | ||
575 | int xid, rc; | ||
576 | __u16 fid; | ||
573 | 577 | ||
574 | xid = GetXid(); | 578 | xid = GetXid(); |
575 | if (pfid == NULL) | ||
576 | open_file = find_readable_file(CIFS_I(inode)); | ||
577 | else | ||
578 | fid = *pfid; | ||
579 | 579 | ||
580 | sb = inode->i_sb; | 580 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, READ_CONTROL, 0, |
581 | if (sb == NULL) { | 581 | &fid, &oplock, NULL, cifs_sb->local_nls, |
582 | FreeXid(xid); | 582 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
583 | return NULL; | 583 | if (rc) { |
584 | } | 584 | cERROR(1, ("Unable to open file to get ACL")); |
585 | cifs_sb = CIFS_SB(sb); | 585 | goto out; |
586 | |||
587 | if (open_file) { | ||
588 | unlock_file = true; | ||
589 | fid = open_file->netfid; | ||
590 | } else if (pfid == NULL) { | ||
591 | int oplock = 0; | ||
592 | /* open file */ | ||
593 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | ||
594 | READ_CONTROL, 0, &fid, &oplock, NULL, | ||
595 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
596 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
597 | if (rc != 0) { | ||
598 | cERROR(1, ("Unable to open file to get ACL")); | ||
599 | FreeXid(xid); | ||
600 | return NULL; | ||
601 | } | ||
602 | } | 586 | } |
603 | 587 | ||
604 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); | 588 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); |
605 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); | 589 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); |
606 | if (unlock_file == true) /* find_readable_file increments ref count */ | ||
607 | atomic_dec(&open_file->wrtPending); | ||
608 | else if (pfid == NULL) /* if opened above we have to close the handle */ | ||
609 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
610 | /* else handle was passed in by caller */ | ||
611 | 590 | ||
591 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
592 | out: | ||
612 | FreeXid(xid); | 593 | FreeXid(xid); |
613 | return pntsd; | 594 | return pntsd; |
614 | } | 595 | } |
615 | 596 | ||
616 | /* Set an ACL on the server */ | 597 | /* Retrieve an ACL from the server */ |
617 | static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | 598 | static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, |
618 | struct inode *inode, const char *path) | 599 | struct inode *inode, const char *path, |
600 | u32 *pacllen) | ||
619 | { | 601 | { |
620 | struct cifsFileInfo *open_file; | 602 | struct cifs_ntsd *pntsd = NULL; |
621 | bool unlock_file = false; | 603 | struct cifsFileInfo *open_file = NULL; |
622 | int xid; | ||
623 | int rc = -EIO; | ||
624 | __u16 fid; | ||
625 | struct super_block *sb; | ||
626 | struct cifs_sb_info *cifs_sb; | ||
627 | 604 | ||
628 | cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); | 605 | if (inode) |
606 | open_file = find_readable_file(CIFS_I(inode)); | ||
607 | if (!open_file) | ||
608 | return get_cifs_acl_by_path(cifs_sb, path, pacllen); | ||
629 | 609 | ||
630 | if (!inode) | 610 | pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen); |
631 | return rc; | 611 | atomic_dec(&open_file->wrtPending); |
612 | return pntsd; | ||
613 | } | ||
632 | 614 | ||
633 | sb = inode->i_sb; | 615 | static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid, |
634 | if (sb == NULL) | 616 | struct cifs_ntsd *pnntsd, u32 acllen) |
635 | return rc; | 617 | { |
618 | int xid, rc; | ||
636 | 619 | ||
637 | cifs_sb = CIFS_SB(sb); | ||
638 | xid = GetXid(); | 620 | xid = GetXid(); |
621 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); | ||
622 | FreeXid(xid); | ||
639 | 623 | ||
640 | open_file = find_readable_file(CIFS_I(inode)); | 624 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); |
641 | if (open_file) { | 625 | return rc; |
642 | unlock_file = true; | 626 | } |
643 | fid = open_file->netfid; | 627 | |
644 | } else { | 628 | static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path, |
645 | int oplock = 0; | 629 | struct cifs_ntsd *pnntsd, u32 acllen) |
646 | /* open file */ | 630 | { |
647 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | 631 | int oplock = 0; |
648 | WRITE_DAC, 0, &fid, &oplock, NULL, | 632 | int xid, rc; |
649 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 633 | __u16 fid; |
650 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 634 | |
651 | if (rc != 0) { | 635 | xid = GetXid(); |
652 | cERROR(1, ("Unable to open file to set ACL")); | 636 | |
653 | FreeXid(xid); | 637 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0, |
654 | return rc; | 638 | &fid, &oplock, NULL, cifs_sb->local_nls, |
655 | } | 639 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
640 | if (rc) { | ||
641 | cERROR(1, ("Unable to open file to set ACL")); | ||
642 | goto out; | ||
656 | } | 643 | } |
657 | 644 | ||
658 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); | 645 | rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); |
659 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); | 646 | cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); |
660 | if (unlock_file) | ||
661 | atomic_dec(&open_file->wrtPending); | ||
662 | else | ||
663 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
664 | 647 | ||
648 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | ||
649 | out: | ||
665 | FreeXid(xid); | 650 | FreeXid(xid); |
651 | return rc; | ||
652 | } | ||
666 | 653 | ||
654 | /* Set an ACL on the server */ | ||
655 | static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | ||
656 | struct inode *inode, const char *path) | ||
657 | { | ||
658 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
659 | struct cifsFileInfo *open_file; | ||
660 | int rc; | ||
661 | |||
662 | cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); | ||
663 | |||
664 | open_file = find_readable_file(CIFS_I(inode)); | ||
665 | if (!open_file) | ||
666 | return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen); | ||
667 | |||
668 | rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen); | ||
669 | atomic_dec(&open_file->wrtPending); | ||
667 | return rc; | 670 | return rc; |
668 | } | 671 | } |
669 | 672 | ||
670 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | 673 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ |
671 | void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid) | 674 | void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode, |
675 | const char *path, const __u16 *pfid) | ||
672 | { | 676 | { |
673 | struct cifs_ntsd *pntsd = NULL; | 677 | struct cifs_ntsd *pntsd = NULL; |
674 | u32 acllen = 0; | 678 | u32 acllen = 0; |
675 | int rc = 0; | 679 | int rc = 0; |
676 | 680 | ||
677 | cFYI(DBG2, ("converting ACL to mode for %s", path)); | 681 | cFYI(DBG2, ("converting ACL to mode for %s", path)); |
678 | pntsd = get_cifs_acl(&acllen, inode, path, pfid); | 682 | |
683 | if (pfid) | ||
684 | pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen); | ||
685 | else | ||
686 | pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen); | ||
679 | 687 | ||
680 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ | 688 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ |
681 | if (pntsd) | 689 | if (pntsd) |
@@ -698,7 +706,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) | |||
698 | cFYI(DBG2, ("set ACL from mode for %s", path)); | 706 | cFYI(DBG2, ("set ACL from mode for %s", path)); |
699 | 707 | ||
700 | /* Get the security descriptor */ | 708 | /* Get the security descriptor */ |
701 | pntsd = get_cifs_acl(&secdesclen, inode, path, NULL); | 709 | pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen); |
702 | 710 | ||
703 | /* Add three ACEs for owner, group, everyone getting rid of | 711 | /* Add three ACEs for owner, group, everyone getting rid of |
704 | other ACEs as chmod disables ACEs and set the security descriptor */ | 712 | other ACEs as chmod disables ACEs and set the security descriptor */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5e6d35804d73..0a10a59b6392 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -146,7 +146,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
146 | #endif | 146 | #endif |
147 | sb->s_blocksize = CIFS_MAX_MSGSIZE; | 147 | sb->s_blocksize = CIFS_MAX_MSGSIZE; |
148 | sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ | 148 | sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */ |
149 | inode = cifs_iget(sb, ROOT_I); | 149 | inode = cifs_root_iget(sb, ROOT_I); |
150 | 150 | ||
151 | if (IS_ERR(inode)) { | 151 | if (IS_ERR(inode)) { |
152 | rc = PTR_ERR(inode); | 152 | rc = PTR_ERR(inode); |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 051b71cfdea9..9570a0e8023f 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -36,7 +36,7 @@ extern void cifs_read_inode(struct inode *); | |||
36 | 36 | ||
37 | /* Functions related to inodes */ | 37 | /* Functions related to inodes */ |
38 | extern const struct inode_operations cifs_dir_inode_ops; | 38 | extern const struct inode_operations cifs_dir_inode_ops; |
39 | extern struct inode *cifs_iget(struct super_block *, unsigned long); | 39 | extern struct inode *cifs_root_iget(struct super_block *, unsigned long); |
40 | extern int cifs_create(struct inode *, struct dentry *, int, | 40 | extern int cifs_create(struct inode *, struct dentry *, int, |
41 | struct nameidata *); | 41 | struct nameidata *); |
42 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, | 42 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, |
@@ -100,5 +100,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
100 | extern const struct export_operations cifs_export_ops; | 100 | extern const struct export_operations cifs_export_ops; |
101 | #endif /* EXPERIMENTAL */ | 101 | #endif /* EXPERIMENTAL */ |
102 | 102 | ||
103 | #define CIFS_VERSION "1.58" | 103 | #define CIFS_VERSION "1.59" |
104 | #endif /* _CIFSFS_H */ | 104 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index fae083930eee..f9452329bcce 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -90,10 +90,10 @@ extern struct oplock_q_entry *AllocOplockQEntry(struct inode *, u16, | |||
90 | struct cifsTconInfo *); | 90 | struct cifsTconInfo *); |
91 | extern void DeleteOplockQEntry(struct oplock_q_entry *); | 91 | extern void DeleteOplockQEntry(struct oplock_q_entry *); |
92 | extern void DeleteTconOplockQEntries(struct cifsTconInfo *); | 92 | extern void DeleteTconOplockQEntries(struct cifsTconInfo *); |
93 | extern struct timespec cifs_NTtimeToUnix(u64 utc_nanoseconds_since_1601); | 93 | extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); |
94 | extern u64 cifs_UnixTimeToNT(struct timespec); | 94 | extern u64 cifs_UnixTimeToNT(struct timespec); |
95 | extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time); | 95 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, |
96 | extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time); | 96 | int offset); |
97 | 97 | ||
98 | extern int cifs_posix_open(char *full_path, struct inode **pinode, | 98 | extern int cifs_posix_open(char *full_path, struct inode **pinode, |
99 | struct super_block *sb, int mode, int oflags, | 99 | struct super_block *sb, int mode, int oflags, |
@@ -108,8 +108,8 @@ extern int cifs_get_inode_info(struct inode **pinode, | |||
108 | extern int cifs_get_inode_info_unix(struct inode **pinode, | 108 | extern int cifs_get_inode_info_unix(struct inode **pinode, |
109 | const unsigned char *search_path, | 109 | const unsigned char *search_path, |
110 | struct super_block *sb, int xid); | 110 | struct super_block *sb, int xid); |
111 | extern void acl_to_uid_mode(struct inode *inode, const char *path, | 111 | extern void acl_to_uid_mode(struct cifs_sb_info *cifs_sb, struct inode *inode, |
112 | const __u16 *pfid); | 112 | const char *path, const __u16 *pfid); |
113 | extern int mode_to_acl(struct inode *inode, const char *path, __u64); | 113 | extern int mode_to_acl(struct inode *inode, const char *path, __u64); |
114 | 114 | ||
115 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, | 115 | extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index d06260251c30..b84c61d5bca4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -524,8 +524,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
524 | int val, seconds, remain, result; | 524 | int val, seconds, remain, result; |
525 | struct timespec ts, utc; | 525 | struct timespec ts, utc; |
526 | utc = CURRENT_TIME; | 526 | utc = CURRENT_TIME; |
527 | ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date), | 527 | ts = cnvrtDosUnixTm(rsp->SrvTime.Date, |
528 | le16_to_cpu(rsp->SrvTime.Time)); | 528 | rsp->SrvTime.Time, 0); |
529 | cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d", | 529 | cFYI(1, ("SrvTime %d sec since 1970 (utc: %d) diff: %d", |
530 | (int)ts.tv_sec, (int)utc.tv_sec, | 530 | (int)ts.tv_sec, (int)utc.tv_sec, |
531 | (int)(utc.tv_sec - ts.tv_sec))); | 531 | (int)(utc.tv_sec - ts.tv_sec))); |
@@ -2427,8 +2427,7 @@ querySymLinkRetry: | |||
2427 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; | 2427 | params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ; |
2428 | pSMB->TotalDataCount = 0; | 2428 | pSMB->TotalDataCount = 0; |
2429 | pSMB->MaxParameterCount = cpu_to_le16(2); | 2429 | pSMB->MaxParameterCount = cpu_to_le16(2); |
2430 | /* BB find exact max data count below from sess structure BB */ | 2430 | pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize); |
2431 | pSMB->MaxDataCount = cpu_to_le16(4000); | ||
2432 | pSMB->MaxSetupCount = 0; | 2431 | pSMB->MaxSetupCount = 0; |
2433 | pSMB->Reserved = 0; | 2432 | pSMB->Reserved = 0; |
2434 | pSMB->Flags = 0; | 2433 | pSMB->Flags = 0; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 4aa81a507b74..97f4311b9a8e 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/namei.h> | 35 | #include <linux/namei.h> |
36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
37 | #include <asm/processor.h> | 37 | #include <asm/processor.h> |
38 | #include <linux/inet.h> | ||
38 | #include <net/ipv6.h> | 39 | #include <net/ipv6.h> |
39 | #include "cifspdu.h" | 40 | #include "cifspdu.h" |
40 | #include "cifsglob.h" | 41 | #include "cifsglob.h" |
@@ -61,7 +62,6 @@ struct smb_vol { | |||
61 | char *domainname; | 62 | char *domainname; |
62 | char *UNC; | 63 | char *UNC; |
63 | char *UNCip; | 64 | char *UNCip; |
64 | char *in6_addr; /* ipv6 address as human readable form of in6_addr */ | ||
65 | char *iocharset; /* local code page for mapping to and from Unicode */ | 65 | char *iocharset; /* local code page for mapping to and from Unicode */ |
66 | char source_rfc1001_name[16]; /* netbios name of client */ | 66 | char source_rfc1001_name[16]; /* netbios name of client */ |
67 | char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ | 67 | char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ |
@@ -827,14 +827,16 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
827 | vol->target_rfc1001_name[0] = 0; | 827 | vol->target_rfc1001_name[0] = 0; |
828 | vol->linux_uid = current_uid(); /* use current_euid() instead? */ | 828 | vol->linux_uid = current_uid(); /* use current_euid() instead? */ |
829 | vol->linux_gid = current_gid(); | 829 | vol->linux_gid = current_gid(); |
830 | vol->dir_mode = S_IRWXUGO; | 830 | |
831 | /* 2767 perms indicate mandatory locking support */ | 831 | /* default to only allowing write access to owner of the mount */ |
832 | vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP); | 832 | vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; |
833 | 833 | ||
834 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ | 834 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ |
835 | vol->rw = true; | 835 | vol->rw = true; |
836 | /* default is always to request posix paths. */ | 836 | /* default is always to request posix paths. */ |
837 | vol->posix_paths = 1; | 837 | vol->posix_paths = 1; |
838 | /* default to using server inode numbers where available */ | ||
839 | vol->server_ino = 1; | ||
838 | 840 | ||
839 | if (!options) | 841 | if (!options) |
840 | return 1; | 842 | return 1; |
@@ -955,10 +957,12 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
955 | } | 957 | } |
956 | strcpy(vol->password, value); | 958 | strcpy(vol->password, value); |
957 | } | 959 | } |
958 | } else if (strnicmp(data, "ip", 2) == 0) { | 960 | } else if (!strnicmp(data, "ip", 2) || |
961 | !strnicmp(data, "addr", 4)) { | ||
959 | if (!value || !*value) { | 962 | if (!value || !*value) { |
960 | vol->UNCip = NULL; | 963 | vol->UNCip = NULL; |
961 | } else if (strnlen(value, 35) < 35) { | 964 | } else if (strnlen(value, INET6_ADDRSTRLEN) < |
965 | INET6_ADDRSTRLEN) { | ||
962 | vol->UNCip = value; | 966 | vol->UNCip = value; |
963 | } else { | 967 | } else { |
964 | printk(KERN_WARNING "CIFS: ip address " | 968 | printk(KERN_WARNING "CIFS: ip address " |
@@ -1092,17 +1096,17 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1092 | return 1; | 1096 | return 1; |
1093 | } | 1097 | } |
1094 | } else if (strnicmp(data, "uid", 3) == 0) { | 1098 | } else if (strnicmp(data, "uid", 3) == 0) { |
1095 | if (value && *value) { | 1099 | if (value && *value) |
1096 | vol->linux_uid = | 1100 | vol->linux_uid = |
1097 | simple_strtoul(value, &value, 0); | 1101 | simple_strtoul(value, &value, 0); |
1102 | } else if (strnicmp(data, "forceuid", 8) == 0) { | ||
1098 | vol->override_uid = 1; | 1103 | vol->override_uid = 1; |
1099 | } | ||
1100 | } else if (strnicmp(data, "gid", 3) == 0) { | 1104 | } else if (strnicmp(data, "gid", 3) == 0) { |
1101 | if (value && *value) { | 1105 | if (value && *value) |
1102 | vol->linux_gid = | 1106 | vol->linux_gid = |
1103 | simple_strtoul(value, &value, 0); | 1107 | simple_strtoul(value, &value, 0); |
1108 | } else if (strnicmp(data, "forcegid", 8) == 0) { | ||
1104 | vol->override_gid = 1; | 1109 | vol->override_gid = 1; |
1105 | } | ||
1106 | } else if (strnicmp(data, "file_mode", 4) == 0) { | 1110 | } else if (strnicmp(data, "file_mode", 4) == 0) { |
1107 | if (value && *value) { | 1111 | if (value && *value) { |
1108 | vol->file_mode = | 1112 | vol->file_mode = |
@@ -1315,16 +1319,6 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1315 | vol->direct_io = 1; | 1319 | vol->direct_io = 1; |
1316 | } else if (strnicmp(data, "forcedirectio", 13) == 0) { | 1320 | } else if (strnicmp(data, "forcedirectio", 13) == 0) { |
1317 | vol->direct_io = 1; | 1321 | vol->direct_io = 1; |
1318 | } else if (strnicmp(data, "in6_addr", 8) == 0) { | ||
1319 | if (!value || !*value) { | ||
1320 | vol->in6_addr = NULL; | ||
1321 | } else if (strnlen(value, 49) == 48) { | ||
1322 | vol->in6_addr = value; | ||
1323 | } else { | ||
1324 | printk(KERN_WARNING "CIFS: ip v6 address not " | ||
1325 | "48 characters long\n"); | ||
1326 | return 1; | ||
1327 | } | ||
1328 | } else if (strnicmp(data, "noac", 4) == 0) { | 1322 | } else if (strnicmp(data, "noac", 4) == 0) { |
1329 | printk(KERN_WARNING "CIFS: Mount option noac not " | 1323 | printk(KERN_WARNING "CIFS: Mount option noac not " |
1330 | "supported. Instead set " | 1324 | "supported. Instead set " |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 302ea15f02e6..06866841b97f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -241,7 +241,7 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | |||
241 | /* BB need same check in cifs_create too? */ | 241 | /* BB need same check in cifs_create too? */ |
242 | /* if not oplocked, invalidate inode pages if mtime or file | 242 | /* if not oplocked, invalidate inode pages if mtime or file |
243 | size changed */ | 243 | size changed */ |
244 | temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime)); | 244 | temp = cifs_NTtimeToUnix(buf->LastWriteTime); |
245 | if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && | 245 | if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && |
246 | (file->f_path.dentry->d_inode->i_size == | 246 | (file->f_path.dentry->d_inode->i_size == |
247 | (loff_t)le64_to_cpu(buf->EndOfFile))) { | 247 | (loff_t)le64_to_cpu(buf->EndOfFile))) { |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 9c869a6dcba1..fad882b075ba 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -85,10 +85,10 @@ static void cifs_unix_info_to_inode(struct inode *inode, | |||
85 | __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes); | 85 | __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes); |
86 | __u64 end_of_file = le64_to_cpu(info->EndOfFile); | 86 | __u64 end_of_file = le64_to_cpu(info->EndOfFile); |
87 | 87 | ||
88 | inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(info->LastAccessTime)); | 88 | inode->i_atime = cifs_NTtimeToUnix(info->LastAccessTime); |
89 | inode->i_mtime = | 89 | inode->i_mtime = |
90 | cifs_NTtimeToUnix(le64_to_cpu(info->LastModificationTime)); | 90 | cifs_NTtimeToUnix(info->LastModificationTime); |
91 | inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(info->LastStatusChange)); | 91 | inode->i_ctime = cifs_NTtimeToUnix(info->LastStatusChange); |
92 | inode->i_mode = le64_to_cpu(info->Permissions); | 92 | inode->i_mode = le64_to_cpu(info->Permissions); |
93 | 93 | ||
94 | /* | 94 | /* |
@@ -554,14 +554,11 @@ int cifs_get_inode_info(struct inode **pinode, | |||
554 | 554 | ||
555 | /* Linux can not store file creation time so ignore it */ | 555 | /* Linux can not store file creation time so ignore it */ |
556 | if (pfindData->LastAccessTime) | 556 | if (pfindData->LastAccessTime) |
557 | inode->i_atime = cifs_NTtimeToUnix | 557 | inode->i_atime = cifs_NTtimeToUnix(pfindData->LastAccessTime); |
558 | (le64_to_cpu(pfindData->LastAccessTime)); | ||
559 | else /* do not need to use current_fs_time - time not stored */ | 558 | else /* do not need to use current_fs_time - time not stored */ |
560 | inode->i_atime = CURRENT_TIME; | 559 | inode->i_atime = CURRENT_TIME; |
561 | inode->i_mtime = | 560 | inode->i_mtime = cifs_NTtimeToUnix(pfindData->LastWriteTime); |
562 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); | 561 | inode->i_ctime = cifs_NTtimeToUnix(pfindData->ChangeTime); |
563 | inode->i_ctime = | ||
564 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | ||
565 | cFYI(DBG2, ("Attributes came in as 0x%x", attr)); | 562 | cFYI(DBG2, ("Attributes came in as 0x%x", attr)); |
566 | if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { | 563 | if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { |
567 | inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; | 564 | inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; |
@@ -629,7 +626,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
629 | /* fill in 0777 bits from ACL */ | 626 | /* fill in 0777 bits from ACL */ |
630 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 627 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
631 | cFYI(1, ("Getting mode bits from ACL")); | 628 | cFYI(1, ("Getting mode bits from ACL")); |
632 | acl_to_uid_mode(inode, full_path, pfid); | 629 | acl_to_uid_mode(cifs_sb, inode, full_path, pfid); |
633 | } | 630 | } |
634 | #endif | 631 | #endif |
635 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { | 632 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { |
@@ -699,7 +696,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) | |||
699 | } | 696 | } |
700 | 697 | ||
701 | /* gets root inode */ | 698 | /* gets root inode */ |
702 | struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | 699 | struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) |
703 | { | 700 | { |
704 | int xid; | 701 | int xid; |
705 | struct cifs_sb_info *cifs_sb; | 702 | struct cifs_sb_info *cifs_sb; |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index e2fe998989a3..32d6baa0a54f 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -853,12 +853,12 @@ smbCalcSize_LE(struct smb_hdr *ptr) | |||
853 | 853 | ||
854 | #define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000) | 854 | #define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000) |
855 | 855 | ||
856 | /* | 856 | /* |
857 | * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) | 857 | * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) |
858 | * into Unix UTC (based 1970-01-01, in seconds). | 858 | * into Unix UTC (based 1970-01-01, in seconds). |
859 | */ | 859 | */ |
860 | struct timespec | 860 | struct timespec |
861 | cifs_NTtimeToUnix(u64 ntutc) | 861 | cifs_NTtimeToUnix(__le64 ntutc) |
862 | { | 862 | { |
863 | struct timespec ts; | 863 | struct timespec ts; |
864 | /* BB what about the timezone? BB */ | 864 | /* BB what about the timezone? BB */ |
@@ -866,7 +866,7 @@ cifs_NTtimeToUnix(u64 ntutc) | |||
866 | /* Subtract the NTFS time offset, then convert to 1s intervals. */ | 866 | /* Subtract the NTFS time offset, then convert to 1s intervals. */ |
867 | u64 t; | 867 | u64 t; |
868 | 868 | ||
869 | t = ntutc - NTFS_TIME_OFFSET; | 869 | t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET; |
870 | ts.tv_nsec = do_div(t, 10000000) * 100; | 870 | ts.tv_nsec = do_div(t, 10000000) * 100; |
871 | ts.tv_sec = t; | 871 | ts.tv_sec = t; |
872 | return ts; | 872 | return ts; |
@@ -883,16 +883,12 @@ cifs_UnixTimeToNT(struct timespec t) | |||
883 | static int total_days_of_prev_months[] = | 883 | static int total_days_of_prev_months[] = |
884 | {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; | 884 | {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; |
885 | 885 | ||
886 | 886 | struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) | |
887 | __le64 cnvrtDosCifsTm(__u16 date, __u16 time) | ||
888 | { | ||
889 | return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time))); | ||
890 | } | ||
891 | |||
892 | struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) | ||
893 | { | 887 | { |
894 | struct timespec ts; | 888 | struct timespec ts; |
895 | int sec, min, days, month, year; | 889 | int sec, min, days, month, year; |
890 | u16 date = le16_to_cpu(le_date); | ||
891 | u16 time = le16_to_cpu(le_time); | ||
896 | SMB_TIME *st = (SMB_TIME *)&time; | 892 | SMB_TIME *st = (SMB_TIME *)&time; |
897 | SMB_DATE *sd = (SMB_DATE *)&date; | 893 | SMB_DATE *sd = (SMB_DATE *)&date; |
898 | 894 | ||
@@ -933,7 +929,7 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) | |||
933 | days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); | 929 | days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); |
934 | sec += 24 * 60 * 60 * days; | 930 | sec += 24 * 60 * 60 * days; |
935 | 931 | ||
936 | ts.tv_sec = sec; | 932 | ts.tv_sec = sec + offset; |
937 | 933 | ||
938 | /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */ | 934 | /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */ |
939 | 935 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 964e097c8203..86d0055dc529 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -115,17 +115,6 @@ construct_dentry(struct qstr *qstring, struct file *file, | |||
115 | return rc; | 115 | return rc; |
116 | } | 116 | } |
117 | 117 | ||
118 | static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode) | ||
119 | { | ||
120 | if ((tcon) && (tcon->ses) && (tcon->ses->server)) { | ||
121 | inode->i_ctime.tv_sec += tcon->ses->server->timeAdj; | ||
122 | inode->i_mtime.tv_sec += tcon->ses->server->timeAdj; | ||
123 | inode->i_atime.tv_sec += tcon->ses->server->timeAdj; | ||
124 | } | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | |||
129 | static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | 118 | static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, |
130 | char *buf, unsigned int *pobject_type, int isNewInode) | 119 | char *buf, unsigned int *pobject_type, int isNewInode) |
131 | { | 120 | { |
@@ -150,26 +139,25 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
150 | allocation_size = le64_to_cpu(pfindData->AllocationSize); | 139 | allocation_size = le64_to_cpu(pfindData->AllocationSize); |
151 | end_of_file = le64_to_cpu(pfindData->EndOfFile); | 140 | end_of_file = le64_to_cpu(pfindData->EndOfFile); |
152 | tmp_inode->i_atime = | 141 | tmp_inode->i_atime = |
153 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); | 142 | cifs_NTtimeToUnix(pfindData->LastAccessTime); |
154 | tmp_inode->i_mtime = | 143 | tmp_inode->i_mtime = |
155 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); | 144 | cifs_NTtimeToUnix(pfindData->LastWriteTime); |
156 | tmp_inode->i_ctime = | 145 | tmp_inode->i_ctime = |
157 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | 146 | cifs_NTtimeToUnix(pfindData->ChangeTime); |
158 | } else { /* legacy, OS2 and DOS style */ | 147 | } else { /* legacy, OS2 and DOS style */ |
159 | /* struct timespec ts;*/ | 148 | int offset = cifs_sb->tcon->ses->server->timeAdj; |
160 | FIND_FILE_STANDARD_INFO *pfindData = | 149 | FIND_FILE_STANDARD_INFO *pfindData = |
161 | (FIND_FILE_STANDARD_INFO *)buf; | 150 | (FIND_FILE_STANDARD_INFO *)buf; |
162 | 151 | ||
163 | tmp_inode->i_mtime = cnvrtDosUnixTm( | 152 | tmp_inode->i_mtime = cnvrtDosUnixTm(pfindData->LastWriteDate, |
164 | le16_to_cpu(pfindData->LastWriteDate), | 153 | pfindData->LastWriteTime, |
165 | le16_to_cpu(pfindData->LastWriteTime)); | 154 | offset); |
166 | tmp_inode->i_atime = cnvrtDosUnixTm( | 155 | tmp_inode->i_atime = cnvrtDosUnixTm(pfindData->LastAccessDate, |
167 | le16_to_cpu(pfindData->LastAccessDate), | 156 | pfindData->LastAccessTime, |
168 | le16_to_cpu(pfindData->LastAccessTime)); | 157 | offset); |
169 | tmp_inode->i_ctime = cnvrtDosUnixTm( | 158 | tmp_inode->i_ctime = cnvrtDosUnixTm(pfindData->LastWriteDate, |
170 | le16_to_cpu(pfindData->LastWriteDate), | 159 | pfindData->LastWriteTime, |
171 | le16_to_cpu(pfindData->LastWriteTime)); | 160 | offset); |
172 | AdjustForTZ(cifs_sb->tcon, tmp_inode); | ||
173 | attr = le16_to_cpu(pfindData->Attributes); | 161 | attr = le16_to_cpu(pfindData->Attributes); |
174 | allocation_size = le32_to_cpu(pfindData->AllocationSize); | 162 | allocation_size = le32_to_cpu(pfindData->AllocationSize); |
175 | end_of_file = le32_to_cpu(pfindData->DataSize); | 163 | end_of_file = le32_to_cpu(pfindData->DataSize); |
@@ -331,11 +319,11 @@ static void unix_fill_in_inode(struct inode *tmp_inode, | |||
331 | local_size = tmp_inode->i_size; | 319 | local_size = tmp_inode->i_size; |
332 | 320 | ||
333 | tmp_inode->i_atime = | 321 | tmp_inode->i_atime = |
334 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); | 322 | cifs_NTtimeToUnix(pfindData->LastAccessTime); |
335 | tmp_inode->i_mtime = | 323 | tmp_inode->i_mtime = |
336 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime)); | 324 | cifs_NTtimeToUnix(pfindData->LastModificationTime); |
337 | tmp_inode->i_ctime = | 325 | tmp_inode->i_ctime = |
338 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange)); | 326 | cifs_NTtimeToUnix(pfindData->LastStatusChange); |
339 | 327 | ||
340 | tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); | 328 | tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions); |
341 | /* since we set the inode type below we need to mask off type | 329 | /* since we set the inode type below we need to mask off type |
diff --git a/fs/coda/file.c b/fs/coda/file.c index 6a347fbc998a..ffd42815fda1 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
@@ -47,6 +47,8 @@ coda_file_splice_read(struct file *coda_file, loff_t *ppos, | |||
47 | struct pipe_inode_info *pipe, size_t count, | 47 | struct pipe_inode_info *pipe, size_t count, |
48 | unsigned int flags) | 48 | unsigned int flags) |
49 | { | 49 | { |
50 | ssize_t (*splice_read)(struct file *, loff_t *, | ||
51 | struct pipe_inode_info *, size_t, unsigned int); | ||
50 | struct coda_file_info *cfi; | 52 | struct coda_file_info *cfi; |
51 | struct file *host_file; | 53 | struct file *host_file; |
52 | 54 | ||
@@ -54,10 +56,11 @@ coda_file_splice_read(struct file *coda_file, loff_t *ppos, | |||
54 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); | 56 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); |
55 | host_file = cfi->cfi_container; | 57 | host_file = cfi->cfi_container; |
56 | 58 | ||
57 | if (!host_file->f_op || !host_file->f_op->splice_read) | 59 | splice_read = host_file->f_op->splice_read; |
58 | return -EINVAL; | 60 | if (!splice_read) |
61 | splice_read = default_file_splice_read; | ||
59 | 62 | ||
60 | return host_file->f_op->splice_read(host_file, ppos, pipe, count,flags); | 63 | return splice_read(host_file, ppos, pipe, count, flags); |
61 | } | 64 | } |
62 | 65 | ||
63 | static ssize_t | 66 | static ssize_t |
diff --git a/fs/compat.c b/fs/compat.c index 681ed81e6be0..bb2a9b2e8173 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1488,7 +1488,7 @@ int compat_do_execve(char * filename, | |||
1488 | if (!bprm) | 1488 | if (!bprm) |
1489 | goto out_files; | 1489 | goto out_files; |
1490 | 1490 | ||
1491 | retval = mutex_lock_interruptible(¤t->cred_exec_mutex); | 1491 | retval = mutex_lock_interruptible(¤t->cred_guard_mutex); |
1492 | if (retval < 0) | 1492 | if (retval < 0) |
1493 | goto out_free; | 1493 | goto out_free; |
1494 | current->in_execve = 1; | 1494 | current->in_execve = 1; |
@@ -1550,7 +1550,7 @@ int compat_do_execve(char * filename, | |||
1550 | /* execve succeeded */ | 1550 | /* execve succeeded */ |
1551 | current->fs->in_exec = 0; | 1551 | current->fs->in_exec = 0; |
1552 | current->in_execve = 0; | 1552 | current->in_execve = 0; |
1553 | mutex_unlock(¤t->cred_exec_mutex); | 1553 | mutex_unlock(¤t->cred_guard_mutex); |
1554 | acct_update_integrals(current); | 1554 | acct_update_integrals(current); |
1555 | free_bprm(bprm); | 1555 | free_bprm(bprm); |
1556 | if (displaced) | 1556 | if (displaced) |
@@ -1573,7 +1573,7 @@ out_unmark: | |||
1573 | 1573 | ||
1574 | out_unlock: | 1574 | out_unlock: |
1575 | current->in_execve = 0; | 1575 | current->in_execve = 0; |
1576 | mutex_unlock(¤t->cred_exec_mutex); | 1576 | mutex_unlock(¤t->cred_guard_mutex); |
1577 | 1577 | ||
1578 | out_free: | 1578 | out_free: |
1579 | free_bprm(bprm); | 1579 | free_bprm(bprm); |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index c68edb969441..9b1d285f9fe6 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -557,8 +557,10 @@ static int __init init_devpts_fs(void) | |||
557 | int err = register_filesystem(&devpts_fs_type); | 557 | int err = register_filesystem(&devpts_fs_type); |
558 | if (!err) { | 558 | if (!err) { |
559 | devpts_mnt = kern_mount(&devpts_fs_type); | 559 | devpts_mnt = kern_mount(&devpts_fs_type); |
560 | if (IS_ERR(devpts_mnt)) | 560 | if (IS_ERR(devpts_mnt)) { |
561 | err = PTR_ERR(devpts_mnt); | 561 | err = PTR_ERR(devpts_mnt); |
562 | unregister_filesystem(&devpts_fs_type); | ||
563 | } | ||
562 | } | 564 | } |
563 | return err; | 565 | return err; |
564 | } | 566 | } |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 05763bbc2050..8b10b87dc01a 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -1127,7 +1127,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, | |||
1127 | rw = WRITE_ODIRECT; | 1127 | rw = WRITE_ODIRECT; |
1128 | 1128 | ||
1129 | if (bdev) | 1129 | if (bdev) |
1130 | bdev_blkbits = blksize_bits(bdev_hardsect_size(bdev)); | 1130 | bdev_blkbits = blksize_bits(bdev_logical_block_size(bdev)); |
1131 | 1131 | ||
1132 | if (offset & blocksize_mask) { | 1132 | if (offset & blocksize_mask) { |
1133 | if (bdev) | 1133 | if (bdev) |
@@ -1025,7 +1025,7 @@ void install_exec_creds(struct linux_binprm *bprm) | |||
1025 | commit_creds(bprm->cred); | 1025 | commit_creds(bprm->cred); |
1026 | bprm->cred = NULL; | 1026 | bprm->cred = NULL; |
1027 | 1027 | ||
1028 | /* cred_exec_mutex must be held at least to this point to prevent | 1028 | /* cred_guard_mutex must be held at least to this point to prevent |
1029 | * ptrace_attach() from altering our determination of the task's | 1029 | * ptrace_attach() from altering our determination of the task's |
1030 | * credentials; any time after this it may be unlocked */ | 1030 | * credentials; any time after this it may be unlocked */ |
1031 | 1031 | ||
@@ -1035,7 +1035,7 @@ EXPORT_SYMBOL(install_exec_creds); | |||
1035 | 1035 | ||
1036 | /* | 1036 | /* |
1037 | * determine how safe it is to execute the proposed program | 1037 | * determine how safe it is to execute the proposed program |
1038 | * - the caller must hold current->cred_exec_mutex to protect against | 1038 | * - the caller must hold current->cred_guard_mutex to protect against |
1039 | * PTRACE_ATTACH | 1039 | * PTRACE_ATTACH |
1040 | */ | 1040 | */ |
1041 | int check_unsafe_exec(struct linux_binprm *bprm) | 1041 | int check_unsafe_exec(struct linux_binprm *bprm) |
@@ -1277,7 +1277,7 @@ int do_execve(char * filename, | |||
1277 | if (!bprm) | 1277 | if (!bprm) |
1278 | goto out_files; | 1278 | goto out_files; |
1279 | 1279 | ||
1280 | retval = mutex_lock_interruptible(¤t->cred_exec_mutex); | 1280 | retval = mutex_lock_interruptible(¤t->cred_guard_mutex); |
1281 | if (retval < 0) | 1281 | if (retval < 0) |
1282 | goto out_free; | 1282 | goto out_free; |
1283 | current->in_execve = 1; | 1283 | current->in_execve = 1; |
@@ -1340,7 +1340,7 @@ int do_execve(char * filename, | |||
1340 | /* execve succeeded */ | 1340 | /* execve succeeded */ |
1341 | current->fs->in_exec = 0; | 1341 | current->fs->in_exec = 0; |
1342 | current->in_execve = 0; | 1342 | current->in_execve = 0; |
1343 | mutex_unlock(¤t->cred_exec_mutex); | 1343 | mutex_unlock(¤t->cred_guard_mutex); |
1344 | acct_update_integrals(current); | 1344 | acct_update_integrals(current); |
1345 | free_bprm(bprm); | 1345 | free_bprm(bprm); |
1346 | if (displaced) | 1346 | if (displaced) |
@@ -1363,7 +1363,7 @@ out_unmark: | |||
1363 | 1363 | ||
1364 | out_unlock: | 1364 | out_unlock: |
1365 | current->in_execve = 0; | 1365 | current->in_execve = 0; |
1366 | mutex_unlock(¤t->cred_exec_mutex); | 1366 | mutex_unlock(¤t->cred_guard_mutex); |
1367 | 1367 | ||
1368 | out_free: | 1368 | out_free: |
1369 | free_bprm(bprm); | 1369 | free_bprm(bprm); |
diff --git a/fs/exofs/osd.c b/fs/exofs/osd.c index b249ae97fb15..06ca92672eb5 100644 --- a/fs/exofs/osd.c +++ b/fs/exofs/osd.c | |||
@@ -50,10 +50,10 @@ int exofs_check_ok_resid(struct osd_request *or, u64 *in_resid, u64 *out_resid) | |||
50 | 50 | ||
51 | /* FIXME: should be include in osd_sense_info */ | 51 | /* FIXME: should be include in osd_sense_info */ |
52 | if (in_resid) | 52 | if (in_resid) |
53 | *in_resid = or->in.req ? or->in.req->data_len : 0; | 53 | *in_resid = or->in.req ? or->in.req->resid_len : 0; |
54 | 54 | ||
55 | if (out_resid) | 55 | if (out_resid) |
56 | *out_resid = or->out.req ? or->out.req->data_len : 0; | 56 | *out_resid = or->out.req ? or->out.req->resid_len : 0; |
57 | 57 | ||
58 | return ret; | 58 | return ret; |
59 | } | 59 | } |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 5c4afe652245..e3c748faf2db 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -1093,6 +1093,7 @@ failed_mount: | |||
1093 | brelse(bh); | 1093 | brelse(bh); |
1094 | failed_sbi: | 1094 | failed_sbi: |
1095 | sb->s_fs_info = NULL; | 1095 | sb->s_fs_info = NULL; |
1096 | kfree(sbi->s_blockgroup_lock); | ||
1096 | kfree(sbi); | 1097 | kfree(sbi); |
1097 | return ret; | 1098 | return ret; |
1098 | } | 1099 | } |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 599dbfe504c3..3c70d52afb10 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -1696,7 +1696,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1696 | goto failed_mount; | 1696 | goto failed_mount; |
1697 | } | 1697 | } |
1698 | 1698 | ||
1699 | hblock = bdev_hardsect_size(sb->s_bdev); | 1699 | hblock = bdev_logical_block_size(sb->s_bdev); |
1700 | if (sb->s_blocksize != blocksize) { | 1700 | if (sb->s_blocksize != blocksize) { |
1701 | /* | 1701 | /* |
1702 | * Make sure the blocksize for the filesystem is larger | 1702 | * Make sure the blocksize for the filesystem is larger |
@@ -2021,6 +2021,7 @@ failed_mount: | |||
2021 | brelse(bh); | 2021 | brelse(bh); |
2022 | out_fail: | 2022 | out_fail: |
2023 | sb->s_fs_info = NULL; | 2023 | sb->s_fs_info = NULL; |
2024 | kfree(sbi->s_blockgroup_lock); | ||
2024 | kfree(sbi); | 2025 | kfree(sbi); |
2025 | lock_kernel(); | 2026 | lock_kernel(); |
2026 | return ret; | 2027 | return ret; |
@@ -2119,7 +2120,7 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb, | |||
2119 | } | 2120 | } |
2120 | 2121 | ||
2121 | blocksize = sb->s_blocksize; | 2122 | blocksize = sb->s_blocksize; |
2122 | hblock = bdev_hardsect_size(bdev); | 2123 | hblock = bdev_logical_block_size(bdev); |
2123 | if (blocksize < hblock) { | 2124 | if (blocksize < hblock) { |
2124 | printk(KERN_ERR | 2125 | printk(KERN_ERR |
2125 | "EXT3-fs: blocksize too small for journal device.\n"); | 2126 | "EXT3-fs: blocksize too small for journal device.\n"); |
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index a8ff003a00f7..8a34710ecf40 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile | |||
@@ -5,8 +5,8 @@ | |||
5 | obj-$(CONFIG_EXT4_FS) += ext4.o | 5 | obj-$(CONFIG_EXT4_FS) += ext4.o |
6 | 6 | ||
7 | ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ | 7 | ext4-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ |
8 | ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \ | 8 | ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \ |
9 | ext4_jbd2.o migrate.o mballoc.o | 9 | ext4_jbd2.o migrate.o mballoc.o block_validity.o |
10 | 10 | ||
11 | ext4-$(CONFIG_EXT4_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o | 11 | ext4-$(CONFIG_EXT4_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o |
12 | ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o | 12 | ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 53c72ad85877..e2126d70dff5 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
20 | #include "ext4.h" | 20 | #include "ext4.h" |
21 | #include "ext4_jbd2.h" | 21 | #include "ext4_jbd2.h" |
22 | #include "group.h" | ||
23 | #include "mballoc.h" | 22 | #include "mballoc.h" |
24 | 23 | ||
25 | /* | 24 | /* |
@@ -88,6 +87,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
88 | ext4_group_t block_group, struct ext4_group_desc *gdp) | 87 | ext4_group_t block_group, struct ext4_group_desc *gdp) |
89 | { | 88 | { |
90 | int bit, bit_max; | 89 | int bit, bit_max; |
90 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
91 | unsigned free_blocks, group_blocks; | 91 | unsigned free_blocks, group_blocks; |
92 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 92 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
93 | 93 | ||
@@ -123,7 +123,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
123 | bit_max += ext4_bg_num_gdb(sb, block_group); | 123 | bit_max += ext4_bg_num_gdb(sb, block_group); |
124 | } | 124 | } |
125 | 125 | ||
126 | if (block_group == sbi->s_groups_count - 1) { | 126 | if (block_group == ngroups - 1) { |
127 | /* | 127 | /* |
128 | * Even though mke2fs always initialize first and last group | 128 | * Even though mke2fs always initialize first and last group |
129 | * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need | 129 | * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need |
@@ -131,7 +131,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, | |||
131 | */ | 131 | */ |
132 | group_blocks = ext4_blocks_count(sbi->s_es) - | 132 | group_blocks = ext4_blocks_count(sbi->s_es) - |
133 | le32_to_cpu(sbi->s_es->s_first_data_block) - | 133 | le32_to_cpu(sbi->s_es->s_first_data_block) - |
134 | (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count - 1)); | 134 | (EXT4_BLOCKS_PER_GROUP(sb) * (ngroups - 1)); |
135 | } else { | 135 | } else { |
136 | group_blocks = EXT4_BLOCKS_PER_GROUP(sb); | 136 | group_blocks = EXT4_BLOCKS_PER_GROUP(sb); |
137 | } | 137 | } |
@@ -205,18 +205,18 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, | |||
205 | { | 205 | { |
206 | unsigned int group_desc; | 206 | unsigned int group_desc; |
207 | unsigned int offset; | 207 | unsigned int offset; |
208 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
208 | struct ext4_group_desc *desc; | 209 | struct ext4_group_desc *desc; |
209 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 210 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
210 | 211 | ||
211 | if (block_group >= sbi->s_groups_count) { | 212 | if (block_group >= ngroups) { |
212 | ext4_error(sb, "ext4_get_group_desc", | 213 | ext4_error(sb, "ext4_get_group_desc", |
213 | "block_group >= groups_count - " | 214 | "block_group >= groups_count - " |
214 | "block_group = %u, groups_count = %u", | 215 | "block_group = %u, groups_count = %u", |
215 | block_group, sbi->s_groups_count); | 216 | block_group, ngroups); |
216 | 217 | ||
217 | return NULL; | 218 | return NULL; |
218 | } | 219 | } |
219 | smp_rmb(); | ||
220 | 220 | ||
221 | group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); | 221 | group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); |
222 | offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); | 222 | offset = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); |
@@ -326,16 +326,16 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
326 | unlock_buffer(bh); | 326 | unlock_buffer(bh); |
327 | return bh; | 327 | return bh; |
328 | } | 328 | } |
329 | spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 329 | ext4_lock_group(sb, block_group); |
330 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 330 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { |
331 | ext4_init_block_bitmap(sb, bh, block_group, desc); | 331 | ext4_init_block_bitmap(sb, bh, block_group, desc); |
332 | set_bitmap_uptodate(bh); | 332 | set_bitmap_uptodate(bh); |
333 | set_buffer_uptodate(bh); | 333 | set_buffer_uptodate(bh); |
334 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 334 | ext4_unlock_group(sb, block_group); |
335 | unlock_buffer(bh); | 335 | unlock_buffer(bh); |
336 | return bh; | 336 | return bh; |
337 | } | 337 | } |
338 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 338 | ext4_unlock_group(sb, block_group); |
339 | if (buffer_uptodate(bh)) { | 339 | if (buffer_uptodate(bh)) { |
340 | /* | 340 | /* |
341 | * if not uninit if bh is uptodate, | 341 | * if not uninit if bh is uptodate, |
@@ -451,7 +451,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, | |||
451 | down_write(&grp->alloc_sem); | 451 | down_write(&grp->alloc_sem); |
452 | for (i = 0, blocks_freed = 0; i < count; i++) { | 452 | for (i = 0, blocks_freed = 0; i < count; i++) { |
453 | BUFFER_TRACE(bitmap_bh, "clear bit"); | 453 | BUFFER_TRACE(bitmap_bh, "clear bit"); |
454 | if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), | 454 | if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), |
455 | bit + i, bitmap_bh->b_data)) { | 455 | bit + i, bitmap_bh->b_data)) { |
456 | ext4_error(sb, __func__, | 456 | ext4_error(sb, __func__, |
457 | "bit already cleared for block %llu", | 457 | "bit already cleared for block %llu", |
@@ -461,11 +461,11 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, | |||
461 | blocks_freed++; | 461 | blocks_freed++; |
462 | } | 462 | } |
463 | } | 463 | } |
464 | spin_lock(sb_bgl_lock(sbi, block_group)); | 464 | ext4_lock_group(sb, block_group); |
465 | blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc); | 465 | blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc); |
466 | ext4_free_blks_set(sb, desc, blk_free_count); | 466 | ext4_free_blks_set(sb, desc, blk_free_count); |
467 | desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); | 467 | desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); |
468 | spin_unlock(sb_bgl_lock(sbi, block_group)); | 468 | ext4_unlock_group(sb, block_group); |
469 | percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); | 469 | percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); |
470 | 470 | ||
471 | if (sbi->s_log_groups_per_flex) { | 471 | if (sbi->s_log_groups_per_flex) { |
@@ -665,7 +665,7 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
665 | ext4_fsblk_t desc_count; | 665 | ext4_fsblk_t desc_count; |
666 | struct ext4_group_desc *gdp; | 666 | struct ext4_group_desc *gdp; |
667 | ext4_group_t i; | 667 | ext4_group_t i; |
668 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | 668 | ext4_group_t ngroups = ext4_get_groups_count(sb); |
669 | #ifdef EXT4FS_DEBUG | 669 | #ifdef EXT4FS_DEBUG |
670 | struct ext4_super_block *es; | 670 | struct ext4_super_block *es; |
671 | ext4_fsblk_t bitmap_count; | 671 | ext4_fsblk_t bitmap_count; |
@@ -677,7 +677,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
677 | bitmap_count = 0; | 677 | bitmap_count = 0; |
678 | gdp = NULL; | 678 | gdp = NULL; |
679 | 679 | ||
680 | smp_rmb(); | ||
681 | for (i = 0; i < ngroups; i++) { | 680 | for (i = 0; i < ngroups; i++) { |
682 | gdp = ext4_get_group_desc(sb, i, NULL); | 681 | gdp = ext4_get_group_desc(sb, i, NULL); |
683 | if (!gdp) | 682 | if (!gdp) |
@@ -700,7 +699,6 @@ ext4_fsblk_t ext4_count_free_blocks(struct super_block *sb) | |||
700 | return bitmap_count; | 699 | return bitmap_count; |
701 | #else | 700 | #else |
702 | desc_count = 0; | 701 | desc_count = 0; |
703 | smp_rmb(); | ||
704 | for (i = 0; i < ngroups; i++) { | 702 | for (i = 0; i < ngroups; i++) { |
705 | gdp = ext4_get_group_desc(sb, i, NULL); | 703 | gdp = ext4_get_group_desc(sb, i, NULL); |
706 | if (!gdp) | 704 | if (!gdp) |
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c new file mode 100644 index 000000000000..50784ef07563 --- /dev/null +++ b/fs/ext4/block_validity.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * linux/fs/ext4/block_validity.c | ||
3 | * | ||
4 | * Copyright (C) 2009 | ||
5 | * Theodore Ts'o (tytso@mit.edu) | ||
6 | * | ||
7 | * Track which blocks in the filesystem are metadata blocks that | ||
8 | * should never be used as data blocks by files or directories. | ||
9 | */ | ||
10 | |||
11 | #include <linux/time.h> | ||
12 | #include <linux/fs.h> | ||
13 | #include <linux/namei.h> | ||
14 | #include <linux/quotaops.h> | ||
15 | #include <linux/buffer_head.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/swap.h> | ||
18 | #include <linux/pagemap.h> | ||
19 | #include <linux/version.h> | ||
20 | #include <linux/blkdev.h> | ||
21 | #include <linux/mutex.h> | ||
22 | #include "ext4.h" | ||
23 | |||
24 | struct ext4_system_zone { | ||
25 | struct rb_node node; | ||
26 | ext4_fsblk_t start_blk; | ||
27 | unsigned int count; | ||
28 | }; | ||
29 | |||
30 | static struct kmem_cache *ext4_system_zone_cachep; | ||
31 | |||
32 | int __init init_ext4_system_zone(void) | ||
33 | { | ||
34 | ext4_system_zone_cachep = KMEM_CACHE(ext4_system_zone, | ||
35 | SLAB_RECLAIM_ACCOUNT); | ||
36 | if (ext4_system_zone_cachep == NULL) | ||
37 | return -ENOMEM; | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | void exit_ext4_system_zone(void) | ||
42 | { | ||
43 | kmem_cache_destroy(ext4_system_zone_cachep); | ||
44 | } | ||
45 | |||
46 | static inline int can_merge(struct ext4_system_zone *entry1, | ||
47 | struct ext4_system_zone *entry2) | ||
48 | { | ||
49 | if ((entry1->start_blk + entry1->count) == entry2->start_blk) | ||
50 | return 1; | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * Mark a range of blocks as belonging to the "system zone" --- that | ||
56 | * is, filesystem metadata blocks which should never be used by | ||
57 | * inodes. | ||
58 | */ | ||
59 | static int add_system_zone(struct ext4_sb_info *sbi, | ||
60 | ext4_fsblk_t start_blk, | ||
61 | unsigned int count) | ||
62 | { | ||
63 | struct ext4_system_zone *new_entry = NULL, *entry; | ||
64 | struct rb_node **n = &sbi->system_blks.rb_node, *node; | ||
65 | struct rb_node *parent = NULL, *new_node = NULL; | ||
66 | |||
67 | while (*n) { | ||
68 | parent = *n; | ||
69 | entry = rb_entry(parent, struct ext4_system_zone, node); | ||
70 | if (start_blk < entry->start_blk) | ||
71 | n = &(*n)->rb_left; | ||
72 | else if (start_blk >= (entry->start_blk + entry->count)) | ||
73 | n = &(*n)->rb_right; | ||
74 | else { | ||
75 | if (start_blk + count > (entry->start_blk + | ||
76 | entry->count)) | ||
77 | entry->count = (start_blk + count - | ||
78 | entry->start_blk); | ||
79 | new_node = *n; | ||
80 | new_entry = rb_entry(new_node, struct ext4_system_zone, | ||
81 | node); | ||
82 | break; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | if (!new_entry) { | ||
87 | new_entry = kmem_cache_alloc(ext4_system_zone_cachep, | ||
88 | GFP_KERNEL); | ||
89 | if (!new_entry) | ||
90 | return -ENOMEM; | ||
91 | new_entry->start_blk = start_blk; | ||
92 | new_entry->count = count; | ||
93 | new_node = &new_entry->node; | ||
94 | |||
95 | rb_link_node(new_node, parent, n); | ||
96 | rb_insert_color(new_node, &sbi->system_blks); | ||
97 | } | ||
98 | |||
99 | /* Can we merge to the left? */ | ||
100 | node = rb_prev(new_node); | ||
101 | if (node) { | ||
102 | entry = rb_entry(node, struct ext4_system_zone, node); | ||
103 | if (can_merge(entry, new_entry)) { | ||
104 | new_entry->start_blk = entry->start_blk; | ||
105 | new_entry->count += entry->count; | ||
106 | rb_erase(node, &sbi->system_blks); | ||
107 | kmem_cache_free(ext4_system_zone_cachep, entry); | ||
108 | } | ||
109 | } | ||
110 | |||
111 | /* Can we merge to the right? */ | ||
112 | node = rb_next(new_node); | ||
113 | if (node) { | ||
114 | entry = rb_entry(node, struct ext4_system_zone, node); | ||
115 | if (can_merge(new_entry, entry)) { | ||
116 | new_entry->count += entry->count; | ||
117 | rb_erase(node, &sbi->system_blks); | ||
118 | kmem_cache_free(ext4_system_zone_cachep, entry); | ||
119 | } | ||
120 | } | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static void debug_print_tree(struct ext4_sb_info *sbi) | ||
125 | { | ||
126 | struct rb_node *node; | ||
127 | struct ext4_system_zone *entry; | ||
128 | int first = 1; | ||
129 | |||
130 | printk(KERN_INFO "System zones: "); | ||
131 | node = rb_first(&sbi->system_blks); | ||
132 | while (node) { | ||
133 | entry = rb_entry(node, struct ext4_system_zone, node); | ||
134 | printk("%s%llu-%llu", first ? "" : ", ", | ||
135 | entry->start_blk, entry->start_blk + entry->count - 1); | ||
136 | first = 0; | ||
137 | node = rb_next(node); | ||
138 | } | ||
139 | printk("\n"); | ||
140 | } | ||
141 | |||
142 | int ext4_setup_system_zone(struct super_block *sb) | ||
143 | { | ||
144 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
145 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
146 | struct ext4_group_desc *gdp; | ||
147 | ext4_group_t i; | ||
148 | int flex_size = ext4_flex_bg_size(sbi); | ||
149 | int ret; | ||
150 | |||
151 | if (!test_opt(sb, BLOCK_VALIDITY)) { | ||
152 | if (EXT4_SB(sb)->system_blks.rb_node) | ||
153 | ext4_release_system_zone(sb); | ||
154 | return 0; | ||
155 | } | ||
156 | if (EXT4_SB(sb)->system_blks.rb_node) | ||
157 | return 0; | ||
158 | |||
159 | for (i=0; i < ngroups; i++) { | ||
160 | if (ext4_bg_has_super(sb, i) && | ||
161 | ((i < 5) || ((i % flex_size) == 0))) | ||
162 | add_system_zone(sbi, ext4_group_first_block_no(sb, i), | ||
163 | sbi->s_gdb_count + 1); | ||
164 | gdp = ext4_get_group_desc(sb, i, NULL); | ||
165 | ret = add_system_zone(sbi, ext4_block_bitmap(sb, gdp), 1); | ||
166 | if (ret) | ||
167 | return ret; | ||
168 | ret = add_system_zone(sbi, ext4_inode_bitmap(sb, gdp), 1); | ||
169 | if (ret) | ||
170 | return ret; | ||
171 | ret = add_system_zone(sbi, ext4_inode_table(sb, gdp), | ||
172 | sbi->s_itb_per_group); | ||
173 | if (ret) | ||
174 | return ret; | ||
175 | } | ||
176 | |||
177 | if (test_opt(sb, DEBUG)) | ||
178 | debug_print_tree(EXT4_SB(sb)); | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | /* Called when the filesystem is unmounted */ | ||
183 | void ext4_release_system_zone(struct super_block *sb) | ||
184 | { | ||
185 | struct rb_node *n = EXT4_SB(sb)->system_blks.rb_node; | ||
186 | struct rb_node *parent; | ||
187 | struct ext4_system_zone *entry; | ||
188 | |||
189 | while (n) { | ||
190 | /* Do the node's children first */ | ||
191 | if (n->rb_left) { | ||
192 | n = n->rb_left; | ||
193 | continue; | ||
194 | } | ||
195 | if (n->rb_right) { | ||
196 | n = n->rb_right; | ||
197 | continue; | ||
198 | } | ||
199 | /* | ||
200 | * The node has no children; free it, and then zero | ||
201 | * out parent's link to it. Finally go to the | ||
202 | * beginning of the loop and try to free the parent | ||
203 | * node. | ||
204 | */ | ||
205 | parent = rb_parent(n); | ||
206 | entry = rb_entry(n, struct ext4_system_zone, node); | ||
207 | kmem_cache_free(ext4_system_zone_cachep, entry); | ||
208 | if (!parent) | ||
209 | EXT4_SB(sb)->system_blks.rb_node = NULL; | ||
210 | else if (parent->rb_left == n) | ||
211 | parent->rb_left = NULL; | ||
212 | else if (parent->rb_right == n) | ||
213 | parent->rb_right = NULL; | ||
214 | n = parent; | ||
215 | } | ||
216 | EXT4_SB(sb)->system_blks.rb_node = NULL; | ||
217 | } | ||
218 | |||
219 | /* | ||
220 | * Returns 1 if the passed-in block region (start_blk, | ||
221 | * start_blk+count) is valid; 0 if some part of the block region | ||
222 | * overlaps with filesystem metadata blocks. | ||
223 | */ | ||
224 | int ext4_data_block_valid(struct ext4_sb_info *sbi, ext4_fsblk_t start_blk, | ||
225 | unsigned int count) | ||
226 | { | ||
227 | struct ext4_system_zone *entry; | ||
228 | struct rb_node *n = sbi->system_blks.rb_node; | ||
229 | |||
230 | if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) || | ||
231 | (start_blk + count > ext4_blocks_count(sbi->s_es))) | ||
232 | return 0; | ||
233 | while (n) { | ||
234 | entry = rb_entry(n, struct ext4_system_zone, node); | ||
235 | if (start_blk + count - 1 < entry->start_blk) | ||
236 | n = n->rb_left; | ||
237 | else if (start_blk >= (entry->start_blk + entry->count)) | ||
238 | n = n->rb_right; | ||
239 | else | ||
240 | return 0; | ||
241 | } | ||
242 | return 1; | ||
243 | } | ||
244 | |||
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index b64789929a65..9dc93168e262 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
@@ -131,8 +131,7 @@ static int ext4_readdir(struct file *filp, | |||
131 | struct buffer_head *bh = NULL; | 131 | struct buffer_head *bh = NULL; |
132 | 132 | ||
133 | map_bh.b_state = 0; | 133 | map_bh.b_state = 0; |
134 | err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh, | 134 | err = ext4_get_blocks(NULL, inode, blk, 1, &map_bh, 0); |
135 | 0, 0, 0); | ||
136 | if (err > 0) { | 135 | if (err > 0) { |
137 | pgoff_t index = map_bh.b_blocknr >> | 136 | pgoff_t index = map_bh.b_blocknr >> |
138 | (PAGE_CACHE_SHIFT - inode->i_blkbits); | 137 | (PAGE_CACHE_SHIFT - inode->i_blkbits); |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index d0f15ef56de1..cc7d5edc38c9 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -21,7 +21,14 @@ | |||
21 | #include <linux/magic.h> | 21 | #include <linux/magic.h> |
22 | #include <linux/jbd2.h> | 22 | #include <linux/jbd2.h> |
23 | #include <linux/quota.h> | 23 | #include <linux/quota.h> |
24 | #include "ext4_i.h" | 24 | #include <linux/rwsem.h> |
25 | #include <linux/rbtree.h> | ||
26 | #include <linux/seqlock.h> | ||
27 | #include <linux/mutex.h> | ||
28 | #include <linux/timer.h> | ||
29 | #include <linux/wait.h> | ||
30 | #include <linux/blockgroup_lock.h> | ||
31 | #include <linux/percpu_counter.h> | ||
25 | 32 | ||
26 | /* | 33 | /* |
27 | * The fourth extended filesystem constants/structures | 34 | * The fourth extended filesystem constants/structures |
@@ -46,6 +53,19 @@ | |||
46 | #define ext4_debug(f, a...) do {} while (0) | 53 | #define ext4_debug(f, a...) do {} while (0) |
47 | #endif | 54 | #endif |
48 | 55 | ||
56 | /* data type for block offset of block group */ | ||
57 | typedef int ext4_grpblk_t; | ||
58 | |||
59 | /* data type for filesystem-wide blocks number */ | ||
60 | typedef unsigned long long ext4_fsblk_t; | ||
61 | |||
62 | /* data type for file logical block number */ | ||
63 | typedef __u32 ext4_lblk_t; | ||
64 | |||
65 | /* data type for block group number */ | ||
66 | typedef unsigned int ext4_group_t; | ||
67 | |||
68 | |||
49 | /* prefer goal again. length */ | 69 | /* prefer goal again. length */ |
50 | #define EXT4_MB_HINT_MERGE 1 | 70 | #define EXT4_MB_HINT_MERGE 1 |
51 | /* blocks already reserved */ | 71 | /* blocks already reserved */ |
@@ -179,9 +199,6 @@ struct flex_groups { | |||
179 | #define EXT4_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not in use */ | 199 | #define EXT4_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not in use */ |
180 | #define EXT4_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */ | 200 | #define EXT4_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */ |
181 | 201 | ||
182 | #ifdef __KERNEL__ | ||
183 | #include "ext4_sb.h" | ||
184 | #endif | ||
185 | /* | 202 | /* |
186 | * Macro-instructions used to manage group descriptors | 203 | * Macro-instructions used to manage group descriptors |
187 | */ | 204 | */ |
@@ -297,10 +314,23 @@ struct ext4_new_group_data { | |||
297 | }; | 314 | }; |
298 | 315 | ||
299 | /* | 316 | /* |
300 | * Following is used by preallocation code to tell get_blocks() that we | 317 | * Flags used by ext4_get_blocks() |
301 | * want uninitialzed extents. | ||
302 | */ | 318 | */ |
303 | #define EXT4_CREATE_UNINITIALIZED_EXT 2 | 319 | /* Allocate any needed blocks and/or convert an unitialized |
320 | extent to be an initialized ext4 */ | ||
321 | #define EXT4_GET_BLOCKS_CREATE 0x0001 | ||
322 | /* Request the creation of an unitialized extent */ | ||
323 | #define EXT4_GET_BLOCKS_UNINIT_EXT 0x0002 | ||
324 | #define EXT4_GET_BLOCKS_CREATE_UNINIT_EXT (EXT4_GET_BLOCKS_UNINIT_EXT|\ | ||
325 | EXT4_GET_BLOCKS_CREATE) | ||
326 | /* Caller is from the delayed allocation writeout path, | ||
327 | so set the magic i_delalloc_reserve_flag after taking the | ||
328 | inode allocation semaphore for */ | ||
329 | #define EXT4_GET_BLOCKS_DELALLOC_RESERVE 0x0004 | ||
330 | /* Call ext4_da_update_reserve_space() after successfully | ||
331 | allocating the blocks */ | ||
332 | #define EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE 0x0008 | ||
333 | |||
304 | 334 | ||
305 | /* | 335 | /* |
306 | * ioctl commands | 336 | * ioctl commands |
@@ -516,6 +546,110 @@ do { \ | |||
516 | #endif /* defined(__KERNEL__) || defined(__linux__) */ | 546 | #endif /* defined(__KERNEL__) || defined(__linux__) */ |
517 | 547 | ||
518 | /* | 548 | /* |
549 | * storage for cached extent | ||
550 | */ | ||
551 | struct ext4_ext_cache { | ||
552 | ext4_fsblk_t ec_start; | ||
553 | ext4_lblk_t ec_block; | ||
554 | __u32 ec_len; /* must be 32bit to return holes */ | ||
555 | __u32 ec_type; | ||
556 | }; | ||
557 | |||
558 | /* | ||
559 | * fourth extended file system inode data in memory | ||
560 | */ | ||
561 | struct ext4_inode_info { | ||
562 | __le32 i_data[15]; /* unconverted */ | ||
563 | __u32 i_flags; | ||
564 | ext4_fsblk_t i_file_acl; | ||
565 | __u32 i_dtime; | ||
566 | |||
567 | /* | ||
568 | * i_block_group is the number of the block group which contains | ||
569 | * this file's inode. Constant across the lifetime of the inode, | ||
570 | * it is ued for making block allocation decisions - we try to | ||
571 | * place a file's data blocks near its inode block, and new inodes | ||
572 | * near to their parent directory's inode. | ||
573 | */ | ||
574 | ext4_group_t i_block_group; | ||
575 | __u32 i_state; /* Dynamic state flags for ext4 */ | ||
576 | |||
577 | ext4_lblk_t i_dir_start_lookup; | ||
578 | #ifdef CONFIG_EXT4_FS_XATTR | ||
579 | /* | ||
580 | * Extended attributes can be read independently of the main file | ||
581 | * data. Taking i_mutex even when reading would cause contention | ||
582 | * between readers of EAs and writers of regular file data, so | ||
583 | * instead we synchronize on xattr_sem when reading or changing | ||
584 | * EAs. | ||
585 | */ | ||
586 | struct rw_semaphore xattr_sem; | ||
587 | #endif | ||
588 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | ||
589 | struct posix_acl *i_acl; | ||
590 | struct posix_acl *i_default_acl; | ||
591 | #endif | ||
592 | |||
593 | struct list_head i_orphan; /* unlinked but open inodes */ | ||
594 | |||
595 | /* | ||
596 | * i_disksize keeps track of what the inode size is ON DISK, not | ||
597 | * in memory. During truncate, i_size is set to the new size by | ||
598 | * the VFS prior to calling ext4_truncate(), but the filesystem won't | ||
599 | * set i_disksize to 0 until the truncate is actually under way. | ||
600 | * | ||
601 | * The intent is that i_disksize always represents the blocks which | ||
602 | * are used by this file. This allows recovery to restart truncate | ||
603 | * on orphans if we crash during truncate. We actually write i_disksize | ||
604 | * into the on-disk inode when writing inodes out, instead of i_size. | ||
605 | * | ||
606 | * The only time when i_disksize and i_size may be different is when | ||
607 | * a truncate is in progress. The only things which change i_disksize | ||
608 | * are ext4_get_block (growth) and ext4_truncate (shrinkth). | ||
609 | */ | ||
610 | loff_t i_disksize; | ||
611 | |||
612 | /* | ||
613 | * i_data_sem is for serialising ext4_truncate() against | ||
614 | * ext4_getblock(). In the 2.4 ext2 design, great chunks of inode's | ||
615 | * data tree are chopped off during truncate. We can't do that in | ||
616 | * ext4 because whenever we perform intermediate commits during | ||
617 | * truncate, the inode and all the metadata blocks *must* be in a | ||
618 | * consistent state which allows truncation of the orphans to restart | ||
619 | * during recovery. Hence we must fix the get_block-vs-truncate race | ||
620 | * by other means, so we have i_data_sem. | ||
621 | */ | ||
622 | struct rw_semaphore i_data_sem; | ||
623 | struct inode vfs_inode; | ||
624 | struct jbd2_inode jinode; | ||
625 | |||
626 | struct ext4_ext_cache i_cached_extent; | ||
627 | /* | ||
628 | * File creation time. Its function is same as that of | ||
629 | * struct timespec i_{a,c,m}time in the generic inode. | ||
630 | */ | ||
631 | struct timespec i_crtime; | ||
632 | |||
633 | /* mballoc */ | ||
634 | struct list_head i_prealloc_list; | ||
635 | spinlock_t i_prealloc_lock; | ||
636 | |||
637 | /* ialloc */ | ||
638 | ext4_group_t i_last_alloc_group; | ||
639 | |||
640 | /* allocation reservation info for delalloc */ | ||
641 | unsigned int i_reserved_data_blocks; | ||
642 | unsigned int i_reserved_meta_blocks; | ||
643 | unsigned int i_allocated_meta_blocks; | ||
644 | unsigned short i_delalloc_reserved_flag; | ||
645 | |||
646 | /* on-disk additional length */ | ||
647 | __u16 i_extra_isize; | ||
648 | |||
649 | spinlock_t i_block_reservation_lock; | ||
650 | }; | ||
651 | |||
652 | /* | ||
519 | * File system states | 653 | * File system states |
520 | */ | 654 | */ |
521 | #define EXT4_VALID_FS 0x0001 /* Unmounted cleanly */ | 655 | #define EXT4_VALID_FS 0x0001 /* Unmounted cleanly */ |
@@ -560,6 +694,7 @@ do { \ | |||
560 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ | 694 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ |
561 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ | 695 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ |
562 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ | 696 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ |
697 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ | ||
563 | 698 | ||
564 | /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ | 699 | /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ |
565 | #ifndef _LINUX_EXT2_FS_H | 700 | #ifndef _LINUX_EXT2_FS_H |
@@ -689,6 +824,137 @@ struct ext4_super_block { | |||
689 | }; | 824 | }; |
690 | 825 | ||
691 | #ifdef __KERNEL__ | 826 | #ifdef __KERNEL__ |
827 | /* | ||
828 | * fourth extended-fs super-block data in memory | ||
829 | */ | ||
830 | struct ext4_sb_info { | ||
831 | unsigned long s_desc_size; /* Size of a group descriptor in bytes */ | ||
832 | unsigned long s_inodes_per_block;/* Number of inodes per block */ | ||
833 | unsigned long s_blocks_per_group;/* Number of blocks in a group */ | ||
834 | unsigned long s_inodes_per_group;/* Number of inodes in a group */ | ||
835 | unsigned long s_itb_per_group; /* Number of inode table blocks per group */ | ||
836 | unsigned long s_gdb_count; /* Number of group descriptor blocks */ | ||
837 | unsigned long s_desc_per_block; /* Number of group descriptors per block */ | ||
838 | ext4_group_t s_groups_count; /* Number of groups in the fs */ | ||
839 | unsigned long s_overhead_last; /* Last calculated overhead */ | ||
840 | unsigned long s_blocks_last; /* Last seen block count */ | ||
841 | loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */ | ||
842 | struct buffer_head * s_sbh; /* Buffer containing the super block */ | ||
843 | struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */ | ||
844 | struct buffer_head **s_group_desc; | ||
845 | unsigned long s_mount_opt; | ||
846 | ext4_fsblk_t s_sb_block; | ||
847 | uid_t s_resuid; | ||
848 | gid_t s_resgid; | ||
849 | unsigned short s_mount_state; | ||
850 | unsigned short s_pad; | ||
851 | int s_addr_per_block_bits; | ||
852 | int s_desc_per_block_bits; | ||
853 | int s_inode_size; | ||
854 | int s_first_ino; | ||
855 | unsigned int s_inode_readahead_blks; | ||
856 | spinlock_t s_next_gen_lock; | ||
857 | u32 s_next_generation; | ||
858 | u32 s_hash_seed[4]; | ||
859 | int s_def_hash_version; | ||
860 | int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ | ||
861 | struct percpu_counter s_freeblocks_counter; | ||
862 | struct percpu_counter s_freeinodes_counter; | ||
863 | struct percpu_counter s_dirs_counter; | ||
864 | struct percpu_counter s_dirtyblocks_counter; | ||
865 | struct blockgroup_lock *s_blockgroup_lock; | ||
866 | struct proc_dir_entry *s_proc; | ||
867 | struct kobject s_kobj; | ||
868 | struct completion s_kobj_unregister; | ||
869 | |||
870 | /* Journaling */ | ||
871 | struct inode *s_journal_inode; | ||
872 | struct journal_s *s_journal; | ||
873 | struct list_head s_orphan; | ||
874 | struct mutex s_orphan_lock; | ||
875 | struct mutex s_resize_lock; | ||
876 | unsigned long s_commit_interval; | ||
877 | u32 s_max_batch_time; | ||
878 | u32 s_min_batch_time; | ||
879 | struct block_device *journal_bdev; | ||
880 | #ifdef CONFIG_JBD2_DEBUG | ||
881 | struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */ | ||
882 | wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */ | ||
883 | #endif | ||
884 | #ifdef CONFIG_QUOTA | ||
885 | char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ | ||
886 | int s_jquota_fmt; /* Format of quota to use */ | ||
887 | #endif | ||
888 | unsigned int s_want_extra_isize; /* New inodes should reserve # bytes */ | ||
889 | struct rb_root system_blks; | ||
890 | |||
891 | #ifdef EXTENTS_STATS | ||
892 | /* ext4 extents stats */ | ||
893 | unsigned long s_ext_min; | ||
894 | unsigned long s_ext_max; | ||
895 | unsigned long s_depth_max; | ||
896 | spinlock_t s_ext_stats_lock; | ||
897 | unsigned long s_ext_blocks; | ||
898 | unsigned long s_ext_extents; | ||
899 | #endif | ||
900 | |||
901 | /* for buddy allocator */ | ||
902 | struct ext4_group_info ***s_group_info; | ||
903 | struct inode *s_buddy_cache; | ||
904 | long s_blocks_reserved; | ||
905 | spinlock_t s_reserve_lock; | ||
906 | spinlock_t s_md_lock; | ||
907 | tid_t s_last_transaction; | ||
908 | unsigned short *s_mb_offsets; | ||
909 | unsigned int *s_mb_maxs; | ||
910 | |||
911 | /* tunables */ | ||
912 | unsigned long s_stripe; | ||
913 | unsigned int s_mb_stream_request; | ||
914 | unsigned int s_mb_max_to_scan; | ||
915 | unsigned int s_mb_min_to_scan; | ||
916 | unsigned int s_mb_stats; | ||
917 | unsigned int s_mb_order2_reqs; | ||
918 | unsigned int s_mb_group_prealloc; | ||
919 | /* where last allocation was done - for stream allocation */ | ||
920 | unsigned long s_mb_last_group; | ||
921 | unsigned long s_mb_last_start; | ||
922 | |||
923 | /* history to debug policy */ | ||
924 | struct ext4_mb_history *s_mb_history; | ||
925 | int s_mb_history_cur; | ||
926 | int s_mb_history_max; | ||
927 | int s_mb_history_num; | ||
928 | spinlock_t s_mb_history_lock; | ||
929 | int s_mb_history_filter; | ||
930 | |||
931 | /* stats for buddy allocator */ | ||
932 | spinlock_t s_mb_pa_lock; | ||
933 | atomic_t s_bal_reqs; /* number of reqs with len > 1 */ | ||
934 | atomic_t s_bal_success; /* we found long enough chunks */ | ||
935 | atomic_t s_bal_allocated; /* in blocks */ | ||
936 | atomic_t s_bal_ex_scanned; /* total extents scanned */ | ||
937 | atomic_t s_bal_goals; /* goal hits */ | ||
938 | atomic_t s_bal_breaks; /* too long searches */ | ||
939 | atomic_t s_bal_2orders; /* 2^order hits */ | ||
940 | spinlock_t s_bal_lock; | ||
941 | unsigned long s_mb_buddies_generated; | ||
942 | unsigned long long s_mb_generation_time; | ||
943 | atomic_t s_mb_lost_chunks; | ||
944 | atomic_t s_mb_preallocated; | ||
945 | atomic_t s_mb_discarded; | ||
946 | |||
947 | /* locality groups */ | ||
948 | struct ext4_locality_group *s_locality_groups; | ||
949 | |||
950 | /* for write statistics */ | ||
951 | unsigned long s_sectors_written_start; | ||
952 | u64 s_kbytes_written; | ||
953 | |||
954 | unsigned int s_log_groups_per_flex; | ||
955 | struct flex_groups *s_flex_groups; | ||
956 | }; | ||
957 | |||
692 | static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) | 958 | static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) |
693 | { | 959 | { |
694 | return sb->s_fs_info; | 960 | return sb->s_fs_info; |
@@ -704,7 +970,6 @@ static inline struct timespec ext4_current_time(struct inode *inode) | |||
704 | current_fs_time(inode->i_sb) : CURRENT_TIME_SEC; | 970 | current_fs_time(inode->i_sb) : CURRENT_TIME_SEC; |
705 | } | 971 | } |
706 | 972 | ||
707 | |||
708 | static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) | 973 | static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) |
709 | { | 974 | { |
710 | return ino == EXT4_ROOT_INO || | 975 | return ino == EXT4_ROOT_INO || |
@@ -1014,6 +1279,14 @@ extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, | |||
1014 | ext4_group_t block_group, | 1279 | ext4_group_t block_group, |
1015 | struct buffer_head ** bh); | 1280 | struct buffer_head ** bh); |
1016 | extern int ext4_should_retry_alloc(struct super_block *sb, int *retries); | 1281 | extern int ext4_should_retry_alloc(struct super_block *sb, int *retries); |
1282 | struct buffer_head *ext4_read_block_bitmap(struct super_block *sb, | ||
1283 | ext4_group_t block_group); | ||
1284 | extern unsigned ext4_init_block_bitmap(struct super_block *sb, | ||
1285 | struct buffer_head *bh, | ||
1286 | ext4_group_t group, | ||
1287 | struct ext4_group_desc *desc); | ||
1288 | #define ext4_free_blocks_after_init(sb, group, desc) \ | ||
1289 | ext4_init_block_bitmap(sb, NULL, group, desc) | ||
1017 | 1290 | ||
1018 | /* dir.c */ | 1291 | /* dir.c */ |
1019 | extern int ext4_check_dir_entry(const char *, struct inode *, | 1292 | extern int ext4_check_dir_entry(const char *, struct inode *, |
@@ -1038,6 +1311,11 @@ extern struct inode * ext4_orphan_get(struct super_block *, unsigned long); | |||
1038 | extern unsigned long ext4_count_free_inodes(struct super_block *); | 1311 | extern unsigned long ext4_count_free_inodes(struct super_block *); |
1039 | extern unsigned long ext4_count_dirs(struct super_block *); | 1312 | extern unsigned long ext4_count_dirs(struct super_block *); |
1040 | extern void ext4_check_inodes_bitmap(struct super_block *); | 1313 | extern void ext4_check_inodes_bitmap(struct super_block *); |
1314 | extern unsigned ext4_init_inode_bitmap(struct super_block *sb, | ||
1315 | struct buffer_head *bh, | ||
1316 | ext4_group_t group, | ||
1317 | struct ext4_group_desc *desc); | ||
1318 | extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap); | ||
1041 | 1319 | ||
1042 | /* mballoc.c */ | 1320 | /* mballoc.c */ |
1043 | extern long ext4_mb_stats; | 1321 | extern long ext4_mb_stats; |
@@ -1123,6 +1401,8 @@ extern void ext4_abort(struct super_block *, const char *, const char *, ...) | |||
1123 | __attribute__ ((format (printf, 3, 4))); | 1401 | __attribute__ ((format (printf, 3, 4))); |
1124 | extern void ext4_warning(struct super_block *, const char *, const char *, ...) | 1402 | extern void ext4_warning(struct super_block *, const char *, const char *, ...) |
1125 | __attribute__ ((format (printf, 3, 4))); | 1403 | __attribute__ ((format (printf, 3, 4))); |
1404 | extern void ext4_msg(struct super_block *, const char *, const char *, ...) | ||
1405 | __attribute__ ((format (printf, 3, 4))); | ||
1126 | extern void ext4_grp_locked_error(struct super_block *, ext4_group_t, | 1406 | extern void ext4_grp_locked_error(struct super_block *, ext4_group_t, |
1127 | const char *, const char *, ...) | 1407 | const char *, const char *, ...) |
1128 | __attribute__ ((format (printf, 4, 5))); | 1408 | __attribute__ ((format (printf, 4, 5))); |
@@ -1161,6 +1441,10 @@ extern void ext4_used_dirs_set(struct super_block *sb, | |||
1161 | struct ext4_group_desc *bg, __u32 count); | 1441 | struct ext4_group_desc *bg, __u32 count); |
1162 | extern void ext4_itable_unused_set(struct super_block *sb, | 1442 | extern void ext4_itable_unused_set(struct super_block *sb, |
1163 | struct ext4_group_desc *bg, __u32 count); | 1443 | struct ext4_group_desc *bg, __u32 count); |
1444 | extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group, | ||
1445 | struct ext4_group_desc *gdp); | ||
1446 | extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group, | ||
1447 | struct ext4_group_desc *gdp); | ||
1164 | 1448 | ||
1165 | static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) | 1449 | static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) |
1166 | { | 1450 | { |
@@ -1228,6 +1512,18 @@ struct ext4_group_info *ext4_get_group_info(struct super_block *sb, | |||
1228 | return grp_info[indexv][indexh]; | 1512 | return grp_info[indexv][indexh]; |
1229 | } | 1513 | } |
1230 | 1514 | ||
1515 | /* | ||
1516 | * Reading s_groups_count requires using smp_rmb() afterwards. See | ||
1517 | * the locking protocol documented in the comments of ext4_group_add() | ||
1518 | * in resize.c | ||
1519 | */ | ||
1520 | static inline ext4_group_t ext4_get_groups_count(struct super_block *sb) | ||
1521 | { | ||
1522 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | ||
1523 | |||
1524 | smp_rmb(); | ||
1525 | return ngroups; | ||
1526 | } | ||
1231 | 1527 | ||
1232 | static inline ext4_group_t ext4_flex_group(struct ext4_sb_info *sbi, | 1528 | static inline ext4_group_t ext4_flex_group(struct ext4_sb_info *sbi, |
1233 | ext4_group_t block_group) | 1529 | ext4_group_t block_group) |
@@ -1283,33 +1579,25 @@ struct ext4_group_info { | |||
1283 | }; | 1579 | }; |
1284 | 1580 | ||
1285 | #define EXT4_GROUP_INFO_NEED_INIT_BIT 0 | 1581 | #define EXT4_GROUP_INFO_NEED_INIT_BIT 0 |
1286 | #define EXT4_GROUP_INFO_LOCKED_BIT 1 | ||
1287 | 1582 | ||
1288 | #define EXT4_MB_GRP_NEED_INIT(grp) \ | 1583 | #define EXT4_MB_GRP_NEED_INIT(grp) \ |
1289 | (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state))) | 1584 | (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state))) |
1290 | 1585 | ||
1291 | static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) | 1586 | static inline spinlock_t *ext4_group_lock_ptr(struct super_block *sb, |
1587 | ext4_group_t group) | ||
1292 | { | 1588 | { |
1293 | struct ext4_group_info *grinfo = ext4_get_group_info(sb, group); | 1589 | return bgl_lock_ptr(EXT4_SB(sb)->s_blockgroup_lock, group); |
1294 | |||
1295 | bit_spin_lock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state)); | ||
1296 | } | 1590 | } |
1297 | 1591 | ||
1298 | static inline void ext4_unlock_group(struct super_block *sb, | 1592 | static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) |
1299 | ext4_group_t group) | ||
1300 | { | 1593 | { |
1301 | struct ext4_group_info *grinfo = ext4_get_group_info(sb, group); | 1594 | spin_lock(ext4_group_lock_ptr(sb, group)); |
1302 | |||
1303 | bit_spin_unlock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state)); | ||
1304 | } | 1595 | } |
1305 | 1596 | ||
1306 | static inline int ext4_is_group_locked(struct super_block *sb, | 1597 | static inline void ext4_unlock_group(struct super_block *sb, |
1307 | ext4_group_t group) | 1598 | ext4_group_t group) |
1308 | { | 1599 | { |
1309 | struct ext4_group_info *grinfo = ext4_get_group_info(sb, group); | 1600 | spin_unlock(ext4_group_lock_ptr(sb, group)); |
1310 | |||
1311 | return bit_spin_is_locked(EXT4_GROUP_INFO_LOCKED_BIT, | ||
1312 | &(grinfo->bb_state)); | ||
1313 | } | 1601 | } |
1314 | 1602 | ||
1315 | /* | 1603 | /* |
@@ -1326,11 +1614,21 @@ extern const struct file_operations ext4_file_operations; | |||
1326 | /* namei.c */ | 1614 | /* namei.c */ |
1327 | extern const struct inode_operations ext4_dir_inode_operations; | 1615 | extern const struct inode_operations ext4_dir_inode_operations; |
1328 | extern const struct inode_operations ext4_special_inode_operations; | 1616 | extern const struct inode_operations ext4_special_inode_operations; |
1617 | extern struct dentry *ext4_get_parent(struct dentry *child); | ||
1329 | 1618 | ||
1330 | /* symlink.c */ | 1619 | /* symlink.c */ |
1331 | extern const struct inode_operations ext4_symlink_inode_operations; | 1620 | extern const struct inode_operations ext4_symlink_inode_operations; |
1332 | extern const struct inode_operations ext4_fast_symlink_inode_operations; | 1621 | extern const struct inode_operations ext4_fast_symlink_inode_operations; |
1333 | 1622 | ||
1623 | /* block_validity */ | ||
1624 | extern void ext4_release_system_zone(struct super_block *sb); | ||
1625 | extern int ext4_setup_system_zone(struct super_block *sb); | ||
1626 | extern int __init init_ext4_system_zone(void); | ||
1627 | extern void exit_ext4_system_zone(void); | ||
1628 | extern int ext4_data_block_valid(struct ext4_sb_info *sbi, | ||
1629 | ext4_fsblk_t start_blk, | ||
1630 | unsigned int count); | ||
1631 | |||
1334 | /* extents.c */ | 1632 | /* extents.c */ |
1335 | extern int ext4_ext_tree_init(handle_t *handle, struct inode *); | 1633 | extern int ext4_ext_tree_init(handle_t *handle, struct inode *); |
1336 | extern int ext4_ext_writepage_trans_blocks(struct inode *, int); | 1634 | extern int ext4_ext_writepage_trans_blocks(struct inode *, int); |
@@ -1338,17 +1636,15 @@ extern int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, | |||
1338 | int chunk); | 1636 | int chunk); |
1339 | extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | 1637 | extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, |
1340 | ext4_lblk_t iblock, unsigned int max_blocks, | 1638 | ext4_lblk_t iblock, unsigned int max_blocks, |
1341 | struct buffer_head *bh_result, | 1639 | struct buffer_head *bh_result, int flags); |
1342 | int create, int extend_disksize); | ||
1343 | extern void ext4_ext_truncate(struct inode *); | 1640 | extern void ext4_ext_truncate(struct inode *); |
1344 | extern void ext4_ext_init(struct super_block *); | 1641 | extern void ext4_ext_init(struct super_block *); |
1345 | extern void ext4_ext_release(struct super_block *); | 1642 | extern void ext4_ext_release(struct super_block *); |
1346 | extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset, | 1643 | extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset, |
1347 | loff_t len); | 1644 | loff_t len); |
1348 | extern int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, | 1645 | extern int ext4_get_blocks(handle_t *handle, struct inode *inode, |
1349 | sector_t block, unsigned int max_blocks, | 1646 | sector_t block, unsigned int max_blocks, |
1350 | struct buffer_head *bh, int create, | 1647 | struct buffer_head *bh, int flags); |
1351 | int extend_disksize, int flag); | ||
1352 | extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 1648 | extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
1353 | __u64 start, __u64 len); | 1649 | __u64 start, __u64 len); |
1354 | 1650 | ||
diff --git a/fs/ext4/ext4_i.h b/fs/ext4/ext4_i.h deleted file mode 100644 index 4ce2187123aa..000000000000 --- a/fs/ext4/ext4_i.h +++ /dev/null | |||
@@ -1,140 +0,0 @@ | |||
1 | /* | ||
2 | * ext4_i.h | ||
3 | * | ||
4 | * Copyright (C) 1992, 1993, 1994, 1995 | ||
5 | * Remy Card (card@masi.ibp.fr) | ||
6 | * Laboratoire MASI - Institut Blaise Pascal | ||
7 | * Universite Pierre et Marie Curie (Paris VI) | ||
8 | * | ||
9 | * from | ||
10 | * | ||
11 | * linux/include/linux/minix_fs_i.h | ||
12 | * | ||
13 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
14 | */ | ||
15 | |||
16 | #ifndef _EXT4_I | ||
17 | #define _EXT4_I | ||
18 | |||
19 | #include <linux/rwsem.h> | ||
20 | #include <linux/rbtree.h> | ||
21 | #include <linux/seqlock.h> | ||
22 | #include <linux/mutex.h> | ||
23 | |||
24 | /* data type for block offset of block group */ | ||
25 | typedef int ext4_grpblk_t; | ||
26 | |||
27 | /* data type for filesystem-wide blocks number */ | ||
28 | typedef unsigned long long ext4_fsblk_t; | ||
29 | |||
30 | /* data type for file logical block number */ | ||
31 | typedef __u32 ext4_lblk_t; | ||
32 | |||
33 | /* data type for block group number */ | ||
34 | typedef unsigned int ext4_group_t; | ||
35 | |||
36 | /* | ||
37 | * storage for cached extent | ||
38 | */ | ||
39 | struct ext4_ext_cache { | ||
40 | ext4_fsblk_t ec_start; | ||
41 | ext4_lblk_t ec_block; | ||
42 | __u32 ec_len; /* must be 32bit to return holes */ | ||
43 | __u32 ec_type; | ||
44 | }; | ||
45 | |||
46 | /* | ||
47 | * fourth extended file system inode data in memory | ||
48 | */ | ||
49 | struct ext4_inode_info { | ||
50 | __le32 i_data[15]; /* unconverted */ | ||
51 | __u32 i_flags; | ||
52 | ext4_fsblk_t i_file_acl; | ||
53 | __u32 i_dtime; | ||
54 | |||
55 | /* | ||
56 | * i_block_group is the number of the block group which contains | ||
57 | * this file's inode. Constant across the lifetime of the inode, | ||
58 | * it is ued for making block allocation decisions - we try to | ||
59 | * place a file's data blocks near its inode block, and new inodes | ||
60 | * near to their parent directory's inode. | ||
61 | */ | ||
62 | ext4_group_t i_block_group; | ||
63 | __u32 i_state; /* Dynamic state flags for ext4 */ | ||
64 | |||
65 | ext4_lblk_t i_dir_start_lookup; | ||
66 | #ifdef CONFIG_EXT4_FS_XATTR | ||
67 | /* | ||
68 | * Extended attributes can be read independently of the main file | ||
69 | * data. Taking i_mutex even when reading would cause contention | ||
70 | * between readers of EAs and writers of regular file data, so | ||
71 | * instead we synchronize on xattr_sem when reading or changing | ||
72 | * EAs. | ||
73 | */ | ||
74 | struct rw_semaphore xattr_sem; | ||
75 | #endif | ||
76 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | ||
77 | struct posix_acl *i_acl; | ||
78 | struct posix_acl *i_default_acl; | ||
79 | #endif | ||
80 | |||
81 | struct list_head i_orphan; /* unlinked but open inodes */ | ||
82 | |||
83 | /* | ||
84 | * i_disksize keeps track of what the inode size is ON DISK, not | ||
85 | * in memory. During truncate, i_size is set to the new size by | ||
86 | * the VFS prior to calling ext4_truncate(), but the filesystem won't | ||
87 | * set i_disksize to 0 until the truncate is actually under way. | ||
88 | * | ||
89 | * The intent is that i_disksize always represents the blocks which | ||
90 | * are used by this file. This allows recovery to restart truncate | ||
91 | * on orphans if we crash during truncate. We actually write i_disksize | ||
92 | * into the on-disk inode when writing inodes out, instead of i_size. | ||
93 | * | ||
94 | * The only time when i_disksize and i_size may be different is when | ||
95 | * a truncate is in progress. The only things which change i_disksize | ||
96 | * are ext4_get_block (growth) and ext4_truncate (shrinkth). | ||
97 | */ | ||
98 | loff_t i_disksize; | ||
99 | |||
100 | /* | ||
101 | * i_data_sem is for serialising ext4_truncate() against | ||
102 | * ext4_getblock(). In the 2.4 ext2 design, great chunks of inode's | ||
103 | * data tree are chopped off during truncate. We can't do that in | ||
104 | * ext4 because whenever we perform intermediate commits during | ||
105 | * truncate, the inode and all the metadata blocks *must* be in a | ||
106 | * consistent state which allows truncation of the orphans to restart | ||
107 | * during recovery. Hence we must fix the get_block-vs-truncate race | ||
108 | * by other means, so we have i_data_sem. | ||
109 | */ | ||
110 | struct rw_semaphore i_data_sem; | ||
111 | struct inode vfs_inode; | ||
112 | struct jbd2_inode jinode; | ||
113 | |||
114 | struct ext4_ext_cache i_cached_extent; | ||
115 | /* | ||
116 | * File creation time. Its function is same as that of | ||
117 | * struct timespec i_{a,c,m}time in the generic inode. | ||
118 | */ | ||
119 | struct timespec i_crtime; | ||
120 | |||
121 | /* mballoc */ | ||
122 | struct list_head i_prealloc_list; | ||
123 | spinlock_t i_prealloc_lock; | ||
124 | |||
125 | /* ialloc */ | ||
126 | ext4_group_t i_last_alloc_group; | ||
127 | |||
128 | /* allocation reservation info for delalloc */ | ||
129 | unsigned int i_reserved_data_blocks; | ||
130 | unsigned int i_reserved_meta_blocks; | ||
131 | unsigned int i_allocated_meta_blocks; | ||
132 | unsigned short i_delalloc_reserved_flag; | ||
133 | |||
134 | /* on-disk additional length */ | ||
135 | __u16 i_extra_isize; | ||
136 | |||
137 | spinlock_t i_block_reservation_lock; | ||
138 | }; | ||
139 | |||
140 | #endif /* _EXT4_I */ | ||
diff --git a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h deleted file mode 100644 index 57b71fefbccf..000000000000 --- a/fs/ext4/ext4_sb.h +++ /dev/null | |||
@@ -1,161 +0,0 @@ | |||
1 | /* | ||
2 | * ext4_sb.h | ||
3 | * | ||
4 | * Copyright (C) 1992, 1993, 1994, 1995 | ||
5 | * Remy Card (card@masi.ibp.fr) | ||
6 | * Laboratoire MASI - Institut Blaise Pascal | ||
7 | * Universite Pierre et Marie Curie (Paris VI) | ||
8 | * | ||
9 | * from | ||
10 | * | ||
11 | * linux/include/linux/minix_fs_sb.h | ||
12 | * | ||
13 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
14 | */ | ||
15 | |||
16 | #ifndef _EXT4_SB | ||
17 | #define _EXT4_SB | ||
18 | |||
19 | #ifdef __KERNEL__ | ||
20 | #include <linux/timer.h> | ||
21 | #include <linux/wait.h> | ||
22 | #include <linux/blockgroup_lock.h> | ||
23 | #include <linux/percpu_counter.h> | ||
24 | #endif | ||
25 | #include <linux/rbtree.h> | ||
26 | |||
27 | /* | ||
28 | * fourth extended-fs super-block data in memory | ||
29 | */ | ||
30 | struct ext4_sb_info { | ||
31 | unsigned long s_desc_size; /* Size of a group descriptor in bytes */ | ||
32 | unsigned long s_inodes_per_block;/* Number of inodes per block */ | ||
33 | unsigned long s_blocks_per_group;/* Number of blocks in a group */ | ||
34 | unsigned long s_inodes_per_group;/* Number of inodes in a group */ | ||
35 | unsigned long s_itb_per_group; /* Number of inode table blocks per group */ | ||
36 | unsigned long s_gdb_count; /* Number of group descriptor blocks */ | ||
37 | unsigned long s_desc_per_block; /* Number of group descriptors per block */ | ||
38 | ext4_group_t s_groups_count; /* Number of groups in the fs */ | ||
39 | unsigned long s_overhead_last; /* Last calculated overhead */ | ||
40 | unsigned long s_blocks_last; /* Last seen block count */ | ||
41 | loff_t s_bitmap_maxbytes; /* max bytes for bitmap files */ | ||
42 | struct buffer_head * s_sbh; /* Buffer containing the super block */ | ||
43 | struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */ | ||
44 | struct buffer_head **s_group_desc; | ||
45 | unsigned long s_mount_opt; | ||
46 | ext4_fsblk_t s_sb_block; | ||
47 | uid_t s_resuid; | ||
48 | gid_t s_resgid; | ||
49 | unsigned short s_mount_state; | ||
50 | unsigned short s_pad; | ||
51 | int s_addr_per_block_bits; | ||
52 | int s_desc_per_block_bits; | ||
53 | int s_inode_size; | ||
54 | int s_first_ino; | ||
55 | unsigned int s_inode_readahead_blks; | ||
56 | spinlock_t s_next_gen_lock; | ||
57 | u32 s_next_generation; | ||
58 | u32 s_hash_seed[4]; | ||
59 | int s_def_hash_version; | ||
60 | int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ | ||
61 | struct percpu_counter s_freeblocks_counter; | ||
62 | struct percpu_counter s_freeinodes_counter; | ||
63 | struct percpu_counter s_dirs_counter; | ||
64 | struct percpu_counter s_dirtyblocks_counter; | ||
65 | struct blockgroup_lock *s_blockgroup_lock; | ||
66 | struct proc_dir_entry *s_proc; | ||
67 | struct kobject s_kobj; | ||
68 | struct completion s_kobj_unregister; | ||
69 | |||
70 | /* Journaling */ | ||
71 | struct inode *s_journal_inode; | ||
72 | struct journal_s *s_journal; | ||
73 | struct list_head s_orphan; | ||
74 | unsigned long s_commit_interval; | ||
75 | u32 s_max_batch_time; | ||
76 | u32 s_min_batch_time; | ||
77 | struct block_device *journal_bdev; | ||
78 | #ifdef CONFIG_JBD2_DEBUG | ||
79 | struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */ | ||
80 | wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */ | ||
81 | #endif | ||
82 | #ifdef CONFIG_QUOTA | ||
83 | char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */ | ||
84 | int s_jquota_fmt; /* Format of quota to use */ | ||
85 | #endif | ||
86 | unsigned int s_want_extra_isize; /* New inodes should reserve # bytes */ | ||
87 | |||
88 | #ifdef EXTENTS_STATS | ||
89 | /* ext4 extents stats */ | ||
90 | unsigned long s_ext_min; | ||
91 | unsigned long s_ext_max; | ||
92 | unsigned long s_depth_max; | ||
93 | spinlock_t s_ext_stats_lock; | ||
94 | unsigned long s_ext_blocks; | ||
95 | unsigned long s_ext_extents; | ||
96 | #endif | ||
97 | |||
98 | /* for buddy allocator */ | ||
99 | struct ext4_group_info ***s_group_info; | ||
100 | struct inode *s_buddy_cache; | ||
101 | long s_blocks_reserved; | ||
102 | spinlock_t s_reserve_lock; | ||
103 | spinlock_t s_md_lock; | ||
104 | tid_t s_last_transaction; | ||
105 | unsigned short *s_mb_offsets; | ||
106 | unsigned int *s_mb_maxs; | ||
107 | |||
108 | /* tunables */ | ||
109 | unsigned long s_stripe; | ||
110 | unsigned int s_mb_stream_request; | ||
111 | unsigned int s_mb_max_to_scan; | ||
112 | unsigned int s_mb_min_to_scan; | ||
113 | unsigned int s_mb_stats; | ||
114 | unsigned int s_mb_order2_reqs; | ||
115 | unsigned int s_mb_group_prealloc; | ||
116 | /* where last allocation was done - for stream allocation */ | ||
117 | unsigned long s_mb_last_group; | ||
118 | unsigned long s_mb_last_start; | ||
119 | |||
120 | /* history to debug policy */ | ||
121 | struct ext4_mb_history *s_mb_history; | ||
122 | int s_mb_history_cur; | ||
123 | int s_mb_history_max; | ||
124 | int s_mb_history_num; | ||
125 | spinlock_t s_mb_history_lock; | ||
126 | int s_mb_history_filter; | ||
127 | |||
128 | /* stats for buddy allocator */ | ||
129 | spinlock_t s_mb_pa_lock; | ||
130 | atomic_t s_bal_reqs; /* number of reqs with len > 1 */ | ||
131 | atomic_t s_bal_success; /* we found long enough chunks */ | ||
132 | atomic_t s_bal_allocated; /* in blocks */ | ||
133 | atomic_t s_bal_ex_scanned; /* total extents scanned */ | ||
134 | atomic_t s_bal_goals; /* goal hits */ | ||
135 | atomic_t s_bal_breaks; /* too long searches */ | ||
136 | atomic_t s_bal_2orders; /* 2^order hits */ | ||
137 | spinlock_t s_bal_lock; | ||
138 | unsigned long s_mb_buddies_generated; | ||
139 | unsigned long long s_mb_generation_time; | ||
140 | atomic_t s_mb_lost_chunks; | ||
141 | atomic_t s_mb_preallocated; | ||
142 | atomic_t s_mb_discarded; | ||
143 | |||
144 | /* locality groups */ | ||
145 | struct ext4_locality_group *s_locality_groups; | ||
146 | |||
147 | /* for write statistics */ | ||
148 | unsigned long s_sectors_written_start; | ||
149 | u64 s_kbytes_written; | ||
150 | |||
151 | unsigned int s_log_groups_per_flex; | ||
152 | struct flex_groups *s_flex_groups; | ||
153 | }; | ||
154 | |||
155 | static inline spinlock_t * | ||
156 | sb_bgl_lock(struct ext4_sb_info *sbi, unsigned int block_group) | ||
157 | { | ||
158 | return bgl_lock_ptr(sbi->s_blockgroup_lock, block_group); | ||
159 | } | ||
160 | |||
161 | #endif /* _EXT4_SB */ | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e3a55eb8b26a..2593f748c3a4 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -326,32 +326,18 @@ ext4_ext_max_entries(struct inode *inode, int depth) | |||
326 | 326 | ||
327 | static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) | 327 | static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext) |
328 | { | 328 | { |
329 | ext4_fsblk_t block = ext_pblock(ext), valid_block; | 329 | ext4_fsblk_t block = ext_pblock(ext); |
330 | int len = ext4_ext_get_actual_len(ext); | 330 | int len = ext4_ext_get_actual_len(ext); |
331 | struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; | ||
332 | 331 | ||
333 | valid_block = le32_to_cpu(es->s_first_data_block) + | 332 | return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len); |
334 | EXT4_SB(inode->i_sb)->s_gdb_count; | ||
335 | if (unlikely(block <= valid_block || | ||
336 | ((block + len) > ext4_blocks_count(es)))) | ||
337 | return 0; | ||
338 | else | ||
339 | return 1; | ||
340 | } | 333 | } |
341 | 334 | ||
342 | static int ext4_valid_extent_idx(struct inode *inode, | 335 | static int ext4_valid_extent_idx(struct inode *inode, |
343 | struct ext4_extent_idx *ext_idx) | 336 | struct ext4_extent_idx *ext_idx) |
344 | { | 337 | { |
345 | ext4_fsblk_t block = idx_pblock(ext_idx), valid_block; | 338 | ext4_fsblk_t block = idx_pblock(ext_idx); |
346 | struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; | ||
347 | 339 | ||
348 | valid_block = le32_to_cpu(es->s_first_data_block) + | 340 | return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, 1); |
349 | EXT4_SB(inode->i_sb)->s_gdb_count; | ||
350 | if (unlikely(block <= valid_block || | ||
351 | (block >= ext4_blocks_count(es)))) | ||
352 | return 0; | ||
353 | else | ||
354 | return 1; | ||
355 | } | 341 | } |
356 | 342 | ||
357 | static int ext4_valid_extent_entries(struct inode *inode, | 343 | static int ext4_valid_extent_entries(struct inode *inode, |
@@ -2097,12 +2083,16 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
2097 | ex = EXT_LAST_EXTENT(eh); | 2083 | ex = EXT_LAST_EXTENT(eh); |
2098 | 2084 | ||
2099 | ex_ee_block = le32_to_cpu(ex->ee_block); | 2085 | ex_ee_block = le32_to_cpu(ex->ee_block); |
2100 | if (ext4_ext_is_uninitialized(ex)) | ||
2101 | uninitialized = 1; | ||
2102 | ex_ee_len = ext4_ext_get_actual_len(ex); | 2086 | ex_ee_len = ext4_ext_get_actual_len(ex); |
2103 | 2087 | ||
2104 | while (ex >= EXT_FIRST_EXTENT(eh) && | 2088 | while (ex >= EXT_FIRST_EXTENT(eh) && |
2105 | ex_ee_block + ex_ee_len > start) { | 2089 | ex_ee_block + ex_ee_len > start) { |
2090 | |||
2091 | if (ext4_ext_is_uninitialized(ex)) | ||
2092 | uninitialized = 1; | ||
2093 | else | ||
2094 | uninitialized = 0; | ||
2095 | |||
2106 | ext_debug("remove ext %lu:%u\n", ex_ee_block, ex_ee_len); | 2096 | ext_debug("remove ext %lu:%u\n", ex_ee_block, ex_ee_len); |
2107 | path[depth].p_ext = ex; | 2097 | path[depth].p_ext = ex; |
2108 | 2098 | ||
@@ -2784,7 +2774,7 @@ fix_extent_len: | |||
2784 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | 2774 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, |
2785 | ext4_lblk_t iblock, | 2775 | ext4_lblk_t iblock, |
2786 | unsigned int max_blocks, struct buffer_head *bh_result, | 2776 | unsigned int max_blocks, struct buffer_head *bh_result, |
2787 | int create, int extend_disksize) | 2777 | int flags) |
2788 | { | 2778 | { |
2789 | struct ext4_ext_path *path = NULL; | 2779 | struct ext4_ext_path *path = NULL; |
2790 | struct ext4_extent_header *eh; | 2780 | struct ext4_extent_header *eh; |
@@ -2793,7 +2783,6 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2793 | int err = 0, depth, ret, cache_type; | 2783 | int err = 0, depth, ret, cache_type; |
2794 | unsigned int allocated = 0; | 2784 | unsigned int allocated = 0; |
2795 | struct ext4_allocation_request ar; | 2785 | struct ext4_allocation_request ar; |
2796 | loff_t disksize; | ||
2797 | 2786 | ||
2798 | __clear_bit(BH_New, &bh_result->b_state); | 2787 | __clear_bit(BH_New, &bh_result->b_state); |
2799 | ext_debug("blocks %u/%u requested for inode %u\n", | 2788 | ext_debug("blocks %u/%u requested for inode %u\n", |
@@ -2803,7 +2792,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2803 | cache_type = ext4_ext_in_cache(inode, iblock, &newex); | 2792 | cache_type = ext4_ext_in_cache(inode, iblock, &newex); |
2804 | if (cache_type) { | 2793 | if (cache_type) { |
2805 | if (cache_type == EXT4_EXT_CACHE_GAP) { | 2794 | if (cache_type == EXT4_EXT_CACHE_GAP) { |
2806 | if (!create) { | 2795 | if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { |
2807 | /* | 2796 | /* |
2808 | * block isn't allocated yet and | 2797 | * block isn't allocated yet and |
2809 | * user doesn't want to allocate it | 2798 | * user doesn't want to allocate it |
@@ -2869,9 +2858,11 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2869 | EXT4_EXT_CACHE_EXTENT); | 2858 | EXT4_EXT_CACHE_EXTENT); |
2870 | goto out; | 2859 | goto out; |
2871 | } | 2860 | } |
2872 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) | 2861 | if (flags & EXT4_GET_BLOCKS_UNINIT_EXT) |
2873 | goto out; | 2862 | goto out; |
2874 | if (!create) { | 2863 | if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { |
2864 | if (allocated > max_blocks) | ||
2865 | allocated = max_blocks; | ||
2875 | /* | 2866 | /* |
2876 | * We have blocks reserved already. We | 2867 | * We have blocks reserved already. We |
2877 | * return allocated blocks so that delalloc | 2868 | * return allocated blocks so that delalloc |
@@ -2879,8 +2870,6 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2879 | * the buffer head will be unmapped so that | 2870 | * the buffer head will be unmapped so that |
2880 | * a read from the block returns 0s. | 2871 | * a read from the block returns 0s. |
2881 | */ | 2872 | */ |
2882 | if (allocated > max_blocks) | ||
2883 | allocated = max_blocks; | ||
2884 | set_buffer_unwritten(bh_result); | 2873 | set_buffer_unwritten(bh_result); |
2885 | bh_result->b_bdev = inode->i_sb->s_bdev; | 2874 | bh_result->b_bdev = inode->i_sb->s_bdev; |
2886 | bh_result->b_blocknr = newblock; | 2875 | bh_result->b_blocknr = newblock; |
@@ -2903,7 +2892,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2903 | * requested block isn't allocated yet; | 2892 | * requested block isn't allocated yet; |
2904 | * we couldn't try to create block if create flag is zero | 2893 | * we couldn't try to create block if create flag is zero |
2905 | */ | 2894 | */ |
2906 | if (!create) { | 2895 | if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { |
2907 | /* | 2896 | /* |
2908 | * put just found gap into cache to speed up | 2897 | * put just found gap into cache to speed up |
2909 | * subsequent requests | 2898 | * subsequent requests |
@@ -2932,10 +2921,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2932 | * EXT_UNINIT_MAX_LEN. | 2921 | * EXT_UNINIT_MAX_LEN. |
2933 | */ | 2922 | */ |
2934 | if (max_blocks > EXT_INIT_MAX_LEN && | 2923 | if (max_blocks > EXT_INIT_MAX_LEN && |
2935 | create != EXT4_CREATE_UNINITIALIZED_EXT) | 2924 | !(flags & EXT4_GET_BLOCKS_UNINIT_EXT)) |
2936 | max_blocks = EXT_INIT_MAX_LEN; | 2925 | max_blocks = EXT_INIT_MAX_LEN; |
2937 | else if (max_blocks > EXT_UNINIT_MAX_LEN && | 2926 | else if (max_blocks > EXT_UNINIT_MAX_LEN && |
2938 | create == EXT4_CREATE_UNINITIALIZED_EXT) | 2927 | (flags & EXT4_GET_BLOCKS_UNINIT_EXT)) |
2939 | max_blocks = EXT_UNINIT_MAX_LEN; | 2928 | max_blocks = EXT_UNINIT_MAX_LEN; |
2940 | 2929 | ||
2941 | /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ | 2930 | /* Check if we can really insert (iblock)::(iblock+max_blocks) extent */ |
@@ -2966,7 +2955,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2966 | /* try to insert new extent into found leaf and return */ | 2955 | /* try to insert new extent into found leaf and return */ |
2967 | ext4_ext_store_pblock(&newex, newblock); | 2956 | ext4_ext_store_pblock(&newex, newblock); |
2968 | newex.ee_len = cpu_to_le16(ar.len); | 2957 | newex.ee_len = cpu_to_le16(ar.len); |
2969 | if (create == EXT4_CREATE_UNINITIALIZED_EXT) /* Mark uninitialized */ | 2958 | if (flags & EXT4_GET_BLOCKS_UNINIT_EXT) /* Mark uninitialized */ |
2970 | ext4_ext_mark_uninitialized(&newex); | 2959 | ext4_ext_mark_uninitialized(&newex); |
2971 | err = ext4_ext_insert_extent(handle, inode, path, &newex); | 2960 | err = ext4_ext_insert_extent(handle, inode, path, &newex); |
2972 | if (err) { | 2961 | if (err) { |
@@ -2983,18 +2972,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
2983 | newblock = ext_pblock(&newex); | 2972 | newblock = ext_pblock(&newex); |
2984 | allocated = ext4_ext_get_actual_len(&newex); | 2973 | allocated = ext4_ext_get_actual_len(&newex); |
2985 | outnew: | 2974 | outnew: |
2986 | if (extend_disksize) { | ||
2987 | disksize = ((loff_t) iblock + ar.len) << inode->i_blkbits; | ||
2988 | if (disksize > i_size_read(inode)) | ||
2989 | disksize = i_size_read(inode); | ||
2990 | if (disksize > EXT4_I(inode)->i_disksize) | ||
2991 | EXT4_I(inode)->i_disksize = disksize; | ||
2992 | } | ||
2993 | |||
2994 | set_buffer_new(bh_result); | 2975 | set_buffer_new(bh_result); |
2995 | 2976 | ||
2996 | /* Cache only when it is _not_ an uninitialized extent */ | 2977 | /* Cache only when it is _not_ an uninitialized extent */ |
2997 | if (create != EXT4_CREATE_UNINITIALIZED_EXT) | 2978 | if ((flags & EXT4_GET_BLOCKS_UNINIT_EXT) == 0) |
2998 | ext4_ext_put_in_cache(inode, iblock, allocated, newblock, | 2979 | ext4_ext_put_in_cache(inode, iblock, allocated, newblock, |
2999 | EXT4_EXT_CACHE_EXTENT); | 2980 | EXT4_EXT_CACHE_EXTENT); |
3000 | out: | 2981 | out: |
@@ -3150,9 +3131,10 @@ retry: | |||
3150 | ret = PTR_ERR(handle); | 3131 | ret = PTR_ERR(handle); |
3151 | break; | 3132 | break; |
3152 | } | 3133 | } |
3153 | ret = ext4_get_blocks_wrap(handle, inode, block, | 3134 | map_bh.b_state = 0; |
3154 | max_blocks, &map_bh, | 3135 | ret = ext4_get_blocks(handle, inode, block, |
3155 | EXT4_CREATE_UNINITIALIZED_EXT, 0, 0); | 3136 | max_blocks, &map_bh, |
3137 | EXT4_GET_BLOCKS_CREATE_UNINIT_EXT); | ||
3156 | if (ret <= 0) { | 3138 | if (ret <= 0) { |
3157 | #ifdef EXT4FS_DEBUG | 3139 | #ifdef EXT4FS_DEBUG |
3158 | WARN_ON(ret <= 0); | 3140 | WARN_ON(ret <= 0); |
@@ -3195,7 +3177,7 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path, | |||
3195 | void *data) | 3177 | void *data) |
3196 | { | 3178 | { |
3197 | struct fiemap_extent_info *fieinfo = data; | 3179 | struct fiemap_extent_info *fieinfo = data; |
3198 | unsigned long blksize_bits = inode->i_sb->s_blocksize_bits; | 3180 | unsigned char blksize_bits = inode->i_sb->s_blocksize_bits; |
3199 | __u64 logical; | 3181 | __u64 logical; |
3200 | __u64 physical; | 3182 | __u64 physical; |
3201 | __u64 length; | 3183 | __u64 length; |
@@ -3242,9 +3224,16 @@ static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path, | |||
3242 | * | 3224 | * |
3243 | * XXX this might miss a single-block extent at EXT_MAX_BLOCK | 3225 | * XXX this might miss a single-block extent at EXT_MAX_BLOCK |
3244 | */ | 3226 | */ |
3245 | if (logical + length - 1 == EXT_MAX_BLOCK || | 3227 | if (ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK || |
3246 | ext4_ext_next_allocated_block(path) == EXT_MAX_BLOCK) | 3228 | newex->ec_block + newex->ec_len - 1 == EXT_MAX_BLOCK) { |
3229 | loff_t size = i_size_read(inode); | ||
3230 | loff_t bs = EXT4_BLOCK_SIZE(inode->i_sb); | ||
3231 | |||
3247 | flags |= FIEMAP_EXTENT_LAST; | 3232 | flags |= FIEMAP_EXTENT_LAST; |
3233 | if ((flags & FIEMAP_EXTENT_DELALLOC) && | ||
3234 | logical+length > size) | ||
3235 | length = (size - logical + bs - 1) & ~(bs-1); | ||
3236 | } | ||
3248 | 3237 | ||
3249 | error = fiemap_fill_next_extent(fieinfo, logical, physical, | 3238 | error = fiemap_fill_next_extent(fieinfo, logical, physical, |
3250 | length, flags); | 3239 | length, flags); |
@@ -3318,10 +3307,10 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
3318 | * Walk the extent tree gathering extent information. | 3307 | * Walk the extent tree gathering extent information. |
3319 | * ext4_ext_fiemap_cb will push extents back to user. | 3308 | * ext4_ext_fiemap_cb will push extents back to user. |
3320 | */ | 3309 | */ |
3321 | down_write(&EXT4_I(inode)->i_data_sem); | 3310 | down_read(&EXT4_I(inode)->i_data_sem); |
3322 | error = ext4_ext_walk_space(inode, start_blk, len_blks, | 3311 | error = ext4_ext_walk_space(inode, start_blk, len_blks, |
3323 | ext4_ext_fiemap_cb, fieinfo); | 3312 | ext4_ext_fiemap_cb, fieinfo); |
3324 | up_write(&EXT4_I(inode)->i_data_sem); | 3313 | up_read(&EXT4_I(inode)->i_data_sem); |
3325 | } | 3314 | } |
3326 | 3315 | ||
3327 | return error; | 3316 | return error; |
diff --git a/fs/ext4/group.h b/fs/ext4/group.h deleted file mode 100644 index c2c0a8d06d0e..000000000000 --- a/fs/ext4/group.h +++ /dev/null | |||
@@ -1,29 +0,0 @@ | |||
1 | /* | ||
2 | * linux/fs/ext4/group.h | ||
3 | * | ||
4 | * Copyright (C) 2007 Cluster File Systems, Inc | ||
5 | * | ||
6 | * Author: Andreas Dilger <adilger@clusterfs.com> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LINUX_EXT4_GROUP_H | ||
10 | #define _LINUX_EXT4_GROUP_H | ||
11 | |||
12 | extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group, | ||
13 | struct ext4_group_desc *gdp); | ||
14 | extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group, | ||
15 | struct ext4_group_desc *gdp); | ||
16 | struct buffer_head *ext4_read_block_bitmap(struct super_block *sb, | ||
17 | ext4_group_t block_group); | ||
18 | extern unsigned ext4_init_block_bitmap(struct super_block *sb, | ||
19 | struct buffer_head *bh, | ||
20 | ext4_group_t group, | ||
21 | struct ext4_group_desc *desc); | ||
22 | #define ext4_free_blocks_after_init(sb, group, desc) \ | ||
23 | ext4_init_block_bitmap(sb, NULL, group, desc) | ||
24 | extern unsigned ext4_init_inode_bitmap(struct super_block *sb, | ||
25 | struct buffer_head *bh, | ||
26 | ext4_group_t group, | ||
27 | struct ext4_group_desc *desc); | ||
28 | extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap); | ||
29 | #endif /* _LINUX_EXT4_GROUP_H */ | ||
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index f18e0a08a6b5..3743bd849bce 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include "ext4_jbd2.h" | 27 | #include "ext4_jbd2.h" |
28 | #include "xattr.h" | 28 | #include "xattr.h" |
29 | #include "acl.h" | 29 | #include "acl.h" |
30 | #include "group.h" | ||
31 | 30 | ||
32 | /* | 31 | /* |
33 | * ialloc.c contains the inodes allocation and deallocation routines | 32 | * ialloc.c contains the inodes allocation and deallocation routines |
@@ -123,16 +122,16 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) | |||
123 | unlock_buffer(bh); | 122 | unlock_buffer(bh); |
124 | return bh; | 123 | return bh; |
125 | } | 124 | } |
126 | spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 125 | ext4_lock_group(sb, block_group); |
127 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { | 126 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { |
128 | ext4_init_inode_bitmap(sb, bh, block_group, desc); | 127 | ext4_init_inode_bitmap(sb, bh, block_group, desc); |
129 | set_bitmap_uptodate(bh); | 128 | set_bitmap_uptodate(bh); |
130 | set_buffer_uptodate(bh); | 129 | set_buffer_uptodate(bh); |
131 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 130 | ext4_unlock_group(sb, block_group); |
132 | unlock_buffer(bh); | 131 | unlock_buffer(bh); |
133 | return bh; | 132 | return bh; |
134 | } | 133 | } |
135 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); | 134 | ext4_unlock_group(sb, block_group); |
136 | if (buffer_uptodate(bh)) { | 135 | if (buffer_uptodate(bh)) { |
137 | /* | 136 | /* |
138 | * if not uninit if bh is uptodate, | 137 | * if not uninit if bh is uptodate, |
@@ -247,9 +246,8 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
247 | goto error_return; | 246 | goto error_return; |
248 | 247 | ||
249 | /* Ok, now we can actually update the inode bitmaps.. */ | 248 | /* Ok, now we can actually update the inode bitmaps.. */ |
250 | spin_lock(sb_bgl_lock(sbi, block_group)); | 249 | cleared = ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), |
251 | cleared = ext4_clear_bit(bit, bitmap_bh->b_data); | 250 | bit, bitmap_bh->b_data); |
252 | spin_unlock(sb_bgl_lock(sbi, block_group)); | ||
253 | if (!cleared) | 251 | if (!cleared) |
254 | ext4_error(sb, "ext4_free_inode", | 252 | ext4_error(sb, "ext4_free_inode", |
255 | "bit already cleared for inode %lu", ino); | 253 | "bit already cleared for inode %lu", ino); |
@@ -261,7 +259,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
261 | if (fatal) goto error_return; | 259 | if (fatal) goto error_return; |
262 | 260 | ||
263 | if (gdp) { | 261 | if (gdp) { |
264 | spin_lock(sb_bgl_lock(sbi, block_group)); | 262 | ext4_lock_group(sb, block_group); |
265 | count = ext4_free_inodes_count(sb, gdp) + 1; | 263 | count = ext4_free_inodes_count(sb, gdp) + 1; |
266 | ext4_free_inodes_set(sb, gdp, count); | 264 | ext4_free_inodes_set(sb, gdp, count); |
267 | if (is_directory) { | 265 | if (is_directory) { |
@@ -277,7 +275,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) | |||
277 | } | 275 | } |
278 | gdp->bg_checksum = ext4_group_desc_csum(sbi, | 276 | gdp->bg_checksum = ext4_group_desc_csum(sbi, |
279 | block_group, gdp); | 277 | block_group, gdp); |
280 | spin_unlock(sb_bgl_lock(sbi, block_group)); | 278 | ext4_unlock_group(sb, block_group); |
281 | percpu_counter_inc(&sbi->s_freeinodes_counter); | 279 | percpu_counter_inc(&sbi->s_freeinodes_counter); |
282 | if (is_directory) | 280 | if (is_directory) |
283 | percpu_counter_dec(&sbi->s_dirs_counter); | 281 | percpu_counter_dec(&sbi->s_dirs_counter); |
@@ -316,7 +314,7 @@ error_return: | |||
316 | static int find_group_dir(struct super_block *sb, struct inode *parent, | 314 | static int find_group_dir(struct super_block *sb, struct inode *parent, |
317 | ext4_group_t *best_group) | 315 | ext4_group_t *best_group) |
318 | { | 316 | { |
319 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | 317 | ext4_group_t ngroups = ext4_get_groups_count(sb); |
320 | unsigned int freei, avefreei; | 318 | unsigned int freei, avefreei; |
321 | struct ext4_group_desc *desc, *best_desc = NULL; | 319 | struct ext4_group_desc *desc, *best_desc = NULL; |
322 | ext4_group_t group; | 320 | ext4_group_t group; |
@@ -349,11 +347,10 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, | |||
349 | { | 347 | { |
350 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 348 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
351 | struct ext4_group_desc *desc; | 349 | struct ext4_group_desc *desc; |
352 | struct buffer_head *bh; | ||
353 | struct flex_groups *flex_group = sbi->s_flex_groups; | 350 | struct flex_groups *flex_group = sbi->s_flex_groups; |
354 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; | 351 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; |
355 | ext4_group_t parent_fbg_group = ext4_flex_group(sbi, parent_group); | 352 | ext4_group_t parent_fbg_group = ext4_flex_group(sbi, parent_group); |
356 | ext4_group_t ngroups = sbi->s_groups_count; | 353 | ext4_group_t ngroups = ext4_get_groups_count(sb); |
357 | int flex_size = ext4_flex_bg_size(sbi); | 354 | int flex_size = ext4_flex_bg_size(sbi); |
358 | ext4_group_t best_flex = parent_fbg_group; | 355 | ext4_group_t best_flex = parent_fbg_group; |
359 | int blocks_per_flex = sbi->s_blocks_per_group * flex_size; | 356 | int blocks_per_flex = sbi->s_blocks_per_group * flex_size; |
@@ -362,7 +359,7 @@ static int find_group_flex(struct super_block *sb, struct inode *parent, | |||
362 | ext4_group_t n_fbg_groups; | 359 | ext4_group_t n_fbg_groups; |
363 | ext4_group_t i; | 360 | ext4_group_t i; |
364 | 361 | ||
365 | n_fbg_groups = (sbi->s_groups_count + flex_size - 1) >> | 362 | n_fbg_groups = (ngroups + flex_size - 1) >> |
366 | sbi->s_log_groups_per_flex; | 363 | sbi->s_log_groups_per_flex; |
367 | 364 | ||
368 | find_close_to_parent: | 365 | find_close_to_parent: |
@@ -404,7 +401,7 @@ find_close_to_parent: | |||
404 | found_flexbg: | 401 | found_flexbg: |
405 | for (i = best_flex * flex_size; i < ngroups && | 402 | for (i = best_flex * flex_size; i < ngroups && |
406 | i < (best_flex + 1) * flex_size; i++) { | 403 | i < (best_flex + 1) * flex_size; i++) { |
407 | desc = ext4_get_group_desc(sb, i, &bh); | 404 | desc = ext4_get_group_desc(sb, i, NULL); |
408 | if (ext4_free_inodes_count(sb, desc)) { | 405 | if (ext4_free_inodes_count(sb, desc)) { |
409 | *best_group = i; | 406 | *best_group = i; |
410 | goto out; | 407 | goto out; |
@@ -478,20 +475,21 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, | |||
478 | { | 475 | { |
479 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; | 476 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; |
480 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 477 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
481 | ext4_group_t ngroups = sbi->s_groups_count; | 478 | ext4_group_t real_ngroups = ext4_get_groups_count(sb); |
482 | int inodes_per_group = EXT4_INODES_PER_GROUP(sb); | 479 | int inodes_per_group = EXT4_INODES_PER_GROUP(sb); |
483 | unsigned int freei, avefreei; | 480 | unsigned int freei, avefreei; |
484 | ext4_fsblk_t freeb, avefreeb; | 481 | ext4_fsblk_t freeb, avefreeb; |
485 | unsigned int ndirs; | 482 | unsigned int ndirs; |
486 | int max_dirs, min_inodes; | 483 | int max_dirs, min_inodes; |
487 | ext4_grpblk_t min_blocks; | 484 | ext4_grpblk_t min_blocks; |
488 | ext4_group_t i, grp, g; | 485 | ext4_group_t i, grp, g, ngroups; |
489 | struct ext4_group_desc *desc; | 486 | struct ext4_group_desc *desc; |
490 | struct orlov_stats stats; | 487 | struct orlov_stats stats; |
491 | int flex_size = ext4_flex_bg_size(sbi); | 488 | int flex_size = ext4_flex_bg_size(sbi); |
492 | 489 | ||
490 | ngroups = real_ngroups; | ||
493 | if (flex_size > 1) { | 491 | if (flex_size > 1) { |
494 | ngroups = (ngroups + flex_size - 1) >> | 492 | ngroups = (real_ngroups + flex_size - 1) >> |
495 | sbi->s_log_groups_per_flex; | 493 | sbi->s_log_groups_per_flex; |
496 | parent_group >>= sbi->s_log_groups_per_flex; | 494 | parent_group >>= sbi->s_log_groups_per_flex; |
497 | } | 495 | } |
@@ -543,7 +541,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, | |||
543 | */ | 541 | */ |
544 | grp *= flex_size; | 542 | grp *= flex_size; |
545 | for (i = 0; i < flex_size; i++) { | 543 | for (i = 0; i < flex_size; i++) { |
546 | if (grp+i >= sbi->s_groups_count) | 544 | if (grp+i >= real_ngroups) |
547 | break; | 545 | break; |
548 | desc = ext4_get_group_desc(sb, grp+i, NULL); | 546 | desc = ext4_get_group_desc(sb, grp+i, NULL); |
549 | if (desc && ext4_free_inodes_count(sb, desc)) { | 547 | if (desc && ext4_free_inodes_count(sb, desc)) { |
@@ -583,7 +581,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent, | |||
583 | } | 581 | } |
584 | 582 | ||
585 | fallback: | 583 | fallback: |
586 | ngroups = sbi->s_groups_count; | 584 | ngroups = real_ngroups; |
587 | avefreei = freei / ngroups; | 585 | avefreei = freei / ngroups; |
588 | fallback_retry: | 586 | fallback_retry: |
589 | parent_group = EXT4_I(parent)->i_block_group; | 587 | parent_group = EXT4_I(parent)->i_block_group; |
@@ -613,9 +611,8 @@ static int find_group_other(struct super_block *sb, struct inode *parent, | |||
613 | ext4_group_t *group, int mode) | 611 | ext4_group_t *group, int mode) |
614 | { | 612 | { |
615 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; | 613 | ext4_group_t parent_group = EXT4_I(parent)->i_block_group; |
616 | ext4_group_t ngroups = EXT4_SB(sb)->s_groups_count; | 614 | ext4_group_t i, last, ngroups = ext4_get_groups_count(sb); |
617 | struct ext4_group_desc *desc; | 615 | struct ext4_group_desc *desc; |
618 | ext4_group_t i, last; | ||
619 | int flex_size = ext4_flex_bg_size(EXT4_SB(sb)); | 616 | int flex_size = ext4_flex_bg_size(EXT4_SB(sb)); |
620 | 617 | ||
621 | /* | 618 | /* |
@@ -708,10 +705,10 @@ static int find_group_other(struct super_block *sb, struct inode *parent, | |||
708 | 705 | ||
709 | /* | 706 | /* |
710 | * claim the inode from the inode bitmap. If the group | 707 | * claim the inode from the inode bitmap. If the group |
711 | * is uninit we need to take the groups's sb_bgl_lock | 708 | * is uninit we need to take the groups's ext4_group_lock |
712 | * and clear the uninit flag. The inode bitmap update | 709 | * and clear the uninit flag. The inode bitmap update |
713 | * and group desc uninit flag clear should be done | 710 | * and group desc uninit flag clear should be done |
714 | * after holding sb_bgl_lock so that ext4_read_inode_bitmap | 711 | * after holding ext4_group_lock so that ext4_read_inode_bitmap |
715 | * doesn't race with the ext4_claim_inode | 712 | * doesn't race with the ext4_claim_inode |
716 | */ | 713 | */ |
717 | static int ext4_claim_inode(struct super_block *sb, | 714 | static int ext4_claim_inode(struct super_block *sb, |
@@ -722,7 +719,7 @@ static int ext4_claim_inode(struct super_block *sb, | |||
722 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 719 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
723 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL); | 720 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL); |
724 | 721 | ||
725 | spin_lock(sb_bgl_lock(sbi, group)); | 722 | ext4_lock_group(sb, group); |
726 | if (ext4_set_bit(ino, inode_bitmap_bh->b_data)) { | 723 | if (ext4_set_bit(ino, inode_bitmap_bh->b_data)) { |
727 | /* not a free inode */ | 724 | /* not a free inode */ |
728 | retval = 1; | 725 | retval = 1; |
@@ -731,7 +728,7 @@ static int ext4_claim_inode(struct super_block *sb, | |||
731 | ino++; | 728 | ino++; |
732 | if ((group == 0 && ino < EXT4_FIRST_INO(sb)) || | 729 | if ((group == 0 && ino < EXT4_FIRST_INO(sb)) || |
733 | ino > EXT4_INODES_PER_GROUP(sb)) { | 730 | ino > EXT4_INODES_PER_GROUP(sb)) { |
734 | spin_unlock(sb_bgl_lock(sbi, group)); | 731 | ext4_unlock_group(sb, group); |
735 | ext4_error(sb, __func__, | 732 | ext4_error(sb, __func__, |
736 | "reserved inode or inode > inodes count - " | 733 | "reserved inode or inode > inodes count - " |
737 | "block_group = %u, inode=%lu", group, | 734 | "block_group = %u, inode=%lu", group, |
@@ -780,7 +777,7 @@ static int ext4_claim_inode(struct super_block *sb, | |||
780 | } | 777 | } |
781 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); | 778 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); |
782 | err_ret: | 779 | err_ret: |
783 | spin_unlock(sb_bgl_lock(sbi, group)); | 780 | ext4_unlock_group(sb, group); |
784 | return retval; | 781 | return retval; |
785 | } | 782 | } |
786 | 783 | ||
@@ -799,11 +796,10 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) | |||
799 | struct super_block *sb; | 796 | struct super_block *sb; |
800 | struct buffer_head *inode_bitmap_bh = NULL; | 797 | struct buffer_head *inode_bitmap_bh = NULL; |
801 | struct buffer_head *group_desc_bh; | 798 | struct buffer_head *group_desc_bh; |
802 | ext4_group_t group = 0; | 799 | ext4_group_t ngroups, group = 0; |
803 | unsigned long ino = 0; | 800 | unsigned long ino = 0; |
804 | struct inode *inode; | 801 | struct inode *inode; |
805 | struct ext4_group_desc *gdp = NULL; | 802 | struct ext4_group_desc *gdp = NULL; |
806 | struct ext4_super_block *es; | ||
807 | struct ext4_inode_info *ei; | 803 | struct ext4_inode_info *ei; |
808 | struct ext4_sb_info *sbi; | 804 | struct ext4_sb_info *sbi; |
809 | int ret2, err = 0; | 805 | int ret2, err = 0; |
@@ -818,15 +814,14 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) | |||
818 | return ERR_PTR(-EPERM); | 814 | return ERR_PTR(-EPERM); |
819 | 815 | ||
820 | sb = dir->i_sb; | 816 | sb = dir->i_sb; |
817 | ngroups = ext4_get_groups_count(sb); | ||
821 | trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id, | 818 | trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id, |
822 | dir->i_ino, mode); | 819 | dir->i_ino, mode); |
823 | inode = new_inode(sb); | 820 | inode = new_inode(sb); |
824 | if (!inode) | 821 | if (!inode) |
825 | return ERR_PTR(-ENOMEM); | 822 | return ERR_PTR(-ENOMEM); |
826 | ei = EXT4_I(inode); | 823 | ei = EXT4_I(inode); |
827 | |||
828 | sbi = EXT4_SB(sb); | 824 | sbi = EXT4_SB(sb); |
829 | es = sbi->s_es; | ||
830 | 825 | ||
831 | if (sbi->s_log_groups_per_flex && test_opt(sb, OLDALLOC)) { | 826 | if (sbi->s_log_groups_per_flex && test_opt(sb, OLDALLOC)) { |
832 | ret2 = find_group_flex(sb, dir, &group); | 827 | ret2 = find_group_flex(sb, dir, &group); |
@@ -856,7 +851,7 @@ got_group: | |||
856 | if (ret2 == -1) | 851 | if (ret2 == -1) |
857 | goto out; | 852 | goto out; |
858 | 853 | ||
859 | for (i = 0; i < sbi->s_groups_count; i++) { | 854 | for (i = 0; i < ngroups; i++) { |
860 | err = -EIO; | 855 | err = -EIO; |
861 | 856 | ||
862 | gdp = ext4_get_group_desc(sb, group, &group_desc_bh); | 857 | gdp = ext4_get_group_desc(sb, group, &group_desc_bh); |
@@ -917,7 +912,7 @@ repeat_in_this_group: | |||
917 | * group descriptor metadata has not yet been updated. | 912 | * group descriptor metadata has not yet been updated. |
918 | * So we just go onto the next blockgroup. | 913 | * So we just go onto the next blockgroup. |
919 | */ | 914 | */ |
920 | if (++group == sbi->s_groups_count) | 915 | if (++group == ngroups) |
921 | group = 0; | 916 | group = 0; |
922 | } | 917 | } |
923 | err = -ENOSPC; | 918 | err = -ENOSPC; |
@@ -938,7 +933,7 @@ got: | |||
938 | } | 933 | } |
939 | 934 | ||
940 | free = 0; | 935 | free = 0; |
941 | spin_lock(sb_bgl_lock(sbi, group)); | 936 | ext4_lock_group(sb, group); |
942 | /* recheck and clear flag under lock if we still need to */ | 937 | /* recheck and clear flag under lock if we still need to */ |
943 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 938 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { |
944 | free = ext4_free_blocks_after_init(sb, group, gdp); | 939 | free = ext4_free_blocks_after_init(sb, group, gdp); |
@@ -947,7 +942,7 @@ got: | |||
947 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, | 942 | gdp->bg_checksum = ext4_group_desc_csum(sbi, group, |
948 | gdp); | 943 | gdp); |
949 | } | 944 | } |
950 | spin_unlock(sb_bgl_lock(sbi, group)); | 945 | ext4_unlock_group(sb, group); |
951 | 946 | ||
952 | /* Don't need to dirty bitmap block if we didn't change it */ | 947 | /* Don't need to dirty bitmap block if we didn't change it */ |
953 | if (free) { | 948 | if (free) { |
@@ -1158,7 +1153,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) | |||
1158 | { | 1153 | { |
1159 | unsigned long desc_count; | 1154 | unsigned long desc_count; |
1160 | struct ext4_group_desc *gdp; | 1155 | struct ext4_group_desc *gdp; |
1161 | ext4_group_t i; | 1156 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
1162 | #ifdef EXT4FS_DEBUG | 1157 | #ifdef EXT4FS_DEBUG |
1163 | struct ext4_super_block *es; | 1158 | struct ext4_super_block *es; |
1164 | unsigned long bitmap_count, x; | 1159 | unsigned long bitmap_count, x; |
@@ -1168,7 +1163,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) | |||
1168 | desc_count = 0; | 1163 | desc_count = 0; |
1169 | bitmap_count = 0; | 1164 | bitmap_count = 0; |
1170 | gdp = NULL; | 1165 | gdp = NULL; |
1171 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 1166 | for (i = 0; i < ngroups; i++) { |
1172 | gdp = ext4_get_group_desc(sb, i, NULL); | 1167 | gdp = ext4_get_group_desc(sb, i, NULL); |
1173 | if (!gdp) | 1168 | if (!gdp) |
1174 | continue; | 1169 | continue; |
@@ -1190,7 +1185,7 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) | |||
1190 | return desc_count; | 1185 | return desc_count; |
1191 | #else | 1186 | #else |
1192 | desc_count = 0; | 1187 | desc_count = 0; |
1193 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 1188 | for (i = 0; i < ngroups; i++) { |
1194 | gdp = ext4_get_group_desc(sb, i, NULL); | 1189 | gdp = ext4_get_group_desc(sb, i, NULL); |
1195 | if (!gdp) | 1190 | if (!gdp) |
1196 | continue; | 1191 | continue; |
@@ -1205,9 +1200,9 @@ unsigned long ext4_count_free_inodes(struct super_block *sb) | |||
1205 | unsigned long ext4_count_dirs(struct super_block * sb) | 1200 | unsigned long ext4_count_dirs(struct super_block * sb) |
1206 | { | 1201 | { |
1207 | unsigned long count = 0; | 1202 | unsigned long count = 0; |
1208 | ext4_group_t i; | 1203 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
1209 | 1204 | ||
1210 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 1205 | for (i = 0; i < ngroups; i++) { |
1211 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); | 1206 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); |
1212 | if (!gdp) | 1207 | if (!gdp) |
1213 | continue; | 1208 | continue; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 2a9ffd528dd1..875db944b22f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -372,20 +372,21 @@ static int ext4_block_to_path(struct inode *inode, | |||
372 | } | 372 | } |
373 | 373 | ||
374 | static int __ext4_check_blockref(const char *function, struct inode *inode, | 374 | static int __ext4_check_blockref(const char *function, struct inode *inode, |
375 | __le32 *p, unsigned int max) { | 375 | __le32 *p, unsigned int max) |
376 | 376 | { | |
377 | unsigned int maxblocks = ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es); | ||
378 | __le32 *bref = p; | 377 | __le32 *bref = p; |
378 | unsigned int blk; | ||
379 | |||
379 | while (bref < p+max) { | 380 | while (bref < p+max) { |
380 | if (unlikely(le32_to_cpu(*bref) >= maxblocks)) { | 381 | blk = le32_to_cpu(*bref++); |
382 | if (blk && | ||
383 | unlikely(!ext4_data_block_valid(EXT4_SB(inode->i_sb), | ||
384 | blk, 1))) { | ||
381 | ext4_error(inode->i_sb, function, | 385 | ext4_error(inode->i_sb, function, |
382 | "block reference %u >= max (%u) " | 386 | "invalid block reference %u " |
383 | "in inode #%lu, offset=%d", | 387 | "in inode #%lu", blk, inode->i_ino); |
384 | le32_to_cpu(*bref), maxblocks, | ||
385 | inode->i_ino, (int)(bref-p)); | ||
386 | return -EIO; | 388 | return -EIO; |
387 | } | 389 | } |
388 | bref++; | ||
389 | } | 390 | } |
390 | return 0; | 391 | return 0; |
391 | } | 392 | } |
@@ -892,6 +893,10 @@ err_out: | |||
892 | } | 893 | } |
893 | 894 | ||
894 | /* | 895 | /* |
896 | * The ext4_ind_get_blocks() function handles non-extents inodes | ||
897 | * (i.e., using the traditional indirect/double-indirect i_blocks | ||
898 | * scheme) for ext4_get_blocks(). | ||
899 | * | ||
895 | * Allocation strategy is simple: if we have to allocate something, we will | 900 | * Allocation strategy is simple: if we have to allocate something, we will |
896 | * have to go the whole way to leaf. So let's do it before attaching anything | 901 | * have to go the whole way to leaf. So let's do it before attaching anything |
897 | * to tree, set linkage between the newborn blocks, write them if sync is | 902 | * to tree, set linkage between the newborn blocks, write them if sync is |
@@ -909,15 +914,16 @@ err_out: | |||
909 | * return = 0, if plain lookup failed. | 914 | * return = 0, if plain lookup failed. |
910 | * return < 0, error case. | 915 | * return < 0, error case. |
911 | * | 916 | * |
912 | * | 917 | * The ext4_ind_get_blocks() function should be called with |
913 | * Need to be called with | 918 | * down_write(&EXT4_I(inode)->i_data_sem) if allocating filesystem |
914 | * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block | 919 | * blocks (i.e., flags has EXT4_GET_BLOCKS_CREATE set) or |
915 | * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem) | 920 | * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system |
921 | * blocks. | ||
916 | */ | 922 | */ |
917 | static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, | 923 | static int ext4_ind_get_blocks(handle_t *handle, struct inode *inode, |
918 | ext4_lblk_t iblock, unsigned int maxblocks, | 924 | ext4_lblk_t iblock, unsigned int maxblocks, |
919 | struct buffer_head *bh_result, | 925 | struct buffer_head *bh_result, |
920 | int create, int extend_disksize) | 926 | int flags) |
921 | { | 927 | { |
922 | int err = -EIO; | 928 | int err = -EIO; |
923 | ext4_lblk_t offsets[4]; | 929 | ext4_lblk_t offsets[4]; |
@@ -927,14 +933,11 @@ static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
927 | int indirect_blks; | 933 | int indirect_blks; |
928 | int blocks_to_boundary = 0; | 934 | int blocks_to_boundary = 0; |
929 | int depth; | 935 | int depth; |
930 | struct ext4_inode_info *ei = EXT4_I(inode); | ||
931 | int count = 0; | 936 | int count = 0; |
932 | ext4_fsblk_t first_block = 0; | 937 | ext4_fsblk_t first_block = 0; |
933 | loff_t disksize; | ||
934 | |||
935 | 938 | ||
936 | J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)); | 939 | J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)); |
937 | J_ASSERT(handle != NULL || create == 0); | 940 | J_ASSERT(handle != NULL || (flags & EXT4_GET_BLOCKS_CREATE) == 0); |
938 | depth = ext4_block_to_path(inode, iblock, offsets, | 941 | depth = ext4_block_to_path(inode, iblock, offsets, |
939 | &blocks_to_boundary); | 942 | &blocks_to_boundary); |
940 | 943 | ||
@@ -963,7 +966,7 @@ static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
963 | } | 966 | } |
964 | 967 | ||
965 | /* Next simple case - plain lookup or failed read of indirect block */ | 968 | /* Next simple case - plain lookup or failed read of indirect block */ |
966 | if (!create || err == -EIO) | 969 | if ((flags & EXT4_GET_BLOCKS_CREATE) == 0 || err == -EIO) |
967 | goto cleanup; | 970 | goto cleanup; |
968 | 971 | ||
969 | /* | 972 | /* |
@@ -997,19 +1000,7 @@ static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
997 | if (!err) | 1000 | if (!err) |
998 | err = ext4_splice_branch(handle, inode, iblock, | 1001 | err = ext4_splice_branch(handle, inode, iblock, |
999 | partial, indirect_blks, count); | 1002 | partial, indirect_blks, count); |
1000 | /* | 1003 | else |
1001 | * i_disksize growing is protected by i_data_sem. Don't forget to | ||
1002 | * protect it if you're about to implement concurrent | ||
1003 | * ext4_get_block() -bzzz | ||
1004 | */ | ||
1005 | if (!err && extend_disksize) { | ||
1006 | disksize = ((loff_t) iblock + count) << inode->i_blkbits; | ||
1007 | if (disksize > i_size_read(inode)) | ||
1008 | disksize = i_size_read(inode); | ||
1009 | if (disksize > ei->i_disksize) | ||
1010 | ei->i_disksize = disksize; | ||
1011 | } | ||
1012 | if (err) | ||
1013 | goto cleanup; | 1004 | goto cleanup; |
1014 | 1005 | ||
1015 | set_buffer_new(bh_result); | 1006 | set_buffer_new(bh_result); |
@@ -1120,8 +1111,23 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) | |||
1120 | ext4_discard_preallocations(inode); | 1111 | ext4_discard_preallocations(inode); |
1121 | } | 1112 | } |
1122 | 1113 | ||
1114 | static int check_block_validity(struct inode *inode, sector_t logical, | ||
1115 | sector_t phys, int len) | ||
1116 | { | ||
1117 | if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), phys, len)) { | ||
1118 | ext4_error(inode->i_sb, "check_block_validity", | ||
1119 | "inode #%lu logical block %llu mapped to %llu " | ||
1120 | "(size %d)", inode->i_ino, | ||
1121 | (unsigned long long) logical, | ||
1122 | (unsigned long long) phys, len); | ||
1123 | WARN_ON(1); | ||
1124 | return -EIO; | ||
1125 | } | ||
1126 | return 0; | ||
1127 | } | ||
1128 | |||
1123 | /* | 1129 | /* |
1124 | * The ext4_get_blocks_wrap() function try to look up the requested blocks, | 1130 | * The ext4_get_blocks() function tries to look up the requested blocks, |
1125 | * and returns if the blocks are already mapped. | 1131 | * and returns if the blocks are already mapped. |
1126 | * | 1132 | * |
1127 | * Otherwise it takes the write lock of the i_data_sem and allocate blocks | 1133 | * Otherwise it takes the write lock of the i_data_sem and allocate blocks |
@@ -1129,7 +1135,7 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) | |||
1129 | * mapped. | 1135 | * mapped. |
1130 | * | 1136 | * |
1131 | * If file type is extents based, it will call ext4_ext_get_blocks(), | 1137 | * If file type is extents based, it will call ext4_ext_get_blocks(), |
1132 | * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping | 1138 | * Otherwise, call with ext4_ind_get_blocks() to handle indirect mapping |
1133 | * based files | 1139 | * based files |
1134 | * | 1140 | * |
1135 | * On success, it returns the number of blocks being mapped or allocate. | 1141 | * On success, it returns the number of blocks being mapped or allocate. |
@@ -1142,9 +1148,9 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) | |||
1142 | * | 1148 | * |
1143 | * It returns the error in case of allocation failure. | 1149 | * It returns the error in case of allocation failure. |
1144 | */ | 1150 | */ |
1145 | int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | 1151 | int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block, |
1146 | unsigned int max_blocks, struct buffer_head *bh, | 1152 | unsigned int max_blocks, struct buffer_head *bh, |
1147 | int create, int extend_disksize, int flag) | 1153 | int flags) |
1148 | { | 1154 | { |
1149 | int retval; | 1155 | int retval; |
1150 | 1156 | ||
@@ -1152,21 +1158,28 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | |||
1152 | clear_buffer_unwritten(bh); | 1158 | clear_buffer_unwritten(bh); |
1153 | 1159 | ||
1154 | /* | 1160 | /* |
1155 | * Try to see if we can get the block without requesting | 1161 | * Try to see if we can get the block without requesting a new |
1156 | * for new file system block. | 1162 | * file system block. |
1157 | */ | 1163 | */ |
1158 | down_read((&EXT4_I(inode)->i_data_sem)); | 1164 | down_read((&EXT4_I(inode)->i_data_sem)); |
1159 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { | 1165 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { |
1160 | retval = ext4_ext_get_blocks(handle, inode, block, max_blocks, | 1166 | retval = ext4_ext_get_blocks(handle, inode, block, max_blocks, |
1161 | bh, 0, 0); | 1167 | bh, 0); |
1162 | } else { | 1168 | } else { |
1163 | retval = ext4_get_blocks_handle(handle, | 1169 | retval = ext4_ind_get_blocks(handle, inode, block, max_blocks, |
1164 | inode, block, max_blocks, bh, 0, 0); | 1170 | bh, 0); |
1165 | } | 1171 | } |
1166 | up_read((&EXT4_I(inode)->i_data_sem)); | 1172 | up_read((&EXT4_I(inode)->i_data_sem)); |
1167 | 1173 | ||
1174 | if (retval > 0 && buffer_mapped(bh)) { | ||
1175 | int ret = check_block_validity(inode, block, | ||
1176 | bh->b_blocknr, retval); | ||
1177 | if (ret != 0) | ||
1178 | return ret; | ||
1179 | } | ||
1180 | |||
1168 | /* If it is only a block(s) look up */ | 1181 | /* If it is only a block(s) look up */ |
1169 | if (!create) | 1182 | if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) |
1170 | return retval; | 1183 | return retval; |
1171 | 1184 | ||
1172 | /* | 1185 | /* |
@@ -1205,7 +1218,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | |||
1205 | * let the underlying get_block() function know to | 1218 | * let the underlying get_block() function know to |
1206 | * avoid double accounting | 1219 | * avoid double accounting |
1207 | */ | 1220 | */ |
1208 | if (flag) | 1221 | if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) |
1209 | EXT4_I(inode)->i_delalloc_reserved_flag = 1; | 1222 | EXT4_I(inode)->i_delalloc_reserved_flag = 1; |
1210 | /* | 1223 | /* |
1211 | * We need to check for EXT4 here because migrate | 1224 | * We need to check for EXT4 here because migrate |
@@ -1213,10 +1226,10 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | |||
1213 | */ | 1226 | */ |
1214 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { | 1227 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { |
1215 | retval = ext4_ext_get_blocks(handle, inode, block, max_blocks, | 1228 | retval = ext4_ext_get_blocks(handle, inode, block, max_blocks, |
1216 | bh, create, extend_disksize); | 1229 | bh, flags); |
1217 | } else { | 1230 | } else { |
1218 | retval = ext4_get_blocks_handle(handle, inode, block, | 1231 | retval = ext4_ind_get_blocks(handle, inode, block, |
1219 | max_blocks, bh, create, extend_disksize); | 1232 | max_blocks, bh, flags); |
1220 | 1233 | ||
1221 | if (retval > 0 && buffer_new(bh)) { | 1234 | if (retval > 0 && buffer_new(bh)) { |
1222 | /* | 1235 | /* |
@@ -1229,18 +1242,23 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | |||
1229 | } | 1242 | } |
1230 | } | 1243 | } |
1231 | 1244 | ||
1232 | if (flag) { | 1245 | if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) |
1233 | EXT4_I(inode)->i_delalloc_reserved_flag = 0; | 1246 | EXT4_I(inode)->i_delalloc_reserved_flag = 0; |
1234 | /* | 1247 | |
1235 | * Update reserved blocks/metadata blocks | 1248 | /* |
1236 | * after successful block allocation | 1249 | * Update reserved blocks/metadata blocks after successful |
1237 | * which were deferred till now | 1250 | * block allocation which had been deferred till now. |
1238 | */ | 1251 | */ |
1239 | if ((retval > 0) && buffer_delay(bh)) | 1252 | if ((retval > 0) && (flags & EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE)) |
1240 | ext4_da_update_reserve_space(inode, retval); | 1253 | ext4_da_update_reserve_space(inode, retval); |
1241 | } | ||
1242 | 1254 | ||
1243 | up_write((&EXT4_I(inode)->i_data_sem)); | 1255 | up_write((&EXT4_I(inode)->i_data_sem)); |
1256 | if (retval > 0 && buffer_mapped(bh)) { | ||
1257 | int ret = check_block_validity(inode, block, | ||
1258 | bh->b_blocknr, retval); | ||
1259 | if (ret != 0) | ||
1260 | return ret; | ||
1261 | } | ||
1244 | return retval; | 1262 | return retval; |
1245 | } | 1263 | } |
1246 | 1264 | ||
@@ -1268,8 +1286,8 @@ int ext4_get_block(struct inode *inode, sector_t iblock, | |||
1268 | started = 1; | 1286 | started = 1; |
1269 | } | 1287 | } |
1270 | 1288 | ||
1271 | ret = ext4_get_blocks_wrap(handle, inode, iblock, | 1289 | ret = ext4_get_blocks(handle, inode, iblock, max_blocks, bh_result, |
1272 | max_blocks, bh_result, create, 0, 0); | 1290 | create ? EXT4_GET_BLOCKS_CREATE : 0); |
1273 | if (ret > 0) { | 1291 | if (ret > 0) { |
1274 | bh_result->b_size = (ret << inode->i_blkbits); | 1292 | bh_result->b_size = (ret << inode->i_blkbits); |
1275 | ret = 0; | 1293 | ret = 0; |
@@ -1288,17 +1306,19 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, | |||
1288 | { | 1306 | { |
1289 | struct buffer_head dummy; | 1307 | struct buffer_head dummy; |
1290 | int fatal = 0, err; | 1308 | int fatal = 0, err; |
1309 | int flags = 0; | ||
1291 | 1310 | ||
1292 | J_ASSERT(handle != NULL || create == 0); | 1311 | J_ASSERT(handle != NULL || create == 0); |
1293 | 1312 | ||
1294 | dummy.b_state = 0; | 1313 | dummy.b_state = 0; |
1295 | dummy.b_blocknr = -1000; | 1314 | dummy.b_blocknr = -1000; |
1296 | buffer_trace_init(&dummy.b_history); | 1315 | buffer_trace_init(&dummy.b_history); |
1297 | err = ext4_get_blocks_wrap(handle, inode, block, 1, | 1316 | if (create) |
1298 | &dummy, create, 1, 0); | 1317 | flags |= EXT4_GET_BLOCKS_CREATE; |
1318 | err = ext4_get_blocks(handle, inode, block, 1, &dummy, flags); | ||
1299 | /* | 1319 | /* |
1300 | * ext4_get_blocks_handle() returns number of blocks | 1320 | * ext4_get_blocks() returns number of blocks mapped. 0 in |
1301 | * mapped. 0 in case of a HOLE. | 1321 | * case of a HOLE. |
1302 | */ | 1322 | */ |
1303 | if (err > 0) { | 1323 | if (err > 0) { |
1304 | if (err > 1) | 1324 | if (err > 1) |
@@ -1439,7 +1459,7 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, | |||
1439 | struct page **pagep, void **fsdata) | 1459 | struct page **pagep, void **fsdata) |
1440 | { | 1460 | { |
1441 | struct inode *inode = mapping->host; | 1461 | struct inode *inode = mapping->host; |
1442 | int ret, needed_blocks = ext4_writepage_trans_blocks(inode); | 1462 | int ret, needed_blocks; |
1443 | handle_t *handle; | 1463 | handle_t *handle; |
1444 | int retries = 0; | 1464 | int retries = 0; |
1445 | struct page *page; | 1465 | struct page *page; |
@@ -1450,6 +1470,11 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, | |||
1450 | "dev %s ino %lu pos %llu len %u flags %u", | 1470 | "dev %s ino %lu pos %llu len %u flags %u", |
1451 | inode->i_sb->s_id, inode->i_ino, | 1471 | inode->i_sb->s_id, inode->i_ino, |
1452 | (unsigned long long) pos, len, flags); | 1472 | (unsigned long long) pos, len, flags); |
1473 | /* | ||
1474 | * Reserve one block more for addition to orphan list in case | ||
1475 | * we allocate blocks but write fails for some reason | ||
1476 | */ | ||
1477 | needed_blocks = ext4_writepage_trans_blocks(inode) + 1; | ||
1453 | index = pos >> PAGE_CACHE_SHIFT; | 1478 | index = pos >> PAGE_CACHE_SHIFT; |
1454 | from = pos & (PAGE_CACHE_SIZE - 1); | 1479 | from = pos & (PAGE_CACHE_SIZE - 1); |
1455 | to = from + len; | 1480 | to = from + len; |
@@ -1483,15 +1508,30 @@ retry: | |||
1483 | 1508 | ||
1484 | if (ret) { | 1509 | if (ret) { |
1485 | unlock_page(page); | 1510 | unlock_page(page); |
1486 | ext4_journal_stop(handle); | ||
1487 | page_cache_release(page); | 1511 | page_cache_release(page); |
1488 | /* | 1512 | /* |
1489 | * block_write_begin may have instantiated a few blocks | 1513 | * block_write_begin may have instantiated a few blocks |
1490 | * outside i_size. Trim these off again. Don't need | 1514 | * outside i_size. Trim these off again. Don't need |
1491 | * i_size_read because we hold i_mutex. | 1515 | * i_size_read because we hold i_mutex. |
1516 | * | ||
1517 | * Add inode to orphan list in case we crash before | ||
1518 | * truncate finishes | ||
1492 | */ | 1519 | */ |
1493 | if (pos + len > inode->i_size) | 1520 | if (pos + len > inode->i_size) |
1521 | ext4_orphan_add(handle, inode); | ||
1522 | |||
1523 | ext4_journal_stop(handle); | ||
1524 | if (pos + len > inode->i_size) { | ||
1494 | vmtruncate(inode, inode->i_size); | 1525 | vmtruncate(inode, inode->i_size); |
1526 | /* | ||
1527 | * If vmtruncate failed early the inode might | ||
1528 | * still be on the orphan list; we need to | ||
1529 | * make sure the inode is removed from the | ||
1530 | * orphan list in that case. | ||
1531 | */ | ||
1532 | if (inode->i_nlink) | ||
1533 | ext4_orphan_del(NULL, inode); | ||
1534 | } | ||
1495 | } | 1535 | } |
1496 | 1536 | ||
1497 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 1537 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) |
@@ -1509,6 +1549,52 @@ static int write_end_fn(handle_t *handle, struct buffer_head *bh) | |||
1509 | return ext4_handle_dirty_metadata(handle, NULL, bh); | 1549 | return ext4_handle_dirty_metadata(handle, NULL, bh); |
1510 | } | 1550 | } |
1511 | 1551 | ||
1552 | static int ext4_generic_write_end(struct file *file, | ||
1553 | struct address_space *mapping, | ||
1554 | loff_t pos, unsigned len, unsigned copied, | ||
1555 | struct page *page, void *fsdata) | ||
1556 | { | ||
1557 | int i_size_changed = 0; | ||
1558 | struct inode *inode = mapping->host; | ||
1559 | handle_t *handle = ext4_journal_current_handle(); | ||
1560 | |||
1561 | copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); | ||
1562 | |||
1563 | /* | ||
1564 | * No need to use i_size_read() here, the i_size | ||
1565 | * cannot change under us because we hold i_mutex. | ||
1566 | * | ||
1567 | * But it's important to update i_size while still holding page lock: | ||
1568 | * page writeout could otherwise come in and zero beyond i_size. | ||
1569 | */ | ||
1570 | if (pos + copied > inode->i_size) { | ||
1571 | i_size_write(inode, pos + copied); | ||
1572 | i_size_changed = 1; | ||
1573 | } | ||
1574 | |||
1575 | if (pos + copied > EXT4_I(inode)->i_disksize) { | ||
1576 | /* We need to mark inode dirty even if | ||
1577 | * new_i_size is less that inode->i_size | ||
1578 | * bu greater than i_disksize.(hint delalloc) | ||
1579 | */ | ||
1580 | ext4_update_i_disksize(inode, (pos + copied)); | ||
1581 | i_size_changed = 1; | ||
1582 | } | ||
1583 | unlock_page(page); | ||
1584 | page_cache_release(page); | ||
1585 | |||
1586 | /* | ||
1587 | * Don't mark the inode dirty under page lock. First, it unnecessarily | ||
1588 | * makes the holding time of page lock longer. Second, it forces lock | ||
1589 | * ordering of page lock and transaction start for journaling | ||
1590 | * filesystems. | ||
1591 | */ | ||
1592 | if (i_size_changed) | ||
1593 | ext4_mark_inode_dirty(handle, inode); | ||
1594 | |||
1595 | return copied; | ||
1596 | } | ||
1597 | |||
1512 | /* | 1598 | /* |
1513 | * We need to pick up the new inode size which generic_commit_write gave us | 1599 | * We need to pick up the new inode size which generic_commit_write gave us |
1514 | * `file' can be NULL - eg, when called from page_symlink(). | 1600 | * `file' can be NULL - eg, when called from page_symlink(). |
@@ -1532,21 +1618,15 @@ static int ext4_ordered_write_end(struct file *file, | |||
1532 | ret = ext4_jbd2_file_inode(handle, inode); | 1618 | ret = ext4_jbd2_file_inode(handle, inode); |
1533 | 1619 | ||
1534 | if (ret == 0) { | 1620 | if (ret == 0) { |
1535 | loff_t new_i_size; | 1621 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, |
1536 | |||
1537 | new_i_size = pos + copied; | ||
1538 | if (new_i_size > EXT4_I(inode)->i_disksize) { | ||
1539 | ext4_update_i_disksize(inode, new_i_size); | ||
1540 | /* We need to mark inode dirty even if | ||
1541 | * new_i_size is less that inode->i_size | ||
1542 | * bu greater than i_disksize.(hint delalloc) | ||
1543 | */ | ||
1544 | ext4_mark_inode_dirty(handle, inode); | ||
1545 | } | ||
1546 | |||
1547 | ret2 = generic_write_end(file, mapping, pos, len, copied, | ||
1548 | page, fsdata); | 1622 | page, fsdata); |
1549 | copied = ret2; | 1623 | copied = ret2; |
1624 | if (pos + len > inode->i_size) | ||
1625 | /* if we have allocated more blocks and copied | ||
1626 | * less. We will have blocks allocated outside | ||
1627 | * inode->i_size. So truncate them | ||
1628 | */ | ||
1629 | ext4_orphan_add(handle, inode); | ||
1550 | if (ret2 < 0) | 1630 | if (ret2 < 0) |
1551 | ret = ret2; | 1631 | ret = ret2; |
1552 | } | 1632 | } |
@@ -1554,6 +1634,18 @@ static int ext4_ordered_write_end(struct file *file, | |||
1554 | if (!ret) | 1634 | if (!ret) |
1555 | ret = ret2; | 1635 | ret = ret2; |
1556 | 1636 | ||
1637 | if (pos + len > inode->i_size) { | ||
1638 | vmtruncate(inode, inode->i_size); | ||
1639 | /* | ||
1640 | * If vmtruncate failed early the inode might still be | ||
1641 | * on the orphan list; we need to make sure the inode | ||
1642 | * is removed from the orphan list in that case. | ||
1643 | */ | ||
1644 | if (inode->i_nlink) | ||
1645 | ext4_orphan_del(NULL, inode); | ||
1646 | } | ||
1647 | |||
1648 | |||
1557 | return ret ? ret : copied; | 1649 | return ret ? ret : copied; |
1558 | } | 1650 | } |
1559 | 1651 | ||
@@ -1565,25 +1657,21 @@ static int ext4_writeback_write_end(struct file *file, | |||
1565 | handle_t *handle = ext4_journal_current_handle(); | 1657 | handle_t *handle = ext4_journal_current_handle(); |
1566 | struct inode *inode = mapping->host; | 1658 | struct inode *inode = mapping->host; |
1567 | int ret = 0, ret2; | 1659 | int ret = 0, ret2; |
1568 | loff_t new_i_size; | ||
1569 | 1660 | ||
1570 | trace_mark(ext4_writeback_write_end, | 1661 | trace_mark(ext4_writeback_write_end, |
1571 | "dev %s ino %lu pos %llu len %u copied %u", | 1662 | "dev %s ino %lu pos %llu len %u copied %u", |
1572 | inode->i_sb->s_id, inode->i_ino, | 1663 | inode->i_sb->s_id, inode->i_ino, |
1573 | (unsigned long long) pos, len, copied); | 1664 | (unsigned long long) pos, len, copied); |
1574 | new_i_size = pos + copied; | 1665 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, |
1575 | if (new_i_size > EXT4_I(inode)->i_disksize) { | ||
1576 | ext4_update_i_disksize(inode, new_i_size); | ||
1577 | /* We need to mark inode dirty even if | ||
1578 | * new_i_size is less that inode->i_size | ||
1579 | * bu greater than i_disksize.(hint delalloc) | ||
1580 | */ | ||
1581 | ext4_mark_inode_dirty(handle, inode); | ||
1582 | } | ||
1583 | |||
1584 | ret2 = generic_write_end(file, mapping, pos, len, copied, | ||
1585 | page, fsdata); | 1666 | page, fsdata); |
1586 | copied = ret2; | 1667 | copied = ret2; |
1668 | if (pos + len > inode->i_size) | ||
1669 | /* if we have allocated more blocks and copied | ||
1670 | * less. We will have blocks allocated outside | ||
1671 | * inode->i_size. So truncate them | ||
1672 | */ | ||
1673 | ext4_orphan_add(handle, inode); | ||
1674 | |||
1587 | if (ret2 < 0) | 1675 | if (ret2 < 0) |
1588 | ret = ret2; | 1676 | ret = ret2; |
1589 | 1677 | ||
@@ -1591,6 +1679,17 @@ static int ext4_writeback_write_end(struct file *file, | |||
1591 | if (!ret) | 1679 | if (!ret) |
1592 | ret = ret2; | 1680 | ret = ret2; |
1593 | 1681 | ||
1682 | if (pos + len > inode->i_size) { | ||
1683 | vmtruncate(inode, inode->i_size); | ||
1684 | /* | ||
1685 | * If vmtruncate failed early the inode might still be | ||
1686 | * on the orphan list; we need to make sure the inode | ||
1687 | * is removed from the orphan list in that case. | ||
1688 | */ | ||
1689 | if (inode->i_nlink) | ||
1690 | ext4_orphan_del(NULL, inode); | ||
1691 | } | ||
1692 | |||
1594 | return ret ? ret : copied; | 1693 | return ret ? ret : copied; |
1595 | } | 1694 | } |
1596 | 1695 | ||
@@ -1635,10 +1734,27 @@ static int ext4_journalled_write_end(struct file *file, | |||
1635 | } | 1734 | } |
1636 | 1735 | ||
1637 | unlock_page(page); | 1736 | unlock_page(page); |
1737 | page_cache_release(page); | ||
1738 | if (pos + len > inode->i_size) | ||
1739 | /* if we have allocated more blocks and copied | ||
1740 | * less. We will have blocks allocated outside | ||
1741 | * inode->i_size. So truncate them | ||
1742 | */ | ||
1743 | ext4_orphan_add(handle, inode); | ||
1744 | |||
1638 | ret2 = ext4_journal_stop(handle); | 1745 | ret2 = ext4_journal_stop(handle); |
1639 | if (!ret) | 1746 | if (!ret) |
1640 | ret = ret2; | 1747 | ret = ret2; |
1641 | page_cache_release(page); | 1748 | if (pos + len > inode->i_size) { |
1749 | vmtruncate(inode, inode->i_size); | ||
1750 | /* | ||
1751 | * If vmtruncate failed early the inode might still be | ||
1752 | * on the orphan list; we need to make sure the inode | ||
1753 | * is removed from the orphan list in that case. | ||
1754 | */ | ||
1755 | if (inode->i_nlink) | ||
1756 | ext4_orphan_del(NULL, inode); | ||
1757 | } | ||
1642 | 1758 | ||
1643 | return ret ? ret : copied; | 1759 | return ret ? ret : copied; |
1644 | } | 1760 | } |
@@ -1852,7 +1968,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd) | |||
1852 | * @logical - first logical block to start assignment with | 1968 | * @logical - first logical block to start assignment with |
1853 | * | 1969 | * |
1854 | * the function goes through all passed space and put actual disk | 1970 | * the function goes through all passed space and put actual disk |
1855 | * block numbers into buffer heads, dropping BH_Delay | 1971 | * block numbers into buffer heads, dropping BH_Delay and BH_Unwritten |
1856 | */ | 1972 | */ |
1857 | static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical, | 1973 | static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical, |
1858 | struct buffer_head *exbh) | 1974 | struct buffer_head *exbh) |
@@ -1902,16 +2018,24 @@ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical, | |||
1902 | do { | 2018 | do { |
1903 | if (cur_logical >= logical + blocks) | 2019 | if (cur_logical >= logical + blocks) |
1904 | break; | 2020 | break; |
1905 | if (buffer_delay(bh)) { | 2021 | |
1906 | bh->b_blocknr = pblock; | 2022 | if (buffer_delay(bh) || |
1907 | clear_buffer_delay(bh); | 2023 | buffer_unwritten(bh)) { |
1908 | bh->b_bdev = inode->i_sb->s_bdev; | 2024 | |
1909 | } else if (buffer_unwritten(bh)) { | 2025 | BUG_ON(bh->b_bdev != inode->i_sb->s_bdev); |
1910 | bh->b_blocknr = pblock; | 2026 | |
1911 | clear_buffer_unwritten(bh); | 2027 | if (buffer_delay(bh)) { |
1912 | set_buffer_mapped(bh); | 2028 | clear_buffer_delay(bh); |
1913 | set_buffer_new(bh); | 2029 | bh->b_blocknr = pblock; |
1914 | bh->b_bdev = inode->i_sb->s_bdev; | 2030 | } else { |
2031 | /* | ||
2032 | * unwritten already should have | ||
2033 | * blocknr assigned. Verify that | ||
2034 | */ | ||
2035 | clear_buffer_unwritten(bh); | ||
2036 | BUG_ON(bh->b_blocknr != pblock); | ||
2037 | } | ||
2038 | |||
1915 | } else if (buffer_mapped(bh)) | 2039 | } else if (buffer_mapped(bh)) |
1916 | BUG_ON(bh->b_blocknr != pblock); | 2040 | BUG_ON(bh->b_blocknr != pblock); |
1917 | 2041 | ||
@@ -1990,51 +2114,6 @@ static void ext4_print_free_blocks(struct inode *inode) | |||
1990 | return; | 2114 | return; |
1991 | } | 2115 | } |
1992 | 2116 | ||
1993 | #define EXT4_DELALLOC_RSVED 1 | ||
1994 | static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, | ||
1995 | struct buffer_head *bh_result, int create) | ||
1996 | { | ||
1997 | int ret; | ||
1998 | unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; | ||
1999 | loff_t disksize = EXT4_I(inode)->i_disksize; | ||
2000 | handle_t *handle = NULL; | ||
2001 | |||
2002 | handle = ext4_journal_current_handle(); | ||
2003 | BUG_ON(!handle); | ||
2004 | ret = ext4_get_blocks_wrap(handle, inode, iblock, max_blocks, | ||
2005 | bh_result, create, 0, EXT4_DELALLOC_RSVED); | ||
2006 | if (ret <= 0) | ||
2007 | return ret; | ||
2008 | |||
2009 | bh_result->b_size = (ret << inode->i_blkbits); | ||
2010 | |||
2011 | if (ext4_should_order_data(inode)) { | ||
2012 | int retval; | ||
2013 | retval = ext4_jbd2_file_inode(handle, inode); | ||
2014 | if (retval) | ||
2015 | /* | ||
2016 | * Failed to add inode for ordered mode. Don't | ||
2017 | * update file size | ||
2018 | */ | ||
2019 | return retval; | ||
2020 | } | ||
2021 | |||
2022 | /* | ||
2023 | * Update on-disk size along with block allocation we don't | ||
2024 | * use 'extend_disksize' as size may change within already | ||
2025 | * allocated block -bzzz | ||
2026 | */ | ||
2027 | disksize = ((loff_t) iblock + ret) << inode->i_blkbits; | ||
2028 | if (disksize > i_size_read(inode)) | ||
2029 | disksize = i_size_read(inode); | ||
2030 | if (disksize > EXT4_I(inode)->i_disksize) { | ||
2031 | ext4_update_i_disksize(inode, disksize); | ||
2032 | ret = ext4_mark_inode_dirty(handle, inode); | ||
2033 | return ret; | ||
2034 | } | ||
2035 | return 0; | ||
2036 | } | ||
2037 | |||
2038 | /* | 2117 | /* |
2039 | * mpage_da_map_blocks - go through given space | 2118 | * mpage_da_map_blocks - go through given space |
2040 | * | 2119 | * |
@@ -2045,29 +2124,57 @@ static int ext4_da_get_block_write(struct inode *inode, sector_t iblock, | |||
2045 | */ | 2124 | */ |
2046 | static int mpage_da_map_blocks(struct mpage_da_data *mpd) | 2125 | static int mpage_da_map_blocks(struct mpage_da_data *mpd) |
2047 | { | 2126 | { |
2048 | int err = 0; | 2127 | int err, blks, get_blocks_flags; |
2049 | struct buffer_head new; | 2128 | struct buffer_head new; |
2050 | sector_t next; | 2129 | sector_t next = mpd->b_blocknr; |
2130 | unsigned max_blocks = mpd->b_size >> mpd->inode->i_blkbits; | ||
2131 | loff_t disksize = EXT4_I(mpd->inode)->i_disksize; | ||
2132 | handle_t *handle = NULL; | ||
2051 | 2133 | ||
2052 | /* | 2134 | /* |
2053 | * We consider only non-mapped and non-allocated blocks | 2135 | * We consider only non-mapped and non-allocated blocks |
2054 | */ | 2136 | */ |
2055 | if ((mpd->b_state & (1 << BH_Mapped)) && | 2137 | if ((mpd->b_state & (1 << BH_Mapped)) && |
2056 | !(mpd->b_state & (1 << BH_Delay))) | 2138 | !(mpd->b_state & (1 << BH_Delay)) && |
2139 | !(mpd->b_state & (1 << BH_Unwritten))) | ||
2057 | return 0; | 2140 | return 0; |
2058 | new.b_state = mpd->b_state; | 2141 | |
2059 | new.b_blocknr = 0; | ||
2060 | new.b_size = mpd->b_size; | ||
2061 | next = mpd->b_blocknr; | ||
2062 | /* | 2142 | /* |
2063 | * If we didn't accumulate anything | 2143 | * If we didn't accumulate anything to write simply return |
2064 | * to write simply return | ||
2065 | */ | 2144 | */ |
2066 | if (!new.b_size) | 2145 | if (!mpd->b_size) |
2067 | return 0; | 2146 | return 0; |
2068 | 2147 | ||
2069 | err = ext4_da_get_block_write(mpd->inode, next, &new, 1); | 2148 | handle = ext4_journal_current_handle(); |
2070 | if (err) { | 2149 | BUG_ON(!handle); |
2150 | |||
2151 | /* | ||
2152 | * Call ext4_get_blocks() to allocate any delayed allocation | ||
2153 | * blocks, or to convert an uninitialized extent to be | ||
2154 | * initialized (in the case where we have written into | ||
2155 | * one or more preallocated blocks). | ||
2156 | * | ||
2157 | * We pass in the magic EXT4_GET_BLOCKS_DELALLOC_RESERVE to | ||
2158 | * indicate that we are on the delayed allocation path. This | ||
2159 | * affects functions in many different parts of the allocation | ||
2160 | * call path. This flag exists primarily because we don't | ||
2161 | * want to change *many* call functions, so ext4_get_blocks() | ||
2162 | * will set the magic i_delalloc_reserved_flag once the | ||
2163 | * inode's allocation semaphore is taken. | ||
2164 | * | ||
2165 | * If the blocks in questions were delalloc blocks, set | ||
2166 | * EXT4_GET_BLOCKS_DELALLOC_RESERVE so the delalloc accounting | ||
2167 | * variables are updated after the blocks have been allocated. | ||
2168 | */ | ||
2169 | new.b_state = 0; | ||
2170 | get_blocks_flags = (EXT4_GET_BLOCKS_CREATE | | ||
2171 | EXT4_GET_BLOCKS_DELALLOC_RESERVE); | ||
2172 | if (mpd->b_state & (1 << BH_Delay)) | ||
2173 | get_blocks_flags |= EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE; | ||
2174 | blks = ext4_get_blocks(handle, mpd->inode, next, max_blocks, | ||
2175 | &new, get_blocks_flags); | ||
2176 | if (blks < 0) { | ||
2177 | err = blks; | ||
2071 | /* | 2178 | /* |
2072 | * If get block returns with error we simply | 2179 | * If get block returns with error we simply |
2073 | * return. Later writepage will redirty the page and | 2180 | * return. Later writepage will redirty the page and |
@@ -2100,12 +2207,14 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd) | |||
2100 | if (err == -ENOSPC) { | 2207 | if (err == -ENOSPC) { |
2101 | ext4_print_free_blocks(mpd->inode); | 2208 | ext4_print_free_blocks(mpd->inode); |
2102 | } | 2209 | } |
2103 | /* invlaidate all the pages */ | 2210 | /* invalidate all the pages */ |
2104 | ext4_da_block_invalidatepages(mpd, next, | 2211 | ext4_da_block_invalidatepages(mpd, next, |
2105 | mpd->b_size >> mpd->inode->i_blkbits); | 2212 | mpd->b_size >> mpd->inode->i_blkbits); |
2106 | return err; | 2213 | return err; |
2107 | } | 2214 | } |
2108 | BUG_ON(new.b_size == 0); | 2215 | BUG_ON(blks == 0); |
2216 | |||
2217 | new.b_size = (blks << mpd->inode->i_blkbits); | ||
2109 | 2218 | ||
2110 | if (buffer_new(&new)) | 2219 | if (buffer_new(&new)) |
2111 | __unmap_underlying_blocks(mpd->inode, &new); | 2220 | __unmap_underlying_blocks(mpd->inode, &new); |
@@ -2118,6 +2227,23 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd) | |||
2118 | (mpd->b_state & (1 << BH_Unwritten))) | 2227 | (mpd->b_state & (1 << BH_Unwritten))) |
2119 | mpage_put_bnr_to_bhs(mpd, next, &new); | 2228 | mpage_put_bnr_to_bhs(mpd, next, &new); |
2120 | 2229 | ||
2230 | if (ext4_should_order_data(mpd->inode)) { | ||
2231 | err = ext4_jbd2_file_inode(handle, mpd->inode); | ||
2232 | if (err) | ||
2233 | return err; | ||
2234 | } | ||
2235 | |||
2236 | /* | ||
2237 | * Update on-disk size along with block allocation. | ||
2238 | */ | ||
2239 | disksize = ((loff_t) next + blks) << mpd->inode->i_blkbits; | ||
2240 | if (disksize > i_size_read(mpd->inode)) | ||
2241 | disksize = i_size_read(mpd->inode); | ||
2242 | if (disksize > EXT4_I(mpd->inode)->i_disksize) { | ||
2243 | ext4_update_i_disksize(mpd->inode, disksize); | ||
2244 | return ext4_mark_inode_dirty(handle, mpd->inode); | ||
2245 | } | ||
2246 | |||
2121 | return 0; | 2247 | return 0; |
2122 | } | 2248 | } |
2123 | 2249 | ||
@@ -2192,6 +2318,17 @@ flush_it: | |||
2192 | return; | 2318 | return; |
2193 | } | 2319 | } |
2194 | 2320 | ||
2321 | static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) | ||
2322 | { | ||
2323 | /* | ||
2324 | * unmapped buffer is possible for holes. | ||
2325 | * delay buffer is possible with delayed allocation. | ||
2326 | * We also need to consider unwritten buffer as unmapped. | ||
2327 | */ | ||
2328 | return (!buffer_mapped(bh) || buffer_delay(bh) || | ||
2329 | buffer_unwritten(bh)) && buffer_dirty(bh); | ||
2330 | } | ||
2331 | |||
2195 | /* | 2332 | /* |
2196 | * __mpage_da_writepage - finds extent of pages and blocks | 2333 | * __mpage_da_writepage - finds extent of pages and blocks |
2197 | * | 2334 | * |
@@ -2276,8 +2413,7 @@ static int __mpage_da_writepage(struct page *page, | |||
2276 | * Otherwise we won't make progress | 2413 | * Otherwise we won't make progress |
2277 | * with the page in ext4_da_writepage | 2414 | * with the page in ext4_da_writepage |
2278 | */ | 2415 | */ |
2279 | if (buffer_dirty(bh) && | 2416 | if (ext4_bh_unmapped_or_delay(NULL, bh)) { |
2280 | (!buffer_mapped(bh) || buffer_delay(bh))) { | ||
2281 | mpage_add_bh_to_extent(mpd, logical, | 2417 | mpage_add_bh_to_extent(mpd, logical, |
2282 | bh->b_size, | 2418 | bh->b_size, |
2283 | bh->b_state); | 2419 | bh->b_state); |
@@ -2303,8 +2439,16 @@ static int __mpage_da_writepage(struct page *page, | |||
2303 | } | 2439 | } |
2304 | 2440 | ||
2305 | /* | 2441 | /* |
2306 | * this is a special callback for ->write_begin() only | 2442 | * This is a special get_blocks_t callback which is used by |
2307 | * it's intention is to return mapped block or reserve space | 2443 | * ext4_da_write_begin(). It will either return mapped block or |
2444 | * reserve space for a single block. | ||
2445 | * | ||
2446 | * For delayed buffer_head we have BH_Mapped, BH_New, BH_Delay set. | ||
2447 | * We also have b_blocknr = -1 and b_bdev initialized properly | ||
2448 | * | ||
2449 | * For unwritten buffer_head we have BH_Mapped, BH_New, BH_Unwritten set. | ||
2450 | * We also have b_blocknr = physicalblock mapping unwritten extent and b_bdev | ||
2451 | * initialized properly. | ||
2308 | */ | 2452 | */ |
2309 | static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, | 2453 | static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, |
2310 | struct buffer_head *bh_result, int create) | 2454 | struct buffer_head *bh_result, int create) |
@@ -2323,7 +2467,7 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, | |||
2323 | * preallocated blocks are unmapped but should treated | 2467 | * preallocated blocks are unmapped but should treated |
2324 | * the same as allocated blocks. | 2468 | * the same as allocated blocks. |
2325 | */ | 2469 | */ |
2326 | ret = ext4_get_blocks_wrap(NULL, inode, iblock, 1, bh_result, 0, 0, 0); | 2470 | ret = ext4_get_blocks(NULL, inode, iblock, 1, bh_result, 0); |
2327 | if ((ret == 0) && !buffer_delay(bh_result)) { | 2471 | if ((ret == 0) && !buffer_delay(bh_result)) { |
2328 | /* the block isn't (pre)allocated yet, let's reserve space */ | 2472 | /* the block isn't (pre)allocated yet, let's reserve space */ |
2329 | /* | 2473 | /* |
@@ -2340,40 +2484,53 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, | |||
2340 | set_buffer_delay(bh_result); | 2484 | set_buffer_delay(bh_result); |
2341 | } else if (ret > 0) { | 2485 | } else if (ret > 0) { |
2342 | bh_result->b_size = (ret << inode->i_blkbits); | 2486 | bh_result->b_size = (ret << inode->i_blkbits); |
2343 | /* | 2487 | if (buffer_unwritten(bh_result)) { |
2344 | * With sub-block writes into unwritten extents | 2488 | /* A delayed write to unwritten bh should |
2345 | * we also need to mark the buffer as new so that | 2489 | * be marked new and mapped. Mapped ensures |
2346 | * the unwritten parts of the buffer gets correctly zeroed. | 2490 | * that we don't do get_block multiple times |
2347 | */ | 2491 | * when we write to the same offset and new |
2348 | if (buffer_unwritten(bh_result)) | 2492 | * ensures that we do proper zero out for |
2493 | * partial write. | ||
2494 | */ | ||
2349 | set_buffer_new(bh_result); | 2495 | set_buffer_new(bh_result); |
2496 | set_buffer_mapped(bh_result); | ||
2497 | } | ||
2350 | ret = 0; | 2498 | ret = 0; |
2351 | } | 2499 | } |
2352 | 2500 | ||
2353 | return ret; | 2501 | return ret; |
2354 | } | 2502 | } |
2355 | 2503 | ||
2356 | static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) | 2504 | /* |
2357 | { | 2505 | * This function is used as a standard get_block_t calback function |
2358 | /* | 2506 | * when there is no desire to allocate any blocks. It is used as a |
2359 | * unmapped buffer is possible for holes. | 2507 | * callback function for block_prepare_write(), nobh_writepage(), and |
2360 | * delay buffer is possible with delayed allocation | 2508 | * block_write_full_page(). These functions should only try to map a |
2361 | */ | 2509 | * single block at a time. |
2362 | return ((!buffer_mapped(bh) || buffer_delay(bh)) && buffer_dirty(bh)); | 2510 | * |
2363 | } | 2511 | * Since this function doesn't do block allocations even if the caller |
2364 | 2512 | * requests it by passing in create=1, it is critically important that | |
2365 | static int ext4_normal_get_block_write(struct inode *inode, sector_t iblock, | 2513 | * any caller checks to make sure that any buffer heads are returned |
2514 | * by this function are either all already mapped or marked for | ||
2515 | * delayed allocation before calling nobh_writepage() or | ||
2516 | * block_write_full_page(). Otherwise, b_blocknr could be left | ||
2517 | * unitialized, and the page write functions will be taken by | ||
2518 | * surprise. | ||
2519 | */ | ||
2520 | static int noalloc_get_block_write(struct inode *inode, sector_t iblock, | ||
2366 | struct buffer_head *bh_result, int create) | 2521 | struct buffer_head *bh_result, int create) |
2367 | { | 2522 | { |
2368 | int ret = 0; | 2523 | int ret = 0; |
2369 | unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; | 2524 | unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; |
2370 | 2525 | ||
2526 | BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize); | ||
2527 | |||
2371 | /* | 2528 | /* |
2372 | * we don't want to do block allocation in writepage | 2529 | * we don't want to do block allocation in writepage |
2373 | * so call get_block_wrap with create = 0 | 2530 | * so call get_block_wrap with create = 0 |
2374 | */ | 2531 | */ |
2375 | ret = ext4_get_blocks_wrap(NULL, inode, iblock, max_blocks, | 2532 | ret = ext4_get_blocks(NULL, inode, iblock, max_blocks, bh_result, 0); |
2376 | bh_result, 0, 0, 0); | 2533 | BUG_ON(create && ret == 0); |
2377 | if (ret > 0) { | 2534 | if (ret > 0) { |
2378 | bh_result->b_size = (ret << inode->i_blkbits); | 2535 | bh_result->b_size = (ret << inode->i_blkbits); |
2379 | ret = 0; | 2536 | ret = 0; |
@@ -2382,10 +2539,11 @@ static int ext4_normal_get_block_write(struct inode *inode, sector_t iblock, | |||
2382 | } | 2539 | } |
2383 | 2540 | ||
2384 | /* | 2541 | /* |
2385 | * get called vi ext4_da_writepages after taking page lock (have journal handle) | 2542 | * This function can get called via... |
2386 | * get called via journal_submit_inode_data_buffers (no journal handle) | 2543 | * - ext4_da_writepages after taking page lock (have journal handle) |
2387 | * get called via shrink_page_list via pdflush (no journal handle) | 2544 | * - journal_submit_inode_data_buffers (no journal handle) |
2388 | * or grab_page_cache when doing write_begin (have journal handle) | 2545 | * - shrink_page_list via pdflush (no journal handle) |
2546 | * - grab_page_cache when doing write_begin (have journal handle) | ||
2389 | */ | 2547 | */ |
2390 | static int ext4_da_writepage(struct page *page, | 2548 | static int ext4_da_writepage(struct page *page, |
2391 | struct writeback_control *wbc) | 2549 | struct writeback_control *wbc) |
@@ -2436,7 +2594,7 @@ static int ext4_da_writepage(struct page *page, | |||
2436 | * do block allocation here. | 2594 | * do block allocation here. |
2437 | */ | 2595 | */ |
2438 | ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, | 2596 | ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, |
2439 | ext4_normal_get_block_write); | 2597 | noalloc_get_block_write); |
2440 | if (!ret) { | 2598 | if (!ret) { |
2441 | page_bufs = page_buffers(page); | 2599 | page_bufs = page_buffers(page); |
2442 | /* check whether all are mapped and non delay */ | 2600 | /* check whether all are mapped and non delay */ |
@@ -2461,11 +2619,10 @@ static int ext4_da_writepage(struct page *page, | |||
2461 | } | 2619 | } |
2462 | 2620 | ||
2463 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) | 2621 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) |
2464 | ret = nobh_writepage(page, ext4_normal_get_block_write, wbc); | 2622 | ret = nobh_writepage(page, noalloc_get_block_write, wbc); |
2465 | else | 2623 | else |
2466 | ret = block_write_full_page(page, | 2624 | ret = block_write_full_page(page, noalloc_get_block_write, |
2467 | ext4_normal_get_block_write, | 2625 | wbc); |
2468 | wbc); | ||
2469 | 2626 | ||
2470 | return ret; | 2627 | return ret; |
2471 | } | 2628 | } |
@@ -2777,7 +2934,7 @@ retry: | |||
2777 | *pagep = page; | 2934 | *pagep = page; |
2778 | 2935 | ||
2779 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, | 2936 | ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, |
2780 | ext4_da_get_block_prep); | 2937 | ext4_da_get_block_prep); |
2781 | if (ret < 0) { | 2938 | if (ret < 0) { |
2782 | unlock_page(page); | 2939 | unlock_page(page); |
2783 | ext4_journal_stop(handle); | 2940 | ext4_journal_stop(handle); |
@@ -2815,7 +2972,7 @@ static int ext4_da_should_update_i_disksize(struct page *page, | |||
2815 | for (i = 0; i < idx; i++) | 2972 | for (i = 0; i < idx; i++) |
2816 | bh = bh->b_this_page; | 2973 | bh = bh->b_this_page; |
2817 | 2974 | ||
2818 | if (!buffer_mapped(bh) || (buffer_delay(bh))) | 2975 | if (!buffer_mapped(bh) || (buffer_delay(bh)) || buffer_unwritten(bh)) |
2819 | return 0; | 2976 | return 0; |
2820 | return 1; | 2977 | return 1; |
2821 | } | 2978 | } |
@@ -3085,12 +3242,10 @@ static int __ext4_normal_writepage(struct page *page, | |||
3085 | struct inode *inode = page->mapping->host; | 3242 | struct inode *inode = page->mapping->host; |
3086 | 3243 | ||
3087 | if (test_opt(inode->i_sb, NOBH)) | 3244 | if (test_opt(inode->i_sb, NOBH)) |
3088 | return nobh_writepage(page, | 3245 | return nobh_writepage(page, noalloc_get_block_write, wbc); |
3089 | ext4_normal_get_block_write, wbc); | ||
3090 | else | 3246 | else |
3091 | return block_write_full_page(page, | 3247 | return block_write_full_page(page, noalloc_get_block_write, |
3092 | ext4_normal_get_block_write, | 3248 | wbc); |
3093 | wbc); | ||
3094 | } | 3249 | } |
3095 | 3250 | ||
3096 | static int ext4_normal_writepage(struct page *page, | 3251 | static int ext4_normal_writepage(struct page *page, |
@@ -3142,7 +3297,7 @@ static int __ext4_journalled_writepage(struct page *page, | |||
3142 | int err; | 3297 | int err; |
3143 | 3298 | ||
3144 | ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, | 3299 | ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, |
3145 | ext4_normal_get_block_write); | 3300 | noalloc_get_block_write); |
3146 | if (ret != 0) | 3301 | if (ret != 0) |
3147 | goto out_unlock; | 3302 | goto out_unlock; |
3148 | 3303 | ||
@@ -3227,9 +3382,8 @@ static int ext4_journalled_writepage(struct page *page, | |||
3227 | * really know unless we go poke around in the buffer_heads. | 3382 | * really know unless we go poke around in the buffer_heads. |
3228 | * But block_write_full_page will do the right thing. | 3383 | * But block_write_full_page will do the right thing. |
3229 | */ | 3384 | */ |
3230 | return block_write_full_page(page, | 3385 | return block_write_full_page(page, noalloc_get_block_write, |
3231 | ext4_normal_get_block_write, | 3386 | wbc); |
3232 | wbc); | ||
3233 | } | 3387 | } |
3234 | no_write: | 3388 | no_write: |
3235 | redirty_page_for_writepage(wbc, page); | 3389 | redirty_page_for_writepage(wbc, page); |
@@ -3973,7 +4127,8 @@ void ext4_truncate(struct inode *inode) | |||
3973 | if (!ext4_can_truncate(inode)) | 4127 | if (!ext4_can_truncate(inode)) |
3974 | return; | 4128 | return; |
3975 | 4129 | ||
3976 | if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC)) | 4130 | if (ei->i_disksize && inode->i_size == 0 && |
4131 | !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC)) | ||
3977 | ei->i_state |= EXT4_STATE_DA_ALLOC_CLOSE; | 4132 | ei->i_state |= EXT4_STATE_DA_ALLOC_CLOSE; |
3978 | 4133 | ||
3979 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { | 4134 | if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { |
@@ -4715,25 +4870,6 @@ int ext4_write_inode(struct inode *inode, int wait) | |||
4715 | return ext4_force_commit(inode->i_sb); | 4870 | return ext4_force_commit(inode->i_sb); |
4716 | } | 4871 | } |
4717 | 4872 | ||
4718 | int __ext4_write_dirty_metadata(struct inode *inode, struct buffer_head *bh) | ||
4719 | { | ||
4720 | int err = 0; | ||
4721 | |||
4722 | mark_buffer_dirty(bh); | ||
4723 | if (inode && inode_needs_sync(inode)) { | ||
4724 | sync_dirty_buffer(bh); | ||
4725 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | ||
4726 | ext4_error(inode->i_sb, __func__, | ||
4727 | "IO error syncing inode, " | ||
4728 | "inode=%lu, block=%llu", | ||
4729 | inode->i_ino, | ||
4730 | (unsigned long long)bh->b_blocknr); | ||
4731 | err = -EIO; | ||
4732 | } | ||
4733 | } | ||
4734 | return err; | ||
4735 | } | ||
4736 | |||
4737 | /* | 4873 | /* |
4738 | * ext4_setattr() | 4874 | * ext4_setattr() |
4739 | * | 4875 | * |
@@ -4930,7 +5066,8 @@ static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) | |||
4930 | */ | 5066 | */ |
4931 | int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) | 5067 | int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) |
4932 | { | 5068 | { |
4933 | int groups, gdpblocks; | 5069 | ext4_group_t groups, ngroups = ext4_get_groups_count(inode->i_sb); |
5070 | int gdpblocks; | ||
4934 | int idxblocks; | 5071 | int idxblocks; |
4935 | int ret = 0; | 5072 | int ret = 0; |
4936 | 5073 | ||
@@ -4957,8 +5094,8 @@ int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk) | |||
4957 | groups += nrblocks; | 5094 | groups += nrblocks; |
4958 | 5095 | ||
4959 | gdpblocks = groups; | 5096 | gdpblocks = groups; |
4960 | if (groups > EXT4_SB(inode->i_sb)->s_groups_count) | 5097 | if (groups > ngroups) |
4961 | groups = EXT4_SB(inode->i_sb)->s_groups_count; | 5098 | groups = ngroups; |
4962 | if (groups > EXT4_SB(inode->i_sb)->s_gdb_count) | 5099 | if (groups > EXT4_SB(inode->i_sb)->s_gdb_count) |
4963 | gdpblocks = EXT4_SB(inode->i_sb)->s_gdb_count; | 5100 | gdpblocks = EXT4_SB(inode->i_sb)->s_gdb_count; |
4964 | 5101 | ||
@@ -4998,7 +5135,7 @@ int ext4_writepage_trans_blocks(struct inode *inode) | |||
4998 | * Calculate the journal credits for a chunk of data modification. | 5135 | * Calculate the journal credits for a chunk of data modification. |
4999 | * | 5136 | * |
5000 | * This is called from DIO, fallocate or whoever calling | 5137 | * This is called from DIO, fallocate or whoever calling |
5001 | * ext4_get_blocks_wrap() to map/allocate a chunk of contigous disk blocks. | 5138 | * ext4_get_blocks() to map/allocate a chunk of contigous disk blocks. |
5002 | * | 5139 | * |
5003 | * journal buffers for data blocks are not included here, as DIO | 5140 | * journal buffers for data blocks are not included here, as DIO |
5004 | * and fallocate do no need to journal data buffers. | 5141 | * and fallocate do no need to journal data buffers. |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index f871677a7984..ed8482e22c0e 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -372,24 +372,12 @@ static inline void mb_set_bit(int bit, void *addr) | |||
372 | ext4_set_bit(bit, addr); | 372 | ext4_set_bit(bit, addr); |
373 | } | 373 | } |
374 | 374 | ||
375 | static inline void mb_set_bit_atomic(spinlock_t *lock, int bit, void *addr) | ||
376 | { | ||
377 | addr = mb_correct_addr_and_bit(&bit, addr); | ||
378 | ext4_set_bit_atomic(lock, bit, addr); | ||
379 | } | ||
380 | |||
381 | static inline void mb_clear_bit(int bit, void *addr) | 375 | static inline void mb_clear_bit(int bit, void *addr) |
382 | { | 376 | { |
383 | addr = mb_correct_addr_and_bit(&bit, addr); | 377 | addr = mb_correct_addr_and_bit(&bit, addr); |
384 | ext4_clear_bit(bit, addr); | 378 | ext4_clear_bit(bit, addr); |
385 | } | 379 | } |
386 | 380 | ||
387 | static inline void mb_clear_bit_atomic(spinlock_t *lock, int bit, void *addr) | ||
388 | { | ||
389 | addr = mb_correct_addr_and_bit(&bit, addr); | ||
390 | ext4_clear_bit_atomic(lock, bit, addr); | ||
391 | } | ||
392 | |||
393 | static inline int mb_find_next_zero_bit(void *addr, int max, int start) | 381 | static inline int mb_find_next_zero_bit(void *addr, int max, int start) |
394 | { | 382 | { |
395 | int fix = 0, ret, tmpmax; | 383 | int fix = 0, ret, tmpmax; |
@@ -448,7 +436,7 @@ static void mb_free_blocks_double(struct inode *inode, struct ext4_buddy *e4b, | |||
448 | 436 | ||
449 | if (unlikely(e4b->bd_info->bb_bitmap == NULL)) | 437 | if (unlikely(e4b->bd_info->bb_bitmap == NULL)) |
450 | return; | 438 | return; |
451 | BUG_ON(!ext4_is_group_locked(sb, e4b->bd_group)); | 439 | assert_spin_locked(ext4_group_lock_ptr(sb, e4b->bd_group)); |
452 | for (i = 0; i < count; i++) { | 440 | for (i = 0; i < count; i++) { |
453 | if (!mb_test_bit(first + i, e4b->bd_info->bb_bitmap)) { | 441 | if (!mb_test_bit(first + i, e4b->bd_info->bb_bitmap)) { |
454 | ext4_fsblk_t blocknr; | 442 | ext4_fsblk_t blocknr; |
@@ -472,7 +460,7 @@ static void mb_mark_used_double(struct ext4_buddy *e4b, int first, int count) | |||
472 | 460 | ||
473 | if (unlikely(e4b->bd_info->bb_bitmap == NULL)) | 461 | if (unlikely(e4b->bd_info->bb_bitmap == NULL)) |
474 | return; | 462 | return; |
475 | BUG_ON(!ext4_is_group_locked(e4b->bd_sb, e4b->bd_group)); | 463 | assert_spin_locked(ext4_group_lock_ptr(e4b->bd_sb, e4b->bd_group)); |
476 | for (i = 0; i < count; i++) { | 464 | for (i = 0; i < count; i++) { |
477 | BUG_ON(mb_test_bit(first + i, e4b->bd_info->bb_bitmap)); | 465 | BUG_ON(mb_test_bit(first + i, e4b->bd_info->bb_bitmap)); |
478 | mb_set_bit(first + i, e4b->bd_info->bb_bitmap); | 466 | mb_set_bit(first + i, e4b->bd_info->bb_bitmap); |
@@ -739,6 +727,7 @@ static void ext4_mb_generate_buddy(struct super_block *sb, | |||
739 | 727 | ||
740 | static int ext4_mb_init_cache(struct page *page, char *incore) | 728 | static int ext4_mb_init_cache(struct page *page, char *incore) |
741 | { | 729 | { |
730 | ext4_group_t ngroups; | ||
742 | int blocksize; | 731 | int blocksize; |
743 | int blocks_per_page; | 732 | int blocks_per_page; |
744 | int groups_per_page; | 733 | int groups_per_page; |
@@ -757,6 +746,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) | |||
757 | 746 | ||
758 | inode = page->mapping->host; | 747 | inode = page->mapping->host; |
759 | sb = inode->i_sb; | 748 | sb = inode->i_sb; |
749 | ngroups = ext4_get_groups_count(sb); | ||
760 | blocksize = 1 << inode->i_blkbits; | 750 | blocksize = 1 << inode->i_blkbits; |
761 | blocks_per_page = PAGE_CACHE_SIZE / blocksize; | 751 | blocks_per_page = PAGE_CACHE_SIZE / blocksize; |
762 | 752 | ||
@@ -780,7 +770,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) | |||
780 | for (i = 0; i < groups_per_page; i++) { | 770 | for (i = 0; i < groups_per_page; i++) { |
781 | struct ext4_group_desc *desc; | 771 | struct ext4_group_desc *desc; |
782 | 772 | ||
783 | if (first_group + i >= EXT4_SB(sb)->s_groups_count) | 773 | if (first_group + i >= ngroups) |
784 | break; | 774 | break; |
785 | 775 | ||
786 | err = -EIO; | 776 | err = -EIO; |
@@ -801,17 +791,17 @@ static int ext4_mb_init_cache(struct page *page, char *incore) | |||
801 | unlock_buffer(bh[i]); | 791 | unlock_buffer(bh[i]); |
802 | continue; | 792 | continue; |
803 | } | 793 | } |
804 | spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); | 794 | ext4_lock_group(sb, first_group + i); |
805 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 795 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { |
806 | ext4_init_block_bitmap(sb, bh[i], | 796 | ext4_init_block_bitmap(sb, bh[i], |
807 | first_group + i, desc); | 797 | first_group + i, desc); |
808 | set_bitmap_uptodate(bh[i]); | 798 | set_bitmap_uptodate(bh[i]); |
809 | set_buffer_uptodate(bh[i]); | 799 | set_buffer_uptodate(bh[i]); |
810 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); | 800 | ext4_unlock_group(sb, first_group + i); |
811 | unlock_buffer(bh[i]); | 801 | unlock_buffer(bh[i]); |
812 | continue; | 802 | continue; |
813 | } | 803 | } |
814 | spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); | 804 | ext4_unlock_group(sb, first_group + i); |
815 | if (buffer_uptodate(bh[i])) { | 805 | if (buffer_uptodate(bh[i])) { |
816 | /* | 806 | /* |
817 | * if not uninit if bh is uptodate, | 807 | * if not uninit if bh is uptodate, |
@@ -852,7 +842,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore) | |||
852 | struct ext4_group_info *grinfo; | 842 | struct ext4_group_info *grinfo; |
853 | 843 | ||
854 | group = (first_block + i) >> 1; | 844 | group = (first_block + i) >> 1; |
855 | if (group >= EXT4_SB(sb)->s_groups_count) | 845 | if (group >= ngroups) |
856 | break; | 846 | break; |
857 | 847 | ||
858 | /* | 848 | /* |
@@ -1078,7 +1068,7 @@ static int mb_find_order_for_block(struct ext4_buddy *e4b, int block) | |||
1078 | return 0; | 1068 | return 0; |
1079 | } | 1069 | } |
1080 | 1070 | ||
1081 | static void mb_clear_bits(spinlock_t *lock, void *bm, int cur, int len) | 1071 | static void mb_clear_bits(void *bm, int cur, int len) |
1082 | { | 1072 | { |
1083 | __u32 *addr; | 1073 | __u32 *addr; |
1084 | 1074 | ||
@@ -1091,15 +1081,12 @@ static void mb_clear_bits(spinlock_t *lock, void *bm, int cur, int len) | |||
1091 | cur += 32; | 1081 | cur += 32; |
1092 | continue; | 1082 | continue; |
1093 | } | 1083 | } |
1094 | if (lock) | 1084 | mb_clear_bit(cur, bm); |
1095 | mb_clear_bit_atomic(lock, cur, bm); | ||
1096 | else | ||
1097 | mb_clear_bit(cur, bm); | ||
1098 | cur++; | 1085 | cur++; |
1099 | } | 1086 | } |
1100 | } | 1087 | } |
1101 | 1088 | ||
1102 | static void mb_set_bits(spinlock_t *lock, void *bm, int cur, int len) | 1089 | static void mb_set_bits(void *bm, int cur, int len) |
1103 | { | 1090 | { |
1104 | __u32 *addr; | 1091 | __u32 *addr; |
1105 | 1092 | ||
@@ -1112,10 +1099,7 @@ static void mb_set_bits(spinlock_t *lock, void *bm, int cur, int len) | |||
1112 | cur += 32; | 1099 | cur += 32; |
1113 | continue; | 1100 | continue; |
1114 | } | 1101 | } |
1115 | if (lock) | 1102 | mb_set_bit(cur, bm); |
1116 | mb_set_bit_atomic(lock, cur, bm); | ||
1117 | else | ||
1118 | mb_set_bit(cur, bm); | ||
1119 | cur++; | 1103 | cur++; |
1120 | } | 1104 | } |
1121 | } | 1105 | } |
@@ -1131,7 +1115,7 @@ static void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b, | |||
1131 | struct super_block *sb = e4b->bd_sb; | 1115 | struct super_block *sb = e4b->bd_sb; |
1132 | 1116 | ||
1133 | BUG_ON(first + count > (sb->s_blocksize << 3)); | 1117 | BUG_ON(first + count > (sb->s_blocksize << 3)); |
1134 | BUG_ON(!ext4_is_group_locked(sb, e4b->bd_group)); | 1118 | assert_spin_locked(ext4_group_lock_ptr(sb, e4b->bd_group)); |
1135 | mb_check_buddy(e4b); | 1119 | mb_check_buddy(e4b); |
1136 | mb_free_blocks_double(inode, e4b, first, count); | 1120 | mb_free_blocks_double(inode, e4b, first, count); |
1137 | 1121 | ||
@@ -1212,7 +1196,7 @@ static int mb_find_extent(struct ext4_buddy *e4b, int order, int block, | |||
1212 | int ord; | 1196 | int ord; |
1213 | void *buddy; | 1197 | void *buddy; |
1214 | 1198 | ||
1215 | BUG_ON(!ext4_is_group_locked(e4b->bd_sb, e4b->bd_group)); | 1199 | assert_spin_locked(ext4_group_lock_ptr(e4b->bd_sb, e4b->bd_group)); |
1216 | BUG_ON(ex == NULL); | 1200 | BUG_ON(ex == NULL); |
1217 | 1201 | ||
1218 | buddy = mb_find_buddy(e4b, order, &max); | 1202 | buddy = mb_find_buddy(e4b, order, &max); |
@@ -1276,7 +1260,7 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex) | |||
1276 | 1260 | ||
1277 | BUG_ON(start + len > (e4b->bd_sb->s_blocksize << 3)); | 1261 | BUG_ON(start + len > (e4b->bd_sb->s_blocksize << 3)); |
1278 | BUG_ON(e4b->bd_group != ex->fe_group); | 1262 | BUG_ON(e4b->bd_group != ex->fe_group); |
1279 | BUG_ON(!ext4_is_group_locked(e4b->bd_sb, e4b->bd_group)); | 1263 | assert_spin_locked(ext4_group_lock_ptr(e4b->bd_sb, e4b->bd_group)); |
1280 | mb_check_buddy(e4b); | 1264 | mb_check_buddy(e4b); |
1281 | mb_mark_used_double(e4b, start, len); | 1265 | mb_mark_used_double(e4b, start, len); |
1282 | 1266 | ||
@@ -1330,8 +1314,7 @@ static int mb_mark_used(struct ext4_buddy *e4b, struct ext4_free_extent *ex) | |||
1330 | e4b->bd_info->bb_counters[ord]++; | 1314 | e4b->bd_info->bb_counters[ord]++; |
1331 | } | 1315 | } |
1332 | 1316 | ||
1333 | mb_set_bits(sb_bgl_lock(EXT4_SB(e4b->bd_sb), ex->fe_group), | 1317 | mb_set_bits(EXT4_MB_BITMAP(e4b), ex->fe_start, len0); |
1334 | EXT4_MB_BITMAP(e4b), ex->fe_start, len0); | ||
1335 | mb_check_buddy(e4b); | 1318 | mb_check_buddy(e4b); |
1336 | 1319 | ||
1337 | return ret; | 1320 | return ret; |
@@ -1726,7 +1709,6 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac, | |||
1726 | unsigned free, fragments; | 1709 | unsigned free, fragments; |
1727 | unsigned i, bits; | 1710 | unsigned i, bits; |
1728 | int flex_size = ext4_flex_bg_size(EXT4_SB(ac->ac_sb)); | 1711 | int flex_size = ext4_flex_bg_size(EXT4_SB(ac->ac_sb)); |
1729 | struct ext4_group_desc *desc; | ||
1730 | struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group); | 1712 | struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group); |
1731 | 1713 | ||
1732 | BUG_ON(cr < 0 || cr >= 4); | 1714 | BUG_ON(cr < 0 || cr >= 4); |
@@ -1742,10 +1724,6 @@ static int ext4_mb_good_group(struct ext4_allocation_context *ac, | |||
1742 | switch (cr) { | 1724 | switch (cr) { |
1743 | case 0: | 1725 | case 0: |
1744 | BUG_ON(ac->ac_2order == 0); | 1726 | BUG_ON(ac->ac_2order == 0); |
1745 | /* If this group is uninitialized, skip it initially */ | ||
1746 | desc = ext4_get_group_desc(ac->ac_sb, group, NULL); | ||
1747 | if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) | ||
1748 | return 0; | ||
1749 | 1727 | ||
1750 | /* Avoid using the first bg of a flexgroup for data files */ | 1728 | /* Avoid using the first bg of a flexgroup for data files */ |
1751 | if ((ac->ac_flags & EXT4_MB_HINT_DATA) && | 1729 | if ((ac->ac_flags & EXT4_MB_HINT_DATA) && |
@@ -1788,6 +1766,7 @@ int ext4_mb_get_buddy_cache_lock(struct super_block *sb, ext4_group_t group) | |||
1788 | int block, pnum; | 1766 | int block, pnum; |
1789 | int blocks_per_page; | 1767 | int blocks_per_page; |
1790 | int groups_per_page; | 1768 | int groups_per_page; |
1769 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
1791 | ext4_group_t first_group; | 1770 | ext4_group_t first_group; |
1792 | struct ext4_group_info *grp; | 1771 | struct ext4_group_info *grp; |
1793 | 1772 | ||
@@ -1807,7 +1786,7 @@ int ext4_mb_get_buddy_cache_lock(struct super_block *sb, ext4_group_t group) | |||
1807 | /* read all groups the page covers into the cache */ | 1786 | /* read all groups the page covers into the cache */ |
1808 | for (i = 0; i < groups_per_page; i++) { | 1787 | for (i = 0; i < groups_per_page; i++) { |
1809 | 1788 | ||
1810 | if ((first_group + i) >= EXT4_SB(sb)->s_groups_count) | 1789 | if ((first_group + i) >= ngroups) |
1811 | break; | 1790 | break; |
1812 | grp = ext4_get_group_info(sb, first_group + i); | 1791 | grp = ext4_get_group_info(sb, first_group + i); |
1813 | /* take all groups write allocation | 1792 | /* take all groups write allocation |
@@ -1945,8 +1924,7 @@ err: | |||
1945 | static noinline_for_stack int | 1924 | static noinline_for_stack int |
1946 | ext4_mb_regular_allocator(struct ext4_allocation_context *ac) | 1925 | ext4_mb_regular_allocator(struct ext4_allocation_context *ac) |
1947 | { | 1926 | { |
1948 | ext4_group_t group; | 1927 | ext4_group_t ngroups, group, i; |
1949 | ext4_group_t i; | ||
1950 | int cr; | 1928 | int cr; |
1951 | int err = 0; | 1929 | int err = 0; |
1952 | int bsbits; | 1930 | int bsbits; |
@@ -1957,6 +1935,7 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) | |||
1957 | 1935 | ||
1958 | sb = ac->ac_sb; | 1936 | sb = ac->ac_sb; |
1959 | sbi = EXT4_SB(sb); | 1937 | sbi = EXT4_SB(sb); |
1938 | ngroups = ext4_get_groups_count(sb); | ||
1960 | BUG_ON(ac->ac_status == AC_STATUS_FOUND); | 1939 | BUG_ON(ac->ac_status == AC_STATUS_FOUND); |
1961 | 1940 | ||
1962 | /* first, try the goal */ | 1941 | /* first, try the goal */ |
@@ -2017,11 +1996,11 @@ repeat: | |||
2017 | */ | 1996 | */ |
2018 | group = ac->ac_g_ex.fe_group; | 1997 | group = ac->ac_g_ex.fe_group; |
2019 | 1998 | ||
2020 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; group++, i++) { | 1999 | for (i = 0; i < ngroups; group++, i++) { |
2021 | struct ext4_group_info *grp; | 2000 | struct ext4_group_info *grp; |
2022 | struct ext4_group_desc *desc; | 2001 | struct ext4_group_desc *desc; |
2023 | 2002 | ||
2024 | if (group == EXT4_SB(sb)->s_groups_count) | 2003 | if (group == ngroups) |
2025 | group = 0; | 2004 | group = 0; |
2026 | 2005 | ||
2027 | /* quick check to skip empty groups */ | 2006 | /* quick check to skip empty groups */ |
@@ -2064,9 +2043,7 @@ repeat: | |||
2064 | 2043 | ||
2065 | ac->ac_groups_scanned++; | 2044 | ac->ac_groups_scanned++; |
2066 | desc = ext4_get_group_desc(sb, group, NULL); | 2045 | desc = ext4_get_group_desc(sb, group, NULL); |
2067 | if (cr == 0 || (desc->bg_flags & | 2046 | if (cr == 0) |
2068 | cpu_to_le16(EXT4_BG_BLOCK_UNINIT) && | ||
2069 | ac->ac_2order != 0)) | ||
2070 | ext4_mb_simple_scan_group(ac, &e4b); | 2047 | ext4_mb_simple_scan_group(ac, &e4b); |
2071 | else if (cr == 1 && | 2048 | else if (cr == 1 && |
2072 | ac->ac_g_ex.fe_len == sbi->s_stripe) | 2049 | ac->ac_g_ex.fe_len == sbi->s_stripe) |
@@ -2315,12 +2292,10 @@ static struct file_operations ext4_mb_seq_history_fops = { | |||
2315 | static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) | 2292 | static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) |
2316 | { | 2293 | { |
2317 | struct super_block *sb = seq->private; | 2294 | struct super_block *sb = seq->private; |
2318 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
2319 | ext4_group_t group; | 2295 | ext4_group_t group; |
2320 | 2296 | ||
2321 | if (*pos < 0 || *pos >= sbi->s_groups_count) | 2297 | if (*pos < 0 || *pos >= ext4_get_groups_count(sb)) |
2322 | return NULL; | 2298 | return NULL; |
2323 | |||
2324 | group = *pos + 1; | 2299 | group = *pos + 1; |
2325 | return (void *) ((unsigned long) group); | 2300 | return (void *) ((unsigned long) group); |
2326 | } | 2301 | } |
@@ -2328,11 +2303,10 @@ static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) | |||
2328 | static void *ext4_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t *pos) | 2303 | static void *ext4_mb_seq_groups_next(struct seq_file *seq, void *v, loff_t *pos) |
2329 | { | 2304 | { |
2330 | struct super_block *sb = seq->private; | 2305 | struct super_block *sb = seq->private; |
2331 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
2332 | ext4_group_t group; | 2306 | ext4_group_t group; |
2333 | 2307 | ||
2334 | ++*pos; | 2308 | ++*pos; |
2335 | if (*pos < 0 || *pos >= sbi->s_groups_count) | 2309 | if (*pos < 0 || *pos >= ext4_get_groups_count(sb)) |
2336 | return NULL; | 2310 | return NULL; |
2337 | group = *pos + 1; | 2311 | group = *pos + 1; |
2338 | return (void *) ((unsigned long) group); | 2312 | return (void *) ((unsigned long) group); |
@@ -2420,7 +2394,8 @@ static void ext4_mb_history_release(struct super_block *sb) | |||
2420 | 2394 | ||
2421 | if (sbi->s_proc != NULL) { | 2395 | if (sbi->s_proc != NULL) { |
2422 | remove_proc_entry("mb_groups", sbi->s_proc); | 2396 | remove_proc_entry("mb_groups", sbi->s_proc); |
2423 | remove_proc_entry("mb_history", sbi->s_proc); | 2397 | if (sbi->s_mb_history_max) |
2398 | remove_proc_entry("mb_history", sbi->s_proc); | ||
2424 | } | 2399 | } |
2425 | kfree(sbi->s_mb_history); | 2400 | kfree(sbi->s_mb_history); |
2426 | } | 2401 | } |
@@ -2431,17 +2406,17 @@ static void ext4_mb_history_init(struct super_block *sb) | |||
2431 | int i; | 2406 | int i; |
2432 | 2407 | ||
2433 | if (sbi->s_proc != NULL) { | 2408 | if (sbi->s_proc != NULL) { |
2434 | proc_create_data("mb_history", S_IRUGO, sbi->s_proc, | 2409 | if (sbi->s_mb_history_max) |
2435 | &ext4_mb_seq_history_fops, sb); | 2410 | proc_create_data("mb_history", S_IRUGO, sbi->s_proc, |
2411 | &ext4_mb_seq_history_fops, sb); | ||
2436 | proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, | 2412 | proc_create_data("mb_groups", S_IRUGO, sbi->s_proc, |
2437 | &ext4_mb_seq_groups_fops, sb); | 2413 | &ext4_mb_seq_groups_fops, sb); |
2438 | } | 2414 | } |
2439 | 2415 | ||
2440 | sbi->s_mb_history_max = 1000; | ||
2441 | sbi->s_mb_history_cur = 0; | 2416 | sbi->s_mb_history_cur = 0; |
2442 | spin_lock_init(&sbi->s_mb_history_lock); | 2417 | spin_lock_init(&sbi->s_mb_history_lock); |
2443 | i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history); | 2418 | i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history); |
2444 | sbi->s_mb_history = kzalloc(i, GFP_KERNEL); | 2419 | sbi->s_mb_history = i ? kzalloc(i, GFP_KERNEL) : NULL; |
2445 | /* if we can't allocate history, then we simple won't use it */ | 2420 | /* if we can't allocate history, then we simple won't use it */ |
2446 | } | 2421 | } |
2447 | 2422 | ||
@@ -2451,7 +2426,7 @@ ext4_mb_store_history(struct ext4_allocation_context *ac) | |||
2451 | struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); | 2426 | struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); |
2452 | struct ext4_mb_history h; | 2427 | struct ext4_mb_history h; |
2453 | 2428 | ||
2454 | if (unlikely(sbi->s_mb_history == NULL)) | 2429 | if (sbi->s_mb_history == NULL) |
2455 | return; | 2430 | return; |
2456 | 2431 | ||
2457 | if (!(ac->ac_op & sbi->s_mb_history_filter)) | 2432 | if (!(ac->ac_op & sbi->s_mb_history_filter)) |
@@ -2587,6 +2562,7 @@ void ext4_mb_update_group_info(struct ext4_group_info *grp, ext4_grpblk_t add) | |||
2587 | 2562 | ||
2588 | static int ext4_mb_init_backend(struct super_block *sb) | 2563 | static int ext4_mb_init_backend(struct super_block *sb) |
2589 | { | 2564 | { |
2565 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
2590 | ext4_group_t i; | 2566 | ext4_group_t i; |
2591 | int metalen; | 2567 | int metalen; |
2592 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2568 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
@@ -2598,7 +2574,7 @@ static int ext4_mb_init_backend(struct super_block *sb) | |||
2598 | struct ext4_group_desc *desc; | 2574 | struct ext4_group_desc *desc; |
2599 | 2575 | ||
2600 | /* This is the number of blocks used by GDT */ | 2576 | /* This is the number of blocks used by GDT */ |
2601 | num_meta_group_infos = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - | 2577 | num_meta_group_infos = (ngroups + EXT4_DESC_PER_BLOCK(sb) - |
2602 | 1) >> EXT4_DESC_PER_BLOCK_BITS(sb); | 2578 | 1) >> EXT4_DESC_PER_BLOCK_BITS(sb); |
2603 | 2579 | ||
2604 | /* | 2580 | /* |
@@ -2644,7 +2620,7 @@ static int ext4_mb_init_backend(struct super_block *sb) | |||
2644 | for (i = 0; i < num_meta_group_infos; i++) { | 2620 | for (i = 0; i < num_meta_group_infos; i++) { |
2645 | if ((i + 1) == num_meta_group_infos) | 2621 | if ((i + 1) == num_meta_group_infos) |
2646 | metalen = sizeof(*meta_group_info) * | 2622 | metalen = sizeof(*meta_group_info) * |
2647 | (sbi->s_groups_count - | 2623 | (ngroups - |
2648 | (i << EXT4_DESC_PER_BLOCK_BITS(sb))); | 2624 | (i << EXT4_DESC_PER_BLOCK_BITS(sb))); |
2649 | meta_group_info = kmalloc(metalen, GFP_KERNEL); | 2625 | meta_group_info = kmalloc(metalen, GFP_KERNEL); |
2650 | if (meta_group_info == NULL) { | 2626 | if (meta_group_info == NULL) { |
@@ -2655,7 +2631,7 @@ static int ext4_mb_init_backend(struct super_block *sb) | |||
2655 | sbi->s_group_info[i] = meta_group_info; | 2631 | sbi->s_group_info[i] = meta_group_info; |
2656 | } | 2632 | } |
2657 | 2633 | ||
2658 | for (i = 0; i < sbi->s_groups_count; i++) { | 2634 | for (i = 0; i < ngroups; i++) { |
2659 | desc = ext4_get_group_desc(sb, i, NULL); | 2635 | desc = ext4_get_group_desc(sb, i, NULL); |
2660 | if (desc == NULL) { | 2636 | if (desc == NULL) { |
2661 | printk(KERN_ERR | 2637 | printk(KERN_ERR |
@@ -2761,7 +2737,7 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery) | |||
2761 | return 0; | 2737 | return 0; |
2762 | } | 2738 | } |
2763 | 2739 | ||
2764 | /* need to called with ext4 group lock (ext4_lock_group) */ | 2740 | /* need to called with the ext4 group lock held */ |
2765 | static void ext4_mb_cleanup_pa(struct ext4_group_info *grp) | 2741 | static void ext4_mb_cleanup_pa(struct ext4_group_info *grp) |
2766 | { | 2742 | { |
2767 | struct ext4_prealloc_space *pa; | 2743 | struct ext4_prealloc_space *pa; |
@@ -2781,13 +2757,14 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp) | |||
2781 | 2757 | ||
2782 | int ext4_mb_release(struct super_block *sb) | 2758 | int ext4_mb_release(struct super_block *sb) |
2783 | { | 2759 | { |
2760 | ext4_group_t ngroups = ext4_get_groups_count(sb); | ||
2784 | ext4_group_t i; | 2761 | ext4_group_t i; |
2785 | int num_meta_group_infos; | 2762 | int num_meta_group_infos; |
2786 | struct ext4_group_info *grinfo; | 2763 | struct ext4_group_info *grinfo; |
2787 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2764 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
2788 | 2765 | ||
2789 | if (sbi->s_group_info) { | 2766 | if (sbi->s_group_info) { |
2790 | for (i = 0; i < sbi->s_groups_count; i++) { | 2767 | for (i = 0; i < ngroups; i++) { |
2791 | grinfo = ext4_get_group_info(sb, i); | 2768 | grinfo = ext4_get_group_info(sb, i); |
2792 | #ifdef DOUBLE_CHECK | 2769 | #ifdef DOUBLE_CHECK |
2793 | kfree(grinfo->bb_bitmap); | 2770 | kfree(grinfo->bb_bitmap); |
@@ -2797,7 +2774,7 @@ int ext4_mb_release(struct super_block *sb) | |||
2797 | ext4_unlock_group(sb, i); | 2774 | ext4_unlock_group(sb, i); |
2798 | kfree(grinfo); | 2775 | kfree(grinfo); |
2799 | } | 2776 | } |
2800 | num_meta_group_infos = (sbi->s_groups_count + | 2777 | num_meta_group_infos = (ngroups + |
2801 | EXT4_DESC_PER_BLOCK(sb) - 1) >> | 2778 | EXT4_DESC_PER_BLOCK(sb) - 1) >> |
2802 | EXT4_DESC_PER_BLOCK_BITS(sb); | 2779 | EXT4_DESC_PER_BLOCK_BITS(sb); |
2803 | for (i = 0; i < num_meta_group_infos; i++) | 2780 | for (i = 0; i < num_meta_group_infos; i++) |
@@ -2984,27 +2961,25 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
2984 | + le32_to_cpu(es->s_first_data_block); | 2961 | + le32_to_cpu(es->s_first_data_block); |
2985 | 2962 | ||
2986 | len = ac->ac_b_ex.fe_len; | 2963 | len = ac->ac_b_ex.fe_len; |
2987 | if (in_range(ext4_block_bitmap(sb, gdp), block, len) || | 2964 | if (!ext4_data_block_valid(sbi, block, len)) { |
2988 | in_range(ext4_inode_bitmap(sb, gdp), block, len) || | ||
2989 | in_range(block, ext4_inode_table(sb, gdp), | ||
2990 | EXT4_SB(sb)->s_itb_per_group) || | ||
2991 | in_range(block + len - 1, ext4_inode_table(sb, gdp), | ||
2992 | EXT4_SB(sb)->s_itb_per_group)) { | ||
2993 | ext4_error(sb, __func__, | 2965 | ext4_error(sb, __func__, |
2994 | "Allocating block %llu in system zone of %d group\n", | 2966 | "Allocating blocks %llu-%llu which overlap " |
2995 | block, ac->ac_b_ex.fe_group); | 2967 | "fs metadata\n", block, block+len); |
2996 | /* File system mounted not to panic on error | 2968 | /* File system mounted not to panic on error |
2997 | * Fix the bitmap and repeat the block allocation | 2969 | * Fix the bitmap and repeat the block allocation |
2998 | * We leak some of the blocks here. | 2970 | * We leak some of the blocks here. |
2999 | */ | 2971 | */ |
3000 | mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), | 2972 | ext4_lock_group(sb, ac->ac_b_ex.fe_group); |
3001 | bitmap_bh->b_data, ac->ac_b_ex.fe_start, | 2973 | mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start, |
3002 | ac->ac_b_ex.fe_len); | 2974 | ac->ac_b_ex.fe_len); |
2975 | ext4_unlock_group(sb, ac->ac_b_ex.fe_group); | ||
3003 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); | 2976 | err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh); |
3004 | if (!err) | 2977 | if (!err) |
3005 | err = -EAGAIN; | 2978 | err = -EAGAIN; |
3006 | goto out_err; | 2979 | goto out_err; |
3007 | } | 2980 | } |
2981 | |||
2982 | ext4_lock_group(sb, ac->ac_b_ex.fe_group); | ||
3008 | #ifdef AGGRESSIVE_CHECK | 2983 | #ifdef AGGRESSIVE_CHECK |
3009 | { | 2984 | { |
3010 | int i; | 2985 | int i; |
@@ -3014,9 +2989,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
3014 | } | 2989 | } |
3015 | } | 2990 | } |
3016 | #endif | 2991 | #endif |
3017 | spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group)); | 2992 | mb_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,ac->ac_b_ex.fe_len); |
3018 | mb_set_bits(NULL, bitmap_bh->b_data, | ||
3019 | ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len); | ||
3020 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { | 2993 | if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { |
3021 | gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); | 2994 | gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); |
3022 | ext4_free_blks_set(sb, gdp, | 2995 | ext4_free_blks_set(sb, gdp, |
@@ -3026,7 +2999,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, | |||
3026 | len = ext4_free_blks_count(sb, gdp) - ac->ac_b_ex.fe_len; | 2999 | len = ext4_free_blks_count(sb, gdp) - ac->ac_b_ex.fe_len; |
3027 | ext4_free_blks_set(sb, gdp, len); | 3000 | ext4_free_blks_set(sb, gdp, len); |
3028 | gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp); | 3001 | gdp->bg_checksum = ext4_group_desc_csum(sbi, ac->ac_b_ex.fe_group, gdp); |
3029 | spin_unlock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group)); | 3002 | |
3003 | ext4_unlock_group(sb, ac->ac_b_ex.fe_group); | ||
3030 | percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len); | 3004 | percpu_counter_sub(&sbi->s_freeblocks_counter, ac->ac_b_ex.fe_len); |
3031 | /* | 3005 | /* |
3032 | * Now reduce the dirty block count also. Should not go negative | 3006 | * Now reduce the dirty block count also. Should not go negative |
@@ -3459,7 +3433,7 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac) | |||
3459 | * the function goes through all block freed in the group | 3433 | * the function goes through all block freed in the group |
3460 | * but not yet committed and marks them used in in-core bitmap. | 3434 | * but not yet committed and marks them used in in-core bitmap. |
3461 | * buddy must be generated from this bitmap | 3435 | * buddy must be generated from this bitmap |
3462 | * Need to be called with ext4 group lock (ext4_lock_group) | 3436 | * Need to be called with the ext4 group lock held |
3463 | */ | 3437 | */ |
3464 | static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, | 3438 | static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, |
3465 | ext4_group_t group) | 3439 | ext4_group_t group) |
@@ -3473,9 +3447,7 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, | |||
3473 | 3447 | ||
3474 | while (n) { | 3448 | while (n) { |
3475 | entry = rb_entry(n, struct ext4_free_data, node); | 3449 | entry = rb_entry(n, struct ext4_free_data, node); |
3476 | mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group), | 3450 | mb_set_bits(bitmap, entry->start_blk, entry->count); |
3477 | bitmap, entry->start_blk, | ||
3478 | entry->count); | ||
3479 | n = rb_next(n); | 3451 | n = rb_next(n); |
3480 | } | 3452 | } |
3481 | return; | 3453 | return; |
@@ -3484,7 +3456,7 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, | |||
3484 | /* | 3456 | /* |
3485 | * the function goes through all preallocation in this group and marks them | 3457 | * the function goes through all preallocation in this group and marks them |
3486 | * used in in-core bitmap. buddy must be generated from this bitmap | 3458 | * used in in-core bitmap. buddy must be generated from this bitmap |
3487 | * Need to be called with ext4 group lock (ext4_lock_group) | 3459 | * Need to be called with ext4 group lock held |
3488 | */ | 3460 | */ |
3489 | static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, | 3461 | static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, |
3490 | ext4_group_t group) | 3462 | ext4_group_t group) |
@@ -3516,8 +3488,7 @@ static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, | |||
3516 | if (unlikely(len == 0)) | 3488 | if (unlikely(len == 0)) |
3517 | continue; | 3489 | continue; |
3518 | BUG_ON(groupnr != group); | 3490 | BUG_ON(groupnr != group); |
3519 | mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group), | 3491 | mb_set_bits(bitmap, start, len); |
3520 | bitmap, start, len); | ||
3521 | preallocated += len; | 3492 | preallocated += len; |
3522 | count++; | 3493 | count++; |
3523 | } | 3494 | } |
@@ -4121,7 +4092,7 @@ static void ext4_mb_return_to_preallocation(struct inode *inode, | |||
4121 | static void ext4_mb_show_ac(struct ext4_allocation_context *ac) | 4092 | static void ext4_mb_show_ac(struct ext4_allocation_context *ac) |
4122 | { | 4093 | { |
4123 | struct super_block *sb = ac->ac_sb; | 4094 | struct super_block *sb = ac->ac_sb; |
4124 | ext4_group_t i; | 4095 | ext4_group_t ngroups, i; |
4125 | 4096 | ||
4126 | printk(KERN_ERR "EXT4-fs: Can't allocate:" | 4097 | printk(KERN_ERR "EXT4-fs: Can't allocate:" |
4127 | " Allocation context details:\n"); | 4098 | " Allocation context details:\n"); |
@@ -4145,7 +4116,8 @@ static void ext4_mb_show_ac(struct ext4_allocation_context *ac) | |||
4145 | printk(KERN_ERR "EXT4-fs: %lu scanned, %d found\n", ac->ac_ex_scanned, | 4116 | printk(KERN_ERR "EXT4-fs: %lu scanned, %d found\n", ac->ac_ex_scanned, |
4146 | ac->ac_found); | 4117 | ac->ac_found); |
4147 | printk(KERN_ERR "EXT4-fs: groups: \n"); | 4118 | printk(KERN_ERR "EXT4-fs: groups: \n"); |
4148 | for (i = 0; i < EXT4_SB(sb)->s_groups_count; i++) { | 4119 | ngroups = ext4_get_groups_count(sb); |
4120 | for (i = 0; i < ngroups; i++) { | ||
4149 | struct ext4_group_info *grp = ext4_get_group_info(sb, i); | 4121 | struct ext4_group_info *grp = ext4_get_group_info(sb, i); |
4150 | struct ext4_prealloc_space *pa; | 4122 | struct ext4_prealloc_space *pa; |
4151 | ext4_grpblk_t start; | 4123 | ext4_grpblk_t start; |
@@ -4469,13 +4441,13 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac) | |||
4469 | 4441 | ||
4470 | static int ext4_mb_discard_preallocations(struct super_block *sb, int needed) | 4442 | static int ext4_mb_discard_preallocations(struct super_block *sb, int needed) |
4471 | { | 4443 | { |
4472 | ext4_group_t i; | 4444 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
4473 | int ret; | 4445 | int ret; |
4474 | int freed = 0; | 4446 | int freed = 0; |
4475 | 4447 | ||
4476 | trace_mark(ext4_mb_discard_preallocations, "dev %s needed %d", | 4448 | trace_mark(ext4_mb_discard_preallocations, "dev %s needed %d", |
4477 | sb->s_id, needed); | 4449 | sb->s_id, needed); |
4478 | for (i = 0; i < EXT4_SB(sb)->s_groups_count && needed > 0; i++) { | 4450 | for (i = 0; i < ngroups && needed > 0; i++) { |
4479 | ret = ext4_mb_discard_group_preallocations(sb, i, needed); | 4451 | ret = ext4_mb_discard_group_preallocations(sb, i, needed); |
4480 | freed += ret; | 4452 | freed += ret; |
4481 | needed -= ret; | 4453 | needed -= ret; |
@@ -4859,29 +4831,25 @@ do_more: | |||
4859 | new_entry->group = block_group; | 4831 | new_entry->group = block_group; |
4860 | new_entry->count = count; | 4832 | new_entry->count = count; |
4861 | new_entry->t_tid = handle->h_transaction->t_tid; | 4833 | new_entry->t_tid = handle->h_transaction->t_tid; |
4834 | |||
4862 | ext4_lock_group(sb, block_group); | 4835 | ext4_lock_group(sb, block_group); |
4863 | mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data, | 4836 | mb_clear_bits(bitmap_bh->b_data, bit, count); |
4864 | bit, count); | ||
4865 | ext4_mb_free_metadata(handle, &e4b, new_entry); | 4837 | ext4_mb_free_metadata(handle, &e4b, new_entry); |
4866 | ext4_unlock_group(sb, block_group); | ||
4867 | } else { | 4838 | } else { |
4868 | ext4_lock_group(sb, block_group); | ||
4869 | /* need to update group_info->bb_free and bitmap | 4839 | /* need to update group_info->bb_free and bitmap |
4870 | * with group lock held. generate_buddy look at | 4840 | * with group lock held. generate_buddy look at |
4871 | * them with group lock_held | 4841 | * them with group lock_held |
4872 | */ | 4842 | */ |
4873 | mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data, | 4843 | ext4_lock_group(sb, block_group); |
4874 | bit, count); | 4844 | mb_clear_bits(bitmap_bh->b_data, bit, count); |
4875 | mb_free_blocks(inode, &e4b, bit, count); | 4845 | mb_free_blocks(inode, &e4b, bit, count); |
4876 | ext4_mb_return_to_preallocation(inode, &e4b, block, count); | 4846 | ext4_mb_return_to_preallocation(inode, &e4b, block, count); |
4877 | ext4_unlock_group(sb, block_group); | ||
4878 | } | 4847 | } |
4879 | 4848 | ||
4880 | spin_lock(sb_bgl_lock(sbi, block_group)); | ||
4881 | ret = ext4_free_blks_count(sb, gdp) + count; | 4849 | ret = ext4_free_blks_count(sb, gdp) + count; |
4882 | ext4_free_blks_set(sb, gdp, ret); | 4850 | ext4_free_blks_set(sb, gdp, ret); |
4883 | gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); | 4851 | gdp->bg_checksum = ext4_group_desc_csum(sbi, block_group, gdp); |
4884 | spin_unlock(sb_bgl_lock(sbi, block_group)); | 4852 | ext4_unlock_group(sb, block_group); |
4885 | percpu_counter_add(&sbi->s_freeblocks_counter, count); | 4853 | percpu_counter_add(&sbi->s_freeblocks_counter, count); |
4886 | 4854 | ||
4887 | if (sbi->s_log_groups_per_flex) { | 4855 | if (sbi->s_log_groups_per_flex) { |
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h index dd9e6cd5f6cf..75e34f69215b 100644 --- a/fs/ext4/mballoc.h +++ b/fs/ext4/mballoc.h | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include "ext4_jbd2.h" | 24 | #include "ext4_jbd2.h" |
25 | #include "ext4.h" | 25 | #include "ext4.h" |
26 | #include "group.h" | ||
27 | 26 | ||
28 | /* | 27 | /* |
29 | * with AGGRESSIVE_CHECK allocator runs consistency checks over | 28 | * with AGGRESSIVE_CHECK allocator runs consistency checks over |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 22098e1cd085..07eb6649e4fa 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include "ext4.h" | 37 | #include "ext4.h" |
38 | #include "ext4_jbd2.h" | 38 | #include "ext4_jbd2.h" |
39 | 39 | ||
40 | #include "namei.h" | ||
41 | #include "xattr.h" | 40 | #include "xattr.h" |
42 | #include "acl.h" | 41 | #include "acl.h" |
43 | 42 | ||
@@ -750,7 +749,7 @@ static int dx_make_map(struct ext4_dir_entry_2 *de, unsigned blocksize, | |||
750 | ext4fs_dirhash(de->name, de->name_len, &h); | 749 | ext4fs_dirhash(de->name, de->name_len, &h); |
751 | map_tail--; | 750 | map_tail--; |
752 | map_tail->hash = h.hash; | 751 | map_tail->hash = h.hash; |
753 | map_tail->offs = (u16) ((char *) de - base); | 752 | map_tail->offs = ((char *) de - base)>>2; |
754 | map_tail->size = le16_to_cpu(de->rec_len); | 753 | map_tail->size = le16_to_cpu(de->rec_len); |
755 | count++; | 754 | count++; |
756 | cond_resched(); | 755 | cond_resched(); |
@@ -1148,7 +1147,8 @@ dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count, | |||
1148 | unsigned rec_len = 0; | 1147 | unsigned rec_len = 0; |
1149 | 1148 | ||
1150 | while (count--) { | 1149 | while (count--) { |
1151 | struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) (from + map->offs); | 1150 | struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) |
1151 | (from + (map->offs<<2)); | ||
1152 | rec_len = EXT4_DIR_REC_LEN(de->name_len); | 1152 | rec_len = EXT4_DIR_REC_LEN(de->name_len); |
1153 | memcpy (to, de, rec_len); | 1153 | memcpy (to, de, rec_len); |
1154 | ((struct ext4_dir_entry_2 *) to)->rec_len = | 1154 | ((struct ext4_dir_entry_2 *) to)->rec_len = |
@@ -1997,7 +1997,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
1997 | if (!ext4_handle_valid(handle)) | 1997 | if (!ext4_handle_valid(handle)) |
1998 | return 0; | 1998 | return 0; |
1999 | 1999 | ||
2000 | lock_super(sb); | 2000 | mutex_lock(&EXT4_SB(sb)->s_orphan_lock); |
2001 | if (!list_empty(&EXT4_I(inode)->i_orphan)) | 2001 | if (!list_empty(&EXT4_I(inode)->i_orphan)) |
2002 | goto out_unlock; | 2002 | goto out_unlock; |
2003 | 2003 | ||
@@ -2006,9 +2006,13 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
2006 | 2006 | ||
2007 | /* @@@ FIXME: Observation from aviro: | 2007 | /* @@@ FIXME: Observation from aviro: |
2008 | * I think I can trigger J_ASSERT in ext4_orphan_add(). We block | 2008 | * I think I can trigger J_ASSERT in ext4_orphan_add(). We block |
2009 | * here (on lock_super()), so race with ext4_link() which might bump | 2009 | * here (on s_orphan_lock), so race with ext4_link() which might bump |
2010 | * ->i_nlink. For, say it, character device. Not a regular file, | 2010 | * ->i_nlink. For, say it, character device. Not a regular file, |
2011 | * not a directory, not a symlink and ->i_nlink > 0. | 2011 | * not a directory, not a symlink and ->i_nlink > 0. |
2012 | * | ||
2013 | * tytso, 4/25/2009: I'm not sure how that could happen; | ||
2014 | * shouldn't the fs core protect us from these sort of | ||
2015 | * unlink()/link() races? | ||
2012 | */ | 2016 | */ |
2013 | J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 2017 | J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
2014 | S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); | 2018 | S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); |
@@ -2045,7 +2049,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
2045 | jbd_debug(4, "orphan inode %lu will point to %d\n", | 2049 | jbd_debug(4, "orphan inode %lu will point to %d\n", |
2046 | inode->i_ino, NEXT_ORPHAN(inode)); | 2050 | inode->i_ino, NEXT_ORPHAN(inode)); |
2047 | out_unlock: | 2051 | out_unlock: |
2048 | unlock_super(sb); | 2052 | mutex_unlock(&EXT4_SB(sb)->s_orphan_lock); |
2049 | ext4_std_error(inode->i_sb, err); | 2053 | ext4_std_error(inode->i_sb, err); |
2050 | return err; | 2054 | return err; |
2051 | } | 2055 | } |
@@ -2066,11 +2070,9 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) | |||
2066 | if (!ext4_handle_valid(handle)) | 2070 | if (!ext4_handle_valid(handle)) |
2067 | return 0; | 2071 | return 0; |
2068 | 2072 | ||
2069 | lock_super(inode->i_sb); | 2073 | mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); |
2070 | if (list_empty(&ei->i_orphan)) { | 2074 | if (list_empty(&ei->i_orphan)) |
2071 | unlock_super(inode->i_sb); | 2075 | goto out; |
2072 | return 0; | ||
2073 | } | ||
2074 | 2076 | ||
2075 | ino_next = NEXT_ORPHAN(inode); | 2077 | ino_next = NEXT_ORPHAN(inode); |
2076 | prev = ei->i_orphan.prev; | 2078 | prev = ei->i_orphan.prev; |
@@ -2120,7 +2122,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) | |||
2120 | out_err: | 2122 | out_err: |
2121 | ext4_std_error(inode->i_sb, err); | 2123 | ext4_std_error(inode->i_sb, err); |
2122 | out: | 2124 | out: |
2123 | unlock_super(inode->i_sb); | 2125 | mutex_unlock(&EXT4_SB(inode->i_sb)->s_orphan_lock); |
2124 | return err; | 2126 | return err; |
2125 | 2127 | ||
2126 | out_brelse: | 2128 | out_brelse: |
@@ -2533,6 +2535,7 @@ const struct inode_operations ext4_dir_inode_operations = { | |||
2533 | .removexattr = generic_removexattr, | 2535 | .removexattr = generic_removexattr, |
2534 | #endif | 2536 | #endif |
2535 | .permission = ext4_permission, | 2537 | .permission = ext4_permission, |
2538 | .fiemap = ext4_fiemap, | ||
2536 | }; | 2539 | }; |
2537 | 2540 | ||
2538 | const struct inode_operations ext4_special_inode_operations = { | 2541 | const struct inode_operations ext4_special_inode_operations = { |
diff --git a/fs/ext4/namei.h b/fs/ext4/namei.h deleted file mode 100644 index 5e4dfff36a00..000000000000 --- a/fs/ext4/namei.h +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | /* linux/fs/ext4/namei.h | ||
2 | * | ||
3 | * Copyright (C) 2005 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | extern struct dentry *ext4_get_parent(struct dentry *child); | ||
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 546c7dd869e1..27eb289eea37 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | 16 | ||
17 | #include "ext4_jbd2.h" | 17 | #include "ext4_jbd2.h" |
18 | #include "group.h" | ||
19 | 18 | ||
20 | #define outside(b, first, last) ((b) < (first) || (b) >= (last)) | 19 | #define outside(b, first, last) ((b) < (first) || (b) >= (last)) |
21 | #define inside(b, first, last) ((b) >= (first) && (b) < (last)) | 20 | #define inside(b, first, last) ((b) >= (first) && (b) < (last)) |
@@ -193,7 +192,7 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
193 | if (IS_ERR(handle)) | 192 | if (IS_ERR(handle)) |
194 | return PTR_ERR(handle); | 193 | return PTR_ERR(handle); |
195 | 194 | ||
196 | lock_super(sb); | 195 | mutex_lock(&sbi->s_resize_lock); |
197 | if (input->group != sbi->s_groups_count) { | 196 | if (input->group != sbi->s_groups_count) { |
198 | err = -EBUSY; | 197 | err = -EBUSY; |
199 | goto exit_journal; | 198 | goto exit_journal; |
@@ -302,7 +301,7 @@ exit_bh: | |||
302 | brelse(bh); | 301 | brelse(bh); |
303 | 302 | ||
304 | exit_journal: | 303 | exit_journal: |
305 | unlock_super(sb); | 304 | mutex_unlock(&sbi->s_resize_lock); |
306 | if ((err2 = ext4_journal_stop(handle)) && !err) | 305 | if ((err2 = ext4_journal_stop(handle)) && !err) |
307 | err = err2; | 306 | err = err2; |
308 | 307 | ||
@@ -643,11 +642,12 @@ exit_free: | |||
643 | * important part is that the new block and inode counts are in the backup | 642 | * important part is that the new block and inode counts are in the backup |
644 | * superblocks, and the location of the new group metadata in the GDT backups. | 643 | * superblocks, and the location of the new group metadata in the GDT backups. |
645 | * | 644 | * |
646 | * We do not need lock_super() for this, because these blocks are not | 645 | * We do not need take the s_resize_lock for this, because these |
647 | * otherwise touched by the filesystem code when it is mounted. We don't | 646 | * blocks are not otherwise touched by the filesystem code when it is |
648 | * need to worry about last changing from sbi->s_groups_count, because the | 647 | * mounted. We don't need to worry about last changing from |
649 | * worst that can happen is that we do not copy the full number of backups | 648 | * sbi->s_groups_count, because the worst that can happen is that we |
650 | * at this time. The resize which changed s_groups_count will backup again. | 649 | * do not copy the full number of backups at this time. The resize |
650 | * which changed s_groups_count will backup again. | ||
651 | */ | 651 | */ |
652 | static void update_backups(struct super_block *sb, | 652 | static void update_backups(struct super_block *sb, |
653 | int blk_off, char *data, int size) | 653 | int blk_off, char *data, int size) |
@@ -809,7 +809,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
809 | goto exit_put; | 809 | goto exit_put; |
810 | } | 810 | } |
811 | 811 | ||
812 | lock_super(sb); | 812 | mutex_lock(&sbi->s_resize_lock); |
813 | if (input->group != sbi->s_groups_count) { | 813 | if (input->group != sbi->s_groups_count) { |
814 | ext4_warning(sb, __func__, | 814 | ext4_warning(sb, __func__, |
815 | "multiple resizers run on filesystem!"); | 815 | "multiple resizers run on filesystem!"); |
@@ -840,7 +840,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
840 | /* | 840 | /* |
841 | * OK, now we've set up the new group. Time to make it active. | 841 | * OK, now we've set up the new group. Time to make it active. |
842 | * | 842 | * |
843 | * Current kernels don't lock all allocations via lock_super(), | 843 | * We do not lock all allocations via s_resize_lock |
844 | * so we have to be safe wrt. concurrent accesses the group | 844 | * so we have to be safe wrt. concurrent accesses the group |
845 | * data. So we need to be careful to set all of the relevant | 845 | * data. So we need to be careful to set all of the relevant |
846 | * group descriptor data etc. *before* we enable the group. | 846 | * group descriptor data etc. *before* we enable the group. |
@@ -900,12 +900,12 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
900 | * | 900 | * |
901 | * The precise rules we use are: | 901 | * The precise rules we use are: |
902 | * | 902 | * |
903 | * * Writers of s_groups_count *must* hold lock_super | 903 | * * Writers of s_groups_count *must* hold s_resize_lock |
904 | * AND | 904 | * AND |
905 | * * Writers must perform a smp_wmb() after updating all dependent | 905 | * * Writers must perform a smp_wmb() after updating all dependent |
906 | * data and before modifying the groups count | 906 | * data and before modifying the groups count |
907 | * | 907 | * |
908 | * * Readers must hold lock_super() over the access | 908 | * * Readers must hold s_resize_lock over the access |
909 | * OR | 909 | * OR |
910 | * * Readers must perform an smp_rmb() after reading the groups count | 910 | * * Readers must perform an smp_rmb() after reading the groups count |
911 | * and before reading any dependent data. | 911 | * and before reading any dependent data. |
@@ -948,7 +948,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
948 | sb->s_dirt = 1; | 948 | sb->s_dirt = 1; |
949 | 949 | ||
950 | exit_journal: | 950 | exit_journal: |
951 | unlock_super(sb); | 951 | mutex_unlock(&sbi->s_resize_lock); |
952 | if ((err2 = ext4_journal_stop(handle)) && !err) | 952 | if ((err2 = ext4_journal_stop(handle)) && !err) |
953 | err = err2; | 953 | err = err2; |
954 | if (!err) { | 954 | if (!err) { |
@@ -986,7 +986,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
986 | 986 | ||
987 | /* We don't need to worry about locking wrt other resizers just | 987 | /* We don't need to worry about locking wrt other resizers just |
988 | * yet: we're going to revalidate es->s_blocks_count after | 988 | * yet: we're going to revalidate es->s_blocks_count after |
989 | * taking lock_super() below. */ | 989 | * taking the s_resize_lock below. */ |
990 | o_blocks_count = ext4_blocks_count(es); | 990 | o_blocks_count = ext4_blocks_count(es); |
991 | o_groups_count = EXT4_SB(sb)->s_groups_count; | 991 | o_groups_count = EXT4_SB(sb)->s_groups_count; |
992 | 992 | ||
@@ -1056,11 +1056,11 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
1056 | goto exit_put; | 1056 | goto exit_put; |
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | lock_super(sb); | 1059 | mutex_lock(&EXT4_SB(sb)->s_resize_lock); |
1060 | if (o_blocks_count != ext4_blocks_count(es)) { | 1060 | if (o_blocks_count != ext4_blocks_count(es)) { |
1061 | ext4_warning(sb, __func__, | 1061 | ext4_warning(sb, __func__, |
1062 | "multiple resizers run on filesystem!"); | 1062 | "multiple resizers run on filesystem!"); |
1063 | unlock_super(sb); | 1063 | mutex_unlock(&EXT4_SB(sb)->s_resize_lock); |
1064 | ext4_journal_stop(handle); | 1064 | ext4_journal_stop(handle); |
1065 | err = -EBUSY; | 1065 | err = -EBUSY; |
1066 | goto exit_put; | 1066 | goto exit_put; |
@@ -1070,14 +1070,14 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
1070 | EXT4_SB(sb)->s_sbh))) { | 1070 | EXT4_SB(sb)->s_sbh))) { |
1071 | ext4_warning(sb, __func__, | 1071 | ext4_warning(sb, __func__, |
1072 | "error %d on journal write access", err); | 1072 | "error %d on journal write access", err); |
1073 | unlock_super(sb); | 1073 | mutex_unlock(&EXT4_SB(sb)->s_resize_lock); |
1074 | ext4_journal_stop(handle); | 1074 | ext4_journal_stop(handle); |
1075 | goto exit_put; | 1075 | goto exit_put; |
1076 | } | 1076 | } |
1077 | ext4_blocks_count_set(es, o_blocks_count + add); | 1077 | ext4_blocks_count_set(es, o_blocks_count + add); |
1078 | ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh); | 1078 | ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh); |
1079 | sb->s_dirt = 1; | 1079 | sb->s_dirt = 1; |
1080 | unlock_super(sb); | 1080 | mutex_unlock(&EXT4_SB(sb)->s_resize_lock); |
1081 | ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, | 1081 | ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, |
1082 | o_blocks_count + add); | 1082 | o_blocks_count + add); |
1083 | /* We add the blocks to the bitmap and set the group need init bit */ | 1083 | /* We add the blocks to the bitmap and set the group need init bit */ |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2958f4e6f222..f016707597a7 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/time.h> | 22 | #include <linux/time.h> |
23 | #include <linux/vmalloc.h> | ||
23 | #include <linux/jbd2.h> | 24 | #include <linux/jbd2.h> |
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
25 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -45,16 +46,20 @@ | |||
45 | #include "ext4_jbd2.h" | 46 | #include "ext4_jbd2.h" |
46 | #include "xattr.h" | 47 | #include "xattr.h" |
47 | #include "acl.h" | 48 | #include "acl.h" |
48 | #include "namei.h" | 49 | |
49 | #include "group.h" | 50 | static int default_mb_history_length = 1000; |
51 | |||
52 | module_param_named(default_mb_history_length, default_mb_history_length, | ||
53 | int, 0644); | ||
54 | MODULE_PARM_DESC(default_mb_history_length, | ||
55 | "Default number of entries saved for mb_history"); | ||
50 | 56 | ||
51 | struct proc_dir_entry *ext4_proc_root; | 57 | struct proc_dir_entry *ext4_proc_root; |
52 | static struct kset *ext4_kset; | 58 | static struct kset *ext4_kset; |
53 | 59 | ||
54 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, | 60 | static int ext4_load_journal(struct super_block *, struct ext4_super_block *, |
55 | unsigned long journal_devnum); | 61 | unsigned long journal_devnum); |
56 | static int ext4_commit_super(struct super_block *sb, | 62 | static int ext4_commit_super(struct super_block *sb, int sync); |
57 | struct ext4_super_block *es, int sync); | ||
58 | static void ext4_mark_recovery_complete(struct super_block *sb, | 63 | static void ext4_mark_recovery_complete(struct super_block *sb, |
59 | struct ext4_super_block *es); | 64 | struct ext4_super_block *es); |
60 | static void ext4_clear_journal_err(struct super_block *sb, | 65 | static void ext4_clear_journal_err(struct super_block *sb, |
@@ -74,7 +79,7 @@ ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, | |||
74 | { | 79 | { |
75 | return le32_to_cpu(bg->bg_block_bitmap_lo) | | 80 | return le32_to_cpu(bg->bg_block_bitmap_lo) | |
76 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 81 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
77 | (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0); | 82 | (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0); |
78 | } | 83 | } |
79 | 84 | ||
80 | ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, | 85 | ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, |
@@ -82,7 +87,7 @@ ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, | |||
82 | { | 87 | { |
83 | return le32_to_cpu(bg->bg_inode_bitmap_lo) | | 88 | return le32_to_cpu(bg->bg_inode_bitmap_lo) | |
84 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 89 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
85 | (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0); | 90 | (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0); |
86 | } | 91 | } |
87 | 92 | ||
88 | ext4_fsblk_t ext4_inode_table(struct super_block *sb, | 93 | ext4_fsblk_t ext4_inode_table(struct super_block *sb, |
@@ -90,7 +95,7 @@ ext4_fsblk_t ext4_inode_table(struct super_block *sb, | |||
90 | { | 95 | { |
91 | return le32_to_cpu(bg->bg_inode_table_lo) | | 96 | return le32_to_cpu(bg->bg_inode_table_lo) | |
92 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 97 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
93 | (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); | 98 | (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); |
94 | } | 99 | } |
95 | 100 | ||
96 | __u32 ext4_free_blks_count(struct super_block *sb, | 101 | __u32 ext4_free_blks_count(struct super_block *sb, |
@@ -98,7 +103,7 @@ __u32 ext4_free_blks_count(struct super_block *sb, | |||
98 | { | 103 | { |
99 | return le16_to_cpu(bg->bg_free_blocks_count_lo) | | 104 | return le16_to_cpu(bg->bg_free_blocks_count_lo) | |
100 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 105 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
101 | (__u32)le16_to_cpu(bg->bg_free_blocks_count_hi) << 16 : 0); | 106 | (__u32)le16_to_cpu(bg->bg_free_blocks_count_hi) << 16 : 0); |
102 | } | 107 | } |
103 | 108 | ||
104 | __u32 ext4_free_inodes_count(struct super_block *sb, | 109 | __u32 ext4_free_inodes_count(struct super_block *sb, |
@@ -106,7 +111,7 @@ __u32 ext4_free_inodes_count(struct super_block *sb, | |||
106 | { | 111 | { |
107 | return le16_to_cpu(bg->bg_free_inodes_count_lo) | | 112 | return le16_to_cpu(bg->bg_free_inodes_count_lo) | |
108 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 113 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
109 | (__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0); | 114 | (__u32)le16_to_cpu(bg->bg_free_inodes_count_hi) << 16 : 0); |
110 | } | 115 | } |
111 | 116 | ||
112 | __u32 ext4_used_dirs_count(struct super_block *sb, | 117 | __u32 ext4_used_dirs_count(struct super_block *sb, |
@@ -114,7 +119,7 @@ __u32 ext4_used_dirs_count(struct super_block *sb, | |||
114 | { | 119 | { |
115 | return le16_to_cpu(bg->bg_used_dirs_count_lo) | | 120 | return le16_to_cpu(bg->bg_used_dirs_count_lo) | |
116 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 121 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
117 | (__u32)le16_to_cpu(bg->bg_used_dirs_count_hi) << 16 : 0); | 122 | (__u32)le16_to_cpu(bg->bg_used_dirs_count_hi) << 16 : 0); |
118 | } | 123 | } |
119 | 124 | ||
120 | __u32 ext4_itable_unused_count(struct super_block *sb, | 125 | __u32 ext4_itable_unused_count(struct super_block *sb, |
@@ -122,7 +127,7 @@ __u32 ext4_itable_unused_count(struct super_block *sb, | |||
122 | { | 127 | { |
123 | return le16_to_cpu(bg->bg_itable_unused_lo) | | 128 | return le16_to_cpu(bg->bg_itable_unused_lo) | |
124 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? | 129 | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? |
125 | (__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0); | 130 | (__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0); |
126 | } | 131 | } |
127 | 132 | ||
128 | void ext4_block_bitmap_set(struct super_block *sb, | 133 | void ext4_block_bitmap_set(struct super_block *sb, |
@@ -202,8 +207,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) | |||
202 | journal = EXT4_SB(sb)->s_journal; | 207 | journal = EXT4_SB(sb)->s_journal; |
203 | if (journal) { | 208 | if (journal) { |
204 | if (is_journal_aborted(journal)) { | 209 | if (is_journal_aborted(journal)) { |
205 | ext4_abort(sb, __func__, | 210 | ext4_abort(sb, __func__, "Detected aborted journal"); |
206 | "Detected aborted journal"); | ||
207 | return ERR_PTR(-EROFS); | 211 | return ERR_PTR(-EROFS); |
208 | } | 212 | } |
209 | return jbd2_journal_start(journal, nblocks); | 213 | return jbd2_journal_start(journal, nblocks); |
@@ -302,10 +306,10 @@ static void ext4_handle_error(struct super_block *sb) | |||
302 | jbd2_journal_abort(journal, -EIO); | 306 | jbd2_journal_abort(journal, -EIO); |
303 | } | 307 | } |
304 | if (test_opt(sb, ERRORS_RO)) { | 308 | if (test_opt(sb, ERRORS_RO)) { |
305 | printk(KERN_CRIT "Remounting filesystem read-only\n"); | 309 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); |
306 | sb->s_flags |= MS_RDONLY; | 310 | sb->s_flags |= MS_RDONLY; |
307 | } | 311 | } |
308 | ext4_commit_super(sb, es, 1); | 312 | ext4_commit_super(sb, 1); |
309 | if (test_opt(sb, ERRORS_PANIC)) | 313 | if (test_opt(sb, ERRORS_PANIC)) |
310 | panic("EXT4-fs (device %s): panic forced after error\n", | 314 | panic("EXT4-fs (device %s): panic forced after error\n", |
311 | sb->s_id); | 315 | sb->s_id); |
@@ -395,8 +399,6 @@ void ext4_abort(struct super_block *sb, const char *function, | |||
395 | { | 399 | { |
396 | va_list args; | 400 | va_list args; |
397 | 401 | ||
398 | printk(KERN_CRIT "ext4_abort called.\n"); | ||
399 | |||
400 | va_start(args, fmt); | 402 | va_start(args, fmt); |
401 | printk(KERN_CRIT "EXT4-fs error (device %s): %s: ", sb->s_id, function); | 403 | printk(KERN_CRIT "EXT4-fs error (device %s): %s: ", sb->s_id, function); |
402 | vprintk(fmt, args); | 404 | vprintk(fmt, args); |
@@ -409,7 +411,7 @@ void ext4_abort(struct super_block *sb, const char *function, | |||
409 | if (sb->s_flags & MS_RDONLY) | 411 | if (sb->s_flags & MS_RDONLY) |
410 | return; | 412 | return; |
411 | 413 | ||
412 | printk(KERN_CRIT "Remounting filesystem read-only\n"); | 414 | ext4_msg(sb, KERN_CRIT, "Remounting filesystem read-only"); |
413 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | 415 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; |
414 | sb->s_flags |= MS_RDONLY; | 416 | sb->s_flags |= MS_RDONLY; |
415 | EXT4_SB(sb)->s_mount_opt |= EXT4_MOUNT_ABORT; | 417 | EXT4_SB(sb)->s_mount_opt |= EXT4_MOUNT_ABORT; |
@@ -417,6 +419,18 @@ void ext4_abort(struct super_block *sb, const char *function, | |||
417 | jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); | 419 | jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO); |
418 | } | 420 | } |
419 | 421 | ||
422 | void ext4_msg (struct super_block * sb, const char *prefix, | ||
423 | const char *fmt, ...) | ||
424 | { | ||
425 | va_list args; | ||
426 | |||
427 | va_start(args, fmt); | ||
428 | printk("%sEXT4-fs (%s): ", prefix, sb->s_id); | ||
429 | vprintk(fmt, args); | ||
430 | printk("\n"); | ||
431 | va_end(args); | ||
432 | } | ||
433 | |||
420 | void ext4_warning(struct super_block *sb, const char *function, | 434 | void ext4_warning(struct super_block *sb, const char *function, |
421 | const char *fmt, ...) | 435 | const char *fmt, ...) |
422 | { | 436 | { |
@@ -431,7 +445,7 @@ void ext4_warning(struct super_block *sb, const char *function, | |||
431 | } | 445 | } |
432 | 446 | ||
433 | void ext4_grp_locked_error(struct super_block *sb, ext4_group_t grp, | 447 | void ext4_grp_locked_error(struct super_block *sb, ext4_group_t grp, |
434 | const char *function, const char *fmt, ...) | 448 | const char *function, const char *fmt, ...) |
435 | __releases(bitlock) | 449 | __releases(bitlock) |
436 | __acquires(bitlock) | 450 | __acquires(bitlock) |
437 | { | 451 | { |
@@ -447,7 +461,7 @@ __acquires(bitlock) | |||
447 | if (test_opt(sb, ERRORS_CONT)) { | 461 | if (test_opt(sb, ERRORS_CONT)) { |
448 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | 462 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; |
449 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | 463 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); |
450 | ext4_commit_super(sb, es, 0); | 464 | ext4_commit_super(sb, 0); |
451 | return; | 465 | return; |
452 | } | 466 | } |
453 | ext4_unlock_group(sb, grp); | 467 | ext4_unlock_group(sb, grp); |
@@ -467,7 +481,6 @@ __acquires(bitlock) | |||
467 | return; | 481 | return; |
468 | } | 482 | } |
469 | 483 | ||
470 | |||
471 | void ext4_update_dynamic_rev(struct super_block *sb) | 484 | void ext4_update_dynamic_rev(struct super_block *sb) |
472 | { | 485 | { |
473 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; | 486 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; |
@@ -496,7 +509,7 @@ void ext4_update_dynamic_rev(struct super_block *sb) | |||
496 | /* | 509 | /* |
497 | * Open the external journal device | 510 | * Open the external journal device |
498 | */ | 511 | */ |
499 | static struct block_device *ext4_blkdev_get(dev_t dev) | 512 | static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb) |
500 | { | 513 | { |
501 | struct block_device *bdev; | 514 | struct block_device *bdev; |
502 | char b[BDEVNAME_SIZE]; | 515 | char b[BDEVNAME_SIZE]; |
@@ -507,7 +520,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev) | |||
507 | return bdev; | 520 | return bdev; |
508 | 521 | ||
509 | fail: | 522 | fail: |
510 | printk(KERN_ERR "EXT4-fs: failed to open journal device %s: %ld\n", | 523 | ext4_msg(sb, KERN_ERR, "failed to open journal device %s: %ld", |
511 | __bdevname(dev, b), PTR_ERR(bdev)); | 524 | __bdevname(dev, b), PTR_ERR(bdev)); |
512 | return NULL; | 525 | return NULL; |
513 | } | 526 | } |
@@ -543,8 +556,8 @@ static void dump_orphan_list(struct super_block *sb, struct ext4_sb_info *sbi) | |||
543 | { | 556 | { |
544 | struct list_head *l; | 557 | struct list_head *l; |
545 | 558 | ||
546 | printk(KERN_ERR "sb orphan head is %d\n", | 559 | ext4_msg(sb, KERN_ERR, "sb orphan head is %d", |
547 | le32_to_cpu(sbi->s_es->s_last_orphan)); | 560 | le32_to_cpu(sbi->s_es->s_last_orphan)); |
548 | 561 | ||
549 | printk(KERN_ERR "sb_info orphan list:\n"); | 562 | printk(KERN_ERR "sb_info orphan list:\n"); |
550 | list_for_each(l, &sbi->s_orphan) { | 563 | list_for_each(l, &sbi->s_orphan) { |
@@ -563,6 +576,7 @@ static void ext4_put_super(struct super_block *sb) | |||
563 | struct ext4_super_block *es = sbi->s_es; | 576 | struct ext4_super_block *es = sbi->s_es; |
564 | int i, err; | 577 | int i, err; |
565 | 578 | ||
579 | ext4_release_system_zone(sb); | ||
566 | ext4_mb_release(sb); | 580 | ext4_mb_release(sb); |
567 | ext4_ext_release(sb); | 581 | ext4_ext_release(sb); |
568 | ext4_xattr_put_super(sb); | 582 | ext4_xattr_put_super(sb); |
@@ -576,7 +590,7 @@ static void ext4_put_super(struct super_block *sb) | |||
576 | if (!(sb->s_flags & MS_RDONLY)) { | 590 | if (!(sb->s_flags & MS_RDONLY)) { |
577 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 591 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
578 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 592 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
579 | ext4_commit_super(sb, es, 1); | 593 | ext4_commit_super(sb, 1); |
580 | } | 594 | } |
581 | if (sbi->s_proc) { | 595 | if (sbi->s_proc) { |
582 | remove_proc_entry(sb->s_id, ext4_proc_root); | 596 | remove_proc_entry(sb->s_id, ext4_proc_root); |
@@ -586,7 +600,10 @@ static void ext4_put_super(struct super_block *sb) | |||
586 | for (i = 0; i < sbi->s_gdb_count; i++) | 600 | for (i = 0; i < sbi->s_gdb_count; i++) |
587 | brelse(sbi->s_group_desc[i]); | 601 | brelse(sbi->s_group_desc[i]); |
588 | kfree(sbi->s_group_desc); | 602 | kfree(sbi->s_group_desc); |
589 | kfree(sbi->s_flex_groups); | 603 | if (is_vmalloc_addr(sbi->s_flex_groups)) |
604 | vfree(sbi->s_flex_groups); | ||
605 | else | ||
606 | kfree(sbi->s_flex_groups); | ||
590 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | 607 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
591 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 608 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
592 | percpu_counter_destroy(&sbi->s_dirs_counter); | 609 | percpu_counter_destroy(&sbi->s_dirs_counter); |
@@ -629,7 +646,6 @@ static void ext4_put_super(struct super_block *sb) | |||
629 | lock_kernel(); | 646 | lock_kernel(); |
630 | kfree(sbi->s_blockgroup_lock); | 647 | kfree(sbi->s_blockgroup_lock); |
631 | kfree(sbi); | 648 | kfree(sbi); |
632 | return; | ||
633 | } | 649 | } |
634 | 650 | ||
635 | static struct kmem_cache *ext4_inode_cachep; | 651 | static struct kmem_cache *ext4_inode_cachep; |
@@ -644,6 +660,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
644 | ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS); | 660 | ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS); |
645 | if (!ei) | 661 | if (!ei) |
646 | return NULL; | 662 | return NULL; |
663 | |||
647 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | 664 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
648 | ei->i_acl = EXT4_ACL_NOT_CACHED; | 665 | ei->i_acl = EXT4_ACL_NOT_CACHED; |
649 | ei->i_default_acl = EXT4_ACL_NOT_CACHED; | 666 | ei->i_default_acl = EXT4_ACL_NOT_CACHED; |
@@ -664,14 +681,16 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
664 | ei->i_allocated_meta_blocks = 0; | 681 | ei->i_allocated_meta_blocks = 0; |
665 | ei->i_delalloc_reserved_flag = 0; | 682 | ei->i_delalloc_reserved_flag = 0; |
666 | spin_lock_init(&(ei->i_block_reservation_lock)); | 683 | spin_lock_init(&(ei->i_block_reservation_lock)); |
684 | |||
667 | return &ei->vfs_inode; | 685 | return &ei->vfs_inode; |
668 | } | 686 | } |
669 | 687 | ||
670 | static void ext4_destroy_inode(struct inode *inode) | 688 | static void ext4_destroy_inode(struct inode *inode) |
671 | { | 689 | { |
672 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { | 690 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { |
673 | printk("EXT4 Inode %p: orphan list check failed!\n", | 691 | ext4_msg(inode->i_sb, KERN_ERR, |
674 | EXT4_I(inode)); | 692 | "Inode %lu (%p): orphan list check failed!", |
693 | inode->i_ino, EXT4_I(inode)); | ||
675 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4, | 694 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 16, 4, |
676 | EXT4_I(inode), sizeof(struct ext4_inode_info), | 695 | EXT4_I(inode), sizeof(struct ext4_inode_info), |
677 | true); | 696 | true); |
@@ -870,12 +889,12 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
870 | seq_puts(seq, ",noauto_da_alloc"); | 889 | seq_puts(seq, ",noauto_da_alloc"); |
871 | 890 | ||
872 | ext4_show_quota_options(seq, sb); | 891 | ext4_show_quota_options(seq, sb); |
892 | |||
873 | return 0; | 893 | return 0; |
874 | } | 894 | } |
875 | 895 | ||
876 | |||
877 | static struct inode *ext4_nfs_get_inode(struct super_block *sb, | 896 | static struct inode *ext4_nfs_get_inode(struct super_block *sb, |
878 | u64 ino, u32 generation) | 897 | u64 ino, u32 generation) |
879 | { | 898 | { |
880 | struct inode *inode; | 899 | struct inode *inode; |
881 | 900 | ||
@@ -904,14 +923,14 @@ static struct inode *ext4_nfs_get_inode(struct super_block *sb, | |||
904 | } | 923 | } |
905 | 924 | ||
906 | static struct dentry *ext4_fh_to_dentry(struct super_block *sb, struct fid *fid, | 925 | static struct dentry *ext4_fh_to_dentry(struct super_block *sb, struct fid *fid, |
907 | int fh_len, int fh_type) | 926 | int fh_len, int fh_type) |
908 | { | 927 | { |
909 | return generic_fh_to_dentry(sb, fid, fh_len, fh_type, | 928 | return generic_fh_to_dentry(sb, fid, fh_len, fh_type, |
910 | ext4_nfs_get_inode); | 929 | ext4_nfs_get_inode); |
911 | } | 930 | } |
912 | 931 | ||
913 | static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid, | 932 | static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid, |
914 | int fh_len, int fh_type) | 933 | int fh_len, int fh_type) |
915 | { | 934 | { |
916 | return generic_fh_to_parent(sb, fid, fh_len, fh_type, | 935 | return generic_fh_to_parent(sb, fid, fh_len, fh_type, |
917 | ext4_nfs_get_inode); | 936 | ext4_nfs_get_inode); |
@@ -923,7 +942,8 @@ static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid, | |||
923 | * which would prevent try_to_free_buffers() from freeing them, we must use | 942 | * which would prevent try_to_free_buffers() from freeing them, we must use |
924 | * jbd2 layer's try_to_free_buffers() function to release them. | 943 | * jbd2 layer's try_to_free_buffers() function to release them. |
925 | */ | 944 | */ |
926 | static int bdev_try_to_free_page(struct super_block *sb, struct page *page, gfp_t wait) | 945 | static int bdev_try_to_free_page(struct super_block *sb, struct page *page, |
946 | gfp_t wait) | ||
927 | { | 947 | { |
928 | journal_t *journal = EXT4_SB(sb)->s_journal; | 948 | journal_t *journal = EXT4_SB(sb)->s_journal; |
929 | 949 | ||
@@ -992,7 +1012,6 @@ static const struct super_operations ext4_sops = { | |||
992 | .dirty_inode = ext4_dirty_inode, | 1012 | .dirty_inode = ext4_dirty_inode, |
993 | .delete_inode = ext4_delete_inode, | 1013 | .delete_inode = ext4_delete_inode, |
994 | .put_super = ext4_put_super, | 1014 | .put_super = ext4_put_super, |
995 | .write_super = ext4_write_super, | ||
996 | .sync_fs = ext4_sync_fs, | 1015 | .sync_fs = ext4_sync_fs, |
997 | .freeze_fs = ext4_freeze, | 1016 | .freeze_fs = ext4_freeze, |
998 | .unfreeze_fs = ext4_unfreeze, | 1017 | .unfreeze_fs = ext4_unfreeze, |
@@ -1007,6 +1026,25 @@ static const struct super_operations ext4_sops = { | |||
1007 | .bdev_try_to_free_page = bdev_try_to_free_page, | 1026 | .bdev_try_to_free_page = bdev_try_to_free_page, |
1008 | }; | 1027 | }; |
1009 | 1028 | ||
1029 | static const struct super_operations ext4_nojournal_sops = { | ||
1030 | .alloc_inode = ext4_alloc_inode, | ||
1031 | .destroy_inode = ext4_destroy_inode, | ||
1032 | .write_inode = ext4_write_inode, | ||
1033 | .dirty_inode = ext4_dirty_inode, | ||
1034 | .delete_inode = ext4_delete_inode, | ||
1035 | .write_super = ext4_write_super, | ||
1036 | .put_super = ext4_put_super, | ||
1037 | .statfs = ext4_statfs, | ||
1038 | .remount_fs = ext4_remount, | ||
1039 | .clear_inode = ext4_clear_inode, | ||
1040 | .show_options = ext4_show_options, | ||
1041 | #ifdef CONFIG_QUOTA | ||
1042 | .quota_read = ext4_quota_read, | ||
1043 | .quota_write = ext4_quota_write, | ||
1044 | #endif | ||
1045 | .bdev_try_to_free_page = bdev_try_to_free_page, | ||
1046 | }; | ||
1047 | |||
1010 | static const struct export_operations ext4_export_ops = { | 1048 | static const struct export_operations ext4_export_ops = { |
1011 | .fh_to_dentry = ext4_fh_to_dentry, | 1049 | .fh_to_dentry = ext4_fh_to_dentry, |
1012 | .fh_to_parent = ext4_fh_to_parent, | 1050 | .fh_to_parent = ext4_fh_to_parent, |
@@ -1023,12 +1061,13 @@ enum { | |||
1023 | Opt_journal_update, Opt_journal_dev, | 1061 | Opt_journal_update, Opt_journal_dev, |
1024 | Opt_journal_checksum, Opt_journal_async_commit, | 1062 | Opt_journal_checksum, Opt_journal_async_commit, |
1025 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, | 1063 | Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, |
1026 | Opt_data_err_abort, Opt_data_err_ignore, | 1064 | Opt_data_err_abort, Opt_data_err_ignore, Opt_mb_history_length, |
1027 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, | 1065 | Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, |
1028 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, | 1066 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, |
1029 | Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, | 1067 | Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, |
1030 | Opt_usrquota, Opt_grpquota, Opt_i_version, | 1068 | Opt_usrquota, Opt_grpquota, Opt_i_version, |
1031 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1069 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
1070 | Opt_block_validity, Opt_noblock_validity, | ||
1032 | Opt_inode_readahead_blks, Opt_journal_ioprio | 1071 | Opt_inode_readahead_blks, Opt_journal_ioprio |
1033 | }; | 1072 | }; |
1034 | 1073 | ||
@@ -1069,6 +1108,7 @@ static const match_table_t tokens = { | |||
1069 | {Opt_data_writeback, "data=writeback"}, | 1108 | {Opt_data_writeback, "data=writeback"}, |
1070 | {Opt_data_err_abort, "data_err=abort"}, | 1109 | {Opt_data_err_abort, "data_err=abort"}, |
1071 | {Opt_data_err_ignore, "data_err=ignore"}, | 1110 | {Opt_data_err_ignore, "data_err=ignore"}, |
1111 | {Opt_mb_history_length, "mb_history_length=%u"}, | ||
1072 | {Opt_offusrjquota, "usrjquota="}, | 1112 | {Opt_offusrjquota, "usrjquota="}, |
1073 | {Opt_usrjquota, "usrjquota=%s"}, | 1113 | {Opt_usrjquota, "usrjquota=%s"}, |
1074 | {Opt_offgrpjquota, "grpjquota="}, | 1114 | {Opt_offgrpjquota, "grpjquota="}, |
@@ -1087,6 +1127,8 @@ static const match_table_t tokens = { | |||
1087 | {Opt_resize, "resize"}, | 1127 | {Opt_resize, "resize"}, |
1088 | {Opt_delalloc, "delalloc"}, | 1128 | {Opt_delalloc, "delalloc"}, |
1089 | {Opt_nodelalloc, "nodelalloc"}, | 1129 | {Opt_nodelalloc, "nodelalloc"}, |
1130 | {Opt_block_validity, "block_validity"}, | ||
1131 | {Opt_noblock_validity, "noblock_validity"}, | ||
1090 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, | 1132 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, |
1091 | {Opt_journal_ioprio, "journal_ioprio=%u"}, | 1133 | {Opt_journal_ioprio, "journal_ioprio=%u"}, |
1092 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, | 1134 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, |
@@ -1102,8 +1144,9 @@ static ext4_fsblk_t get_sb_block(void **data) | |||
1102 | 1144 | ||
1103 | if (!options || strncmp(options, "sb=", 3) != 0) | 1145 | if (!options || strncmp(options, "sb=", 3) != 0) |
1104 | return 1; /* Default location */ | 1146 | return 1; /* Default location */ |
1147 | |||
1105 | options += 3; | 1148 | options += 3; |
1106 | /*todo: use simple_strtoll with >32bit ext4 */ | 1149 | /* TODO: use simple_strtoll with >32bit ext4 */ |
1107 | sb_block = simple_strtoul(options, &options, 0); | 1150 | sb_block = simple_strtoul(options, &options, 0); |
1108 | if (*options && *options != ',') { | 1151 | if (*options && *options != ',') { |
1109 | printk(KERN_ERR "EXT4-fs: Invalid sb specification: %s\n", | 1152 | printk(KERN_ERR "EXT4-fs: Invalid sb specification: %s\n", |
@@ -1113,6 +1156,7 @@ static ext4_fsblk_t get_sb_block(void **data) | |||
1113 | if (*options == ',') | 1156 | if (*options == ',') |
1114 | options++; | 1157 | options++; |
1115 | *data = (void *) options; | 1158 | *data = (void *) options; |
1159 | |||
1116 | return sb_block; | 1160 | return sb_block; |
1117 | } | 1161 | } |
1118 | 1162 | ||
@@ -1206,8 +1250,7 @@ static int parse_options(char *options, struct super_block *sb, | |||
1206 | #else | 1250 | #else |
1207 | case Opt_user_xattr: | 1251 | case Opt_user_xattr: |
1208 | case Opt_nouser_xattr: | 1252 | case Opt_nouser_xattr: |
1209 | printk(KERN_ERR "EXT4 (no)user_xattr options " | 1253 | ext4_msg(sb, KERN_ERR, "(no)user_xattr options not supported"); |
1210 | "not supported\n"); | ||
1211 | break; | 1254 | break; |
1212 | #endif | 1255 | #endif |
1213 | #ifdef CONFIG_EXT4_FS_POSIX_ACL | 1256 | #ifdef CONFIG_EXT4_FS_POSIX_ACL |
@@ -1220,8 +1263,7 @@ static int parse_options(char *options, struct super_block *sb, | |||
1220 | #else | 1263 | #else |
1221 | case Opt_acl: | 1264 | case Opt_acl: |
1222 | case Opt_noacl: | 1265 | case Opt_noacl: |
1223 | printk(KERN_ERR "EXT4 (no)acl options " | 1266 | ext4_msg(sb, KERN_ERR, "(no)acl options not supported"); |
1224 | "not supported\n"); | ||
1225 | break; | 1267 | break; |
1226 | #endif | 1268 | #endif |
1227 | case Opt_journal_update: | 1269 | case Opt_journal_update: |
@@ -1231,16 +1273,16 @@ static int parse_options(char *options, struct super_block *sb, | |||
1231 | user to specify an existing inode to be the | 1273 | user to specify an existing inode to be the |
1232 | journal file. */ | 1274 | journal file. */ |
1233 | if (is_remount) { | 1275 | if (is_remount) { |
1234 | printk(KERN_ERR "EXT4-fs: cannot specify " | 1276 | ext4_msg(sb, KERN_ERR, |
1235 | "journal on remount\n"); | 1277 | "Cannot specify journal on remount"); |
1236 | return 0; | 1278 | return 0; |
1237 | } | 1279 | } |
1238 | set_opt(sbi->s_mount_opt, UPDATE_JOURNAL); | 1280 | set_opt(sbi->s_mount_opt, UPDATE_JOURNAL); |
1239 | break; | 1281 | break; |
1240 | case Opt_journal_dev: | 1282 | case Opt_journal_dev: |
1241 | if (is_remount) { | 1283 | if (is_remount) { |
1242 | printk(KERN_ERR "EXT4-fs: cannot specify " | 1284 | ext4_msg(sb, KERN_ERR, |
1243 | "journal on remount\n"); | 1285 | "Cannot specify journal on remount"); |
1244 | return 0; | 1286 | return 0; |
1245 | } | 1287 | } |
1246 | if (match_int(&args[0], &option)) | 1288 | if (match_int(&args[0], &option)) |
@@ -1294,9 +1336,8 @@ static int parse_options(char *options, struct super_block *sb, | |||
1294 | if (is_remount) { | 1336 | if (is_remount) { |
1295 | if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS) | 1337 | if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS) |
1296 | != data_opt) { | 1338 | != data_opt) { |
1297 | printk(KERN_ERR | 1339 | ext4_msg(sb, KERN_ERR, |
1298 | "EXT4-fs: cannot change data " | 1340 | "Cannot change data mode on remount"); |
1299 | "mode on remount\n"); | ||
1300 | return 0; | 1341 | return 0; |
1301 | } | 1342 | } |
1302 | } else { | 1343 | } else { |
@@ -1310,6 +1351,13 @@ static int parse_options(char *options, struct super_block *sb, | |||
1310 | case Opt_data_err_ignore: | 1351 | case Opt_data_err_ignore: |
1311 | clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); | 1352 | clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); |
1312 | break; | 1353 | break; |
1354 | case Opt_mb_history_length: | ||
1355 | if (match_int(&args[0], &option)) | ||
1356 | return 0; | ||
1357 | if (option < 0) | ||
1358 | return 0; | ||
1359 | sbi->s_mb_history_max = option; | ||
1360 | break; | ||
1313 | #ifdef CONFIG_QUOTA | 1361 | #ifdef CONFIG_QUOTA |
1314 | case Opt_usrjquota: | 1362 | case Opt_usrjquota: |
1315 | qtype = USRQUOTA; | 1363 | qtype = USRQUOTA; |
@@ -1319,31 +1367,31 @@ static int parse_options(char *options, struct super_block *sb, | |||
1319 | set_qf_name: | 1367 | set_qf_name: |
1320 | if (sb_any_quota_loaded(sb) && | 1368 | if (sb_any_quota_loaded(sb) && |
1321 | !sbi->s_qf_names[qtype]) { | 1369 | !sbi->s_qf_names[qtype]) { |
1322 | printk(KERN_ERR | 1370 | ext4_msg(sb, KERN_ERR, |
1323 | "EXT4-fs: Cannot change journaled " | 1371 | "Cannot change journaled " |
1324 | "quota options when quota turned on.\n"); | 1372 | "quota options when quota turned on"); |
1325 | return 0; | 1373 | return 0; |
1326 | } | 1374 | } |
1327 | qname = match_strdup(&args[0]); | 1375 | qname = match_strdup(&args[0]); |
1328 | if (!qname) { | 1376 | if (!qname) { |
1329 | printk(KERN_ERR | 1377 | ext4_msg(sb, KERN_ERR, |
1330 | "EXT4-fs: not enough memory for " | 1378 | "Not enough memory for " |
1331 | "storing quotafile name.\n"); | 1379 | "storing quotafile name"); |
1332 | return 0; | 1380 | return 0; |
1333 | } | 1381 | } |
1334 | if (sbi->s_qf_names[qtype] && | 1382 | if (sbi->s_qf_names[qtype] && |
1335 | strcmp(sbi->s_qf_names[qtype], qname)) { | 1383 | strcmp(sbi->s_qf_names[qtype], qname)) { |
1336 | printk(KERN_ERR | 1384 | ext4_msg(sb, KERN_ERR, |
1337 | "EXT4-fs: %s quota file already " | 1385 | "%s quota file already " |
1338 | "specified.\n", QTYPE2NAME(qtype)); | 1386 | "specified", QTYPE2NAME(qtype)); |
1339 | kfree(qname); | 1387 | kfree(qname); |
1340 | return 0; | 1388 | return 0; |
1341 | } | 1389 | } |
1342 | sbi->s_qf_names[qtype] = qname; | 1390 | sbi->s_qf_names[qtype] = qname; |
1343 | if (strchr(sbi->s_qf_names[qtype], '/')) { | 1391 | if (strchr(sbi->s_qf_names[qtype], '/')) { |
1344 | printk(KERN_ERR | 1392 | ext4_msg(sb, KERN_ERR, |
1345 | "EXT4-fs: quotafile must be on " | 1393 | "quotafile must be on " |
1346 | "filesystem root.\n"); | 1394 | "filesystem root"); |
1347 | kfree(sbi->s_qf_names[qtype]); | 1395 | kfree(sbi->s_qf_names[qtype]); |
1348 | sbi->s_qf_names[qtype] = NULL; | 1396 | sbi->s_qf_names[qtype] = NULL; |
1349 | return 0; | 1397 | return 0; |
@@ -1358,9 +1406,9 @@ set_qf_name: | |||
1358 | clear_qf_name: | 1406 | clear_qf_name: |
1359 | if (sb_any_quota_loaded(sb) && | 1407 | if (sb_any_quota_loaded(sb) && |
1360 | sbi->s_qf_names[qtype]) { | 1408 | sbi->s_qf_names[qtype]) { |
1361 | printk(KERN_ERR "EXT4-fs: Cannot change " | 1409 | ext4_msg(sb, KERN_ERR, "Cannot change " |
1362 | "journaled quota options when " | 1410 | "journaled quota options when " |
1363 | "quota turned on.\n"); | 1411 | "quota turned on"); |
1364 | return 0; | 1412 | return 0; |
1365 | } | 1413 | } |
1366 | /* | 1414 | /* |
@@ -1377,9 +1425,9 @@ clear_qf_name: | |||
1377 | set_qf_format: | 1425 | set_qf_format: |
1378 | if (sb_any_quota_loaded(sb) && | 1426 | if (sb_any_quota_loaded(sb) && |
1379 | sbi->s_jquota_fmt != qfmt) { | 1427 | sbi->s_jquota_fmt != qfmt) { |
1380 | printk(KERN_ERR "EXT4-fs: Cannot change " | 1428 | ext4_msg(sb, KERN_ERR, "Cannot change " |
1381 | "journaled quota options when " | 1429 | "journaled quota options when " |
1382 | "quota turned on.\n"); | 1430 | "quota turned on"); |
1383 | return 0; | 1431 | return 0; |
1384 | } | 1432 | } |
1385 | sbi->s_jquota_fmt = qfmt; | 1433 | sbi->s_jquota_fmt = qfmt; |
@@ -1395,8 +1443,8 @@ set_qf_format: | |||
1395 | break; | 1443 | break; |
1396 | case Opt_noquota: | 1444 | case Opt_noquota: |
1397 | if (sb_any_quota_loaded(sb)) { | 1445 | if (sb_any_quota_loaded(sb)) { |
1398 | printk(KERN_ERR "EXT4-fs: Cannot change quota " | 1446 | ext4_msg(sb, KERN_ERR, "Cannot change quota " |
1399 | "options when quota turned on.\n"); | 1447 | "options when quota turned on"); |
1400 | return 0; | 1448 | return 0; |
1401 | } | 1449 | } |
1402 | clear_opt(sbi->s_mount_opt, QUOTA); | 1450 | clear_opt(sbi->s_mount_opt, QUOTA); |
@@ -1407,8 +1455,8 @@ set_qf_format: | |||
1407 | case Opt_quota: | 1455 | case Opt_quota: |
1408 | case Opt_usrquota: | 1456 | case Opt_usrquota: |
1409 | case Opt_grpquota: | 1457 | case Opt_grpquota: |
1410 | printk(KERN_ERR | 1458 | ext4_msg(sb, KERN_ERR, |
1411 | "EXT4-fs: quota options not supported.\n"); | 1459 | "quota options not supported"); |
1412 | break; | 1460 | break; |
1413 | case Opt_usrjquota: | 1461 | case Opt_usrjquota: |
1414 | case Opt_grpjquota: | 1462 | case Opt_grpjquota: |
@@ -1416,9 +1464,8 @@ set_qf_format: | |||
1416 | case Opt_offgrpjquota: | 1464 | case Opt_offgrpjquota: |
1417 | case Opt_jqfmt_vfsold: | 1465 | case Opt_jqfmt_vfsold: |
1418 | case Opt_jqfmt_vfsv0: | 1466 | case Opt_jqfmt_vfsv0: |
1419 | printk(KERN_ERR | 1467 | ext4_msg(sb, KERN_ERR, |
1420 | "EXT4-fs: journaled quota options not " | 1468 | "journaled quota options not supported"); |
1421 | "supported.\n"); | ||
1422 | break; | 1469 | break; |
1423 | case Opt_noquota: | 1470 | case Opt_noquota: |
1424 | break; | 1471 | break; |
@@ -1443,8 +1490,9 @@ set_qf_format: | |||
1443 | break; | 1490 | break; |
1444 | case Opt_resize: | 1491 | case Opt_resize: |
1445 | if (!is_remount) { | 1492 | if (!is_remount) { |
1446 | printk("EXT4-fs: resize option only available " | 1493 | ext4_msg(sb, KERN_ERR, |
1447 | "for remount\n"); | 1494 | "resize option only available " |
1495 | "for remount"); | ||
1448 | return 0; | 1496 | return 0; |
1449 | } | 1497 | } |
1450 | if (match_int(&args[0], &option) != 0) | 1498 | if (match_int(&args[0], &option) != 0) |
@@ -1474,14 +1522,21 @@ set_qf_format: | |||
1474 | case Opt_delalloc: | 1522 | case Opt_delalloc: |
1475 | set_opt(sbi->s_mount_opt, DELALLOC); | 1523 | set_opt(sbi->s_mount_opt, DELALLOC); |
1476 | break; | 1524 | break; |
1525 | case Opt_block_validity: | ||
1526 | set_opt(sbi->s_mount_opt, BLOCK_VALIDITY); | ||
1527 | break; | ||
1528 | case Opt_noblock_validity: | ||
1529 | clear_opt(sbi->s_mount_opt, BLOCK_VALIDITY); | ||
1530 | break; | ||
1477 | case Opt_inode_readahead_blks: | 1531 | case Opt_inode_readahead_blks: |
1478 | if (match_int(&args[0], &option)) | 1532 | if (match_int(&args[0], &option)) |
1479 | return 0; | 1533 | return 0; |
1480 | if (option < 0 || option > (1 << 30)) | 1534 | if (option < 0 || option > (1 << 30)) |
1481 | return 0; | 1535 | return 0; |
1482 | if (option & (option - 1)) { | 1536 | if (!is_power_of_2(option)) { |
1483 | printk(KERN_ERR "EXT4-fs: inode_readahead_blks" | 1537 | ext4_msg(sb, KERN_ERR, |
1484 | " must be a power of 2\n"); | 1538 | "EXT4-fs: inode_readahead_blks" |
1539 | " must be a power of 2"); | ||
1485 | return 0; | 1540 | return 0; |
1486 | } | 1541 | } |
1487 | sbi->s_inode_readahead_blks = option; | 1542 | sbi->s_inode_readahead_blks = option; |
@@ -1508,9 +1563,9 @@ set_qf_format: | |||
1508 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); | 1563 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); |
1509 | break; | 1564 | break; |
1510 | default: | 1565 | default: |
1511 | printk(KERN_ERR | 1566 | ext4_msg(sb, KERN_ERR, |
1512 | "EXT4-fs: Unrecognized mount option \"%s\" " | 1567 | "Unrecognized mount option \"%s\" " |
1513 | "or missing value\n", p); | 1568 | "or missing value", p); |
1514 | return 0; | 1569 | return 0; |
1515 | } | 1570 | } |
1516 | } | 1571 | } |
@@ -1528,21 +1583,21 @@ set_qf_format: | |||
1528 | (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) || | 1583 | (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) || |
1529 | (sbi->s_qf_names[GRPQUOTA] && | 1584 | (sbi->s_qf_names[GRPQUOTA] && |
1530 | (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) { | 1585 | (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) { |
1531 | printk(KERN_ERR "EXT4-fs: old and new quota " | 1586 | ext4_msg(sb, KERN_ERR, "old and new quota " |
1532 | "format mixing.\n"); | 1587 | "format mixing"); |
1533 | return 0; | 1588 | return 0; |
1534 | } | 1589 | } |
1535 | 1590 | ||
1536 | if (!sbi->s_jquota_fmt) { | 1591 | if (!sbi->s_jquota_fmt) { |
1537 | printk(KERN_ERR "EXT4-fs: journaled quota format " | 1592 | ext4_msg(sb, KERN_ERR, "journaled quota format " |
1538 | "not specified.\n"); | 1593 | "not specified"); |
1539 | return 0; | 1594 | return 0; |
1540 | } | 1595 | } |
1541 | } else { | 1596 | } else { |
1542 | if (sbi->s_jquota_fmt) { | 1597 | if (sbi->s_jquota_fmt) { |
1543 | printk(KERN_ERR "EXT4-fs: journaled quota format " | 1598 | ext4_msg(sb, KERN_ERR, "journaled quota format " |
1544 | "specified with no journaling " | 1599 | "specified with no journaling " |
1545 | "enabled.\n"); | 1600 | "enabled"); |
1546 | return 0; | 1601 | return 0; |
1547 | } | 1602 | } |
1548 | } | 1603 | } |
@@ -1557,32 +1612,32 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, | |||
1557 | int res = 0; | 1612 | int res = 0; |
1558 | 1613 | ||
1559 | if (le32_to_cpu(es->s_rev_level) > EXT4_MAX_SUPP_REV) { | 1614 | if (le32_to_cpu(es->s_rev_level) > EXT4_MAX_SUPP_REV) { |
1560 | printk(KERN_ERR "EXT4-fs warning: revision level too high, " | 1615 | ext4_msg(sb, KERN_ERR, "revision level too high, " |
1561 | "forcing read-only mode\n"); | 1616 | "forcing read-only mode"); |
1562 | res = MS_RDONLY; | 1617 | res = MS_RDONLY; |
1563 | } | 1618 | } |
1564 | if (read_only) | 1619 | if (read_only) |
1565 | return res; | 1620 | return res; |
1566 | if (!(sbi->s_mount_state & EXT4_VALID_FS)) | 1621 | if (!(sbi->s_mount_state & EXT4_VALID_FS)) |
1567 | printk(KERN_WARNING "EXT4-fs warning: mounting unchecked fs, " | 1622 | ext4_msg(sb, KERN_WARNING, "warning: mounting unchecked fs, " |
1568 | "running e2fsck is recommended\n"); | 1623 | "running e2fsck is recommended"); |
1569 | else if ((sbi->s_mount_state & EXT4_ERROR_FS)) | 1624 | else if ((sbi->s_mount_state & EXT4_ERROR_FS)) |
1570 | printk(KERN_WARNING | 1625 | ext4_msg(sb, KERN_WARNING, |
1571 | "EXT4-fs warning: mounting fs with errors, " | 1626 | "warning: mounting fs with errors, " |
1572 | "running e2fsck is recommended\n"); | 1627 | "running e2fsck is recommended"); |
1573 | else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 && | 1628 | else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 && |
1574 | le16_to_cpu(es->s_mnt_count) >= | 1629 | le16_to_cpu(es->s_mnt_count) >= |
1575 | (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count)) | 1630 | (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count)) |
1576 | printk(KERN_WARNING | 1631 | ext4_msg(sb, KERN_WARNING, |
1577 | "EXT4-fs warning: maximal mount count reached, " | 1632 | "warning: maximal mount count reached, " |
1578 | "running e2fsck is recommended\n"); | 1633 | "running e2fsck is recommended"); |
1579 | else if (le32_to_cpu(es->s_checkinterval) && | 1634 | else if (le32_to_cpu(es->s_checkinterval) && |
1580 | (le32_to_cpu(es->s_lastcheck) + | 1635 | (le32_to_cpu(es->s_lastcheck) + |
1581 | le32_to_cpu(es->s_checkinterval) <= get_seconds())) | 1636 | le32_to_cpu(es->s_checkinterval) <= get_seconds())) |
1582 | printk(KERN_WARNING | 1637 | ext4_msg(sb, KERN_WARNING, |
1583 | "EXT4-fs warning: checktime reached, " | 1638 | "warning: checktime reached, " |
1584 | "running e2fsck is recommended\n"); | 1639 | "running e2fsck is recommended"); |
1585 | if (!sbi->s_journal) | 1640 | if (!sbi->s_journal) |
1586 | es->s_state &= cpu_to_le16(~EXT4_VALID_FS); | 1641 | es->s_state &= cpu_to_le16(~EXT4_VALID_FS); |
1587 | if (!(__s16) le16_to_cpu(es->s_max_mnt_count)) | 1642 | if (!(__s16) le16_to_cpu(es->s_max_mnt_count)) |
1588 | es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT); | 1643 | es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT); |
@@ -1592,7 +1647,7 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, | |||
1592 | if (sbi->s_journal) | 1647 | if (sbi->s_journal) |
1593 | EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 1648 | EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
1594 | 1649 | ||
1595 | ext4_commit_super(sb, es, 1); | 1650 | ext4_commit_super(sb, 1); |
1596 | if (test_opt(sb, DEBUG)) | 1651 | if (test_opt(sb, DEBUG)) |
1597 | printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%u, " | 1652 | printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%u, " |
1598 | "bpg=%lu, ipg=%lu, mo=%04lx]\n", | 1653 | "bpg=%lu, ipg=%lu, mo=%04lx]\n", |
@@ -1603,11 +1658,11 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, | |||
1603 | sbi->s_mount_opt); | 1658 | sbi->s_mount_opt); |
1604 | 1659 | ||
1605 | if (EXT4_SB(sb)->s_journal) { | 1660 | if (EXT4_SB(sb)->s_journal) { |
1606 | printk(KERN_INFO "EXT4 FS on %s, %s journal on %s\n", | 1661 | ext4_msg(sb, KERN_INFO, "%s journal on %s", |
1607 | sb->s_id, EXT4_SB(sb)->s_journal->j_inode ? "internal" : | 1662 | EXT4_SB(sb)->s_journal->j_inode ? "internal" : |
1608 | "external", EXT4_SB(sb)->s_journal->j_devname); | 1663 | "external", EXT4_SB(sb)->s_journal->j_devname); |
1609 | } else { | 1664 | } else { |
1610 | printk(KERN_INFO "EXT4 FS on %s, no journal\n", sb->s_id); | 1665 | ext4_msg(sb, KERN_INFO, "no journal"); |
1611 | } | 1666 | } |
1612 | return res; | 1667 | return res; |
1613 | } | 1668 | } |
@@ -1616,10 +1671,10 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
1616 | { | 1671 | { |
1617 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1672 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
1618 | struct ext4_group_desc *gdp = NULL; | 1673 | struct ext4_group_desc *gdp = NULL; |
1619 | struct buffer_head *bh; | ||
1620 | ext4_group_t flex_group_count; | 1674 | ext4_group_t flex_group_count; |
1621 | ext4_group_t flex_group; | 1675 | ext4_group_t flex_group; |
1622 | int groups_per_flex = 0; | 1676 | int groups_per_flex = 0; |
1677 | size_t size; | ||
1623 | int i; | 1678 | int i; |
1624 | 1679 | ||
1625 | if (!sbi->s_es->s_log_groups_per_flex) { | 1680 | if (!sbi->s_es->s_log_groups_per_flex) { |
@@ -1634,16 +1689,21 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
1634 | flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + | 1689 | flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + |
1635 | ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << | 1690 | ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << |
1636 | EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex; | 1691 | EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex; |
1637 | sbi->s_flex_groups = kzalloc(flex_group_count * | 1692 | size = flex_group_count * sizeof(struct flex_groups); |
1638 | sizeof(struct flex_groups), GFP_KERNEL); | 1693 | sbi->s_flex_groups = kzalloc(size, GFP_KERNEL); |
1694 | if (sbi->s_flex_groups == NULL) { | ||
1695 | sbi->s_flex_groups = vmalloc(size); | ||
1696 | if (sbi->s_flex_groups) | ||
1697 | memset(sbi->s_flex_groups, 0, size); | ||
1698 | } | ||
1639 | if (sbi->s_flex_groups == NULL) { | 1699 | if (sbi->s_flex_groups == NULL) { |
1640 | printk(KERN_ERR "EXT4-fs: not enough memory for " | 1700 | ext4_msg(sb, KERN_ERR, "not enough memory for " |
1641 | "%u flex groups\n", flex_group_count); | 1701 | "%u flex groups", flex_group_count); |
1642 | goto failed; | 1702 | goto failed; |
1643 | } | 1703 | } |
1644 | 1704 | ||
1645 | for (i = 0; i < sbi->s_groups_count; i++) { | 1705 | for (i = 0; i < sbi->s_groups_count; i++) { |
1646 | gdp = ext4_get_group_desc(sb, i, &bh); | 1706 | gdp = ext4_get_group_desc(sb, i, NULL); |
1647 | 1707 | ||
1648 | flex_group = ext4_flex_group(sbi, i); | 1708 | flex_group = ext4_flex_group(sbi, i); |
1649 | atomic_set(&sbi->s_flex_groups[flex_group].free_inodes, | 1709 | atomic_set(&sbi->s_flex_groups[flex_group].free_inodes, |
@@ -1724,44 +1784,44 @@ static int ext4_check_descriptors(struct super_block *sb) | |||
1724 | 1784 | ||
1725 | block_bitmap = ext4_block_bitmap(sb, gdp); | 1785 | block_bitmap = ext4_block_bitmap(sb, gdp); |
1726 | if (block_bitmap < first_block || block_bitmap > last_block) { | 1786 | if (block_bitmap < first_block || block_bitmap > last_block) { |
1727 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1787 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
1728 | "Block bitmap for group %u not in group " | 1788 | "Block bitmap for group %u not in group " |
1729 | "(block %llu)!\n", i, block_bitmap); | 1789 | "(block %llu)!", i, block_bitmap); |
1730 | return 0; | 1790 | return 0; |
1731 | } | 1791 | } |
1732 | inode_bitmap = ext4_inode_bitmap(sb, gdp); | 1792 | inode_bitmap = ext4_inode_bitmap(sb, gdp); |
1733 | if (inode_bitmap < first_block || inode_bitmap > last_block) { | 1793 | if (inode_bitmap < first_block || inode_bitmap > last_block) { |
1734 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1794 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
1735 | "Inode bitmap for group %u not in group " | 1795 | "Inode bitmap for group %u not in group " |
1736 | "(block %llu)!\n", i, inode_bitmap); | 1796 | "(block %llu)!", i, inode_bitmap); |
1737 | return 0; | 1797 | return 0; |
1738 | } | 1798 | } |
1739 | inode_table = ext4_inode_table(sb, gdp); | 1799 | inode_table = ext4_inode_table(sb, gdp); |
1740 | if (inode_table < first_block || | 1800 | if (inode_table < first_block || |
1741 | inode_table + sbi->s_itb_per_group - 1 > last_block) { | 1801 | inode_table + sbi->s_itb_per_group - 1 > last_block) { |
1742 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1802 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
1743 | "Inode table for group %u not in group " | 1803 | "Inode table for group %u not in group " |
1744 | "(block %llu)!\n", i, inode_table); | 1804 | "(block %llu)!", i, inode_table); |
1745 | return 0; | 1805 | return 0; |
1746 | } | 1806 | } |
1747 | spin_lock(sb_bgl_lock(sbi, i)); | 1807 | ext4_lock_group(sb, i); |
1748 | if (!ext4_group_desc_csum_verify(sbi, i, gdp)) { | 1808 | if (!ext4_group_desc_csum_verify(sbi, i, gdp)) { |
1749 | printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: " | 1809 | ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " |
1750 | "Checksum for group %u failed (%u!=%u)\n", | 1810 | "Checksum for group %u failed (%u!=%u)", |
1751 | i, le16_to_cpu(ext4_group_desc_csum(sbi, i, | 1811 | i, le16_to_cpu(ext4_group_desc_csum(sbi, i, |
1752 | gdp)), le16_to_cpu(gdp->bg_checksum)); | 1812 | gdp)), le16_to_cpu(gdp->bg_checksum)); |
1753 | if (!(sb->s_flags & MS_RDONLY)) { | 1813 | if (!(sb->s_flags & MS_RDONLY)) { |
1754 | spin_unlock(sb_bgl_lock(sbi, i)); | 1814 | ext4_unlock_group(sb, i); |
1755 | return 0; | 1815 | return 0; |
1756 | } | 1816 | } |
1757 | } | 1817 | } |
1758 | spin_unlock(sb_bgl_lock(sbi, i)); | 1818 | ext4_unlock_group(sb, i); |
1759 | if (!flexbg_flag) | 1819 | if (!flexbg_flag) |
1760 | first_block += EXT4_BLOCKS_PER_GROUP(sb); | 1820 | first_block += EXT4_BLOCKS_PER_GROUP(sb); |
1761 | } | 1821 | } |
1762 | 1822 | ||
1763 | ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb)); | 1823 | ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb)); |
1764 | sbi->s_es->s_free_inodes_count = cpu_to_le32(ext4_count_free_inodes(sb)); | 1824 | sbi->s_es->s_free_inodes_count =cpu_to_le32(ext4_count_free_inodes(sb)); |
1765 | return 1; | 1825 | return 1; |
1766 | } | 1826 | } |
1767 | 1827 | ||
@@ -1796,8 +1856,8 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1796 | } | 1856 | } |
1797 | 1857 | ||
1798 | if (bdev_read_only(sb->s_bdev)) { | 1858 | if (bdev_read_only(sb->s_bdev)) { |
1799 | printk(KERN_ERR "EXT4-fs: write access " | 1859 | ext4_msg(sb, KERN_ERR, "write access " |
1800 | "unavailable, skipping orphan cleanup.\n"); | 1860 | "unavailable, skipping orphan cleanup"); |
1801 | return; | 1861 | return; |
1802 | } | 1862 | } |
1803 | 1863 | ||
@@ -1811,8 +1871,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1811 | } | 1871 | } |
1812 | 1872 | ||
1813 | if (s_flags & MS_RDONLY) { | 1873 | if (s_flags & MS_RDONLY) { |
1814 | printk(KERN_INFO "EXT4-fs: %s: orphan cleanup on readonly fs\n", | 1874 | ext4_msg(sb, KERN_INFO, "orphan cleanup on readonly fs"); |
1815 | sb->s_id); | ||
1816 | sb->s_flags &= ~MS_RDONLY; | 1875 | sb->s_flags &= ~MS_RDONLY; |
1817 | } | 1876 | } |
1818 | #ifdef CONFIG_QUOTA | 1877 | #ifdef CONFIG_QUOTA |
@@ -1823,9 +1882,9 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1823 | if (EXT4_SB(sb)->s_qf_names[i]) { | 1882 | if (EXT4_SB(sb)->s_qf_names[i]) { |
1824 | int ret = ext4_quota_on_mount(sb, i); | 1883 | int ret = ext4_quota_on_mount(sb, i); |
1825 | if (ret < 0) | 1884 | if (ret < 0) |
1826 | printk(KERN_ERR | 1885 | ext4_msg(sb, KERN_ERR, |
1827 | "EXT4-fs: Cannot turn on journaled " | 1886 | "Cannot turn on journaled " |
1828 | "quota: error %d\n", ret); | 1887 | "quota: error %d", ret); |
1829 | } | 1888 | } |
1830 | } | 1889 | } |
1831 | #endif | 1890 | #endif |
@@ -1842,16 +1901,16 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1842 | list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); | 1901 | list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); |
1843 | vfs_dq_init(inode); | 1902 | vfs_dq_init(inode); |
1844 | if (inode->i_nlink) { | 1903 | if (inode->i_nlink) { |
1845 | printk(KERN_DEBUG | 1904 | ext4_msg(sb, KERN_DEBUG, |
1846 | "%s: truncating inode %lu to %lld bytes\n", | 1905 | "%s: truncating inode %lu to %lld bytes", |
1847 | __func__, inode->i_ino, inode->i_size); | 1906 | __func__, inode->i_ino, inode->i_size); |
1848 | jbd_debug(2, "truncating inode %lu to %lld bytes\n", | 1907 | jbd_debug(2, "truncating inode %lu to %lld bytes\n", |
1849 | inode->i_ino, inode->i_size); | 1908 | inode->i_ino, inode->i_size); |
1850 | ext4_truncate(inode); | 1909 | ext4_truncate(inode); |
1851 | nr_truncates++; | 1910 | nr_truncates++; |
1852 | } else { | 1911 | } else { |
1853 | printk(KERN_DEBUG | 1912 | ext4_msg(sb, KERN_DEBUG, |
1854 | "%s: deleting unreferenced inode %lu\n", | 1913 | "%s: deleting unreferenced inode %lu", |
1855 | __func__, inode->i_ino); | 1914 | __func__, inode->i_ino); |
1856 | jbd_debug(2, "deleting unreferenced inode %lu\n", | 1915 | jbd_debug(2, "deleting unreferenced inode %lu\n", |
1857 | inode->i_ino); | 1916 | inode->i_ino); |
@@ -1863,11 +1922,11 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1863 | #define PLURAL(x) (x), ((x) == 1) ? "" : "s" | 1922 | #define PLURAL(x) (x), ((x) == 1) ? "" : "s" |
1864 | 1923 | ||
1865 | if (nr_orphans) | 1924 | if (nr_orphans) |
1866 | printk(KERN_INFO "EXT4-fs: %s: %d orphan inode%s deleted\n", | 1925 | ext4_msg(sb, KERN_INFO, "%d orphan inode%s deleted", |
1867 | sb->s_id, PLURAL(nr_orphans)); | 1926 | PLURAL(nr_orphans)); |
1868 | if (nr_truncates) | 1927 | if (nr_truncates) |
1869 | printk(KERN_INFO "EXT4-fs: %s: %d truncate%s cleaned up\n", | 1928 | ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up", |
1870 | sb->s_id, PLURAL(nr_truncates)); | 1929 | PLURAL(nr_truncates)); |
1871 | #ifdef CONFIG_QUOTA | 1930 | #ifdef CONFIG_QUOTA |
1872 | /* Turn quotas off */ | 1931 | /* Turn quotas off */ |
1873 | for (i = 0; i < MAXQUOTAS; i++) { | 1932 | for (i = 0; i < MAXQUOTAS; i++) { |
@@ -1877,6 +1936,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1877 | #endif | 1936 | #endif |
1878 | sb->s_flags = s_flags; /* Restore MS_RDONLY status */ | 1937 | sb->s_flags = s_flags; /* Restore MS_RDONLY status */ |
1879 | } | 1938 | } |
1939 | |||
1880 | /* | 1940 | /* |
1881 | * Maximal extent format file size. | 1941 | * Maximal extent format file size. |
1882 | * Resulting logical blkno at s_maxbytes must fit in our on-disk | 1942 | * Resulting logical blkno at s_maxbytes must fit in our on-disk |
@@ -1927,19 +1987,19 @@ static loff_t ext4_max_bitmap_size(int bits, int has_huge_files) | |||
1927 | loff_t res = EXT4_NDIR_BLOCKS; | 1987 | loff_t res = EXT4_NDIR_BLOCKS; |
1928 | int meta_blocks; | 1988 | int meta_blocks; |
1929 | loff_t upper_limit; | 1989 | loff_t upper_limit; |
1930 | /* This is calculated to be the largest file size for a | 1990 | /* This is calculated to be the largest file size for a dense, block |
1931 | * dense, bitmapped file such that the total number of | 1991 | * mapped file such that the file's total number of 512-byte sectors, |
1932 | * sectors in the file, including data and all indirect blocks, | 1992 | * including data and all indirect blocks, does not exceed (2^48 - 1). |
1933 | * does not exceed 2^48 -1 | 1993 | * |
1934 | * __u32 i_blocks_lo and _u16 i_blocks_high representing the | 1994 | * __u32 i_blocks_lo and _u16 i_blocks_high represent the total |
1935 | * total number of 512 bytes blocks of the file | 1995 | * number of 512-byte sectors of the file. |
1936 | */ | 1996 | */ |
1937 | 1997 | ||
1938 | if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) { | 1998 | if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) { |
1939 | /* | 1999 | /* |
1940 | * !has_huge_files or CONFIG_LBD is not enabled | 2000 | * !has_huge_files or CONFIG_LBD not enabled implies that |
1941 | * implies the inode i_block represent total blocks in | 2001 | * the inode i_block field represents total file blocks in |
1942 | * 512 bytes 32 == size of vfs inode i_blocks * 8 | 2002 | * 2^32 512-byte sectors == size of vfs inode i_blocks * 8 |
1943 | */ | 2003 | */ |
1944 | upper_limit = (1LL << 32) - 1; | 2004 | upper_limit = (1LL << 32) - 1; |
1945 | 2005 | ||
@@ -1981,7 +2041,7 @@ static loff_t ext4_max_bitmap_size(int bits, int has_huge_files) | |||
1981 | } | 2041 | } |
1982 | 2042 | ||
1983 | static ext4_fsblk_t descriptor_loc(struct super_block *sb, | 2043 | static ext4_fsblk_t descriptor_loc(struct super_block *sb, |
1984 | ext4_fsblk_t logical_sb_block, int nr) | 2044 | ext4_fsblk_t logical_sb_block, int nr) |
1985 | { | 2045 | { |
1986 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 2046 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
1987 | ext4_group_t bg, first_meta_bg; | 2047 | ext4_group_t bg, first_meta_bg; |
@@ -1995,6 +2055,7 @@ static ext4_fsblk_t descriptor_loc(struct super_block *sb, | |||
1995 | bg = sbi->s_desc_per_block * nr; | 2055 | bg = sbi->s_desc_per_block * nr; |
1996 | if (ext4_bg_has_super(sb, bg)) | 2056 | if (ext4_bg_has_super(sb, bg)) |
1997 | has_super = 1; | 2057 | has_super = 1; |
2058 | |||
1998 | return (has_super + ext4_group_first_block_no(sb, bg)); | 2059 | return (has_super + ext4_group_first_block_no(sb, bg)); |
1999 | } | 2060 | } |
2000 | 2061 | ||
@@ -2091,8 +2152,7 @@ static ssize_t inode_readahead_blks_store(struct ext4_attr *a, | |||
2091 | if (parse_strtoul(buf, 0x40000000, &t)) | 2152 | if (parse_strtoul(buf, 0x40000000, &t)) |
2092 | return -EINVAL; | 2153 | return -EINVAL; |
2093 | 2154 | ||
2094 | /* inode_readahead_blks must be a power of 2 */ | 2155 | if (!is_power_of_2(t)) |
2095 | if (t & (t-1)) | ||
2096 | return -EINVAL; | 2156 | return -EINVAL; |
2097 | 2157 | ||
2098 | sbi->s_inode_readahead_blks = t; | 2158 | sbi->s_inode_readahead_blks = t; |
@@ -2100,7 +2160,7 @@ static ssize_t inode_readahead_blks_store(struct ext4_attr *a, | |||
2100 | } | 2160 | } |
2101 | 2161 | ||
2102 | static ssize_t sbi_ui_show(struct ext4_attr *a, | 2162 | static ssize_t sbi_ui_show(struct ext4_attr *a, |
2103 | struct ext4_sb_info *sbi, char *buf) | 2163 | struct ext4_sb_info *sbi, char *buf) |
2104 | { | 2164 | { |
2105 | unsigned int *ui = (unsigned int *) (((char *) sbi) + a->offset); | 2165 | unsigned int *ui = (unsigned int *) (((char *) sbi) + a->offset); |
2106 | 2166 | ||
@@ -2205,7 +2265,6 @@ static struct kobj_type ext4_ktype = { | |||
2205 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) | 2265 | static int ext4_fill_super(struct super_block *sb, void *data, int silent) |
2206 | __releases(kernel_lock) | 2266 | __releases(kernel_lock) |
2207 | __acquires(kernel_lock) | 2267 | __acquires(kernel_lock) |
2208 | |||
2209 | { | 2268 | { |
2210 | struct buffer_head *bh; | 2269 | struct buffer_head *bh; |
2211 | struct ext4_super_block *es = NULL; | 2270 | struct ext4_super_block *es = NULL; |
@@ -2256,7 +2315,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2256 | 2315 | ||
2257 | blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); | 2316 | blocksize = sb_min_blocksize(sb, EXT4_MIN_BLOCK_SIZE); |
2258 | if (!blocksize) { | 2317 | if (!blocksize) { |
2259 | printk(KERN_ERR "EXT4-fs: unable to set blocksize\n"); | 2318 | ext4_msg(sb, KERN_ERR, "unable to set blocksize"); |
2260 | goto out_fail; | 2319 | goto out_fail; |
2261 | } | 2320 | } |
2262 | 2321 | ||
@@ -2272,7 +2331,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2272 | } | 2331 | } |
2273 | 2332 | ||
2274 | if (!(bh = sb_bread(sb, logical_sb_block))) { | 2333 | if (!(bh = sb_bread(sb, logical_sb_block))) { |
2275 | printk(KERN_ERR "EXT4-fs: unable to read superblock\n"); | 2334 | ext4_msg(sb, KERN_ERR, "unable to read superblock"); |
2276 | goto out_fail; | 2335 | goto out_fail; |
2277 | } | 2336 | } |
2278 | /* | 2337 | /* |
@@ -2321,6 +2380,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2321 | sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ; | 2380 | sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ; |
2322 | sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; | 2381 | sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; |
2323 | sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; | 2382 | sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; |
2383 | sbi->s_mb_history_max = default_mb_history_length; | ||
2324 | 2384 | ||
2325 | set_opt(sbi->s_mount_opt, BARRIER); | 2385 | set_opt(sbi->s_mount_opt, BARRIER); |
2326 | 2386 | ||
@@ -2330,7 +2390,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2330 | */ | 2390 | */ |
2331 | set_opt(sbi->s_mount_opt, DELALLOC); | 2391 | set_opt(sbi->s_mount_opt, DELALLOC); |
2332 | 2392 | ||
2333 | |||
2334 | if (!parse_options((char *) data, sb, &journal_devnum, | 2393 | if (!parse_options((char *) data, sb, &journal_devnum, |
2335 | &journal_ioprio, NULL, 0)) | 2394 | &journal_ioprio, NULL, 0)) |
2336 | goto failed_mount; | 2395 | goto failed_mount; |
@@ -2342,9 +2401,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2342 | (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || | 2401 | (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || |
2343 | EXT4_HAS_RO_COMPAT_FEATURE(sb, ~0U) || | 2402 | EXT4_HAS_RO_COMPAT_FEATURE(sb, ~0U) || |
2344 | EXT4_HAS_INCOMPAT_FEATURE(sb, ~0U))) | 2403 | EXT4_HAS_INCOMPAT_FEATURE(sb, ~0U))) |
2345 | printk(KERN_WARNING | 2404 | ext4_msg(sb, KERN_WARNING, |
2346 | "EXT4-fs warning: feature flags set on rev 0 fs, " | 2405 | "feature flags set on rev 0 fs, " |
2347 | "running e2fsck is recommended\n"); | 2406 | "running e2fsck is recommended"); |
2348 | 2407 | ||
2349 | /* | 2408 | /* |
2350 | * Check feature flags regardless of the revision level, since we | 2409 | * Check feature flags regardless of the revision level, since we |
@@ -2353,16 +2412,18 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2353 | */ | 2412 | */ |
2354 | features = EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP); | 2413 | features = EXT4_HAS_INCOMPAT_FEATURE(sb, ~EXT4_FEATURE_INCOMPAT_SUPP); |
2355 | if (features) { | 2414 | if (features) { |
2356 | printk(KERN_ERR "EXT4-fs: %s: couldn't mount because of " | 2415 | ext4_msg(sb, KERN_ERR, |
2357 | "unsupported optional features (%x).\n", sb->s_id, | 2416 | "Couldn't mount because of " |
2417 | "unsupported optional features (%x)", | ||
2358 | (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_incompat) & | 2418 | (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_incompat) & |
2359 | ~EXT4_FEATURE_INCOMPAT_SUPP)); | 2419 | ~EXT4_FEATURE_INCOMPAT_SUPP)); |
2360 | goto failed_mount; | 2420 | goto failed_mount; |
2361 | } | 2421 | } |
2362 | features = EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP); | 2422 | features = EXT4_HAS_RO_COMPAT_FEATURE(sb, ~EXT4_FEATURE_RO_COMPAT_SUPP); |
2363 | if (!(sb->s_flags & MS_RDONLY) && features) { | 2423 | if (!(sb->s_flags & MS_RDONLY) && features) { |
2364 | printk(KERN_ERR "EXT4-fs: %s: couldn't mount RDWR because of " | 2424 | ext4_msg(sb, KERN_ERR, |
2365 | "unsupported optional features (%x).\n", sb->s_id, | 2425 | "Couldn't mount RDWR because of " |
2426 | "unsupported optional features (%x)", | ||
2366 | (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) & | 2427 | (le32_to_cpu(EXT4_SB(sb)->s_es->s_feature_ro_compat) & |
2367 | ~EXT4_FEATURE_RO_COMPAT_SUPP)); | 2428 | ~EXT4_FEATURE_RO_COMPAT_SUPP)); |
2368 | goto failed_mount; | 2429 | goto failed_mount; |
@@ -2376,9 +2437,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2376 | */ | 2437 | */ |
2377 | if (sizeof(root->i_blocks) < sizeof(u64) && | 2438 | if (sizeof(root->i_blocks) < sizeof(u64) && |
2378 | !(sb->s_flags & MS_RDONLY)) { | 2439 | !(sb->s_flags & MS_RDONLY)) { |
2379 | printk(KERN_ERR "EXT4-fs: %s: Filesystem with huge " | 2440 | ext4_msg(sb, KERN_ERR, "Filesystem with huge " |
2380 | "files cannot be mounted read-write " | 2441 | "files cannot be mounted read-write " |
2381 | "without CONFIG_LBD.\n", sb->s_id); | 2442 | "without CONFIG_LBD"); |
2382 | goto failed_mount; | 2443 | goto failed_mount; |
2383 | } | 2444 | } |
2384 | } | 2445 | } |
@@ -2386,17 +2447,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2386 | 2447 | ||
2387 | if (blocksize < EXT4_MIN_BLOCK_SIZE || | 2448 | if (blocksize < EXT4_MIN_BLOCK_SIZE || |
2388 | blocksize > EXT4_MAX_BLOCK_SIZE) { | 2449 | blocksize > EXT4_MAX_BLOCK_SIZE) { |
2389 | printk(KERN_ERR | 2450 | ext4_msg(sb, KERN_ERR, |
2390 | "EXT4-fs: Unsupported filesystem blocksize %d on %s.\n", | 2451 | "Unsupported filesystem blocksize %d", blocksize); |
2391 | blocksize, sb->s_id); | ||
2392 | goto failed_mount; | 2452 | goto failed_mount; |
2393 | } | 2453 | } |
2394 | 2454 | ||
2395 | if (sb->s_blocksize != blocksize) { | 2455 | if (sb->s_blocksize != blocksize) { |
2396 | |||
2397 | /* Validate the filesystem blocksize */ | 2456 | /* Validate the filesystem blocksize */ |
2398 | if (!sb_set_blocksize(sb, blocksize)) { | 2457 | if (!sb_set_blocksize(sb, blocksize)) { |
2399 | printk(KERN_ERR "EXT4-fs: bad block size %d.\n", | 2458 | ext4_msg(sb, KERN_ERR, "bad block size %d", |
2400 | blocksize); | 2459 | blocksize); |
2401 | goto failed_mount; | 2460 | goto failed_mount; |
2402 | } | 2461 | } |
@@ -2406,15 +2465,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2406 | offset = do_div(logical_sb_block, blocksize); | 2465 | offset = do_div(logical_sb_block, blocksize); |
2407 | bh = sb_bread(sb, logical_sb_block); | 2466 | bh = sb_bread(sb, logical_sb_block); |
2408 | if (!bh) { | 2467 | if (!bh) { |
2409 | printk(KERN_ERR | 2468 | ext4_msg(sb, KERN_ERR, |
2410 | "EXT4-fs: Can't read superblock on 2nd try.\n"); | 2469 | "Can't read superblock on 2nd try"); |
2411 | goto failed_mount; | 2470 | goto failed_mount; |
2412 | } | 2471 | } |
2413 | es = (struct ext4_super_block *)(((char *)bh->b_data) + offset); | 2472 | es = (struct ext4_super_block *)(((char *)bh->b_data) + offset); |
2414 | sbi->s_es = es; | 2473 | sbi->s_es = es; |
2415 | if (es->s_magic != cpu_to_le16(EXT4_SUPER_MAGIC)) { | 2474 | if (es->s_magic != cpu_to_le16(EXT4_SUPER_MAGIC)) { |
2416 | printk(KERN_ERR | 2475 | ext4_msg(sb, KERN_ERR, |
2417 | "EXT4-fs: Magic mismatch, very weird !\n"); | 2476 | "Magic mismatch, very weird!"); |
2418 | goto failed_mount; | 2477 | goto failed_mount; |
2419 | } | 2478 | } |
2420 | } | 2479 | } |
@@ -2432,30 +2491,33 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2432 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || | 2491 | if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || |
2433 | (!is_power_of_2(sbi->s_inode_size)) || | 2492 | (!is_power_of_2(sbi->s_inode_size)) || |
2434 | (sbi->s_inode_size > blocksize)) { | 2493 | (sbi->s_inode_size > blocksize)) { |
2435 | printk(KERN_ERR | 2494 | ext4_msg(sb, KERN_ERR, |
2436 | "EXT4-fs: unsupported inode size: %d\n", | 2495 | "unsupported inode size: %d", |
2437 | sbi->s_inode_size); | 2496 | sbi->s_inode_size); |
2438 | goto failed_mount; | 2497 | goto failed_mount; |
2439 | } | 2498 | } |
2440 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) | 2499 | if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) |
2441 | sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); | 2500 | sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); |
2442 | } | 2501 | } |
2502 | |||
2443 | sbi->s_desc_size = le16_to_cpu(es->s_desc_size); | 2503 | sbi->s_desc_size = le16_to_cpu(es->s_desc_size); |
2444 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) { | 2504 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) { |
2445 | if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT || | 2505 | if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT || |
2446 | sbi->s_desc_size > EXT4_MAX_DESC_SIZE || | 2506 | sbi->s_desc_size > EXT4_MAX_DESC_SIZE || |
2447 | !is_power_of_2(sbi->s_desc_size)) { | 2507 | !is_power_of_2(sbi->s_desc_size)) { |
2448 | printk(KERN_ERR | 2508 | ext4_msg(sb, KERN_ERR, |
2449 | "EXT4-fs: unsupported descriptor size %lu\n", | 2509 | "unsupported descriptor size %lu", |
2450 | sbi->s_desc_size); | 2510 | sbi->s_desc_size); |
2451 | goto failed_mount; | 2511 | goto failed_mount; |
2452 | } | 2512 | } |
2453 | } else | 2513 | } else |
2454 | sbi->s_desc_size = EXT4_MIN_DESC_SIZE; | 2514 | sbi->s_desc_size = EXT4_MIN_DESC_SIZE; |
2515 | |||
2455 | sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); | 2516 | sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); |
2456 | sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); | 2517 | sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); |
2457 | if (EXT4_INODE_SIZE(sb) == 0 || EXT4_INODES_PER_GROUP(sb) == 0) | 2518 | if (EXT4_INODE_SIZE(sb) == 0 || EXT4_INODES_PER_GROUP(sb) == 0) |
2458 | goto cantfind_ext4; | 2519 | goto cantfind_ext4; |
2520 | |||
2459 | sbi->s_inodes_per_block = blocksize / EXT4_INODE_SIZE(sb); | 2521 | sbi->s_inodes_per_block = blocksize / EXT4_INODE_SIZE(sb); |
2460 | if (sbi->s_inodes_per_block == 0) | 2522 | if (sbi->s_inodes_per_block == 0) |
2461 | goto cantfind_ext4; | 2523 | goto cantfind_ext4; |
@@ -2466,6 +2528,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2466 | sbi->s_mount_state = le16_to_cpu(es->s_state); | 2528 | sbi->s_mount_state = le16_to_cpu(es->s_state); |
2467 | sbi->s_addr_per_block_bits = ilog2(EXT4_ADDR_PER_BLOCK(sb)); | 2529 | sbi->s_addr_per_block_bits = ilog2(EXT4_ADDR_PER_BLOCK(sb)); |
2468 | sbi->s_desc_per_block_bits = ilog2(EXT4_DESC_PER_BLOCK(sb)); | 2530 | sbi->s_desc_per_block_bits = ilog2(EXT4_DESC_PER_BLOCK(sb)); |
2531 | |||
2469 | for (i = 0; i < 4; i++) | 2532 | for (i = 0; i < 4; i++) |
2470 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); | 2533 | sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); |
2471 | sbi->s_def_hash_version = es->s_def_hash_version; | 2534 | sbi->s_def_hash_version = es->s_def_hash_version; |
@@ -2483,25 +2546,24 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2483 | } | 2546 | } |
2484 | 2547 | ||
2485 | if (sbi->s_blocks_per_group > blocksize * 8) { | 2548 | if (sbi->s_blocks_per_group > blocksize * 8) { |
2486 | printk(KERN_ERR | 2549 | ext4_msg(sb, KERN_ERR, |
2487 | "EXT4-fs: #blocks per group too big: %lu\n", | 2550 | "#blocks per group too big: %lu", |
2488 | sbi->s_blocks_per_group); | 2551 | sbi->s_blocks_per_group); |
2489 | goto failed_mount; | 2552 | goto failed_mount; |
2490 | } | 2553 | } |
2491 | if (sbi->s_inodes_per_group > blocksize * 8) { | 2554 | if (sbi->s_inodes_per_group > blocksize * 8) { |
2492 | printk(KERN_ERR | 2555 | ext4_msg(sb, KERN_ERR, |
2493 | "EXT4-fs: #inodes per group too big: %lu\n", | 2556 | "#inodes per group too big: %lu", |
2494 | sbi->s_inodes_per_group); | 2557 | sbi->s_inodes_per_group); |
2495 | goto failed_mount; | 2558 | goto failed_mount; |
2496 | } | 2559 | } |
2497 | 2560 | ||
2498 | if (ext4_blocks_count(es) > | 2561 | if (ext4_blocks_count(es) > |
2499 | (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { | 2562 | (sector_t)(~0ULL) >> (sb->s_blocksize_bits - 9)) { |
2500 | printk(KERN_ERR "EXT4-fs: filesystem on %s:" | 2563 | ext4_msg(sb, KERN_ERR, "filesystem" |
2501 | " too large to mount safely\n", sb->s_id); | 2564 | " too large to mount safely"); |
2502 | if (sizeof(sector_t) < 8) | 2565 | if (sizeof(sector_t) < 8) |
2503 | printk(KERN_WARNING "EXT4-fs: CONFIG_LBD not " | 2566 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBD not enabled"); |
2504 | "enabled\n"); | ||
2505 | goto failed_mount; | 2567 | goto failed_mount; |
2506 | } | 2568 | } |
2507 | 2569 | ||
@@ -2511,21 +2573,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2511 | /* check blocks count against device size */ | 2573 | /* check blocks count against device size */ |
2512 | blocks_count = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits; | 2574 | blocks_count = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits; |
2513 | if (blocks_count && ext4_blocks_count(es) > blocks_count) { | 2575 | if (blocks_count && ext4_blocks_count(es) > blocks_count) { |
2514 | printk(KERN_WARNING "EXT4-fs: bad geometry: block count %llu " | 2576 | ext4_msg(sb, KERN_WARNING, "bad geometry: block count %llu " |
2515 | "exceeds size of device (%llu blocks)\n", | 2577 | "exceeds size of device (%llu blocks)", |
2516 | ext4_blocks_count(es), blocks_count); | 2578 | ext4_blocks_count(es), blocks_count); |
2517 | goto failed_mount; | 2579 | goto failed_mount; |
2518 | } | 2580 | } |
2519 | 2581 | ||
2520 | /* | 2582 | /* |
2521 | * It makes no sense for the first data block to be beyond the end | 2583 | * It makes no sense for the first data block to be beyond the end |
2522 | * of the filesystem. | 2584 | * of the filesystem. |
2523 | */ | 2585 | */ |
2524 | if (le32_to_cpu(es->s_first_data_block) >= ext4_blocks_count(es)) { | 2586 | if (le32_to_cpu(es->s_first_data_block) >= ext4_blocks_count(es)) { |
2525 | printk(KERN_WARNING "EXT4-fs: bad geometry: first data" | 2587 | ext4_msg(sb, KERN_WARNING, "bad geometry: first data" |
2526 | "block %u is beyond end of filesystem (%llu)\n", | 2588 | "block %u is beyond end of filesystem (%llu)", |
2527 | le32_to_cpu(es->s_first_data_block), | 2589 | le32_to_cpu(es->s_first_data_block), |
2528 | ext4_blocks_count(es)); | 2590 | ext4_blocks_count(es)); |
2529 | goto failed_mount; | 2591 | goto failed_mount; |
2530 | } | 2592 | } |
2531 | blocks_count = (ext4_blocks_count(es) - | 2593 | blocks_count = (ext4_blocks_count(es) - |
@@ -2533,9 +2595,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2533 | EXT4_BLOCKS_PER_GROUP(sb) - 1); | 2595 | EXT4_BLOCKS_PER_GROUP(sb) - 1); |
2534 | do_div(blocks_count, EXT4_BLOCKS_PER_GROUP(sb)); | 2596 | do_div(blocks_count, EXT4_BLOCKS_PER_GROUP(sb)); |
2535 | if (blocks_count > ((uint64_t)1<<32) - EXT4_DESC_PER_BLOCK(sb)) { | 2597 | if (blocks_count > ((uint64_t)1<<32) - EXT4_DESC_PER_BLOCK(sb)) { |
2536 | printk(KERN_WARNING "EXT4-fs: groups count too large: %u " | 2598 | ext4_msg(sb, KERN_WARNING, "groups count too large: %u " |
2537 | "(block count %llu, first data block %u, " | 2599 | "(block count %llu, first data block %u, " |
2538 | "blocks per group %lu)\n", sbi->s_groups_count, | 2600 | "blocks per group %lu)", sbi->s_groups_count, |
2539 | ext4_blocks_count(es), | 2601 | ext4_blocks_count(es), |
2540 | le32_to_cpu(es->s_first_data_block), | 2602 | le32_to_cpu(es->s_first_data_block), |
2541 | EXT4_BLOCKS_PER_GROUP(sb)); | 2603 | EXT4_BLOCKS_PER_GROUP(sb)); |
@@ -2547,7 +2609,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2547 | sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *), | 2609 | sbi->s_group_desc = kmalloc(db_count * sizeof(struct buffer_head *), |
2548 | GFP_KERNEL); | 2610 | GFP_KERNEL); |
2549 | if (sbi->s_group_desc == NULL) { | 2611 | if (sbi->s_group_desc == NULL) { |
2550 | printk(KERN_ERR "EXT4-fs: not enough memory\n"); | 2612 | ext4_msg(sb, KERN_ERR, "not enough memory"); |
2551 | goto failed_mount; | 2613 | goto failed_mount; |
2552 | } | 2614 | } |
2553 | 2615 | ||
@@ -2562,21 +2624,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2562 | block = descriptor_loc(sb, logical_sb_block, i); | 2624 | block = descriptor_loc(sb, logical_sb_block, i); |
2563 | sbi->s_group_desc[i] = sb_bread(sb, block); | 2625 | sbi->s_group_desc[i] = sb_bread(sb, block); |
2564 | if (!sbi->s_group_desc[i]) { | 2626 | if (!sbi->s_group_desc[i]) { |
2565 | printk(KERN_ERR "EXT4-fs: " | 2627 | ext4_msg(sb, KERN_ERR, |
2566 | "can't read group descriptor %d\n", i); | 2628 | "can't read group descriptor %d", i); |
2567 | db_count = i; | 2629 | db_count = i; |
2568 | goto failed_mount2; | 2630 | goto failed_mount2; |
2569 | } | 2631 | } |
2570 | } | 2632 | } |
2571 | if (!ext4_check_descriptors(sb)) { | 2633 | if (!ext4_check_descriptors(sb)) { |
2572 | printk(KERN_ERR "EXT4-fs: group descriptors corrupted!\n"); | 2634 | ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); |
2573 | goto failed_mount2; | 2635 | goto failed_mount2; |
2574 | } | 2636 | } |
2575 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) | 2637 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) |
2576 | if (!ext4_fill_flex_info(sb)) { | 2638 | if (!ext4_fill_flex_info(sb)) { |
2577 | printk(KERN_ERR | 2639 | ext4_msg(sb, KERN_ERR, |
2578 | "EXT4-fs: unable to initialize " | 2640 | "unable to initialize " |
2579 | "flex_bg meta info!\n"); | 2641 | "flex_bg meta info!"); |
2580 | goto failed_mount2; | 2642 | goto failed_mount2; |
2581 | } | 2643 | } |
2582 | 2644 | ||
@@ -2598,7 +2660,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2598 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | 2660 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); |
2599 | } | 2661 | } |
2600 | if (err) { | 2662 | if (err) { |
2601 | printk(KERN_ERR "EXT4-fs: insufficient memory\n"); | 2663 | ext4_msg(sb, KERN_ERR, "insufficient memory"); |
2602 | goto failed_mount3; | 2664 | goto failed_mount3; |
2603 | } | 2665 | } |
2604 | 2666 | ||
@@ -2607,7 +2669,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2607 | /* | 2669 | /* |
2608 | * set up enough so that it can read an inode | 2670 | * set up enough so that it can read an inode |
2609 | */ | 2671 | */ |
2610 | sb->s_op = &ext4_sops; | 2672 | if (!test_opt(sb, NOLOAD) && |
2673 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) | ||
2674 | sb->s_op = &ext4_sops; | ||
2675 | else | ||
2676 | sb->s_op = &ext4_nojournal_sops; | ||
2611 | sb->s_export_op = &ext4_export_ops; | 2677 | sb->s_export_op = &ext4_export_ops; |
2612 | sb->s_xattr = ext4_xattr_handlers; | 2678 | sb->s_xattr = ext4_xattr_handlers; |
2613 | #ifdef CONFIG_QUOTA | 2679 | #ifdef CONFIG_QUOTA |
@@ -2615,6 +2681,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2615 | sb->dq_op = &ext4_quota_operations; | 2681 | sb->dq_op = &ext4_quota_operations; |
2616 | #endif | 2682 | #endif |
2617 | INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ | 2683 | INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ |
2684 | mutex_init(&sbi->s_orphan_lock); | ||
2685 | mutex_init(&sbi->s_resize_lock); | ||
2618 | 2686 | ||
2619 | sb->s_root = NULL; | 2687 | sb->s_root = NULL; |
2620 | 2688 | ||
@@ -2632,13 +2700,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2632 | goto failed_mount3; | 2700 | goto failed_mount3; |
2633 | if (!(sb->s_flags & MS_RDONLY) && | 2701 | if (!(sb->s_flags & MS_RDONLY) && |
2634 | EXT4_SB(sb)->s_journal->j_failed_commit) { | 2702 | EXT4_SB(sb)->s_journal->j_failed_commit) { |
2635 | printk(KERN_CRIT "EXT4-fs error (device %s): " | 2703 | ext4_msg(sb, KERN_CRIT, "error: " |
2636 | "ext4_fill_super: Journal transaction " | 2704 | "ext4_fill_super: Journal transaction " |
2637 | "%u is corrupt\n", sb->s_id, | 2705 | "%u is corrupt", |
2638 | EXT4_SB(sb)->s_journal->j_failed_commit); | 2706 | EXT4_SB(sb)->s_journal->j_failed_commit); |
2639 | if (test_opt(sb, ERRORS_RO)) { | 2707 | if (test_opt(sb, ERRORS_RO)) { |
2640 | printk(KERN_CRIT | 2708 | ext4_msg(sb, KERN_CRIT, |
2641 | "Mounting filesystem read-only\n"); | 2709 | "Mounting filesystem read-only"); |
2642 | sb->s_flags |= MS_RDONLY; | 2710 | sb->s_flags |= MS_RDONLY; |
2643 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | 2711 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; |
2644 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | 2712 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); |
@@ -2646,14 +2714,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2646 | if (test_opt(sb, ERRORS_PANIC)) { | 2714 | if (test_opt(sb, ERRORS_PANIC)) { |
2647 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | 2715 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; |
2648 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | 2716 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); |
2649 | ext4_commit_super(sb, es, 1); | 2717 | ext4_commit_super(sb, 1); |
2650 | goto failed_mount4; | 2718 | goto failed_mount4; |
2651 | } | 2719 | } |
2652 | } | 2720 | } |
2653 | } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && | 2721 | } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && |
2654 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { | 2722 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { |
2655 | printk(KERN_ERR "EXT4-fs: required journal recovery " | 2723 | ext4_msg(sb, KERN_ERR, "required journal recovery " |
2656 | "suppressed and not mounted read-only\n"); | 2724 | "suppressed and not mounted read-only"); |
2657 | goto failed_mount4; | 2725 | goto failed_mount4; |
2658 | } else { | 2726 | } else { |
2659 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); | 2727 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); |
@@ -2666,7 +2734,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2666 | if (ext4_blocks_count(es) > 0xffffffffULL && | 2734 | if (ext4_blocks_count(es) > 0xffffffffULL && |
2667 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, | 2735 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, |
2668 | JBD2_FEATURE_INCOMPAT_64BIT)) { | 2736 | JBD2_FEATURE_INCOMPAT_64BIT)) { |
2669 | printk(KERN_ERR "EXT4-fs: Failed to set 64-bit journal feature\n"); | 2737 | ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature"); |
2670 | goto failed_mount4; | 2738 | goto failed_mount4; |
2671 | } | 2739 | } |
2672 | 2740 | ||
@@ -2704,8 +2772,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2704 | case EXT4_MOUNT_WRITEBACK_DATA: | 2772 | case EXT4_MOUNT_WRITEBACK_DATA: |
2705 | if (!jbd2_journal_check_available_features | 2773 | if (!jbd2_journal_check_available_features |
2706 | (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) { | 2774 | (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) { |
2707 | printk(KERN_ERR "EXT4-fs: Journal does not support " | 2775 | ext4_msg(sb, KERN_ERR, "Journal does not support " |
2708 | "requested data journaling mode\n"); | 2776 | "requested data journaling mode"); |
2709 | goto failed_mount4; | 2777 | goto failed_mount4; |
2710 | } | 2778 | } |
2711 | default: | 2779 | default: |
@@ -2717,8 +2785,8 @@ no_journal: | |||
2717 | 2785 | ||
2718 | if (test_opt(sb, NOBH)) { | 2786 | if (test_opt(sb, NOBH)) { |
2719 | if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { | 2787 | if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { |
2720 | printk(KERN_WARNING "EXT4-fs: Ignoring nobh option - " | 2788 | ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " |
2721 | "its supported only with writeback mode\n"); | 2789 | "its supported only with writeback mode"); |
2722 | clear_opt(sbi->s_mount_opt, NOBH); | 2790 | clear_opt(sbi->s_mount_opt, NOBH); |
2723 | } | 2791 | } |
2724 | } | 2792 | } |
@@ -2729,18 +2797,18 @@ no_journal: | |||
2729 | 2797 | ||
2730 | root = ext4_iget(sb, EXT4_ROOT_INO); | 2798 | root = ext4_iget(sb, EXT4_ROOT_INO); |
2731 | if (IS_ERR(root)) { | 2799 | if (IS_ERR(root)) { |
2732 | printk(KERN_ERR "EXT4-fs: get root inode failed\n"); | 2800 | ext4_msg(sb, KERN_ERR, "get root inode failed"); |
2733 | ret = PTR_ERR(root); | 2801 | ret = PTR_ERR(root); |
2734 | goto failed_mount4; | 2802 | goto failed_mount4; |
2735 | } | 2803 | } |
2736 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { | 2804 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { |
2737 | iput(root); | 2805 | iput(root); |
2738 | printk(KERN_ERR "EXT4-fs: corrupt root inode, run e2fsck\n"); | 2806 | ext4_msg(sb, KERN_ERR, "corrupt root inode, run e2fsck"); |
2739 | goto failed_mount4; | 2807 | goto failed_mount4; |
2740 | } | 2808 | } |
2741 | sb->s_root = d_alloc_root(root); | 2809 | sb->s_root = d_alloc_root(root); |
2742 | if (!sb->s_root) { | 2810 | if (!sb->s_root) { |
2743 | printk(KERN_ERR "EXT4-fs: get root dentry failed\n"); | 2811 | ext4_msg(sb, KERN_ERR, "get root dentry failed"); |
2744 | iput(root); | 2812 | iput(root); |
2745 | ret = -ENOMEM; | 2813 | ret = -ENOMEM; |
2746 | goto failed_mount4; | 2814 | goto failed_mount4; |
@@ -2769,22 +2837,29 @@ no_journal: | |||
2769 | sbi->s_inode_size) { | 2837 | sbi->s_inode_size) { |
2770 | sbi->s_want_extra_isize = sizeof(struct ext4_inode) - | 2838 | sbi->s_want_extra_isize = sizeof(struct ext4_inode) - |
2771 | EXT4_GOOD_OLD_INODE_SIZE; | 2839 | EXT4_GOOD_OLD_INODE_SIZE; |
2772 | printk(KERN_INFO "EXT4-fs: required extra inode space not" | 2840 | ext4_msg(sb, KERN_INFO, "required extra inode space not" |
2773 | "available.\n"); | 2841 | "available"); |
2774 | } | 2842 | } |
2775 | 2843 | ||
2776 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | 2844 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { |
2777 | printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - " | 2845 | ext4_msg(sb, KERN_WARNING, "Ignoring delalloc option - " |
2778 | "requested data journaling mode\n"); | 2846 | "requested data journaling mode"); |
2779 | clear_opt(sbi->s_mount_opt, DELALLOC); | 2847 | clear_opt(sbi->s_mount_opt, DELALLOC); |
2780 | } else if (test_opt(sb, DELALLOC)) | 2848 | } else if (test_opt(sb, DELALLOC)) |
2781 | printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n"); | 2849 | ext4_msg(sb, KERN_INFO, "delayed allocation enabled"); |
2850 | |||
2851 | err = ext4_setup_system_zone(sb); | ||
2852 | if (err) { | ||
2853 | ext4_msg(sb, KERN_ERR, "failed to initialize system " | ||
2854 | "zone (%d)\n", err); | ||
2855 | goto failed_mount4; | ||
2856 | } | ||
2782 | 2857 | ||
2783 | ext4_ext_init(sb); | 2858 | ext4_ext_init(sb); |
2784 | err = ext4_mb_init(sb, needs_recovery); | 2859 | err = ext4_mb_init(sb, needs_recovery); |
2785 | if (err) { | 2860 | if (err) { |
2786 | printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n", | 2861 | ext4_msg(sb, KERN_ERR, "failed to initalize mballoc (%d)", |
2787 | err); | 2862 | err); |
2788 | goto failed_mount4; | 2863 | goto failed_mount4; |
2789 | } | 2864 | } |
2790 | 2865 | ||
@@ -2798,19 +2873,11 @@ no_journal: | |||
2798 | goto failed_mount4; | 2873 | goto failed_mount4; |
2799 | }; | 2874 | }; |
2800 | 2875 | ||
2801 | /* | ||
2802 | * akpm: core read_super() calls in here with the superblock locked. | ||
2803 | * That deadlocks, because orphan cleanup needs to lock the superblock | ||
2804 | * in numerous places. Here we just pop the lock - it's relatively | ||
2805 | * harmless, because we are now ready to accept write_super() requests, | ||
2806 | * and aviro says that's the only reason for hanging onto the | ||
2807 | * superblock lock. | ||
2808 | */ | ||
2809 | EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; | 2876 | EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; |
2810 | ext4_orphan_cleanup(sb, es); | 2877 | ext4_orphan_cleanup(sb, es); |
2811 | EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; | 2878 | EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; |
2812 | if (needs_recovery) { | 2879 | if (needs_recovery) { |
2813 | printk(KERN_INFO "EXT4-fs: recovery complete.\n"); | 2880 | ext4_msg(sb, KERN_INFO, "recovery complete"); |
2814 | ext4_mark_recovery_complete(sb, es); | 2881 | ext4_mark_recovery_complete(sb, es); |
2815 | } | 2882 | } |
2816 | if (EXT4_SB(sb)->s_journal) { | 2883 | if (EXT4_SB(sb)->s_journal) { |
@@ -2823,25 +2890,30 @@ no_journal: | |||
2823 | } else | 2890 | } else |
2824 | descr = "out journal"; | 2891 | descr = "out journal"; |
2825 | 2892 | ||
2826 | printk(KERN_INFO "EXT4-fs: mounted filesystem %s with%s\n", | 2893 | ext4_msg(sb, KERN_INFO, "mounted filesystem with%s", descr); |
2827 | sb->s_id, descr); | ||
2828 | 2894 | ||
2829 | lock_kernel(); | 2895 | lock_kernel(); |
2830 | return 0; | 2896 | return 0; |
2831 | 2897 | ||
2832 | cantfind_ext4: | 2898 | cantfind_ext4: |
2833 | if (!silent) | 2899 | if (!silent) |
2834 | printk(KERN_ERR "VFS: Can't find ext4 filesystem on dev %s.\n", | 2900 | ext4_msg(sb, KERN_ERR, "VFS: Can't find ext4 filesystem"); |
2835 | sb->s_id); | ||
2836 | goto failed_mount; | 2901 | goto failed_mount; |
2837 | 2902 | ||
2838 | failed_mount4: | 2903 | failed_mount4: |
2839 | printk(KERN_ERR "EXT4-fs (device %s): mount failed\n", sb->s_id); | 2904 | ext4_msg(sb, KERN_ERR, "mount failed"); |
2905 | ext4_release_system_zone(sb); | ||
2840 | if (sbi->s_journal) { | 2906 | if (sbi->s_journal) { |
2841 | jbd2_journal_destroy(sbi->s_journal); | 2907 | jbd2_journal_destroy(sbi->s_journal); |
2842 | sbi->s_journal = NULL; | 2908 | sbi->s_journal = NULL; |
2843 | } | 2909 | } |
2844 | failed_mount3: | 2910 | failed_mount3: |
2911 | if (sbi->s_flex_groups) { | ||
2912 | if (is_vmalloc_addr(sbi->s_flex_groups)) | ||
2913 | vfree(sbi->s_flex_groups); | ||
2914 | else | ||
2915 | kfree(sbi->s_flex_groups); | ||
2916 | } | ||
2845 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | 2917 | percpu_counter_destroy(&sbi->s_freeblocks_counter); |
2846 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 2918 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
2847 | percpu_counter_destroy(&sbi->s_dirs_counter); | 2919 | percpu_counter_destroy(&sbi->s_dirs_counter); |
@@ -2862,6 +2934,7 @@ failed_mount: | |||
2862 | brelse(bh); | 2934 | brelse(bh); |
2863 | out_fail: | 2935 | out_fail: |
2864 | sb->s_fs_info = NULL; | 2936 | sb->s_fs_info = NULL; |
2937 | kfree(sbi->s_blockgroup_lock); | ||
2865 | kfree(sbi); | 2938 | kfree(sbi); |
2866 | lock_kernel(); | 2939 | lock_kernel(); |
2867 | return ret; | 2940 | return ret; |
@@ -2906,27 +2979,27 @@ static journal_t *ext4_get_journal(struct super_block *sb, | |||
2906 | 2979 | ||
2907 | journal_inode = ext4_iget(sb, journal_inum); | 2980 | journal_inode = ext4_iget(sb, journal_inum); |
2908 | if (IS_ERR(journal_inode)) { | 2981 | if (IS_ERR(journal_inode)) { |
2909 | printk(KERN_ERR "EXT4-fs: no journal found.\n"); | 2982 | ext4_msg(sb, KERN_ERR, "no journal found"); |
2910 | return NULL; | 2983 | return NULL; |
2911 | } | 2984 | } |
2912 | if (!journal_inode->i_nlink) { | 2985 | if (!journal_inode->i_nlink) { |
2913 | make_bad_inode(journal_inode); | 2986 | make_bad_inode(journal_inode); |
2914 | iput(journal_inode); | 2987 | iput(journal_inode); |
2915 | printk(KERN_ERR "EXT4-fs: journal inode is deleted.\n"); | 2988 | ext4_msg(sb, KERN_ERR, "journal inode is deleted"); |
2916 | return NULL; | 2989 | return NULL; |
2917 | } | 2990 | } |
2918 | 2991 | ||
2919 | jbd_debug(2, "Journal inode found at %p: %lld bytes\n", | 2992 | jbd_debug(2, "Journal inode found at %p: %lld bytes\n", |
2920 | journal_inode, journal_inode->i_size); | 2993 | journal_inode, journal_inode->i_size); |
2921 | if (!S_ISREG(journal_inode->i_mode)) { | 2994 | if (!S_ISREG(journal_inode->i_mode)) { |
2922 | printk(KERN_ERR "EXT4-fs: invalid journal inode.\n"); | 2995 | ext4_msg(sb, KERN_ERR, "invalid journal inode"); |
2923 | iput(journal_inode); | 2996 | iput(journal_inode); |
2924 | return NULL; | 2997 | return NULL; |
2925 | } | 2998 | } |
2926 | 2999 | ||
2927 | journal = jbd2_journal_init_inode(journal_inode); | 3000 | journal = jbd2_journal_init_inode(journal_inode); |
2928 | if (!journal) { | 3001 | if (!journal) { |
2929 | printk(KERN_ERR "EXT4-fs: Could not load journal inode\n"); | 3002 | ext4_msg(sb, KERN_ERR, "Could not load journal inode"); |
2930 | iput(journal_inode); | 3003 | iput(journal_inode); |
2931 | return NULL; | 3004 | return NULL; |
2932 | } | 3005 | } |
@@ -2950,22 +3023,22 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, | |||
2950 | 3023 | ||
2951 | BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)); | 3024 | BUG_ON(!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)); |
2952 | 3025 | ||
2953 | bdev = ext4_blkdev_get(j_dev); | 3026 | bdev = ext4_blkdev_get(j_dev, sb); |
2954 | if (bdev == NULL) | 3027 | if (bdev == NULL) |
2955 | return NULL; | 3028 | return NULL; |
2956 | 3029 | ||
2957 | if (bd_claim(bdev, sb)) { | 3030 | if (bd_claim(bdev, sb)) { |
2958 | printk(KERN_ERR | 3031 | ext4_msg(sb, KERN_ERR, |
2959 | "EXT4-fs: failed to claim external journal device.\n"); | 3032 | "failed to claim external journal device"); |
2960 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE); | 3033 | blkdev_put(bdev, FMODE_READ|FMODE_WRITE); |
2961 | return NULL; | 3034 | return NULL; |
2962 | } | 3035 | } |
2963 | 3036 | ||
2964 | blocksize = sb->s_blocksize; | 3037 | blocksize = sb->s_blocksize; |
2965 | hblock = bdev_hardsect_size(bdev); | 3038 | hblock = bdev_logical_block_size(bdev); |
2966 | if (blocksize < hblock) { | 3039 | if (blocksize < hblock) { |
2967 | printk(KERN_ERR | 3040 | ext4_msg(sb, KERN_ERR, |
2968 | "EXT4-fs: blocksize too small for journal device.\n"); | 3041 | "blocksize too small for journal device"); |
2969 | goto out_bdev; | 3042 | goto out_bdev; |
2970 | } | 3043 | } |
2971 | 3044 | ||
@@ -2973,8 +3046,8 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, | |||
2973 | offset = EXT4_MIN_BLOCK_SIZE % blocksize; | 3046 | offset = EXT4_MIN_BLOCK_SIZE % blocksize; |
2974 | set_blocksize(bdev, blocksize); | 3047 | set_blocksize(bdev, blocksize); |
2975 | if (!(bh = __bread(bdev, sb_block, blocksize))) { | 3048 | if (!(bh = __bread(bdev, sb_block, blocksize))) { |
2976 | printk(KERN_ERR "EXT4-fs: couldn't read superblock of " | 3049 | ext4_msg(sb, KERN_ERR, "couldn't read superblock of " |
2977 | "external journal\n"); | 3050 | "external journal"); |
2978 | goto out_bdev; | 3051 | goto out_bdev; |
2979 | } | 3052 | } |
2980 | 3053 | ||
@@ -2982,14 +3055,14 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, | |||
2982 | if ((le16_to_cpu(es->s_magic) != EXT4_SUPER_MAGIC) || | 3055 | if ((le16_to_cpu(es->s_magic) != EXT4_SUPER_MAGIC) || |
2983 | !(le32_to_cpu(es->s_feature_incompat) & | 3056 | !(le32_to_cpu(es->s_feature_incompat) & |
2984 | EXT4_FEATURE_INCOMPAT_JOURNAL_DEV)) { | 3057 | EXT4_FEATURE_INCOMPAT_JOURNAL_DEV)) { |
2985 | printk(KERN_ERR "EXT4-fs: external journal has " | 3058 | ext4_msg(sb, KERN_ERR, "external journal has " |
2986 | "bad superblock\n"); | 3059 | "bad superblock"); |
2987 | brelse(bh); | 3060 | brelse(bh); |
2988 | goto out_bdev; | 3061 | goto out_bdev; |
2989 | } | 3062 | } |
2990 | 3063 | ||
2991 | if (memcmp(EXT4_SB(sb)->s_es->s_journal_uuid, es->s_uuid, 16)) { | 3064 | if (memcmp(EXT4_SB(sb)->s_es->s_journal_uuid, es->s_uuid, 16)) { |
2992 | printk(KERN_ERR "EXT4-fs: journal UUID does not match\n"); | 3065 | ext4_msg(sb, KERN_ERR, "journal UUID does not match"); |
2993 | brelse(bh); | 3066 | brelse(bh); |
2994 | goto out_bdev; | 3067 | goto out_bdev; |
2995 | } | 3068 | } |
@@ -3001,25 +3074,26 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, | |||
3001 | journal = jbd2_journal_init_dev(bdev, sb->s_bdev, | 3074 | journal = jbd2_journal_init_dev(bdev, sb->s_bdev, |
3002 | start, len, blocksize); | 3075 | start, len, blocksize); |
3003 | if (!journal) { | 3076 | if (!journal) { |
3004 | printk(KERN_ERR "EXT4-fs: failed to create device journal\n"); | 3077 | ext4_msg(sb, KERN_ERR, "failed to create device journal"); |
3005 | goto out_bdev; | 3078 | goto out_bdev; |
3006 | } | 3079 | } |
3007 | journal->j_private = sb; | 3080 | journal->j_private = sb; |
3008 | ll_rw_block(READ, 1, &journal->j_sb_buffer); | 3081 | ll_rw_block(READ, 1, &journal->j_sb_buffer); |
3009 | wait_on_buffer(journal->j_sb_buffer); | 3082 | wait_on_buffer(journal->j_sb_buffer); |
3010 | if (!buffer_uptodate(journal->j_sb_buffer)) { | 3083 | if (!buffer_uptodate(journal->j_sb_buffer)) { |
3011 | printk(KERN_ERR "EXT4-fs: I/O error on journal device\n"); | 3084 | ext4_msg(sb, KERN_ERR, "I/O error on journal device"); |
3012 | goto out_journal; | 3085 | goto out_journal; |
3013 | } | 3086 | } |
3014 | if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) { | 3087 | if (be32_to_cpu(journal->j_superblock->s_nr_users) != 1) { |
3015 | printk(KERN_ERR "EXT4-fs: External journal has more than one " | 3088 | ext4_msg(sb, KERN_ERR, "External journal has more than one " |
3016 | "user (unsupported) - %d\n", | 3089 | "user (unsupported) - %d", |
3017 | be32_to_cpu(journal->j_superblock->s_nr_users)); | 3090 | be32_to_cpu(journal->j_superblock->s_nr_users)); |
3018 | goto out_journal; | 3091 | goto out_journal; |
3019 | } | 3092 | } |
3020 | EXT4_SB(sb)->journal_bdev = bdev; | 3093 | EXT4_SB(sb)->journal_bdev = bdev; |
3021 | ext4_init_journal_params(sb, journal); | 3094 | ext4_init_journal_params(sb, journal); |
3022 | return journal; | 3095 | return journal; |
3096 | |||
3023 | out_journal: | 3097 | out_journal: |
3024 | jbd2_journal_destroy(journal); | 3098 | jbd2_journal_destroy(journal); |
3025 | out_bdev: | 3099 | out_bdev: |
@@ -3041,8 +3115,8 @@ static int ext4_load_journal(struct super_block *sb, | |||
3041 | 3115 | ||
3042 | if (journal_devnum && | 3116 | if (journal_devnum && |
3043 | journal_devnum != le32_to_cpu(es->s_journal_dev)) { | 3117 | journal_devnum != le32_to_cpu(es->s_journal_dev)) { |
3044 | printk(KERN_INFO "EXT4-fs: external journal device major/minor " | 3118 | ext4_msg(sb, KERN_INFO, "external journal device major/minor " |
3045 | "numbers have changed\n"); | 3119 | "numbers have changed"); |
3046 | journal_dev = new_decode_dev(journal_devnum); | 3120 | journal_dev = new_decode_dev(journal_devnum); |
3047 | } else | 3121 | } else |
3048 | journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev)); | 3122 | journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev)); |
@@ -3054,24 +3128,23 @@ static int ext4_load_journal(struct super_block *sb, | |||
3054 | * crash? For recovery, we need to check in advance whether we | 3128 | * crash? For recovery, we need to check in advance whether we |
3055 | * can get read-write access to the device. | 3129 | * can get read-write access to the device. |
3056 | */ | 3130 | */ |
3057 | |||
3058 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { | 3131 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { |
3059 | if (sb->s_flags & MS_RDONLY) { | 3132 | if (sb->s_flags & MS_RDONLY) { |
3060 | printk(KERN_INFO "EXT4-fs: INFO: recovery " | 3133 | ext4_msg(sb, KERN_INFO, "INFO: recovery " |
3061 | "required on readonly filesystem.\n"); | 3134 | "required on readonly filesystem"); |
3062 | if (really_read_only) { | 3135 | if (really_read_only) { |
3063 | printk(KERN_ERR "EXT4-fs: write access " | 3136 | ext4_msg(sb, KERN_ERR, "write access " |
3064 | "unavailable, cannot proceed.\n"); | 3137 | "unavailable, cannot proceed"); |
3065 | return -EROFS; | 3138 | return -EROFS; |
3066 | } | 3139 | } |
3067 | printk(KERN_INFO "EXT4-fs: write access will " | 3140 | ext4_msg(sb, KERN_INFO, "write access will " |
3068 | "be enabled during recovery.\n"); | 3141 | "be enabled during recovery"); |
3069 | } | 3142 | } |
3070 | } | 3143 | } |
3071 | 3144 | ||
3072 | if (journal_inum && journal_dev) { | 3145 | if (journal_inum && journal_dev) { |
3073 | printk(KERN_ERR "EXT4-fs: filesystem has both journal " | 3146 | ext4_msg(sb, KERN_ERR, "filesystem has both journal " |
3074 | "and inode journals!\n"); | 3147 | "and inode journals!"); |
3075 | return -EINVAL; | 3148 | return -EINVAL; |
3076 | } | 3149 | } |
3077 | 3150 | ||
@@ -3084,14 +3157,14 @@ static int ext4_load_journal(struct super_block *sb, | |||
3084 | } | 3157 | } |
3085 | 3158 | ||
3086 | if (journal->j_flags & JBD2_BARRIER) | 3159 | if (journal->j_flags & JBD2_BARRIER) |
3087 | printk(KERN_INFO "EXT4-fs: barriers enabled\n"); | 3160 | ext4_msg(sb, KERN_INFO, "barriers enabled"); |
3088 | else | 3161 | else |
3089 | printk(KERN_INFO "EXT4-fs: barriers disabled\n"); | 3162 | ext4_msg(sb, KERN_INFO, "barriers disabled"); |
3090 | 3163 | ||
3091 | if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) { | 3164 | if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) { |
3092 | err = jbd2_journal_update_format(journal); | 3165 | err = jbd2_journal_update_format(journal); |
3093 | if (err) { | 3166 | if (err) { |
3094 | printk(KERN_ERR "EXT4-fs: error updating journal.\n"); | 3167 | ext4_msg(sb, KERN_ERR, "error updating journal"); |
3095 | jbd2_journal_destroy(journal); | 3168 | jbd2_journal_destroy(journal); |
3096 | return err; | 3169 | return err; |
3097 | } | 3170 | } |
@@ -3103,7 +3176,7 @@ static int ext4_load_journal(struct super_block *sb, | |||
3103 | err = jbd2_journal_load(journal); | 3176 | err = jbd2_journal_load(journal); |
3104 | 3177 | ||
3105 | if (err) { | 3178 | if (err) { |
3106 | printk(KERN_ERR "EXT4-fs: error loading journal.\n"); | 3179 | ext4_msg(sb, KERN_ERR, "error loading journal"); |
3107 | jbd2_journal_destroy(journal); | 3180 | jbd2_journal_destroy(journal); |
3108 | return err; | 3181 | return err; |
3109 | } | 3182 | } |
@@ -3114,18 +3187,17 @@ static int ext4_load_journal(struct super_block *sb, | |||
3114 | if (journal_devnum && | 3187 | if (journal_devnum && |
3115 | journal_devnum != le32_to_cpu(es->s_journal_dev)) { | 3188 | journal_devnum != le32_to_cpu(es->s_journal_dev)) { |
3116 | es->s_journal_dev = cpu_to_le32(journal_devnum); | 3189 | es->s_journal_dev = cpu_to_le32(journal_devnum); |
3117 | sb->s_dirt = 1; | ||
3118 | 3190 | ||
3119 | /* Make sure we flush the recovery flag to disk. */ | 3191 | /* Make sure we flush the recovery flag to disk. */ |
3120 | ext4_commit_super(sb, es, 1); | 3192 | ext4_commit_super(sb, 1); |
3121 | } | 3193 | } |
3122 | 3194 | ||
3123 | return 0; | 3195 | return 0; |
3124 | } | 3196 | } |
3125 | 3197 | ||
3126 | static int ext4_commit_super(struct super_block *sb, | 3198 | static int ext4_commit_super(struct super_block *sb, int sync) |
3127 | struct ext4_super_block *es, int sync) | ||
3128 | { | 3199 | { |
3200 | struct ext4_super_block *es = EXT4_SB(sb)->s_es; | ||
3129 | struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; | 3201 | struct buffer_head *sbh = EXT4_SB(sb)->s_sbh; |
3130 | int error = 0; | 3202 | int error = 0; |
3131 | 3203 | ||
@@ -3140,8 +3212,8 @@ static int ext4_commit_super(struct super_block *sb, | |||
3140 | * be remapped. Nothing we can do but to retry the | 3212 | * be remapped. Nothing we can do but to retry the |
3141 | * write and hope for the best. | 3213 | * write and hope for the best. |
3142 | */ | 3214 | */ |
3143 | printk(KERN_ERR "EXT4-fs: previous I/O error to " | 3215 | ext4_msg(sb, KERN_ERR, "previous I/O error to " |
3144 | "superblock detected for %s.\n", sb->s_id); | 3216 | "superblock detected"); |
3145 | clear_buffer_write_io_error(sbh); | 3217 | clear_buffer_write_io_error(sbh); |
3146 | set_buffer_uptodate(sbh); | 3218 | set_buffer_uptodate(sbh); |
3147 | } | 3219 | } |
@@ -3154,7 +3226,7 @@ static int ext4_commit_super(struct super_block *sb, | |||
3154 | &EXT4_SB(sb)->s_freeblocks_counter)); | 3226 | &EXT4_SB(sb)->s_freeblocks_counter)); |
3155 | es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive( | 3227 | es->s_free_inodes_count = cpu_to_le32(percpu_counter_sum_positive( |
3156 | &EXT4_SB(sb)->s_freeinodes_counter)); | 3228 | &EXT4_SB(sb)->s_freeinodes_counter)); |
3157 | 3229 | sb->s_dirt = 0; | |
3158 | BUFFER_TRACE(sbh, "marking dirty"); | 3230 | BUFFER_TRACE(sbh, "marking dirty"); |
3159 | mark_buffer_dirty(sbh); | 3231 | mark_buffer_dirty(sbh); |
3160 | if (sync) { | 3232 | if (sync) { |
@@ -3164,8 +3236,8 @@ static int ext4_commit_super(struct super_block *sb, | |||
3164 | 3236 | ||
3165 | error = buffer_write_io_error(sbh); | 3237 | error = buffer_write_io_error(sbh); |
3166 | if (error) { | 3238 | if (error) { |
3167 | printk(KERN_ERR "EXT4-fs: I/O error while writing " | 3239 | ext4_msg(sb, KERN_ERR, "I/O error while writing " |
3168 | "superblock for %s.\n", sb->s_id); | 3240 | "superblock"); |
3169 | clear_buffer_write_io_error(sbh); | 3241 | clear_buffer_write_io_error(sbh); |
3170 | set_buffer_uptodate(sbh); | 3242 | set_buffer_uptodate(sbh); |
3171 | } | 3243 | } |
@@ -3173,7 +3245,6 @@ static int ext4_commit_super(struct super_block *sb, | |||
3173 | return error; | 3245 | return error; |
3174 | } | 3246 | } |
3175 | 3247 | ||
3176 | |||
3177 | /* | 3248 | /* |
3178 | * Have we just finished recovery? If so, and if we are mounting (or | 3249 | * Have we just finished recovery? If so, and if we are mounting (or |
3179 | * remounting) the filesystem readonly, then we will end up with a | 3250 | * remounting) the filesystem readonly, then we will end up with a |
@@ -3192,14 +3263,11 @@ static void ext4_mark_recovery_complete(struct super_block *sb, | |||
3192 | if (jbd2_journal_flush(journal) < 0) | 3263 | if (jbd2_journal_flush(journal) < 0) |
3193 | goto out; | 3264 | goto out; |
3194 | 3265 | ||
3195 | lock_super(sb); | ||
3196 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && | 3266 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER) && |
3197 | sb->s_flags & MS_RDONLY) { | 3267 | sb->s_flags & MS_RDONLY) { |
3198 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 3268 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
3199 | sb->s_dirt = 0; | 3269 | ext4_commit_super(sb, 1); |
3200 | ext4_commit_super(sb, es, 1); | ||
3201 | } | 3270 | } |
3202 | unlock_super(sb); | ||
3203 | 3271 | ||
3204 | out: | 3272 | out: |
3205 | jbd2_journal_unlock_updates(journal); | 3273 | jbd2_journal_unlock_updates(journal); |
@@ -3238,7 +3306,7 @@ static void ext4_clear_journal_err(struct super_block *sb, | |||
3238 | 3306 | ||
3239 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | 3307 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; |
3240 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | 3308 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); |
3241 | ext4_commit_super(sb, es, 1); | 3309 | ext4_commit_super(sb, 1); |
3242 | 3310 | ||
3243 | jbd2_journal_clear_err(journal); | 3311 | jbd2_journal_clear_err(journal); |
3244 | } | 3312 | } |
@@ -3257,29 +3325,15 @@ int ext4_force_commit(struct super_block *sb) | |||
3257 | return 0; | 3325 | return 0; |
3258 | 3326 | ||
3259 | journal = EXT4_SB(sb)->s_journal; | 3327 | journal = EXT4_SB(sb)->s_journal; |
3260 | if (journal) { | 3328 | if (journal) |
3261 | sb->s_dirt = 0; | ||
3262 | ret = ext4_journal_force_commit(journal); | 3329 | ret = ext4_journal_force_commit(journal); |
3263 | } | ||
3264 | 3330 | ||
3265 | return ret; | 3331 | return ret; |
3266 | } | 3332 | } |
3267 | 3333 | ||
3268 | /* | ||
3269 | * Ext4 always journals updates to the superblock itself, so we don't | ||
3270 | * have to propagate any other updates to the superblock on disk at this | ||
3271 | * point. (We can probably nuke this function altogether, and remove | ||
3272 | * any mention to sb->s_dirt in all of fs/ext4; eventual cleanup...) | ||
3273 | */ | ||
3274 | static void ext4_write_super(struct super_block *sb) | 3334 | static void ext4_write_super(struct super_block *sb) |
3275 | { | 3335 | { |
3276 | if (EXT4_SB(sb)->s_journal) { | 3336 | ext4_commit_super(sb, 1); |
3277 | if (mutex_trylock(&sb->s_lock) != 0) | ||
3278 | BUG(); | ||
3279 | sb->s_dirt = 0; | ||
3280 | } else { | ||
3281 | ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); | ||
3282 | } | ||
3283 | } | 3337 | } |
3284 | 3338 | ||
3285 | static int ext4_sync_fs(struct super_block *sb, int wait) | 3339 | static int ext4_sync_fs(struct super_block *sb, int wait) |
@@ -3288,16 +3342,9 @@ static int ext4_sync_fs(struct super_block *sb, int wait) | |||
3288 | tid_t target; | 3342 | tid_t target; |
3289 | 3343 | ||
3290 | trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); | 3344 | trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); |
3291 | sb->s_dirt = 0; | 3345 | if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { |
3292 | if (EXT4_SB(sb)->s_journal) { | 3346 | if (wait) |
3293 | if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, | 3347 | jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target); |
3294 | &target)) { | ||
3295 | if (wait) | ||
3296 | jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, | ||
3297 | target); | ||
3298 | } | ||
3299 | } else { | ||
3300 | ext4_commit_super(sb, EXT4_SB(sb)->s_es, wait); | ||
3301 | } | 3348 | } |
3302 | return ret; | 3349 | return ret; |
3303 | } | 3350 | } |
@@ -3310,34 +3357,32 @@ static int ext4_freeze(struct super_block *sb) | |||
3310 | { | 3357 | { |
3311 | int error = 0; | 3358 | int error = 0; |
3312 | journal_t *journal; | 3359 | journal_t *journal; |
3313 | sb->s_dirt = 0; | ||
3314 | 3360 | ||
3315 | if (!(sb->s_flags & MS_RDONLY)) { | 3361 | if (sb->s_flags & MS_RDONLY) |
3316 | journal = EXT4_SB(sb)->s_journal; | 3362 | return 0; |
3317 | 3363 | ||
3318 | if (journal) { | 3364 | journal = EXT4_SB(sb)->s_journal; |
3319 | /* Now we set up the journal barrier. */ | ||
3320 | jbd2_journal_lock_updates(journal); | ||
3321 | 3365 | ||
3322 | /* | 3366 | /* Now we set up the journal barrier. */ |
3323 | * We don't want to clear needs_recovery flag when we | 3367 | jbd2_journal_lock_updates(journal); |
3324 | * failed to flush the journal. | ||
3325 | */ | ||
3326 | error = jbd2_journal_flush(journal); | ||
3327 | if (error < 0) | ||
3328 | goto out; | ||
3329 | } | ||
3330 | 3368 | ||
3331 | /* Journal blocked and flushed, clear needs_recovery flag. */ | 3369 | /* |
3332 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 3370 | * Don't clear the needs_recovery flag if we failed to flush |
3333 | error = ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); | 3371 | * the journal. |
3334 | if (error) | 3372 | */ |
3335 | goto out; | 3373 | error = jbd2_journal_flush(journal); |
3374 | if (error < 0) { | ||
3375 | out: | ||
3376 | jbd2_journal_unlock_updates(journal); | ||
3377 | return error; | ||
3336 | } | 3378 | } |
3379 | |||
3380 | /* Journal blocked and flushed, clear needs_recovery flag. */ | ||
3381 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | ||
3382 | error = ext4_commit_super(sb, 1); | ||
3383 | if (error) | ||
3384 | goto out; | ||
3337 | return 0; | 3385 | return 0; |
3338 | out: | ||
3339 | jbd2_journal_unlock_updates(journal); | ||
3340 | return error; | ||
3341 | } | 3386 | } |
3342 | 3387 | ||
3343 | /* | 3388 | /* |
@@ -3346,14 +3391,15 @@ out: | |||
3346 | */ | 3391 | */ |
3347 | static int ext4_unfreeze(struct super_block *sb) | 3392 | static int ext4_unfreeze(struct super_block *sb) |
3348 | { | 3393 | { |
3349 | if (EXT4_SB(sb)->s_journal && !(sb->s_flags & MS_RDONLY)) { | 3394 | if (sb->s_flags & MS_RDONLY) |
3350 | lock_super(sb); | 3395 | return 0; |
3351 | /* Reser the needs_recovery flag before the fs is unlocked. */ | 3396 | |
3352 | EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 3397 | lock_super(sb); |
3353 | ext4_commit_super(sb, EXT4_SB(sb)->s_es, 1); | 3398 | /* Reset the needs_recovery flag before the fs is unlocked. */ |
3354 | unlock_super(sb); | 3399 | EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
3355 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 3400 | ext4_commit_super(sb, 1); |
3356 | } | 3401 | unlock_super(sb); |
3402 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
3357 | return 0; | 3403 | return 0; |
3358 | } | 3404 | } |
3359 | 3405 | ||
@@ -3432,22 +3478,15 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3432 | (sbi->s_mount_state & EXT4_VALID_FS)) | 3478 | (sbi->s_mount_state & EXT4_VALID_FS)) |
3433 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 3479 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
3434 | 3480 | ||
3435 | /* | 3481 | if (sbi->s_journal) |
3436 | * We have to unlock super so that we can wait for | ||
3437 | * transactions. | ||
3438 | */ | ||
3439 | if (sbi->s_journal) { | ||
3440 | unlock_super(sb); | ||
3441 | ext4_mark_recovery_complete(sb, es); | 3482 | ext4_mark_recovery_complete(sb, es); |
3442 | lock_super(sb); | ||
3443 | } | ||
3444 | } else { | 3483 | } else { |
3445 | int ret; | 3484 | int ret; |
3446 | if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, | 3485 | if ((ret = EXT4_HAS_RO_COMPAT_FEATURE(sb, |
3447 | ~EXT4_FEATURE_RO_COMPAT_SUPP))) { | 3486 | ~EXT4_FEATURE_RO_COMPAT_SUPP))) { |
3448 | printk(KERN_WARNING "EXT4-fs: %s: couldn't " | 3487 | ext4_msg(sb, KERN_WARNING, "couldn't " |
3449 | "remount RDWR because of unsupported " | 3488 | "remount RDWR because of unsupported " |
3450 | "optional features (%x).\n", sb->s_id, | 3489 | "optional features (%x)", |
3451 | (le32_to_cpu(sbi->s_es->s_feature_ro_compat) & | 3490 | (le32_to_cpu(sbi->s_es->s_feature_ro_compat) & |
3452 | ~EXT4_FEATURE_RO_COMPAT_SUPP)); | 3491 | ~EXT4_FEATURE_RO_COMPAT_SUPP)); |
3453 | err = -EROFS; | 3492 | err = -EROFS; |
@@ -3456,17 +3495,15 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3456 | 3495 | ||
3457 | /* | 3496 | /* |
3458 | * Make sure the group descriptor checksums | 3497 | * Make sure the group descriptor checksums |
3459 | * are sane. If they aren't, refuse to | 3498 | * are sane. If they aren't, refuse to remount r/w. |
3460 | * remount r/w. | ||
3461 | */ | 3499 | */ |
3462 | for (g = 0; g < sbi->s_groups_count; g++) { | 3500 | for (g = 0; g < sbi->s_groups_count; g++) { |
3463 | struct ext4_group_desc *gdp = | 3501 | struct ext4_group_desc *gdp = |
3464 | ext4_get_group_desc(sb, g, NULL); | 3502 | ext4_get_group_desc(sb, g, NULL); |
3465 | 3503 | ||
3466 | if (!ext4_group_desc_csum_verify(sbi, g, gdp)) { | 3504 | if (!ext4_group_desc_csum_verify(sbi, g, gdp)) { |
3467 | printk(KERN_ERR | 3505 | ext4_msg(sb, KERN_ERR, |
3468 | "EXT4-fs: ext4_remount: " | 3506 | "ext4_remount: Checksum for group %u failed (%u!=%u)", |
3469 | "Checksum for group %u failed (%u!=%u)\n", | ||
3470 | g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)), | 3507 | g, le16_to_cpu(ext4_group_desc_csum(sbi, g, gdp)), |
3471 | le16_to_cpu(gdp->bg_checksum)); | 3508 | le16_to_cpu(gdp->bg_checksum)); |
3472 | err = -EINVAL; | 3509 | err = -EINVAL; |
@@ -3480,11 +3517,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3480 | * require a full umount/remount for now. | 3517 | * require a full umount/remount for now. |
3481 | */ | 3518 | */ |
3482 | if (es->s_last_orphan) { | 3519 | if (es->s_last_orphan) { |
3483 | printk(KERN_WARNING "EXT4-fs: %s: couldn't " | 3520 | ext4_msg(sb, KERN_WARNING, "Couldn't " |
3484 | "remount RDWR because of unprocessed " | 3521 | "remount RDWR because of unprocessed " |
3485 | "orphan inode list. Please " | 3522 | "orphan inode list. Please " |
3486 | "umount/remount instead.\n", | 3523 | "umount/remount instead"); |
3487 | sb->s_id); | ||
3488 | err = -EINVAL; | 3524 | err = -EINVAL; |
3489 | goto restore_opts; | 3525 | goto restore_opts; |
3490 | } | 3526 | } |
@@ -3504,8 +3540,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3504 | sb->s_flags &= ~MS_RDONLY; | 3540 | sb->s_flags &= ~MS_RDONLY; |
3505 | } | 3541 | } |
3506 | } | 3542 | } |
3543 | ext4_setup_system_zone(sb); | ||
3507 | if (sbi->s_journal == NULL) | 3544 | if (sbi->s_journal == NULL) |
3508 | ext4_commit_super(sb, es, 1); | 3545 | ext4_commit_super(sb, 1); |
3509 | 3546 | ||
3510 | #ifdef CONFIG_QUOTA | 3547 | #ifdef CONFIG_QUOTA |
3511 | /* Release old quota file names */ | 3548 | /* Release old quota file names */ |
@@ -3515,6 +3552,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3515 | kfree(old_opts.s_qf_names[i]); | 3552 | kfree(old_opts.s_qf_names[i]); |
3516 | #endif | 3553 | #endif |
3517 | return 0; | 3554 | return 0; |
3555 | |||
3518 | restore_opts: | 3556 | restore_opts: |
3519 | sb->s_flags = old_sb_flags; | 3557 | sb->s_flags = old_sb_flags; |
3520 | sbi->s_mount_opt = old_opts.s_mount_opt; | 3558 | sbi->s_mount_opt = old_opts.s_mount_opt; |
@@ -3545,9 +3583,8 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
3545 | if (test_opt(sb, MINIX_DF)) { | 3583 | if (test_opt(sb, MINIX_DF)) { |
3546 | sbi->s_overhead_last = 0; | 3584 | sbi->s_overhead_last = 0; |
3547 | } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { | 3585 | } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { |
3548 | ext4_group_t ngroups = sbi->s_groups_count, i; | 3586 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
3549 | ext4_fsblk_t overhead = 0; | 3587 | ext4_fsblk_t overhead = 0; |
3550 | smp_rmb(); | ||
3551 | 3588 | ||
3552 | /* | 3589 | /* |
3553 | * Compute the overhead (FS structures). This is constant | 3590 | * Compute the overhead (FS structures). This is constant |
@@ -3599,11 +3636,12 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
3599 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | 3636 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); |
3600 | buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; | 3637 | buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; |
3601 | buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; | 3638 | buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; |
3639 | |||
3602 | return 0; | 3640 | return 0; |
3603 | } | 3641 | } |
3604 | 3642 | ||
3605 | /* Helper function for writing quotas on sync - we need to start transaction before quota file | 3643 | /* Helper function for writing quotas on sync - we need to start transaction |
3606 | * is locked for write. Otherwise the are possible deadlocks: | 3644 | * before quota file is locked for write. Otherwise the are possible deadlocks: |
3607 | * Process 1 Process 2 | 3645 | * Process 1 Process 2 |
3608 | * ext4_create() quota_sync() | 3646 | * ext4_create() quota_sync() |
3609 | * jbd2_journal_start() write_dquot() | 3647 | * jbd2_journal_start() write_dquot() |
@@ -3627,7 +3665,7 @@ static int ext4_write_dquot(struct dquot *dquot) | |||
3627 | 3665 | ||
3628 | inode = dquot_to_inode(dquot); | 3666 | inode = dquot_to_inode(dquot); |
3629 | handle = ext4_journal_start(inode, | 3667 | handle = ext4_journal_start(inode, |
3630 | EXT4_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); | 3668 | EXT4_QUOTA_TRANS_BLOCKS(dquot->dq_sb)); |
3631 | if (IS_ERR(handle)) | 3669 | if (IS_ERR(handle)) |
3632 | return PTR_ERR(handle); | 3670 | return PTR_ERR(handle); |
3633 | ret = dquot_commit(dquot); | 3671 | ret = dquot_commit(dquot); |
@@ -3643,7 +3681,7 @@ static int ext4_acquire_dquot(struct dquot *dquot) | |||
3643 | handle_t *handle; | 3681 | handle_t *handle; |
3644 | 3682 | ||
3645 | handle = ext4_journal_start(dquot_to_inode(dquot), | 3683 | handle = ext4_journal_start(dquot_to_inode(dquot), |
3646 | EXT4_QUOTA_INIT_BLOCKS(dquot->dq_sb)); | 3684 | EXT4_QUOTA_INIT_BLOCKS(dquot->dq_sb)); |
3647 | if (IS_ERR(handle)) | 3685 | if (IS_ERR(handle)) |
3648 | return PTR_ERR(handle); | 3686 | return PTR_ERR(handle); |
3649 | ret = dquot_acquire(dquot); | 3687 | ret = dquot_acquire(dquot); |
@@ -3659,7 +3697,7 @@ static int ext4_release_dquot(struct dquot *dquot) | |||
3659 | handle_t *handle; | 3697 | handle_t *handle; |
3660 | 3698 | ||
3661 | handle = ext4_journal_start(dquot_to_inode(dquot), | 3699 | handle = ext4_journal_start(dquot_to_inode(dquot), |
3662 | EXT4_QUOTA_DEL_BLOCKS(dquot->dq_sb)); | 3700 | EXT4_QUOTA_DEL_BLOCKS(dquot->dq_sb)); |
3663 | if (IS_ERR(handle)) { | 3701 | if (IS_ERR(handle)) { |
3664 | /* Release dquot anyway to avoid endless cycle in dqput() */ | 3702 | /* Release dquot anyway to avoid endless cycle in dqput() */ |
3665 | dquot_release(dquot); | 3703 | dquot_release(dquot); |
@@ -3707,7 +3745,7 @@ static int ext4_write_info(struct super_block *sb, int type) | |||
3707 | static int ext4_quota_on_mount(struct super_block *sb, int type) | 3745 | static int ext4_quota_on_mount(struct super_block *sb, int type) |
3708 | { | 3746 | { |
3709 | return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type], | 3747 | return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type], |
3710 | EXT4_SB(sb)->s_jquota_fmt, type); | 3748 | EXT4_SB(sb)->s_jquota_fmt, type); |
3711 | } | 3749 | } |
3712 | 3750 | ||
3713 | /* | 3751 | /* |
@@ -3738,9 +3776,9 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
3738 | if (EXT4_SB(sb)->s_qf_names[type]) { | 3776 | if (EXT4_SB(sb)->s_qf_names[type]) { |
3739 | /* Quotafile not in fs root? */ | 3777 | /* Quotafile not in fs root? */ |
3740 | if (path.dentry->d_parent != sb->s_root) | 3778 | if (path.dentry->d_parent != sb->s_root) |
3741 | printk(KERN_WARNING | 3779 | ext4_msg(sb, KERN_WARNING, |
3742 | "EXT4-fs: Quota file not on filesystem root. " | 3780 | "Quota file not on filesystem root. " |
3743 | "Journaled quota will not work.\n"); | 3781 | "Journaled quota will not work"); |
3744 | } | 3782 | } |
3745 | 3783 | ||
3746 | /* | 3784 | /* |
@@ -3823,8 +3861,8 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3823 | handle_t *handle = journal_current_handle(); | 3861 | handle_t *handle = journal_current_handle(); |
3824 | 3862 | ||
3825 | if (EXT4_SB(sb)->s_journal && !handle) { | 3863 | if (EXT4_SB(sb)->s_journal && !handle) { |
3826 | printk(KERN_WARNING "EXT4-fs: Quota write (off=%llu, len=%llu)" | 3864 | ext4_msg(sb, KERN_WARNING, "Quota write (off=%llu, len=%llu)" |
3827 | " cancelled because transaction is not started.\n", | 3865 | " cancelled because transaction is not started", |
3828 | (unsigned long long)off, (unsigned long long)len); | 3866 | (unsigned long long)off, (unsigned long long)len); |
3829 | return -EIO; | 3867 | return -EIO; |
3830 | } | 3868 | } |
@@ -3878,10 +3916,10 @@ out: | |||
3878 | 3916 | ||
3879 | #endif | 3917 | #endif |
3880 | 3918 | ||
3881 | static int ext4_get_sb(struct file_system_type *fs_type, | 3919 | static int ext4_get_sb(struct file_system_type *fs_type, int flags, |
3882 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 3920 | const char *dev_name, void *data, struct vfsmount *mnt) |
3883 | { | 3921 | { |
3884 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super, mnt); | 3922 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); |
3885 | } | 3923 | } |
3886 | 3924 | ||
3887 | static struct file_system_type ext4_fs_type = { | 3925 | static struct file_system_type ext4_fs_type = { |
@@ -3893,14 +3931,14 @@ static struct file_system_type ext4_fs_type = { | |||
3893 | }; | 3931 | }; |
3894 | 3932 | ||
3895 | #ifdef CONFIG_EXT4DEV_COMPAT | 3933 | #ifdef CONFIG_EXT4DEV_COMPAT |
3896 | static int ext4dev_get_sb(struct file_system_type *fs_type, | 3934 | static int ext4dev_get_sb(struct file_system_type *fs_type, int flags, |
3897 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 3935 | const char *dev_name, void *data,struct vfsmount *mnt) |
3898 | { | 3936 | { |
3899 | printk(KERN_WARNING "EXT4-fs: Update your userspace programs " | 3937 | printk(KERN_WARNING "EXT4-fs (%s): Update your userspace programs " |
3900 | "to mount using ext4\n"); | 3938 | "to mount using ext4\n", dev_name); |
3901 | printk(KERN_WARNING "EXT4-fs: ext4dev backwards compatibility " | 3939 | printk(KERN_WARNING "EXT4-fs (%s): ext4dev backwards compatibility " |
3902 | "will go away by 2.6.31\n"); | 3940 | "will go away by 2.6.31\n", dev_name); |
3903 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super, mnt); | 3941 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); |
3904 | } | 3942 | } |
3905 | 3943 | ||
3906 | static struct file_system_type ext4dev_fs_type = { | 3944 | static struct file_system_type ext4dev_fs_type = { |
@@ -3917,13 +3955,16 @@ static int __init init_ext4_fs(void) | |||
3917 | { | 3955 | { |
3918 | int err; | 3956 | int err; |
3919 | 3957 | ||
3958 | err = init_ext4_system_zone(); | ||
3959 | if (err) | ||
3960 | return err; | ||
3920 | ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj); | 3961 | ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj); |
3921 | if (!ext4_kset) | 3962 | if (!ext4_kset) |
3922 | return -ENOMEM; | 3963 | goto out4; |
3923 | ext4_proc_root = proc_mkdir("fs/ext4", NULL); | 3964 | ext4_proc_root = proc_mkdir("fs/ext4", NULL); |
3924 | err = init_ext4_mballoc(); | 3965 | err = init_ext4_mballoc(); |
3925 | if (err) | 3966 | if (err) |
3926 | return err; | 3967 | goto out3; |
3927 | 3968 | ||
3928 | err = init_ext4_xattr(); | 3969 | err = init_ext4_xattr(); |
3929 | if (err) | 3970 | if (err) |
@@ -3948,6 +3989,11 @@ out1: | |||
3948 | exit_ext4_xattr(); | 3989 | exit_ext4_xattr(); |
3949 | out2: | 3990 | out2: |
3950 | exit_ext4_mballoc(); | 3991 | exit_ext4_mballoc(); |
3992 | out3: | ||
3993 | remove_proc_entry("fs/ext4", NULL); | ||
3994 | kset_unregister(ext4_kset); | ||
3995 | out4: | ||
3996 | exit_ext4_system_zone(); | ||
3951 | return err; | 3997 | return err; |
3952 | } | 3998 | } |
3953 | 3999 | ||
@@ -3962,6 +4008,7 @@ static void __exit exit_ext4_fs(void) | |||
3962 | exit_ext4_mballoc(); | 4008 | exit_ext4_mballoc(); |
3963 | remove_proc_entry("fs/ext4", NULL); | 4009 | remove_proc_entry("fs/ext4", NULL); |
3964 | kset_unregister(ext4_kset); | 4010 | kset_unregister(ext4_kset); |
4011 | exit_ext4_system_zone(); | ||
3965 | } | 4012 | } |
3966 | 4013 | ||
3967 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); | 4014 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); |
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index 3a981b7f64ca..cad957cdb1e5 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig | |||
@@ -7,6 +7,7 @@ config GFS2_FS | |||
7 | select IP_SCTP if DLM_SCTP | 7 | select IP_SCTP if DLM_SCTP |
8 | select FS_POSIX_ACL | 8 | select FS_POSIX_ACL |
9 | select CRC32 | 9 | select CRC32 |
10 | select SLOW_WORK | ||
10 | help | 11 | help |
11 | A cluster filesystem. | 12 | A cluster filesystem. |
12 | 13 | ||
diff --git a/fs/gfs2/Makefile b/fs/gfs2/Makefile index a851ea4bdf70..d53a9bea1c2f 100644 --- a/fs/gfs2/Makefile +++ b/fs/gfs2/Makefile | |||
@@ -1,8 +1,8 @@ | |||
1 | obj-$(CONFIG_GFS2_FS) += gfs2.o | 1 | obj-$(CONFIG_GFS2_FS) += gfs2.o |
2 | gfs2-y := acl.o bmap.o dir.o eaops.o eattr.o glock.o \ | 2 | gfs2-y := acl.o bmap.o dir.o eaops.o eattr.o glock.o \ |
3 | glops.o inode.o log.o lops.o main.o meta_io.o \ | 3 | glops.o inode.o log.o lops.o main.o meta_io.o \ |
4 | mount.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ | 4 | aops.o dentry.o export.o file.o \ |
5 | ops_fstype.o ops_inode.o ops_super.o quota.o \ | 5 | ops_fstype.o ops_inode.o quota.o \ |
6 | recovery.o rgrp.o super.o sys.o trans.o util.o | 6 | recovery.o rgrp.o super.o sys.o trans.o util.o |
7 | 7 | ||
8 | gfs2-$(CONFIG_GFS2_FS_LOCKING_DLM) += lock_dlm.o | 8 | gfs2-$(CONFIG_GFS2_FS_LOCKING_DLM) += lock_dlm.o |
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/aops.c index a6dde1751e17..03ebb439ace0 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/aops.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "inode.h" | 28 | #include "inode.h" |
29 | #include "log.h" | 29 | #include "log.h" |
30 | #include "meta_io.h" | 30 | #include "meta_io.h" |
31 | #include "ops_address.h" | ||
32 | #include "quota.h" | 31 | #include "quota.h" |
33 | #include "trans.h" | 32 | #include "trans.h" |
34 | #include "rgrp.h" | 33 | #include "rgrp.h" |
@@ -781,10 +780,12 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh, | |||
781 | unlock_page(page); | 780 | unlock_page(page); |
782 | page_cache_release(page); | 781 | page_cache_release(page); |
783 | 782 | ||
784 | if (inode->i_size < to) { | 783 | if (copied) { |
785 | i_size_write(inode, to); | 784 | if (inode->i_size < to) { |
786 | ip->i_disksize = inode->i_size; | 785 | i_size_write(inode, to); |
787 | di->di_size = cpu_to_be64(inode->i_size); | 786 | ip->i_disksize = inode->i_size; |
787 | } | ||
788 | gfs2_dinode_out(ip, di); | ||
788 | mark_inode_dirty(inode); | 789 | mark_inode_dirty(inode); |
789 | } | 790 | } |
790 | 791 | ||
@@ -824,7 +825,6 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, | |||
824 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 825 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
825 | struct buffer_head *dibh; | 826 | struct buffer_head *dibh; |
826 | struct gfs2_alloc *al = ip->i_alloc; | 827 | struct gfs2_alloc *al = ip->i_alloc; |
827 | struct gfs2_dinode *di; | ||
828 | unsigned int from = pos & (PAGE_CACHE_SIZE - 1); | 828 | unsigned int from = pos & (PAGE_CACHE_SIZE - 1); |
829 | unsigned int to = from + len; | 829 | unsigned int to = from + len; |
830 | int ret; | 830 | int ret; |
@@ -847,11 +847,10 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, | |||
847 | gfs2_page_add_databufs(ip, page, from, to); | 847 | gfs2_page_add_databufs(ip, page, from, to); |
848 | 848 | ||
849 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); | 849 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); |
850 | 850 | if (ret > 0) { | |
851 | if (likely(ret >= 0) && (inode->i_size > ip->i_disksize)) { | 851 | if (inode->i_size > ip->i_disksize) |
852 | di = (struct gfs2_dinode *)dibh->b_data; | 852 | ip->i_disksize = inode->i_size; |
853 | ip->i_disksize = inode->i_size; | 853 | gfs2_dinode_out(ip, dibh->b_data); |
854 | di->di_size = cpu_to_be64(inode->i_size); | ||
855 | mark_inode_dirty(inode); | 854 | mark_inode_dirty(inode); |
856 | } | 855 | } |
857 | 856 | ||
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 3a5d3f883e10..329763530dc0 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include "trans.h" | 25 | #include "trans.h" |
26 | #include "dir.h" | 26 | #include "dir.h" |
27 | #include "util.h" | 27 | #include "util.h" |
28 | #include "ops_address.h" | ||
29 | 28 | ||
30 | /* This doesn't need to be that large as max 64 bit pointers in a 4k | 29 | /* This doesn't need to be that large as max 64 bit pointers in a 4k |
31 | * block is 512, so __u16 is fine for that. It saves stack space to | 30 | * block is 512, so __u16 is fine for that. It saves stack space to |
@@ -136,7 +135,9 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page) | |||
136 | and write it out to disk */ | 135 | and write it out to disk */ |
137 | 136 | ||
138 | unsigned int n = 1; | 137 | unsigned int n = 1; |
139 | block = gfs2_alloc_block(ip, &n); | 138 | error = gfs2_alloc_block(ip, &block, &n); |
139 | if (error) | ||
140 | goto out_brelse; | ||
140 | if (isdir) { | 141 | if (isdir) { |
141 | gfs2_trans_add_unrevoke(GFS2_SB(&ip->i_inode), block, 1); | 142 | gfs2_trans_add_unrevoke(GFS2_SB(&ip->i_inode), block, 1); |
142 | error = gfs2_dir_get_new_buffer(ip, block, &bh); | 143 | error = gfs2_dir_get_new_buffer(ip, block, &bh); |
@@ -476,8 +477,11 @@ static int gfs2_bmap_alloc(struct inode *inode, const sector_t lblock, | |||
476 | blks = dblks + iblks; | 477 | blks = dblks + iblks; |
477 | i = sheight; | 478 | i = sheight; |
478 | do { | 479 | do { |
480 | int error; | ||
479 | n = blks - alloced; | 481 | n = blks - alloced; |
480 | bn = gfs2_alloc_block(ip, &n); | 482 | error = gfs2_alloc_block(ip, &bn, &n); |
483 | if (error) | ||
484 | return error; | ||
481 | alloced += n; | 485 | alloced += n; |
482 | if (state != ALLOC_DATA || gfs2_is_jdata(ip)) | 486 | if (state != ALLOC_DATA || gfs2_is_jdata(ip)) |
483 | gfs2_trans_add_unrevoke(sdp, bn, n); | 487 | gfs2_trans_add_unrevoke(sdp, bn, n); |
@@ -1008,7 +1012,7 @@ static int gfs2_block_truncate_page(struct address_space *mapping) | |||
1008 | gfs2_trans_add_bh(ip->i_gl, bh, 0); | 1012 | gfs2_trans_add_bh(ip->i_gl, bh, 0); |
1009 | 1013 | ||
1010 | zero_user(page, offset, length); | 1014 | zero_user(page, offset, length); |
1011 | 1015 | mark_buffer_dirty(bh); | |
1012 | unlock: | 1016 | unlock: |
1013 | unlock_page(page); | 1017 | unlock_page(page); |
1014 | page_cache_release(page); | 1018 | page_cache_release(page); |
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/dentry.c index 022c66cd5606..022c66cd5606 100644 --- a/fs/gfs2/ops_dentry.c +++ b/fs/gfs2/dentry.c | |||
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index aef4d0c06748..297d7e5cebad 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -803,13 +803,20 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, | |||
803 | { | 803 | { |
804 | struct gfs2_inode *ip = GFS2_I(inode); | 804 | struct gfs2_inode *ip = GFS2_I(inode); |
805 | unsigned int n = 1; | 805 | unsigned int n = 1; |
806 | u64 bn = gfs2_alloc_block(ip, &n); | 806 | u64 bn; |
807 | struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn); | 807 | int error; |
808 | struct buffer_head *bh; | ||
808 | struct gfs2_leaf *leaf; | 809 | struct gfs2_leaf *leaf; |
809 | struct gfs2_dirent *dent; | 810 | struct gfs2_dirent *dent; |
810 | struct qstr name = { .name = "", .len = 0, .hash = 0 }; | 811 | struct qstr name = { .name = "", .len = 0, .hash = 0 }; |
812 | |||
813 | error = gfs2_alloc_block(ip, &bn, &n); | ||
814 | if (error) | ||
815 | return NULL; | ||
816 | bh = gfs2_meta_new(ip->i_gl, bn); | ||
811 | if (!bh) | 817 | if (!bh) |
812 | return NULL; | 818 | return NULL; |
819 | |||
813 | gfs2_trans_add_unrevoke(GFS2_SB(inode), bn, 1); | 820 | gfs2_trans_add_unrevoke(GFS2_SB(inode), bn, 1); |
814 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 821 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
815 | gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF); | 822 | gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF); |
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index 899763aed217..07ea9529adda 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c | |||
@@ -582,8 +582,11 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp) | |||
582 | struct gfs2_ea_header *ea; | 582 | struct gfs2_ea_header *ea; |
583 | unsigned int n = 1; | 583 | unsigned int n = 1; |
584 | u64 block; | 584 | u64 block; |
585 | int error; | ||
585 | 586 | ||
586 | block = gfs2_alloc_block(ip, &n); | 587 | error = gfs2_alloc_block(ip, &block, &n); |
588 | if (error) | ||
589 | return error; | ||
587 | gfs2_trans_add_unrevoke(sdp, block, 1); | 590 | gfs2_trans_add_unrevoke(sdp, block, 1); |
588 | *bhp = gfs2_meta_new(ip->i_gl, block); | 591 | *bhp = gfs2_meta_new(ip->i_gl, block); |
589 | gfs2_trans_add_bh(ip->i_gl, *bhp, 1); | 592 | gfs2_trans_add_bh(ip->i_gl, *bhp, 1); |
@@ -617,6 +620,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
617 | struct gfs2_ea_request *er) | 620 | struct gfs2_ea_request *er) |
618 | { | 621 | { |
619 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 622 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
623 | int error; | ||
620 | 624 | ||
621 | ea->ea_data_len = cpu_to_be32(er->er_data_len); | 625 | ea->ea_data_len = cpu_to_be32(er->er_data_len); |
622 | ea->ea_name_len = er->er_name_len; | 626 | ea->ea_name_len = er->er_name_len; |
@@ -642,7 +646,9 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
642 | int mh_size = sizeof(struct gfs2_meta_header); | 646 | int mh_size = sizeof(struct gfs2_meta_header); |
643 | unsigned int n = 1; | 647 | unsigned int n = 1; |
644 | 648 | ||
645 | block = gfs2_alloc_block(ip, &n); | 649 | error = gfs2_alloc_block(ip, &block, &n); |
650 | if (error) | ||
651 | return error; | ||
646 | gfs2_trans_add_unrevoke(sdp, block, 1); | 652 | gfs2_trans_add_unrevoke(sdp, block, 1); |
647 | bh = gfs2_meta_new(ip->i_gl, block); | 653 | bh = gfs2_meta_new(ip->i_gl, block); |
648 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 654 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
@@ -963,7 +969,9 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
963 | } else { | 969 | } else { |
964 | u64 blk; | 970 | u64 blk; |
965 | unsigned int n = 1; | 971 | unsigned int n = 1; |
966 | blk = gfs2_alloc_block(ip, &n); | 972 | error = gfs2_alloc_block(ip, &blk, &n); |
973 | if (error) | ||
974 | return error; | ||
967 | gfs2_trans_add_unrevoke(sdp, blk, 1); | 975 | gfs2_trans_add_unrevoke(sdp, blk, 1); |
968 | indbh = gfs2_meta_new(ip->i_gl, blk); | 976 | indbh = gfs2_meta_new(ip->i_gl, blk); |
969 | gfs2_trans_add_bh(ip->i_gl, indbh, 1); | 977 | gfs2_trans_add_bh(ip->i_gl, indbh, 1); |
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/export.c index 9200ef221716..9200ef221716 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/export.c | |||
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/file.c index 5d82e91887e3..73318a3ce6f1 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/file.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include "trans.h" | 39 | #include "trans.h" |
40 | #include "util.h" | 40 | #include "util.h" |
41 | #include "eaops.h" | 41 | #include "eaops.h" |
42 | #include "ops_address.h" | ||
43 | 42 | ||
44 | /** | 43 | /** |
45 | * gfs2_llseek - seek to a location in a file | 44 | * gfs2_llseek - seek to a location in a file |
@@ -425,33 +424,36 @@ static struct vm_operations_struct gfs2_vm_ops = { | |||
425 | .page_mkwrite = gfs2_page_mkwrite, | 424 | .page_mkwrite = gfs2_page_mkwrite, |
426 | }; | 425 | }; |
427 | 426 | ||
428 | |||
429 | /** | 427 | /** |
430 | * gfs2_mmap - | 428 | * gfs2_mmap - |
431 | * @file: The file to map | 429 | * @file: The file to map |
432 | * @vma: The VMA which described the mapping | 430 | * @vma: The VMA which described the mapping |
433 | * | 431 | * |
434 | * Returns: 0 or error code | 432 | * There is no need to get a lock here unless we should be updating |
433 | * atime. We ignore any locking errors since the only consequence is | ||
434 | * a missed atime update (which will just be deferred until later). | ||
435 | * | ||
436 | * Returns: 0 | ||
435 | */ | 437 | */ |
436 | 438 | ||
437 | static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) | 439 | static int gfs2_mmap(struct file *file, struct vm_area_struct *vma) |
438 | { | 440 | { |
439 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); | 441 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); |
440 | struct gfs2_holder i_gh; | ||
441 | int error; | ||
442 | 442 | ||
443 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); | 443 | if (!(file->f_flags & O_NOATIME)) { |
444 | error = gfs2_glock_nq(&i_gh); | 444 | struct gfs2_holder i_gh; |
445 | if (error) { | 445 | int error; |
446 | gfs2_holder_uninit(&i_gh); | ||
447 | return error; | ||
448 | } | ||
449 | 446 | ||
447 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); | ||
448 | error = gfs2_glock_nq(&i_gh); | ||
449 | file_accessed(file); | ||
450 | if (error == 0) | ||
451 | gfs2_glock_dq_uninit(&i_gh); | ||
452 | } | ||
450 | vma->vm_ops = &gfs2_vm_ops; | 453 | vma->vm_ops = &gfs2_vm_ops; |
454 | vma->vm_flags |= VM_CAN_NONLINEAR; | ||
451 | 455 | ||
452 | gfs2_glock_dq_uninit(&i_gh); | 456 | return 0; |
453 | |||
454 | return error; | ||
455 | } | 457 | } |
456 | 458 | ||
457 | /** | 459 | /** |
@@ -692,12 +694,10 @@ static void do_unflock(struct file *file, struct file_lock *fl) | |||
692 | 694 | ||
693 | static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) | 695 | static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) |
694 | { | 696 | { |
695 | struct gfs2_inode *ip = GFS2_I(file->f_mapping->host); | ||
696 | |||
697 | if (!(fl->fl_flags & FL_FLOCK)) | 697 | if (!(fl->fl_flags & FL_FLOCK)) |
698 | return -ENOLCK; | 698 | return -ENOLCK; |
699 | if (__mandatory_lock(&ip->i_inode)) | 699 | if (fl->fl_type & LOCK_MAND) |
700 | return -ENOLCK; | 700 | return -EOPNOTSUPP; |
701 | 701 | ||
702 | if (fl->fl_type == F_UNLCK) { | 702 | if (fl->fl_type == F_UNLCK) { |
703 | do_unflock(file, fl); | 703 | do_unflock(file, fl); |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index ff4981090489..2bf62bcc5181 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -796,22 +796,37 @@ void gfs2_holder_uninit(struct gfs2_holder *gh) | |||
796 | gh->gh_ip = 0; | 796 | gh->gh_ip = 0; |
797 | } | 797 | } |
798 | 798 | ||
799 | static int just_schedule(void *word) | 799 | /** |
800 | * gfs2_glock_holder_wait | ||
801 | * @word: unused | ||
802 | * | ||
803 | * This function and gfs2_glock_demote_wait both show up in the WCHAN | ||
804 | * field. Thus I've separated these otherwise identical functions in | ||
805 | * order to be more informative to the user. | ||
806 | */ | ||
807 | |||
808 | static int gfs2_glock_holder_wait(void *word) | ||
800 | { | 809 | { |
801 | schedule(); | 810 | schedule(); |
802 | return 0; | 811 | return 0; |
803 | } | 812 | } |
804 | 813 | ||
814 | static int gfs2_glock_demote_wait(void *word) | ||
815 | { | ||
816 | schedule(); | ||
817 | return 0; | ||
818 | } | ||
819 | |||
805 | static void wait_on_holder(struct gfs2_holder *gh) | 820 | static void wait_on_holder(struct gfs2_holder *gh) |
806 | { | 821 | { |
807 | might_sleep(); | 822 | might_sleep(); |
808 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, just_schedule, TASK_UNINTERRUPTIBLE); | 823 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, gfs2_glock_holder_wait, TASK_UNINTERRUPTIBLE); |
809 | } | 824 | } |
810 | 825 | ||
811 | static void wait_on_demote(struct gfs2_glock *gl) | 826 | static void wait_on_demote(struct gfs2_glock *gl) |
812 | { | 827 | { |
813 | might_sleep(); | 828 | might_sleep(); |
814 | wait_on_bit(&gl->gl_flags, GLF_DEMOTE, just_schedule, TASK_UNINTERRUPTIBLE); | 829 | wait_on_bit(&gl->gl_flags, GLF_DEMOTE, gfs2_glock_demote_wait, TASK_UNINTERRUPTIBLE); |
815 | } | 830 | } |
816 | 831 | ||
817 | /** | 832 | /** |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 70f87f43afa2..d5e4ab155ca0 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -310,24 +310,6 @@ static void rgrp_go_unlock(struct gfs2_holder *gh) | |||
310 | } | 310 | } |
311 | 311 | ||
312 | /** | 312 | /** |
313 | * rgrp_go_dump - print out an rgrp | ||
314 | * @seq: The iterator | ||
315 | * @gl: The glock in question | ||
316 | * | ||
317 | */ | ||
318 | |||
319 | static int rgrp_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) | ||
320 | { | ||
321 | const struct gfs2_rgrpd *rgd = gl->gl_object; | ||
322 | if (rgd == NULL) | ||
323 | return 0; | ||
324 | gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u\n", | ||
325 | (unsigned long long)rgd->rd_addr, rgd->rd_flags, | ||
326 | rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes); | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | /** | ||
331 | * trans_go_sync - promote/demote the transaction glock | 313 | * trans_go_sync - promote/demote the transaction glock |
332 | * @gl: the glock | 314 | * @gl: the glock |
333 | * @state: the requested state | 315 | * @state: the requested state |
@@ -410,7 +392,7 @@ const struct gfs2_glock_operations gfs2_rgrp_glops = { | |||
410 | .go_demote_ok = rgrp_go_demote_ok, | 392 | .go_demote_ok = rgrp_go_demote_ok, |
411 | .go_lock = rgrp_go_lock, | 393 | .go_lock = rgrp_go_lock, |
412 | .go_unlock = rgrp_go_unlock, | 394 | .go_unlock = rgrp_go_unlock, |
413 | .go_dump = rgrp_go_dump, | 395 | .go_dump = gfs2_rgrp_dump, |
414 | .go_type = LM_TYPE_RGRP, | 396 | .go_type = LM_TYPE_RGRP, |
415 | .go_min_hold_time = HZ / 5, | 397 | .go_min_hold_time = HZ / 5, |
416 | }; | 398 | }; |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 399d1b978049..225347fbff3c 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/workqueue.h> | 14 | #include <linux/workqueue.h> |
15 | #include <linux/slow-work.h> | ||
15 | #include <linux/dlm.h> | 16 | #include <linux/dlm.h> |
16 | #include <linux/buffer_head.h> | 17 | #include <linux/buffer_head.h> |
17 | 18 | ||
@@ -63,9 +64,12 @@ struct gfs2_log_element { | |||
63 | const struct gfs2_log_operations *le_ops; | 64 | const struct gfs2_log_operations *le_ops; |
64 | }; | 65 | }; |
65 | 66 | ||
67 | #define GBF_FULL 1 | ||
68 | |||
66 | struct gfs2_bitmap { | 69 | struct gfs2_bitmap { |
67 | struct buffer_head *bi_bh; | 70 | struct buffer_head *bi_bh; |
68 | char *bi_clone; | 71 | char *bi_clone; |
72 | unsigned long bi_flags; | ||
69 | u32 bi_offset; | 73 | u32 bi_offset; |
70 | u32 bi_start; | 74 | u32 bi_start; |
71 | u32 bi_len; | 75 | u32 bi_len; |
@@ -90,10 +94,11 @@ struct gfs2_rgrpd { | |||
90 | struct gfs2_sbd *rd_sbd; | 94 | struct gfs2_sbd *rd_sbd; |
91 | unsigned int rd_bh_count; | 95 | unsigned int rd_bh_count; |
92 | u32 rd_last_alloc; | 96 | u32 rd_last_alloc; |
93 | unsigned char rd_flags; | 97 | u32 rd_flags; |
94 | #define GFS2_RDF_CHECK 0x01 /* Need to check for unlinked inodes */ | 98 | #define GFS2_RDF_CHECK 0x10000000 /* check for unlinked inodes */ |
95 | #define GFS2_RDF_NOALLOC 0x02 /* rg prohibits allocation */ | 99 | #define GFS2_RDF_UPTODATE 0x20000000 /* rg is up to date */ |
96 | #define GFS2_RDF_UPTODATE 0x04 /* rg is up to date */ | 100 | #define GFS2_RDF_ERROR 0x40000000 /* error in rg */ |
101 | #define GFS2_RDF_MASK 0xf0000000 /* mask for internal flags */ | ||
97 | }; | 102 | }; |
98 | 103 | ||
99 | enum gfs2_state_bits { | 104 | enum gfs2_state_bits { |
@@ -376,11 +381,11 @@ struct gfs2_journal_extent { | |||
376 | struct gfs2_jdesc { | 381 | struct gfs2_jdesc { |
377 | struct list_head jd_list; | 382 | struct list_head jd_list; |
378 | struct list_head extent_list; | 383 | struct list_head extent_list; |
379 | 384 | struct slow_work jd_work; | |
380 | struct inode *jd_inode; | 385 | struct inode *jd_inode; |
386 | unsigned long jd_flags; | ||
387 | #define JDF_RECOVERY 1 | ||
381 | unsigned int jd_jid; | 388 | unsigned int jd_jid; |
382 | int jd_dirty; | ||
383 | |||
384 | unsigned int jd_blocks; | 389 | unsigned int jd_blocks; |
385 | }; | 390 | }; |
386 | 391 | ||
@@ -390,9 +395,6 @@ struct gfs2_statfs_change_host { | |||
390 | s64 sc_dinodes; | 395 | s64 sc_dinodes; |
391 | }; | 396 | }; |
392 | 397 | ||
393 | #define GFS2_GLOCKD_DEFAULT 1 | ||
394 | #define GFS2_GLOCKD_MAX 16 | ||
395 | |||
396 | #define GFS2_QUOTA_DEFAULT GFS2_QUOTA_OFF | 398 | #define GFS2_QUOTA_DEFAULT GFS2_QUOTA_OFF |
397 | #define GFS2_QUOTA_OFF 0 | 399 | #define GFS2_QUOTA_OFF 0 |
398 | #define GFS2_QUOTA_ACCOUNT 1 | 400 | #define GFS2_QUOTA_ACCOUNT 1 |
@@ -418,6 +420,7 @@ struct gfs2_args { | |||
418 | unsigned int ar_data:2; /* ordered/writeback */ | 420 | unsigned int ar_data:2; /* ordered/writeback */ |
419 | unsigned int ar_meta:1; /* mount metafs */ | 421 | unsigned int ar_meta:1; /* mount metafs */ |
420 | unsigned int ar_discard:1; /* discard requests */ | 422 | unsigned int ar_discard:1; /* discard requests */ |
423 | int ar_commit; /* Commit interval */ | ||
421 | }; | 424 | }; |
422 | 425 | ||
423 | struct gfs2_tune { | 426 | struct gfs2_tune { |
@@ -426,7 +429,6 @@ struct gfs2_tune { | |||
426 | unsigned int gt_incore_log_blocks; | 429 | unsigned int gt_incore_log_blocks; |
427 | unsigned int gt_log_flush_secs; | 430 | unsigned int gt_log_flush_secs; |
428 | 431 | ||
429 | unsigned int gt_recoverd_secs; | ||
430 | unsigned int gt_logd_secs; | 432 | unsigned int gt_logd_secs; |
431 | 433 | ||
432 | unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */ | 434 | unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */ |
@@ -447,6 +449,7 @@ enum { | |||
447 | SDF_JOURNAL_LIVE = 1, | 449 | SDF_JOURNAL_LIVE = 1, |
448 | SDF_SHUTDOWN = 2, | 450 | SDF_SHUTDOWN = 2, |
449 | SDF_NOBARRIERS = 3, | 451 | SDF_NOBARRIERS = 3, |
452 | SDF_NORECOVERY = 4, | ||
450 | }; | 453 | }; |
451 | 454 | ||
452 | #define GFS2_FSNAME_LEN 256 | 455 | #define GFS2_FSNAME_LEN 256 |
@@ -493,7 +496,6 @@ struct lm_lockstruct { | |||
493 | unsigned long ls_flags; | 496 | unsigned long ls_flags; |
494 | dlm_lockspace_t *ls_dlm; | 497 | dlm_lockspace_t *ls_dlm; |
495 | 498 | ||
496 | int ls_recover_jid; | ||
497 | int ls_recover_jid_done; | 499 | int ls_recover_jid_done; |
498 | int ls_recover_jid_status; | 500 | int ls_recover_jid_status; |
499 | }; | 501 | }; |
@@ -582,7 +584,6 @@ struct gfs2_sbd { | |||
582 | 584 | ||
583 | /* Daemon stuff */ | 585 | /* Daemon stuff */ |
584 | 586 | ||
585 | struct task_struct *sd_recoverd_process; | ||
586 | struct task_struct *sd_logd_process; | 587 | struct task_struct *sd_logd_process; |
587 | struct task_struct *sd_quotad_process; | 588 | struct task_struct *sd_quotad_process; |
588 | 589 | ||
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 5a31d426116f..2f94bd723698 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include "inode.h" | 30 | #include "inode.h" |
31 | #include "log.h" | 31 | #include "log.h" |
32 | #include "meta_io.h" | 32 | #include "meta_io.h" |
33 | #include "ops_address.h" | ||
34 | #include "quota.h" | 33 | #include "quota.h" |
35 | #include "rgrp.h" | 34 | #include "rgrp.h" |
36 | #include "trans.h" | 35 | #include "trans.h" |
@@ -1047,154 +1046,7 @@ fail: | |||
1047 | return ERR_PTR(error); | 1046 | return ERR_PTR(error); |
1048 | } | 1047 | } |
1049 | 1048 | ||
1050 | /** | 1049 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1051 | * gfs2_rmdiri - Remove a directory | ||
1052 | * @dip: The parent directory of the directory to be removed | ||
1053 | * @name: The name of the directory to be removed | ||
1054 | * @ip: The GFS2 inode of the directory to be removed | ||
1055 | * | ||
1056 | * Assumes Glocks on dip and ip are held | ||
1057 | * | ||
1058 | * Returns: errno | ||
1059 | */ | ||
1060 | |||
1061 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | ||
1062 | struct gfs2_inode *ip) | ||
1063 | { | ||
1064 | struct qstr dotname; | ||
1065 | int error; | ||
1066 | |||
1067 | if (ip->i_entries != 2) { | ||
1068 | if (gfs2_consist_inode(ip)) | ||
1069 | gfs2_dinode_print(ip); | ||
1070 | return -EIO; | ||
1071 | } | ||
1072 | |||
1073 | error = gfs2_dir_del(dip, name); | ||
1074 | if (error) | ||
1075 | return error; | ||
1076 | |||
1077 | error = gfs2_change_nlink(dip, -1); | ||
1078 | if (error) | ||
1079 | return error; | ||
1080 | |||
1081 | gfs2_str2qstr(&dotname, "."); | ||
1082 | error = gfs2_dir_del(ip, &dotname); | ||
1083 | if (error) | ||
1084 | return error; | ||
1085 | |||
1086 | gfs2_str2qstr(&dotname, ".."); | ||
1087 | error = gfs2_dir_del(ip, &dotname); | ||
1088 | if (error) | ||
1089 | return error; | ||
1090 | |||
1091 | /* It looks odd, but it really should be done twice */ | ||
1092 | error = gfs2_change_nlink(ip, -1); | ||
1093 | if (error) | ||
1094 | return error; | ||
1095 | |||
1096 | error = gfs2_change_nlink(ip, -1); | ||
1097 | if (error) | ||
1098 | return error; | ||
1099 | |||
1100 | return error; | ||
1101 | } | ||
1102 | |||
1103 | /* | ||
1104 | * gfs2_unlink_ok - check to see that a inode is still in a directory | ||
1105 | * @dip: the directory | ||
1106 | * @name: the name of the file | ||
1107 | * @ip: the inode | ||
1108 | * | ||
1109 | * Assumes that the lock on (at least) @dip is held. | ||
1110 | * | ||
1111 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | ||
1112 | */ | ||
1113 | |||
1114 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
1115 | const struct gfs2_inode *ip) | ||
1116 | { | ||
1117 | int error; | ||
1118 | |||
1119 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | ||
1120 | return -EPERM; | ||
1121 | |||
1122 | if ((dip->i_inode.i_mode & S_ISVTX) && | ||
1123 | dip->i_inode.i_uid != current_fsuid() && | ||
1124 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | ||
1125 | return -EPERM; | ||
1126 | |||
1127 | if (IS_APPEND(&dip->i_inode)) | ||
1128 | return -EPERM; | ||
1129 | |||
1130 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | ||
1131 | if (error) | ||
1132 | return error; | ||
1133 | |||
1134 | error = gfs2_dir_check(&dip->i_inode, name, ip); | ||
1135 | if (error) | ||
1136 | return error; | ||
1137 | |||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1141 | /** | ||
1142 | * gfs2_readlinki - return the contents of a symlink | ||
1143 | * @ip: the symlink's inode | ||
1144 | * @buf: a pointer to the buffer to be filled | ||
1145 | * @len: a pointer to the length of @buf | ||
1146 | * | ||
1147 | * If @buf is too small, a piece of memory is kmalloc()ed and needs | ||
1148 | * to be freed by the caller. | ||
1149 | * | ||
1150 | * Returns: errno | ||
1151 | */ | ||
1152 | |||
1153 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | ||
1154 | { | ||
1155 | struct gfs2_holder i_gh; | ||
1156 | struct buffer_head *dibh; | ||
1157 | unsigned int x; | ||
1158 | int error; | ||
1159 | |||
1160 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); | ||
1161 | error = gfs2_glock_nq(&i_gh); | ||
1162 | if (error) { | ||
1163 | gfs2_holder_uninit(&i_gh); | ||
1164 | return error; | ||
1165 | } | ||
1166 | |||
1167 | if (!ip->i_disksize) { | ||
1168 | gfs2_consist_inode(ip); | ||
1169 | error = -EIO; | ||
1170 | goto out; | ||
1171 | } | ||
1172 | |||
1173 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
1174 | if (error) | ||
1175 | goto out; | ||
1176 | |||
1177 | x = ip->i_disksize + 1; | ||
1178 | if (x > *len) { | ||
1179 | *buf = kmalloc(x, GFP_NOFS); | ||
1180 | if (!*buf) { | ||
1181 | error = -ENOMEM; | ||
1182 | goto out_brelse; | ||
1183 | } | ||
1184 | } | ||
1185 | |||
1186 | memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x); | ||
1187 | *len = x; | ||
1188 | |||
1189 | out_brelse: | ||
1190 | brelse(dibh); | ||
1191 | out: | ||
1192 | gfs2_glock_dq_uninit(&i_gh); | ||
1193 | return error; | ||
1194 | } | ||
1195 | |||
1196 | static int | ||
1197 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | ||
1198 | { | 1050 | { |
1199 | struct buffer_head *dibh; | 1051 | struct buffer_head *dibh; |
1200 | int error; | 1052 | int error; |
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index c30be2b66580..c341aaf67adb 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -11,8 +11,16 @@ | |||
11 | #define __INODE_DOT_H__ | 11 | #define __INODE_DOT_H__ |
12 | 12 | ||
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/buffer_head.h> | ||
15 | #include <linux/mm.h> | ||
14 | #include "util.h" | 16 | #include "util.h" |
15 | 17 | ||
18 | extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); | ||
19 | extern int gfs2_internal_read(struct gfs2_inode *ip, | ||
20 | struct file_ra_state *ra_state, | ||
21 | char *buf, loff_t *pos, unsigned size); | ||
22 | extern void gfs2_set_aops(struct inode *inode); | ||
23 | |||
16 | static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) | 24 | static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) |
17 | { | 25 | { |
18 | return !ip->i_height; | 26 | return !ip->i_height; |
@@ -73,30 +81,26 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip, | |||
73 | } | 81 | } |
74 | 82 | ||
75 | 83 | ||
76 | void gfs2_set_iop(struct inode *inode); | 84 | extern void gfs2_set_iop(struct inode *inode); |
77 | struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, | 85 | extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, |
78 | u64 no_addr, u64 no_formal_ino, | 86 | u64 no_addr, u64 no_formal_ino, |
79 | int skip_freeing); | 87 | int skip_freeing); |
80 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); | 88 | extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); |
81 | 89 | ||
82 | int gfs2_inode_refresh(struct gfs2_inode *ip); | 90 | extern int gfs2_inode_refresh(struct gfs2_inode *ip); |
83 | 91 | ||
84 | int gfs2_dinode_dealloc(struct gfs2_inode *inode); | 92 | extern int gfs2_dinode_dealloc(struct gfs2_inode *inode); |
85 | int gfs2_change_nlink(struct gfs2_inode *ip, int diff); | 93 | extern int gfs2_change_nlink(struct gfs2_inode *ip, int diff); |
86 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 94 | extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
87 | int is_root); | 95 | int is_root); |
88 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 96 | extern struct inode *gfs2_createi(struct gfs2_holder *ghs, |
89 | unsigned int mode, dev_t dev); | 97 | const struct qstr *name, |
90 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | 98 | unsigned int mode, dev_t dev); |
91 | struct gfs2_inode *ip); | 99 | extern int gfs2_permission(struct inode *inode, int mask); |
92 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 100 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
93 | const struct gfs2_inode *ip); | 101 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
94 | int gfs2_permission(struct inode *inode, int mask); | 102 | extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); |
95 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); | 103 | extern void gfs2_dinode_print(const struct gfs2_inode *ip); |
96 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | ||
97 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | ||
98 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); | ||
99 | void gfs2_dinode_print(const struct gfs2_inode *ip); | ||
100 | 104 | ||
101 | extern const struct inode_operations gfs2_file_iops; | 105 | extern const struct inode_operations gfs2_file_iops; |
102 | extern const struct inode_operations gfs2_dir_iops; | 106 | extern const struct inode_operations gfs2_dir_iops; |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 98918a756410..aa62cf5976e8 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -120,7 +120,7 @@ __acquires(&sdp->sd_log_lock) | |||
120 | lock_buffer(bh); | 120 | lock_buffer(bh); |
121 | if (test_clear_buffer_dirty(bh)) { | 121 | if (test_clear_buffer_dirty(bh)) { |
122 | bh->b_end_io = end_buffer_write_sync; | 122 | bh->b_end_io = end_buffer_write_sync; |
123 | submit_bh(WRITE, bh); | 123 | submit_bh(WRITE_SYNC_PLUG, bh); |
124 | } else { | 124 | } else { |
125 | unlock_buffer(bh); | 125 | unlock_buffer(bh); |
126 | brelse(bh); | 126 | brelse(bh); |
@@ -604,7 +604,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) | |||
604 | if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) | 604 | if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) |
605 | goto skip_barrier; | 605 | goto skip_barrier; |
606 | get_bh(bh); | 606 | get_bh(bh); |
607 | submit_bh(WRITE_BARRIER | (1 << BIO_RW_META), bh); | 607 | submit_bh(WRITE_SYNC | (1 << BIO_RW_BARRIER) | (1 << BIO_RW_META), bh); |
608 | wait_on_buffer(bh); | 608 | wait_on_buffer(bh); |
609 | if (buffer_eopnotsupp(bh)) { | 609 | if (buffer_eopnotsupp(bh)) { |
610 | clear_buffer_eopnotsupp(bh); | 610 | clear_buffer_eopnotsupp(bh); |
@@ -664,7 +664,7 @@ static void gfs2_ordered_write(struct gfs2_sbd *sdp) | |||
664 | lock_buffer(bh); | 664 | lock_buffer(bh); |
665 | if (buffer_mapped(bh) && test_clear_buffer_dirty(bh)) { | 665 | if (buffer_mapped(bh) && test_clear_buffer_dirty(bh)) { |
666 | bh->b_end_io = end_buffer_write_sync; | 666 | bh->b_end_io = end_buffer_write_sync; |
667 | submit_bh(WRITE, bh); | 667 | submit_bh(WRITE_SYNC_PLUG, bh); |
668 | } else { | 668 | } else { |
669 | unlock_buffer(bh); | 669 | unlock_buffer(bh); |
670 | brelse(bh); | 670 | brelse(bh); |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 80e4f5f898bb..00315f50fa46 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/completion.h> | 13 | #include <linux/completion.h> |
14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
15 | #include <linux/gfs2_ondisk.h> | 15 | #include <linux/gfs2_ondisk.h> |
16 | #include <linux/bio.h> | ||
17 | #include <linux/fs.h> | ||
16 | 18 | ||
17 | #include "gfs2.h" | 19 | #include "gfs2.h" |
18 | #include "incore.h" | 20 | #include "incore.h" |
@@ -189,7 +191,7 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
189 | } | 191 | } |
190 | 192 | ||
191 | gfs2_log_unlock(sdp); | 193 | gfs2_log_unlock(sdp); |
192 | submit_bh(WRITE, bh); | 194 | submit_bh(WRITE_SYNC_PLUG, bh); |
193 | gfs2_log_lock(sdp); | 195 | gfs2_log_lock(sdp); |
194 | 196 | ||
195 | n = 0; | 197 | n = 0; |
@@ -199,7 +201,7 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
199 | gfs2_log_unlock(sdp); | 201 | gfs2_log_unlock(sdp); |
200 | lock_buffer(bd2->bd_bh); | 202 | lock_buffer(bd2->bd_bh); |
201 | bh = gfs2_log_fake_buf(sdp, bd2->bd_bh); | 203 | bh = gfs2_log_fake_buf(sdp, bd2->bd_bh); |
202 | submit_bh(WRITE, bh); | 204 | submit_bh(WRITE_SYNC_PLUG, bh); |
203 | gfs2_log_lock(sdp); | 205 | gfs2_log_lock(sdp); |
204 | if (++n >= num) | 206 | if (++n >= num) |
205 | break; | 207 | break; |
@@ -341,7 +343,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | |||
341 | sdp->sd_log_num_revoke--; | 343 | sdp->sd_log_num_revoke--; |
342 | 344 | ||
343 | if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { | 345 | if (offset + sizeof(u64) > sdp->sd_sb.sb_bsize) { |
344 | submit_bh(WRITE, bh); | 346 | submit_bh(WRITE_SYNC_PLUG, bh); |
345 | 347 | ||
346 | bh = gfs2_log_get_buf(sdp); | 348 | bh = gfs2_log_get_buf(sdp); |
347 | mh = (struct gfs2_meta_header *)bh->b_data; | 349 | mh = (struct gfs2_meta_header *)bh->b_data; |
@@ -358,7 +360,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | |||
358 | } | 360 | } |
359 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); | 361 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); |
360 | 362 | ||
361 | submit_bh(WRITE, bh); | 363 | submit_bh(WRITE_SYNC_PLUG, bh); |
362 | } | 364 | } |
363 | 365 | ||
364 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, | 366 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, |
@@ -560,7 +562,7 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
560 | ptr = bh_log_ptr(bh); | 562 | ptr = bh_log_ptr(bh); |
561 | 563 | ||
562 | get_bh(bh); | 564 | get_bh(bh); |
563 | submit_bh(WRITE, bh); | 565 | submit_bh(WRITE_SYNC_PLUG, bh); |
564 | gfs2_log_lock(sdp); | 566 | gfs2_log_lock(sdp); |
565 | while(!list_empty(list)) { | 567 | while(!list_empty(list)) { |
566 | bd = list_entry(list->next, struct gfs2_bufdata, bd_le.le_list); | 568 | bd = list_entry(list->next, struct gfs2_bufdata, bd_le.le_list); |
@@ -586,7 +588,7 @@ static void gfs2_write_blocks(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
586 | } else { | 588 | } else { |
587 | bh1 = gfs2_log_fake_buf(sdp, bd->bd_bh); | 589 | bh1 = gfs2_log_fake_buf(sdp, bd->bd_bh); |
588 | } | 590 | } |
589 | submit_bh(WRITE, bh1); | 591 | submit_bh(WRITE_SYNC_PLUG, bh1); |
590 | gfs2_log_lock(sdp); | 592 | gfs2_log_lock(sdp); |
591 | ptr += 2; | 593 | ptr += 2; |
592 | } | 594 | } |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index a6892ed0840a..eacd78a5d082 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/gfs2_ondisk.h> | 16 | #include <linux/gfs2_ondisk.h> |
17 | #include <asm/atomic.h> | 17 | #include <asm/atomic.h> |
18 | #include <linux/slow-work.h> | ||
18 | 19 | ||
19 | #include "gfs2.h" | 20 | #include "gfs2.h" |
20 | #include "incore.h" | 21 | #include "incore.h" |
@@ -113,12 +114,18 @@ static int __init init_gfs2_fs(void) | |||
113 | if (error) | 114 | if (error) |
114 | goto fail_unregister; | 115 | goto fail_unregister; |
115 | 116 | ||
117 | error = slow_work_register_user(); | ||
118 | if (error) | ||
119 | goto fail_slow; | ||
120 | |||
116 | gfs2_register_debugfs(); | 121 | gfs2_register_debugfs(); |
117 | 122 | ||
118 | printk("GFS2 (built %s %s) installed\n", __DATE__, __TIME__); | 123 | printk("GFS2 (built %s %s) installed\n", __DATE__, __TIME__); |
119 | 124 | ||
120 | return 0; | 125 | return 0; |
121 | 126 | ||
127 | fail_slow: | ||
128 | unregister_filesystem(&gfs2meta_fs_type); | ||
122 | fail_unregister: | 129 | fail_unregister: |
123 | unregister_filesystem(&gfs2_fs_type); | 130 | unregister_filesystem(&gfs2_fs_type); |
124 | fail: | 131 | fail: |
@@ -156,6 +163,7 @@ static void __exit exit_gfs2_fs(void) | |||
156 | gfs2_unregister_debugfs(); | 163 | gfs2_unregister_debugfs(); |
157 | unregister_filesystem(&gfs2_fs_type); | 164 | unregister_filesystem(&gfs2_fs_type); |
158 | unregister_filesystem(&gfs2meta_fs_type); | 165 | unregister_filesystem(&gfs2meta_fs_type); |
166 | slow_work_unregister_user(); | ||
159 | 167 | ||
160 | kmem_cache_destroy(gfs2_quotad_cachep); | 168 | kmem_cache_destroy(gfs2_quotad_cachep); |
161 | kmem_cache_destroy(gfs2_rgrpd_cachep); | 169 | kmem_cache_destroy(gfs2_rgrpd_cachep); |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 8d6f13256b26..cb8d7a93d5ec 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -31,19 +31,66 @@ | |||
31 | #include "rgrp.h" | 31 | #include "rgrp.h" |
32 | #include "trans.h" | 32 | #include "trans.h" |
33 | #include "util.h" | 33 | #include "util.h" |
34 | #include "ops_address.h" | ||
35 | 34 | ||
36 | static int aspace_get_block(struct inode *inode, sector_t lblock, | 35 | static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wbc) |
37 | struct buffer_head *bh_result, int create) | ||
38 | { | 36 | { |
39 | gfs2_assert_warn(inode->i_sb->s_fs_info, 0); | 37 | int err; |
40 | return -EOPNOTSUPP; | 38 | struct buffer_head *bh, *head; |
41 | } | 39 | int nr_underway = 0; |
40 | int write_op = (1 << BIO_RW_META) | ((wbc->sync_mode == WB_SYNC_ALL ? | ||
41 | WRITE_SYNC_PLUG : WRITE)); | ||
42 | |||
43 | BUG_ON(!PageLocked(page)); | ||
44 | BUG_ON(!page_has_buffers(page)); | ||
45 | |||
46 | head = page_buffers(page); | ||
47 | bh = head; | ||
48 | |||
49 | do { | ||
50 | if (!buffer_mapped(bh)) | ||
51 | continue; | ||
52 | /* | ||
53 | * If it's a fully non-blocking write attempt and we cannot | ||
54 | * lock the buffer then redirty the page. Note that this can | ||
55 | * potentially cause a busy-wait loop from pdflush and kswapd | ||
56 | * activity, but those code paths have their own higher-level | ||
57 | * throttling. | ||
58 | */ | ||
59 | if (wbc->sync_mode != WB_SYNC_NONE || !wbc->nonblocking) { | ||
60 | lock_buffer(bh); | ||
61 | } else if (!trylock_buffer(bh)) { | ||
62 | redirty_page_for_writepage(wbc, page); | ||
63 | continue; | ||
64 | } | ||
65 | if (test_clear_buffer_dirty(bh)) { | ||
66 | mark_buffer_async_write(bh); | ||
67 | } else { | ||
68 | unlock_buffer(bh); | ||
69 | } | ||
70 | } while ((bh = bh->b_this_page) != head); | ||
71 | |||
72 | /* | ||
73 | * The page and its buffers are protected by PageWriteback(), so we can | ||
74 | * drop the bh refcounts early. | ||
75 | */ | ||
76 | BUG_ON(PageWriteback(page)); | ||
77 | set_page_writeback(page); | ||
78 | |||
79 | do { | ||
80 | struct buffer_head *next = bh->b_this_page; | ||
81 | if (buffer_async_write(bh)) { | ||
82 | submit_bh(write_op, bh); | ||
83 | nr_underway++; | ||
84 | } | ||
85 | bh = next; | ||
86 | } while (bh != head); | ||
87 | unlock_page(page); | ||
42 | 88 | ||
43 | static int gfs2_aspace_writepage(struct page *page, | 89 | err = 0; |
44 | struct writeback_control *wbc) | 90 | if (nr_underway == 0) |
45 | { | 91 | end_page_writeback(page); |
46 | return block_write_full_page(page, aspace_get_block, wbc); | 92 | |
93 | return err; | ||
47 | } | 94 | } |
48 | 95 | ||
49 | static const struct address_space_operations aspace_aops = { | 96 | static const struct address_space_operations aspace_aops = { |
@@ -201,16 +248,32 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) | |||
201 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | 248 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, |
202 | struct buffer_head **bhp) | 249 | struct buffer_head **bhp) |
203 | { | 250 | { |
204 | *bhp = gfs2_getbuf(gl, blkno, CREATE); | 251 | struct gfs2_sbd *sdp = gl->gl_sbd; |
205 | if (!buffer_uptodate(*bhp)) { | 252 | struct buffer_head *bh; |
206 | ll_rw_block(READ_META, 1, bhp); | 253 | |
207 | if (flags & DIO_WAIT) { | 254 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) |
208 | int error = gfs2_meta_wait(gl->gl_sbd, *bhp); | 255 | return -EIO; |
209 | if (error) { | 256 | |
210 | brelse(*bhp); | 257 | *bhp = bh = gfs2_getbuf(gl, blkno, CREATE); |
211 | return error; | 258 | |
212 | } | 259 | lock_buffer(bh); |
213 | } | 260 | if (buffer_uptodate(bh)) { |
261 | unlock_buffer(bh); | ||
262 | return 0; | ||
263 | } | ||
264 | bh->b_end_io = end_buffer_read_sync; | ||
265 | get_bh(bh); | ||
266 | submit_bh(READ_SYNC | (1 << BIO_RW_META), bh); | ||
267 | if (!(flags & DIO_WAIT)) | ||
268 | return 0; | ||
269 | |||
270 | wait_on_buffer(bh); | ||
271 | if (unlikely(!buffer_uptodate(bh))) { | ||
272 | struct gfs2_trans *tr = current->journal_info; | ||
273 | if (tr && tr->tr_touched) | ||
274 | gfs2_io_error_bh(sdp, bh); | ||
275 | brelse(bh); | ||
276 | return -EIO; | ||
214 | } | 277 | } |
215 | 278 | ||
216 | return 0; | 279 | return 0; |
@@ -404,7 +467,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | |||
404 | if (buffer_uptodate(first_bh)) | 467 | if (buffer_uptodate(first_bh)) |
405 | goto out; | 468 | goto out; |
406 | if (!buffer_locked(first_bh)) | 469 | if (!buffer_locked(first_bh)) |
407 | ll_rw_block(READ_META, 1, &first_bh); | 470 | ll_rw_block(READ_SYNC | (1 << BIO_RW_META), 1, &first_bh); |
408 | 471 | ||
409 | dblock++; | 472 | dblock++; |
410 | extlen--; | 473 | extlen--; |
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c deleted file mode 100644 index f7e8527a21e0..000000000000 --- a/fs/gfs2/mount.c +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/slab.h> | ||
11 | #include <linux/spinlock.h> | ||
12 | #include <linux/completion.h> | ||
13 | #include <linux/buffer_head.h> | ||
14 | #include <linux/gfs2_ondisk.h> | ||
15 | #include <linux/parser.h> | ||
16 | |||
17 | #include "gfs2.h" | ||
18 | #include "incore.h" | ||
19 | #include "super.h" | ||
20 | #include "sys.h" | ||
21 | #include "util.h" | ||
22 | |||
23 | enum { | ||
24 | Opt_lockproto, | ||
25 | Opt_locktable, | ||
26 | Opt_hostdata, | ||
27 | Opt_spectator, | ||
28 | Opt_ignore_local_fs, | ||
29 | Opt_localflocks, | ||
30 | Opt_localcaching, | ||
31 | Opt_debug, | ||
32 | Opt_nodebug, | ||
33 | Opt_upgrade, | ||
34 | Opt_acl, | ||
35 | Opt_noacl, | ||
36 | Opt_quota_off, | ||
37 | Opt_quota_account, | ||
38 | Opt_quota_on, | ||
39 | Opt_quota, | ||
40 | Opt_noquota, | ||
41 | Opt_suiddir, | ||
42 | Opt_nosuiddir, | ||
43 | Opt_data_writeback, | ||
44 | Opt_data_ordered, | ||
45 | Opt_meta, | ||
46 | Opt_discard, | ||
47 | Opt_nodiscard, | ||
48 | Opt_err, | ||
49 | }; | ||
50 | |||
51 | static const match_table_t tokens = { | ||
52 | {Opt_lockproto, "lockproto=%s"}, | ||
53 | {Opt_locktable, "locktable=%s"}, | ||
54 | {Opt_hostdata, "hostdata=%s"}, | ||
55 | {Opt_spectator, "spectator"}, | ||
56 | {Opt_ignore_local_fs, "ignore_local_fs"}, | ||
57 | {Opt_localflocks, "localflocks"}, | ||
58 | {Opt_localcaching, "localcaching"}, | ||
59 | {Opt_debug, "debug"}, | ||
60 | {Opt_nodebug, "nodebug"}, | ||
61 | {Opt_upgrade, "upgrade"}, | ||
62 | {Opt_acl, "acl"}, | ||
63 | {Opt_noacl, "noacl"}, | ||
64 | {Opt_quota_off, "quota=off"}, | ||
65 | {Opt_quota_account, "quota=account"}, | ||
66 | {Opt_quota_on, "quota=on"}, | ||
67 | {Opt_quota, "quota"}, | ||
68 | {Opt_noquota, "noquota"}, | ||
69 | {Opt_suiddir, "suiddir"}, | ||
70 | {Opt_nosuiddir, "nosuiddir"}, | ||
71 | {Opt_data_writeback, "data=writeback"}, | ||
72 | {Opt_data_ordered, "data=ordered"}, | ||
73 | {Opt_meta, "meta"}, | ||
74 | {Opt_discard, "discard"}, | ||
75 | {Opt_nodiscard, "nodiscard"}, | ||
76 | {Opt_err, NULL} | ||
77 | }; | ||
78 | |||
79 | /** | ||
80 | * gfs2_mount_args - Parse mount options | ||
81 | * @sdp: | ||
82 | * @data: | ||
83 | * | ||
84 | * Return: errno | ||
85 | */ | ||
86 | |||
87 | int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) | ||
88 | { | ||
89 | char *o; | ||
90 | int token; | ||
91 | substring_t tmp[MAX_OPT_ARGS]; | ||
92 | |||
93 | /* Split the options into tokens with the "," character and | ||
94 | process them */ | ||
95 | |||
96 | while (1) { | ||
97 | o = strsep(&options, ","); | ||
98 | if (o == NULL) | ||
99 | break; | ||
100 | if (*o == '\0') | ||
101 | continue; | ||
102 | |||
103 | token = match_token(o, tokens, tmp); | ||
104 | switch (token) { | ||
105 | case Opt_lockproto: | ||
106 | match_strlcpy(args->ar_lockproto, &tmp[0], | ||
107 | GFS2_LOCKNAME_LEN); | ||
108 | break; | ||
109 | case Opt_locktable: | ||
110 | match_strlcpy(args->ar_locktable, &tmp[0], | ||
111 | GFS2_LOCKNAME_LEN); | ||
112 | break; | ||
113 | case Opt_hostdata: | ||
114 | match_strlcpy(args->ar_hostdata, &tmp[0], | ||
115 | GFS2_LOCKNAME_LEN); | ||
116 | break; | ||
117 | case Opt_spectator: | ||
118 | args->ar_spectator = 1; | ||
119 | break; | ||
120 | case Opt_ignore_local_fs: | ||
121 | args->ar_ignore_local_fs = 1; | ||
122 | break; | ||
123 | case Opt_localflocks: | ||
124 | args->ar_localflocks = 1; | ||
125 | break; | ||
126 | case Opt_localcaching: | ||
127 | args->ar_localcaching = 1; | ||
128 | break; | ||
129 | case Opt_debug: | ||
130 | args->ar_debug = 1; | ||
131 | break; | ||
132 | case Opt_nodebug: | ||
133 | args->ar_debug = 0; | ||
134 | break; | ||
135 | case Opt_upgrade: | ||
136 | args->ar_upgrade = 1; | ||
137 | break; | ||
138 | case Opt_acl: | ||
139 | args->ar_posix_acl = 1; | ||
140 | break; | ||
141 | case Opt_noacl: | ||
142 | args->ar_posix_acl = 0; | ||
143 | break; | ||
144 | case Opt_quota_off: | ||
145 | case Opt_noquota: | ||
146 | args->ar_quota = GFS2_QUOTA_OFF; | ||
147 | break; | ||
148 | case Opt_quota_account: | ||
149 | args->ar_quota = GFS2_QUOTA_ACCOUNT; | ||
150 | break; | ||
151 | case Opt_quota_on: | ||
152 | case Opt_quota: | ||
153 | args->ar_quota = GFS2_QUOTA_ON; | ||
154 | break; | ||
155 | case Opt_suiddir: | ||
156 | args->ar_suiddir = 1; | ||
157 | break; | ||
158 | case Opt_nosuiddir: | ||
159 | args->ar_suiddir = 0; | ||
160 | break; | ||
161 | case Opt_data_writeback: | ||
162 | args->ar_data = GFS2_DATA_WRITEBACK; | ||
163 | break; | ||
164 | case Opt_data_ordered: | ||
165 | args->ar_data = GFS2_DATA_ORDERED; | ||
166 | break; | ||
167 | case Opt_meta: | ||
168 | args->ar_meta = 1; | ||
169 | break; | ||
170 | case Opt_discard: | ||
171 | args->ar_discard = 1; | ||
172 | break; | ||
173 | case Opt_nodiscard: | ||
174 | args->ar_discard = 0; | ||
175 | break; | ||
176 | case Opt_err: | ||
177 | default: | ||
178 | fs_info(sdp, "invalid mount option: %s\n", o); | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | } | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
diff --git a/fs/gfs2/ops_address.h b/fs/gfs2/ops_address.h deleted file mode 100644 index 5da21285bba4..000000000000 --- a/fs/gfs2/ops_address.h +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __OPS_ADDRESS_DOT_H__ | ||
11 | #define __OPS_ADDRESS_DOT_H__ | ||
12 | |||
13 | #include <linux/fs.h> | ||
14 | #include <linux/buffer_head.h> | ||
15 | #include <linux/mm.h> | ||
16 | |||
17 | extern int gfs2_releasepage(struct page *page, gfp_t gfp_mask); | ||
18 | extern int gfs2_internal_read(struct gfs2_inode *ip, | ||
19 | struct file_ra_state *ra_state, | ||
20 | char *buf, loff_t *pos, unsigned size); | ||
21 | extern void gfs2_set_aops(struct inode *inode); | ||
22 | |||
23 | #endif /* __OPS_ADDRESS_DOT_H__ */ | ||
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 1ff9473ea753..cc34f271b3e7 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
18 | #include <linux/mount.h> | 18 | #include <linux/mount.h> |
19 | #include <linux/gfs2_ondisk.h> | 19 | #include <linux/gfs2_ondisk.h> |
20 | #include <linux/slow-work.h> | ||
20 | 21 | ||
21 | #include "gfs2.h" | 22 | #include "gfs2.h" |
22 | #include "incore.h" | 23 | #include "incore.h" |
@@ -55,8 +56,6 @@ static void gfs2_tune_init(struct gfs2_tune *gt) | |||
55 | spin_lock_init(>->gt_spin); | 56 | spin_lock_init(>->gt_spin); |
56 | 57 | ||
57 | gt->gt_incore_log_blocks = 1024; | 58 | gt->gt_incore_log_blocks = 1024; |
58 | gt->gt_log_flush_secs = 60; | ||
59 | gt->gt_recoverd_secs = 60; | ||
60 | gt->gt_logd_secs = 1; | 59 | gt->gt_logd_secs = 1; |
61 | gt->gt_quota_simul_sync = 64; | 60 | gt->gt_quota_simul_sync = 64; |
62 | gt->gt_quota_warn_period = 10; | 61 | gt->gt_quota_warn_period = 10; |
@@ -526,11 +525,11 @@ static int init_sb(struct gfs2_sbd *sdp, int silent) | |||
526 | } | 525 | } |
527 | 526 | ||
528 | /* Set up the buffer cache and SB for real */ | 527 | /* Set up the buffer cache and SB for real */ |
529 | if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) { | 528 | if (sdp->sd_sb.sb_bsize < bdev_logical_block_size(sb->s_bdev)) { |
530 | ret = -EINVAL; | 529 | ret = -EINVAL; |
531 | fs_err(sdp, "FS block size (%u) is too small for device " | 530 | fs_err(sdp, "FS block size (%u) is too small for device " |
532 | "block size (%u)\n", | 531 | "block size (%u)\n", |
533 | sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev)); | 532 | sdp->sd_sb.sb_bsize, bdev_logical_block_size(sb->s_bdev)); |
534 | goto out; | 533 | goto out; |
535 | } | 534 | } |
536 | if (sdp->sd_sb.sb_bsize > PAGE_SIZE) { | 535 | if (sdp->sd_sb.sb_bsize > PAGE_SIZE) { |
@@ -676,6 +675,7 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) | |||
676 | break; | 675 | break; |
677 | 676 | ||
678 | INIT_LIST_HEAD(&jd->extent_list); | 677 | INIT_LIST_HEAD(&jd->extent_list); |
678 | slow_work_init(&jd->jd_work, &gfs2_recover_ops); | ||
679 | jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1); | 679 | jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1); |
680 | if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { | 680 | if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { |
681 | if (!jd->jd_inode) | 681 | if (!jd->jd_inode) |
@@ -701,14 +701,13 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) | |||
701 | { | 701 | { |
702 | struct inode *master = sdp->sd_master_dir->d_inode; | 702 | struct inode *master = sdp->sd_master_dir->d_inode; |
703 | struct gfs2_holder ji_gh; | 703 | struct gfs2_holder ji_gh; |
704 | struct task_struct *p; | ||
705 | struct gfs2_inode *ip; | 704 | struct gfs2_inode *ip; |
706 | int jindex = 1; | 705 | int jindex = 1; |
707 | int error = 0; | 706 | int error = 0; |
708 | 707 | ||
709 | if (undo) { | 708 | if (undo) { |
710 | jindex = 0; | 709 | jindex = 0; |
711 | goto fail_recoverd; | 710 | goto fail_jinode_gh; |
712 | } | 711 | } |
713 | 712 | ||
714 | sdp->sd_jindex = gfs2_lookup_simple(master, "jindex"); | 713 | sdp->sd_jindex = gfs2_lookup_simple(master, "jindex"); |
@@ -801,18 +800,8 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) | |||
801 | gfs2_glock_dq_uninit(&ji_gh); | 800 | gfs2_glock_dq_uninit(&ji_gh); |
802 | jindex = 0; | 801 | jindex = 0; |
803 | 802 | ||
804 | p = kthread_run(gfs2_recoverd, sdp, "gfs2_recoverd"); | ||
805 | error = IS_ERR(p); | ||
806 | if (error) { | ||
807 | fs_err(sdp, "can't start recoverd thread: %d\n", error); | ||
808 | goto fail_jinode_gh; | ||
809 | } | ||
810 | sdp->sd_recoverd_process = p; | ||
811 | |||
812 | return 0; | 803 | return 0; |
813 | 804 | ||
814 | fail_recoverd: | ||
815 | kthread_stop(sdp->sd_recoverd_process); | ||
816 | fail_jinode_gh: | 805 | fail_jinode_gh: |
817 | if (!sdp->sd_args.ar_spectator) | 806 | if (!sdp->sd_args.ar_spectator) |
818 | gfs2_glock_dq_uninit(&sdp->sd_jinode_gh); | 807 | gfs2_glock_dq_uninit(&sdp->sd_jinode_gh); |
@@ -1165,6 +1154,7 @@ static int fill_super(struct super_block *sb, void *data, int silent) | |||
1165 | 1154 | ||
1166 | sdp->sd_args.ar_quota = GFS2_QUOTA_DEFAULT; | 1155 | sdp->sd_args.ar_quota = GFS2_QUOTA_DEFAULT; |
1167 | sdp->sd_args.ar_data = GFS2_DATA_DEFAULT; | 1156 | sdp->sd_args.ar_data = GFS2_DATA_DEFAULT; |
1157 | sdp->sd_args.ar_commit = 60; | ||
1168 | 1158 | ||
1169 | error = gfs2_mount_args(sdp, &sdp->sd_args, data); | 1159 | error = gfs2_mount_args(sdp, &sdp->sd_args, data); |
1170 | if (error) { | 1160 | if (error) { |
@@ -1172,8 +1162,10 @@ static int fill_super(struct super_block *sb, void *data, int silent) | |||
1172 | goto fail; | 1162 | goto fail; |
1173 | } | 1163 | } |
1174 | 1164 | ||
1175 | if (sdp->sd_args.ar_spectator) | 1165 | if (sdp->sd_args.ar_spectator) { |
1176 | sb->s_flags |= MS_RDONLY; | 1166 | sb->s_flags |= MS_RDONLY; |
1167 | set_bit(SDF_NORECOVERY, &sdp->sd_flags); | ||
1168 | } | ||
1177 | if (sdp->sd_args.ar_posix_acl) | 1169 | if (sdp->sd_args.ar_posix_acl) |
1178 | sb->s_flags |= MS_POSIXACL; | 1170 | sb->s_flags |= MS_POSIXACL; |
1179 | 1171 | ||
@@ -1191,6 +1183,8 @@ static int fill_super(struct super_block *sb, void *data, int silent) | |||
1191 | GFS2_BASIC_BLOCK_SHIFT; | 1183 | GFS2_BASIC_BLOCK_SHIFT; |
1192 | sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; | 1184 | sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; |
1193 | 1185 | ||
1186 | sdp->sd_tune.gt_log_flush_secs = sdp->sd_args.ar_commit; | ||
1187 | |||
1194 | error = init_names(sdp, silent); | 1188 | error = init_names(sdp, silent); |
1195 | if (error) | 1189 | if (error) |
1196 | goto fail; | 1190 | goto fail; |
@@ -1279,9 +1273,22 @@ static int gfs2_get_sb(struct file_system_type *fs_type, int flags, | |||
1279 | return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); | 1273 | return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); |
1280 | } | 1274 | } |
1281 | 1275 | ||
1282 | static struct super_block *get_gfs2_sb(const char *dev_name) | 1276 | static int test_meta_super(struct super_block *s, void *ptr) |
1277 | { | ||
1278 | struct block_device *bdev = ptr; | ||
1279 | return (bdev == s->s_bdev); | ||
1280 | } | ||
1281 | |||
1282 | static int set_meta_super(struct super_block *s, void *ptr) | ||
1283 | { | 1283 | { |
1284 | struct super_block *sb; | 1284 | return -EINVAL; |
1285 | } | ||
1286 | |||
1287 | static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, | ||
1288 | const char *dev_name, void *data, struct vfsmount *mnt) | ||
1289 | { | ||
1290 | struct super_block *s; | ||
1291 | struct gfs2_sbd *sdp; | ||
1285 | struct path path; | 1292 | struct path path; |
1286 | int error; | 1293 | int error; |
1287 | 1294 | ||
@@ -1289,30 +1296,17 @@ static struct super_block *get_gfs2_sb(const char *dev_name) | |||
1289 | if (error) { | 1296 | if (error) { |
1290 | printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n", | 1297 | printk(KERN_WARNING "GFS2: path_lookup on %s returned error %d\n", |
1291 | dev_name, error); | 1298 | dev_name, error); |
1292 | return NULL; | 1299 | return error; |
1293 | } | 1300 | } |
1294 | sb = path.dentry->d_inode->i_sb; | 1301 | s = sget(&gfs2_fs_type, test_meta_super, set_meta_super, |
1295 | if (sb && (sb->s_type == &gfs2_fs_type)) | 1302 | path.dentry->d_inode->i_sb->s_bdev); |
1296 | atomic_inc(&sb->s_active); | ||
1297 | else | ||
1298 | sb = NULL; | ||
1299 | path_put(&path); | 1303 | path_put(&path); |
1300 | return sb; | 1304 | if (IS_ERR(s)) { |
1301 | } | ||
1302 | |||
1303 | static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, | ||
1304 | const char *dev_name, void *data, struct vfsmount *mnt) | ||
1305 | { | ||
1306 | struct super_block *sb = NULL; | ||
1307 | struct gfs2_sbd *sdp; | ||
1308 | |||
1309 | sb = get_gfs2_sb(dev_name); | ||
1310 | if (!sb) { | ||
1311 | printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n"); | 1305 | printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n"); |
1312 | return -ENOENT; | 1306 | return PTR_ERR(s); |
1313 | } | 1307 | } |
1314 | sdp = sb->s_fs_info; | 1308 | sdp = s->s_fs_info; |
1315 | mnt->mnt_sb = sb; | 1309 | mnt->mnt_sb = s; |
1316 | mnt->mnt_root = dget(sdp->sd_master_dir); | 1310 | mnt->mnt_root = dget(sdp->sd_master_dir); |
1317 | return 0; | 1311 | return 0; |
1318 | } | 1312 | } |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 1c70fa5168d6..f8bd20baf99c 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -262,6 +262,44 @@ out_parent: | |||
262 | return error; | 262 | return error; |
263 | } | 263 | } |
264 | 264 | ||
265 | /* | ||
266 | * gfs2_unlink_ok - check to see that a inode is still in a directory | ||
267 | * @dip: the directory | ||
268 | * @name: the name of the file | ||
269 | * @ip: the inode | ||
270 | * | ||
271 | * Assumes that the lock on (at least) @dip is held. | ||
272 | * | ||
273 | * Returns: 0 if the parent/child relationship is correct, errno if it isn't | ||
274 | */ | ||
275 | |||
276 | static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | ||
277 | const struct gfs2_inode *ip) | ||
278 | { | ||
279 | int error; | ||
280 | |||
281 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | ||
282 | return -EPERM; | ||
283 | |||
284 | if ((dip->i_inode.i_mode & S_ISVTX) && | ||
285 | dip->i_inode.i_uid != current_fsuid() && | ||
286 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) | ||
287 | return -EPERM; | ||
288 | |||
289 | if (IS_APPEND(&dip->i_inode)) | ||
290 | return -EPERM; | ||
291 | |||
292 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); | ||
293 | if (error) | ||
294 | return error; | ||
295 | |||
296 | error = gfs2_dir_check(&dip->i_inode, name, ip); | ||
297 | if (error) | ||
298 | return error; | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
265 | /** | 303 | /** |
266 | * gfs2_unlink - Unlink a file | 304 | * gfs2_unlink - Unlink a file |
267 | * @dir: The inode of the directory containing the file to unlink | 305 | * @dir: The inode of the directory containing the file to unlink |
@@ -473,6 +511,59 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
473 | } | 511 | } |
474 | 512 | ||
475 | /** | 513 | /** |
514 | * gfs2_rmdiri - Remove a directory | ||
515 | * @dip: The parent directory of the directory to be removed | ||
516 | * @name: The name of the directory to be removed | ||
517 | * @ip: The GFS2 inode of the directory to be removed | ||
518 | * | ||
519 | * Assumes Glocks on dip and ip are held | ||
520 | * | ||
521 | * Returns: errno | ||
522 | */ | ||
523 | |||
524 | static int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | ||
525 | struct gfs2_inode *ip) | ||
526 | { | ||
527 | struct qstr dotname; | ||
528 | int error; | ||
529 | |||
530 | if (ip->i_entries != 2) { | ||
531 | if (gfs2_consist_inode(ip)) | ||
532 | gfs2_dinode_print(ip); | ||
533 | return -EIO; | ||
534 | } | ||
535 | |||
536 | error = gfs2_dir_del(dip, name); | ||
537 | if (error) | ||
538 | return error; | ||
539 | |||
540 | error = gfs2_change_nlink(dip, -1); | ||
541 | if (error) | ||
542 | return error; | ||
543 | |||
544 | gfs2_str2qstr(&dotname, "."); | ||
545 | error = gfs2_dir_del(ip, &dotname); | ||
546 | if (error) | ||
547 | return error; | ||
548 | |||
549 | gfs2_str2qstr(&dotname, ".."); | ||
550 | error = gfs2_dir_del(ip, &dotname); | ||
551 | if (error) | ||
552 | return error; | ||
553 | |||
554 | /* It looks odd, but it really should be done twice */ | ||
555 | error = gfs2_change_nlink(ip, -1); | ||
556 | if (error) | ||
557 | return error; | ||
558 | |||
559 | error = gfs2_change_nlink(ip, -1); | ||
560 | if (error) | ||
561 | return error; | ||
562 | |||
563 | return error; | ||
564 | } | ||
565 | |||
566 | /** | ||
476 | * gfs2_rmdir - Remove a directory | 567 | * gfs2_rmdir - Remove a directory |
477 | * @dir: The parent directory of the directory to be removed | 568 | * @dir: The parent directory of the directory to be removed |
478 | * @dentry: The dentry of the directory to remove | 569 | * @dentry: The dentry of the directory to remove |
@@ -885,6 +976,61 @@ out: | |||
885 | } | 976 | } |
886 | 977 | ||
887 | /** | 978 | /** |
979 | * gfs2_readlinki - return the contents of a symlink | ||
980 | * @ip: the symlink's inode | ||
981 | * @buf: a pointer to the buffer to be filled | ||
982 | * @len: a pointer to the length of @buf | ||
983 | * | ||
984 | * If @buf is too small, a piece of memory is kmalloc()ed and needs | ||
985 | * to be freed by the caller. | ||
986 | * | ||
987 | * Returns: errno | ||
988 | */ | ||
989 | |||
990 | static int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | ||
991 | { | ||
992 | struct gfs2_holder i_gh; | ||
993 | struct buffer_head *dibh; | ||
994 | unsigned int x; | ||
995 | int error; | ||
996 | |||
997 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); | ||
998 | error = gfs2_glock_nq(&i_gh); | ||
999 | if (error) { | ||
1000 | gfs2_holder_uninit(&i_gh); | ||
1001 | return error; | ||
1002 | } | ||
1003 | |||
1004 | if (!ip->i_disksize) { | ||
1005 | gfs2_consist_inode(ip); | ||
1006 | error = -EIO; | ||
1007 | goto out; | ||
1008 | } | ||
1009 | |||
1010 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
1011 | if (error) | ||
1012 | goto out; | ||
1013 | |||
1014 | x = ip->i_disksize + 1; | ||
1015 | if (x > *len) { | ||
1016 | *buf = kmalloc(x, GFP_NOFS); | ||
1017 | if (!*buf) { | ||
1018 | error = -ENOMEM; | ||
1019 | goto out_brelse; | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | memcpy(*buf, dibh->b_data + sizeof(struct gfs2_dinode), x); | ||
1024 | *len = x; | ||
1025 | |||
1026 | out_brelse: | ||
1027 | brelse(dibh); | ||
1028 | out: | ||
1029 | gfs2_glock_dq_uninit(&i_gh); | ||
1030 | return error; | ||
1031 | } | ||
1032 | |||
1033 | /** | ||
888 | * gfs2_readlink - Read the value of a symlink | 1034 | * gfs2_readlink - Read the value of a symlink |
889 | * @dentry: the symlink | 1035 | * @dentry: the symlink |
890 | * @buf: the buffer to read the symlink data into | 1036 | * @buf: the buffer to read the symlink data into |
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c deleted file mode 100644 index 458019569dcb..000000000000 --- a/fs/gfs2/ops_super.c +++ /dev/null | |||
@@ -1,723 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/sched.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/completion.h> | ||
14 | #include <linux/buffer_head.h> | ||
15 | #include <linux/statfs.h> | ||
16 | #include <linux/seq_file.h> | ||
17 | #include <linux/mount.h> | ||
18 | #include <linux/kthread.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/gfs2_ondisk.h> | ||
21 | #include <linux/crc32.h> | ||
22 | #include <linux/time.h> | ||
23 | |||
24 | #include "gfs2.h" | ||
25 | #include "incore.h" | ||
26 | #include "glock.h" | ||
27 | #include "inode.h" | ||
28 | #include "log.h" | ||
29 | #include "quota.h" | ||
30 | #include "recovery.h" | ||
31 | #include "rgrp.h" | ||
32 | #include "super.h" | ||
33 | #include "sys.h" | ||
34 | #include "util.h" | ||
35 | #include "trans.h" | ||
36 | #include "dir.h" | ||
37 | #include "eattr.h" | ||
38 | #include "bmap.h" | ||
39 | #include "meta_io.h" | ||
40 | |||
41 | #define args_neq(a1, a2, x) ((a1)->ar_##x != (a2)->ar_##x) | ||
42 | |||
43 | /** | ||
44 | * gfs2_write_inode - Make sure the inode is stable on the disk | ||
45 | * @inode: The inode | ||
46 | * @sync: synchronous write flag | ||
47 | * | ||
48 | * Returns: errno | ||
49 | */ | ||
50 | |||
51 | static int gfs2_write_inode(struct inode *inode, int sync) | ||
52 | { | ||
53 | struct gfs2_inode *ip = GFS2_I(inode); | ||
54 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
55 | struct gfs2_holder gh; | ||
56 | struct buffer_head *bh; | ||
57 | struct timespec atime; | ||
58 | struct gfs2_dinode *di; | ||
59 | int ret = 0; | ||
60 | |||
61 | /* Check this is a "normal" inode, etc */ | ||
62 | if (!test_bit(GIF_USER, &ip->i_flags) || | ||
63 | (current->flags & PF_MEMALLOC)) | ||
64 | return 0; | ||
65 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
66 | if (ret) | ||
67 | goto do_flush; | ||
68 | ret = gfs2_trans_begin(sdp, RES_DINODE, 0); | ||
69 | if (ret) | ||
70 | goto do_unlock; | ||
71 | ret = gfs2_meta_inode_buffer(ip, &bh); | ||
72 | if (ret == 0) { | ||
73 | di = (struct gfs2_dinode *)bh->b_data; | ||
74 | atime.tv_sec = be64_to_cpu(di->di_atime); | ||
75 | atime.tv_nsec = be32_to_cpu(di->di_atime_nsec); | ||
76 | if (timespec_compare(&inode->i_atime, &atime) > 0) { | ||
77 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | ||
78 | gfs2_dinode_out(ip, bh->b_data); | ||
79 | } | ||
80 | brelse(bh); | ||
81 | } | ||
82 | gfs2_trans_end(sdp); | ||
83 | do_unlock: | ||
84 | gfs2_glock_dq_uninit(&gh); | ||
85 | do_flush: | ||
86 | if (sync != 0) | ||
87 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | ||
88 | return ret; | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * gfs2_make_fs_ro - Turn a Read-Write FS into a Read-Only one | ||
93 | * @sdp: the filesystem | ||
94 | * | ||
95 | * Returns: errno | ||
96 | */ | ||
97 | |||
98 | static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | ||
99 | { | ||
100 | struct gfs2_holder t_gh; | ||
101 | int error; | ||
102 | |||
103 | gfs2_quota_sync(sdp); | ||
104 | gfs2_statfs_sync(sdp); | ||
105 | |||
106 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, | ||
107 | &t_gh); | ||
108 | if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
109 | return error; | ||
110 | |||
111 | gfs2_meta_syncfs(sdp); | ||
112 | gfs2_log_shutdown(sdp); | ||
113 | |||
114 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | ||
115 | |||
116 | if (t_gh.gh_gl) | ||
117 | gfs2_glock_dq_uninit(&t_gh); | ||
118 | |||
119 | gfs2_quota_cleanup(sdp); | ||
120 | |||
121 | return error; | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * gfs2_put_super - Unmount the filesystem | ||
126 | * @sb: The VFS superblock | ||
127 | * | ||
128 | */ | ||
129 | |||
130 | static void gfs2_put_super(struct super_block *sb) | ||
131 | { | ||
132 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
133 | int error; | ||
134 | |||
135 | /* Unfreeze the filesystem, if we need to */ | ||
136 | |||
137 | mutex_lock(&sdp->sd_freeze_lock); | ||
138 | if (sdp->sd_freeze_count) | ||
139 | gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); | ||
140 | mutex_unlock(&sdp->sd_freeze_lock); | ||
141 | |||
142 | kthread_stop(sdp->sd_quotad_process); | ||
143 | kthread_stop(sdp->sd_logd_process); | ||
144 | kthread_stop(sdp->sd_recoverd_process); | ||
145 | |||
146 | if (!(sb->s_flags & MS_RDONLY)) { | ||
147 | error = gfs2_make_fs_ro(sdp); | ||
148 | if (error) | ||
149 | gfs2_io_error(sdp); | ||
150 | } | ||
151 | /* At this point, we're through modifying the disk */ | ||
152 | |||
153 | /* Release stuff */ | ||
154 | |||
155 | iput(sdp->sd_jindex); | ||
156 | iput(sdp->sd_inum_inode); | ||
157 | iput(sdp->sd_statfs_inode); | ||
158 | iput(sdp->sd_rindex); | ||
159 | iput(sdp->sd_quota_inode); | ||
160 | |||
161 | gfs2_glock_put(sdp->sd_rename_gl); | ||
162 | gfs2_glock_put(sdp->sd_trans_gl); | ||
163 | |||
164 | if (!sdp->sd_args.ar_spectator) { | ||
165 | gfs2_glock_dq_uninit(&sdp->sd_journal_gh); | ||
166 | gfs2_glock_dq_uninit(&sdp->sd_jinode_gh); | ||
167 | gfs2_glock_dq_uninit(&sdp->sd_ir_gh); | ||
168 | gfs2_glock_dq_uninit(&sdp->sd_sc_gh); | ||
169 | gfs2_glock_dq_uninit(&sdp->sd_qc_gh); | ||
170 | iput(sdp->sd_ir_inode); | ||
171 | iput(sdp->sd_sc_inode); | ||
172 | iput(sdp->sd_qc_inode); | ||
173 | } | ||
174 | |||
175 | gfs2_glock_dq_uninit(&sdp->sd_live_gh); | ||
176 | gfs2_clear_rgrpd(sdp); | ||
177 | gfs2_jindex_free(sdp); | ||
178 | /* Take apart glock structures and buffer lists */ | ||
179 | gfs2_gl_hash_clear(sdp); | ||
180 | /* Unmount the locking protocol */ | ||
181 | gfs2_lm_unmount(sdp); | ||
182 | |||
183 | /* At this point, we're through participating in the lockspace */ | ||
184 | gfs2_sys_fs_del(sdp); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * gfs2_write_super | ||
189 | * @sb: the superblock | ||
190 | * | ||
191 | */ | ||
192 | |||
193 | static void gfs2_write_super(struct super_block *sb) | ||
194 | { | ||
195 | sb->s_dirt = 0; | ||
196 | } | ||
197 | |||
198 | /** | ||
199 | * gfs2_sync_fs - sync the filesystem | ||
200 | * @sb: the superblock | ||
201 | * | ||
202 | * Flushes the log to disk. | ||
203 | */ | ||
204 | |||
205 | static int gfs2_sync_fs(struct super_block *sb, int wait) | ||
206 | { | ||
207 | sb->s_dirt = 0; | ||
208 | if (wait && sb->s_fs_info) | ||
209 | gfs2_log_flush(sb->s_fs_info, NULL); | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | /** | ||
214 | * gfs2_freeze - prevent further writes to the filesystem | ||
215 | * @sb: the VFS structure for the filesystem | ||
216 | * | ||
217 | */ | ||
218 | |||
219 | static int gfs2_freeze(struct super_block *sb) | ||
220 | { | ||
221 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
222 | int error; | ||
223 | |||
224 | if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
225 | return -EINVAL; | ||
226 | |||
227 | for (;;) { | ||
228 | error = gfs2_freeze_fs(sdp); | ||
229 | if (!error) | ||
230 | break; | ||
231 | |||
232 | switch (error) { | ||
233 | case -EBUSY: | ||
234 | fs_err(sdp, "waiting for recovery before freeze\n"); | ||
235 | break; | ||
236 | |||
237 | default: | ||
238 | fs_err(sdp, "error freezing FS: %d\n", error); | ||
239 | break; | ||
240 | } | ||
241 | |||
242 | fs_err(sdp, "retrying...\n"); | ||
243 | msleep(1000); | ||
244 | } | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | /** | ||
249 | * gfs2_unfreeze - reallow writes to the filesystem | ||
250 | * @sb: the VFS structure for the filesystem | ||
251 | * | ||
252 | */ | ||
253 | |||
254 | static int gfs2_unfreeze(struct super_block *sb) | ||
255 | { | ||
256 | gfs2_unfreeze_fs(sb->s_fs_info); | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * statfs_fill - fill in the sg for a given RG | ||
262 | * @rgd: the RG | ||
263 | * @sc: the sc structure | ||
264 | * | ||
265 | * Returns: 0 on success, -ESTALE if the LVB is invalid | ||
266 | */ | ||
267 | |||
268 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | ||
269 | struct gfs2_statfs_change_host *sc) | ||
270 | { | ||
271 | gfs2_rgrp_verify(rgd); | ||
272 | sc->sc_total += rgd->rd_data; | ||
273 | sc->sc_free += rgd->rd_free; | ||
274 | sc->sc_dinodes += rgd->rd_dinodes; | ||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | /** | ||
279 | * gfs2_statfs_slow - Stat a filesystem using asynchronous locking | ||
280 | * @sdp: the filesystem | ||
281 | * @sc: the sc info that will be returned | ||
282 | * | ||
283 | * Any error (other than a signal) will cause this routine to fall back | ||
284 | * to the synchronous version. | ||
285 | * | ||
286 | * FIXME: This really shouldn't busy wait like this. | ||
287 | * | ||
288 | * Returns: errno | ||
289 | */ | ||
290 | |||
291 | static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
292 | { | ||
293 | struct gfs2_holder ri_gh; | ||
294 | struct gfs2_rgrpd *rgd_next; | ||
295 | struct gfs2_holder *gha, *gh; | ||
296 | unsigned int slots = 64; | ||
297 | unsigned int x; | ||
298 | int done; | ||
299 | int error = 0, err; | ||
300 | |||
301 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); | ||
302 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | ||
303 | if (!gha) | ||
304 | return -ENOMEM; | ||
305 | |||
306 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
307 | if (error) | ||
308 | goto out; | ||
309 | |||
310 | rgd_next = gfs2_rgrpd_get_first(sdp); | ||
311 | |||
312 | for (;;) { | ||
313 | done = 1; | ||
314 | |||
315 | for (x = 0; x < slots; x++) { | ||
316 | gh = gha + x; | ||
317 | |||
318 | if (gh->gh_gl && gfs2_glock_poll(gh)) { | ||
319 | err = gfs2_glock_wait(gh); | ||
320 | if (err) { | ||
321 | gfs2_holder_uninit(gh); | ||
322 | error = err; | ||
323 | } else { | ||
324 | if (!error) | ||
325 | error = statfs_slow_fill( | ||
326 | gh->gh_gl->gl_object, sc); | ||
327 | gfs2_glock_dq_uninit(gh); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | if (gh->gh_gl) | ||
332 | done = 0; | ||
333 | else if (rgd_next && !error) { | ||
334 | error = gfs2_glock_nq_init(rgd_next->rd_gl, | ||
335 | LM_ST_SHARED, | ||
336 | GL_ASYNC, | ||
337 | gh); | ||
338 | rgd_next = gfs2_rgrpd_get_next(rgd_next); | ||
339 | done = 0; | ||
340 | } | ||
341 | |||
342 | if (signal_pending(current)) | ||
343 | error = -ERESTARTSYS; | ||
344 | } | ||
345 | |||
346 | if (done) | ||
347 | break; | ||
348 | |||
349 | yield(); | ||
350 | } | ||
351 | |||
352 | gfs2_glock_dq_uninit(&ri_gh); | ||
353 | |||
354 | out: | ||
355 | kfree(gha); | ||
356 | return error; | ||
357 | } | ||
358 | |||
359 | /** | ||
360 | * gfs2_statfs_i - Do a statfs | ||
361 | * @sdp: the filesystem | ||
362 | * @sg: the sg structure | ||
363 | * | ||
364 | * Returns: errno | ||
365 | */ | ||
366 | |||
367 | static int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
368 | { | ||
369 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
370 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | ||
371 | |||
372 | spin_lock(&sdp->sd_statfs_spin); | ||
373 | |||
374 | *sc = *m_sc; | ||
375 | sc->sc_total += l_sc->sc_total; | ||
376 | sc->sc_free += l_sc->sc_free; | ||
377 | sc->sc_dinodes += l_sc->sc_dinodes; | ||
378 | |||
379 | spin_unlock(&sdp->sd_statfs_spin); | ||
380 | |||
381 | if (sc->sc_free < 0) | ||
382 | sc->sc_free = 0; | ||
383 | if (sc->sc_free > sc->sc_total) | ||
384 | sc->sc_free = sc->sc_total; | ||
385 | if (sc->sc_dinodes < 0) | ||
386 | sc->sc_dinodes = 0; | ||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * gfs2_statfs - Gather and return stats about the filesystem | ||
393 | * @sb: The superblock | ||
394 | * @statfsbuf: The buffer | ||
395 | * | ||
396 | * Returns: 0 on success or error code | ||
397 | */ | ||
398 | |||
399 | static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | ||
400 | { | ||
401 | struct super_block *sb = dentry->d_inode->i_sb; | ||
402 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
403 | struct gfs2_statfs_change_host sc; | ||
404 | int error; | ||
405 | |||
406 | if (gfs2_tune_get(sdp, gt_statfs_slow)) | ||
407 | error = gfs2_statfs_slow(sdp, &sc); | ||
408 | else | ||
409 | error = gfs2_statfs_i(sdp, &sc); | ||
410 | |||
411 | if (error) | ||
412 | return error; | ||
413 | |||
414 | buf->f_type = GFS2_MAGIC; | ||
415 | buf->f_bsize = sdp->sd_sb.sb_bsize; | ||
416 | buf->f_blocks = sc.sc_total; | ||
417 | buf->f_bfree = sc.sc_free; | ||
418 | buf->f_bavail = sc.sc_free; | ||
419 | buf->f_files = sc.sc_dinodes + sc.sc_free; | ||
420 | buf->f_ffree = sc.sc_free; | ||
421 | buf->f_namelen = GFS2_FNAMESIZE; | ||
422 | |||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * gfs2_remount_fs - called when the FS is remounted | ||
428 | * @sb: the filesystem | ||
429 | * @flags: the remount flags | ||
430 | * @data: extra data passed in (not used right now) | ||
431 | * | ||
432 | * Returns: errno | ||
433 | */ | ||
434 | |||
435 | static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | ||
436 | { | ||
437 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
438 | struct gfs2_args args = sdp->sd_args; /* Default to current settings */ | ||
439 | int error; | ||
440 | |||
441 | error = gfs2_mount_args(sdp, &args, data); | ||
442 | if (error) | ||
443 | return error; | ||
444 | |||
445 | /* Not allowed to change locking details */ | ||
446 | if (strcmp(args.ar_lockproto, sdp->sd_args.ar_lockproto) || | ||
447 | strcmp(args.ar_locktable, sdp->sd_args.ar_locktable) || | ||
448 | strcmp(args.ar_hostdata, sdp->sd_args.ar_hostdata)) | ||
449 | return -EINVAL; | ||
450 | |||
451 | /* Some flags must not be changed */ | ||
452 | if (args_neq(&args, &sdp->sd_args, spectator) || | ||
453 | args_neq(&args, &sdp->sd_args, ignore_local_fs) || | ||
454 | args_neq(&args, &sdp->sd_args, localflocks) || | ||
455 | args_neq(&args, &sdp->sd_args, localcaching) || | ||
456 | args_neq(&args, &sdp->sd_args, meta)) | ||
457 | return -EINVAL; | ||
458 | |||
459 | if (sdp->sd_args.ar_spectator) | ||
460 | *flags |= MS_RDONLY; | ||
461 | |||
462 | if ((sb->s_flags ^ *flags) & MS_RDONLY) { | ||
463 | if (*flags & MS_RDONLY) | ||
464 | error = gfs2_make_fs_ro(sdp); | ||
465 | else | ||
466 | error = gfs2_make_fs_rw(sdp); | ||
467 | if (error) | ||
468 | return error; | ||
469 | } | ||
470 | |||
471 | sdp->sd_args = args; | ||
472 | if (sdp->sd_args.ar_posix_acl) | ||
473 | sb->s_flags |= MS_POSIXACL; | ||
474 | else | ||
475 | sb->s_flags &= ~MS_POSIXACL; | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | /** | ||
480 | * gfs2_drop_inode - Drop an inode (test for remote unlink) | ||
481 | * @inode: The inode to drop | ||
482 | * | ||
483 | * If we've received a callback on an iopen lock then its because a | ||
484 | * remote node tried to deallocate the inode but failed due to this node | ||
485 | * still having the inode open. Here we mark the link count zero | ||
486 | * since we know that it must have reached zero if the GLF_DEMOTE flag | ||
487 | * is set on the iopen glock. If we didn't do a disk read since the | ||
488 | * remote node removed the final link then we might otherwise miss | ||
489 | * this event. This check ensures that this node will deallocate the | ||
490 | * inode's blocks, or alternatively pass the baton on to another | ||
491 | * node for later deallocation. | ||
492 | */ | ||
493 | |||
494 | static void gfs2_drop_inode(struct inode *inode) | ||
495 | { | ||
496 | struct gfs2_inode *ip = GFS2_I(inode); | ||
497 | |||
498 | if (test_bit(GIF_USER, &ip->i_flags) && inode->i_nlink) { | ||
499 | struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl; | ||
500 | if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags)) | ||
501 | clear_nlink(inode); | ||
502 | } | ||
503 | generic_drop_inode(inode); | ||
504 | } | ||
505 | |||
506 | /** | ||
507 | * gfs2_clear_inode - Deallocate an inode when VFS is done with it | ||
508 | * @inode: The VFS inode | ||
509 | * | ||
510 | */ | ||
511 | |||
512 | static void gfs2_clear_inode(struct inode *inode) | ||
513 | { | ||
514 | struct gfs2_inode *ip = GFS2_I(inode); | ||
515 | |||
516 | /* This tells us its a "real" inode and not one which only | ||
517 | * serves to contain an address space (see rgrp.c, meta_io.c) | ||
518 | * which therefore doesn't have its own glocks. | ||
519 | */ | ||
520 | if (test_bit(GIF_USER, &ip->i_flags)) { | ||
521 | ip->i_gl->gl_object = NULL; | ||
522 | gfs2_glock_put(ip->i_gl); | ||
523 | ip->i_gl = NULL; | ||
524 | if (ip->i_iopen_gh.gh_gl) { | ||
525 | ip->i_iopen_gh.gh_gl->gl_object = NULL; | ||
526 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | ||
527 | } | ||
528 | } | ||
529 | } | ||
530 | |||
531 | static int is_ancestor(const struct dentry *d1, const struct dentry *d2) | ||
532 | { | ||
533 | do { | ||
534 | if (d1 == d2) | ||
535 | return 1; | ||
536 | d1 = d1->d_parent; | ||
537 | } while (!IS_ROOT(d1)); | ||
538 | return 0; | ||
539 | } | ||
540 | |||
541 | /** | ||
542 | * gfs2_show_options - Show mount options for /proc/mounts | ||
543 | * @s: seq_file structure | ||
544 | * @mnt: vfsmount | ||
545 | * | ||
546 | * Returns: 0 on success or error code | ||
547 | */ | ||
548 | |||
549 | static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | ||
550 | { | ||
551 | struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; | ||
552 | struct gfs2_args *args = &sdp->sd_args; | ||
553 | |||
554 | if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) | ||
555 | seq_printf(s, ",meta"); | ||
556 | if (args->ar_lockproto[0]) | ||
557 | seq_printf(s, ",lockproto=%s", args->ar_lockproto); | ||
558 | if (args->ar_locktable[0]) | ||
559 | seq_printf(s, ",locktable=%s", args->ar_locktable); | ||
560 | if (args->ar_hostdata[0]) | ||
561 | seq_printf(s, ",hostdata=%s", args->ar_hostdata); | ||
562 | if (args->ar_spectator) | ||
563 | seq_printf(s, ",spectator"); | ||
564 | if (args->ar_ignore_local_fs) | ||
565 | seq_printf(s, ",ignore_local_fs"); | ||
566 | if (args->ar_localflocks) | ||
567 | seq_printf(s, ",localflocks"); | ||
568 | if (args->ar_localcaching) | ||
569 | seq_printf(s, ",localcaching"); | ||
570 | if (args->ar_debug) | ||
571 | seq_printf(s, ",debug"); | ||
572 | if (args->ar_upgrade) | ||
573 | seq_printf(s, ",upgrade"); | ||
574 | if (args->ar_posix_acl) | ||
575 | seq_printf(s, ",acl"); | ||
576 | if (args->ar_quota != GFS2_QUOTA_DEFAULT) { | ||
577 | char *state; | ||
578 | switch (args->ar_quota) { | ||
579 | case GFS2_QUOTA_OFF: | ||
580 | state = "off"; | ||
581 | break; | ||
582 | case GFS2_QUOTA_ACCOUNT: | ||
583 | state = "account"; | ||
584 | break; | ||
585 | case GFS2_QUOTA_ON: | ||
586 | state = "on"; | ||
587 | break; | ||
588 | default: | ||
589 | state = "unknown"; | ||
590 | break; | ||
591 | } | ||
592 | seq_printf(s, ",quota=%s", state); | ||
593 | } | ||
594 | if (args->ar_suiddir) | ||
595 | seq_printf(s, ",suiddir"); | ||
596 | if (args->ar_data != GFS2_DATA_DEFAULT) { | ||
597 | char *state; | ||
598 | switch (args->ar_data) { | ||
599 | case GFS2_DATA_WRITEBACK: | ||
600 | state = "writeback"; | ||
601 | break; | ||
602 | case GFS2_DATA_ORDERED: | ||
603 | state = "ordered"; | ||
604 | break; | ||
605 | default: | ||
606 | state = "unknown"; | ||
607 | break; | ||
608 | } | ||
609 | seq_printf(s, ",data=%s", state); | ||
610 | } | ||
611 | if (args->ar_discard) | ||
612 | seq_printf(s, ",discard"); | ||
613 | |||
614 | return 0; | ||
615 | } | ||
616 | |||
617 | /* | ||
618 | * We have to (at the moment) hold the inodes main lock to cover | ||
619 | * the gap between unlocking the shared lock on the iopen lock and | ||
620 | * taking the exclusive lock. I'd rather do a shared -> exclusive | ||
621 | * conversion on the iopen lock, but we can change that later. This | ||
622 | * is safe, just less efficient. | ||
623 | */ | ||
624 | |||
625 | static void gfs2_delete_inode(struct inode *inode) | ||
626 | { | ||
627 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | ||
628 | struct gfs2_inode *ip = GFS2_I(inode); | ||
629 | struct gfs2_holder gh; | ||
630 | int error; | ||
631 | |||
632 | if (!test_bit(GIF_USER, &ip->i_flags)) | ||
633 | goto out; | ||
634 | |||
635 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
636 | if (unlikely(error)) { | ||
637 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | ||
638 | goto out; | ||
639 | } | ||
640 | |||
641 | gfs2_glock_dq_wait(&ip->i_iopen_gh); | ||
642 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); | ||
643 | error = gfs2_glock_nq(&ip->i_iopen_gh); | ||
644 | if (error) | ||
645 | goto out_truncate; | ||
646 | |||
647 | if (S_ISDIR(inode->i_mode) && | ||
648 | (ip->i_diskflags & GFS2_DIF_EXHASH)) { | ||
649 | error = gfs2_dir_exhash_dealloc(ip); | ||
650 | if (error) | ||
651 | goto out_unlock; | ||
652 | } | ||
653 | |||
654 | if (ip->i_eattr) { | ||
655 | error = gfs2_ea_dealloc(ip); | ||
656 | if (error) | ||
657 | goto out_unlock; | ||
658 | } | ||
659 | |||
660 | if (!gfs2_is_stuffed(ip)) { | ||
661 | error = gfs2_file_dealloc(ip); | ||
662 | if (error) | ||
663 | goto out_unlock; | ||
664 | } | ||
665 | |||
666 | error = gfs2_dinode_dealloc(ip); | ||
667 | if (error) | ||
668 | goto out_unlock; | ||
669 | |||
670 | out_truncate: | ||
671 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | ||
672 | if (error) | ||
673 | goto out_unlock; | ||
674 | /* Needs to be done before glock release & also in a transaction */ | ||
675 | truncate_inode_pages(&inode->i_data, 0); | ||
676 | gfs2_trans_end(sdp); | ||
677 | |||
678 | out_unlock: | ||
679 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) | ||
680 | gfs2_glock_dq(&ip->i_iopen_gh); | ||
681 | gfs2_holder_uninit(&ip->i_iopen_gh); | ||
682 | gfs2_glock_dq_uninit(&gh); | ||
683 | if (error && error != GLR_TRYFAILED) | ||
684 | fs_warn(sdp, "gfs2_delete_inode: %d\n", error); | ||
685 | out: | ||
686 | truncate_inode_pages(&inode->i_data, 0); | ||
687 | clear_inode(inode); | ||
688 | } | ||
689 | |||
690 | static struct inode *gfs2_alloc_inode(struct super_block *sb) | ||
691 | { | ||
692 | struct gfs2_inode *ip; | ||
693 | |||
694 | ip = kmem_cache_alloc(gfs2_inode_cachep, GFP_KERNEL); | ||
695 | if (ip) { | ||
696 | ip->i_flags = 0; | ||
697 | ip->i_gl = NULL; | ||
698 | } | ||
699 | return &ip->i_inode; | ||
700 | } | ||
701 | |||
702 | static void gfs2_destroy_inode(struct inode *inode) | ||
703 | { | ||
704 | kmem_cache_free(gfs2_inode_cachep, inode); | ||
705 | } | ||
706 | |||
707 | const struct super_operations gfs2_super_ops = { | ||
708 | .alloc_inode = gfs2_alloc_inode, | ||
709 | .destroy_inode = gfs2_destroy_inode, | ||
710 | .write_inode = gfs2_write_inode, | ||
711 | .delete_inode = gfs2_delete_inode, | ||
712 | .put_super = gfs2_put_super, | ||
713 | .write_super = gfs2_write_super, | ||
714 | .sync_fs = gfs2_sync_fs, | ||
715 | .freeze_fs = gfs2_freeze, | ||
716 | .unfreeze_fs = gfs2_unfreeze, | ||
717 | .statfs = gfs2_statfs, | ||
718 | .remount_fs = gfs2_remount_fs, | ||
719 | .clear_inode = gfs2_clear_inode, | ||
720 | .drop_inode = gfs2_drop_inode, | ||
721 | .show_options = gfs2_show_options, | ||
722 | }; | ||
723 | |||
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 152e6c4a0dca..2e9b9326bfc9 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -60,7 +60,6 @@ | |||
60 | #include "super.h" | 60 | #include "super.h" |
61 | #include "trans.h" | 61 | #include "trans.h" |
62 | #include "inode.h" | 62 | #include "inode.h" |
63 | #include "ops_address.h" | ||
64 | #include "util.h" | 63 | #include "util.h" |
65 | 64 | ||
66 | #define QUOTA_USER 1 | 65 | #define QUOTA_USER 1 |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 247e8f7d6b3d..59d2695509d3 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -13,8 +13,7 @@ | |||
13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/gfs2_ondisk.h> | 14 | #include <linux/gfs2_ondisk.h> |
15 | #include <linux/crc32.h> | 15 | #include <linux/crc32.h> |
16 | #include <linux/kthread.h> | 16 | #include <linux/slow-work.h> |
17 | #include <linux/freezer.h> | ||
18 | 17 | ||
19 | #include "gfs2.h" | 18 | #include "gfs2.h" |
20 | #include "incore.h" | 19 | #include "incore.h" |
@@ -441,18 +440,25 @@ static void gfs2_recovery_done(struct gfs2_sbd *sdp, unsigned int jid, | |||
441 | kobject_uevent_env(&sdp->sd_kobj, KOBJ_CHANGE, envp); | 440 | kobject_uevent_env(&sdp->sd_kobj, KOBJ_CHANGE, envp); |
442 | } | 441 | } |
443 | 442 | ||
444 | /** | 443 | static int gfs2_recover_get_ref(struct slow_work *work) |
445 | * gfs2_recover_journal - recover a given journal | 444 | { |
446 | * @jd: the struct gfs2_jdesc describing the journal | 445 | struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work); |
447 | * | 446 | if (test_and_set_bit(JDF_RECOVERY, &jd->jd_flags)) |
448 | * Acquire the journal's lock, check to see if the journal is clean, and | 447 | return -EBUSY; |
449 | * do recovery if necessary. | 448 | return 0; |
450 | * | 449 | } |
451 | * Returns: errno | ||
452 | */ | ||
453 | 450 | ||
454 | int gfs2_recover_journal(struct gfs2_jdesc *jd) | 451 | static void gfs2_recover_put_ref(struct slow_work *work) |
452 | { | ||
453 | struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work); | ||
454 | clear_bit(JDF_RECOVERY, &jd->jd_flags); | ||
455 | smp_mb__after_clear_bit(); | ||
456 | wake_up_bit(&jd->jd_flags, JDF_RECOVERY); | ||
457 | } | ||
458 | |||
459 | static void gfs2_recover_work(struct slow_work *work) | ||
455 | { | 460 | { |
461 | struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work); | ||
456 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 462 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
457 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 463 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
458 | struct gfs2_log_header_host head; | 464 | struct gfs2_log_header_host head; |
@@ -569,7 +575,7 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd) | |||
569 | gfs2_glock_dq_uninit(&j_gh); | 575 | gfs2_glock_dq_uninit(&j_gh); |
570 | 576 | ||
571 | fs_info(sdp, "jid=%u: Done\n", jd->jd_jid); | 577 | fs_info(sdp, "jid=%u: Done\n", jd->jd_jid); |
572 | return 0; | 578 | return; |
573 | 579 | ||
574 | fail_gunlock_tr: | 580 | fail_gunlock_tr: |
575 | gfs2_glock_dq_uninit(&t_gh); | 581 | gfs2_glock_dq_uninit(&t_gh); |
@@ -584,70 +590,28 @@ fail_gunlock_j: | |||
584 | 590 | ||
585 | fail: | 591 | fail: |
586 | gfs2_recovery_done(sdp, jd->jd_jid, LM_RD_GAVEUP); | 592 | gfs2_recovery_done(sdp, jd->jd_jid, LM_RD_GAVEUP); |
587 | return error; | ||
588 | } | 593 | } |
589 | 594 | ||
590 | static struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp) | 595 | struct slow_work_ops gfs2_recover_ops = { |
591 | { | 596 | .get_ref = gfs2_recover_get_ref, |
592 | struct gfs2_jdesc *jd; | 597 | .put_ref = gfs2_recover_put_ref, |
593 | int found = 0; | 598 | .execute = gfs2_recover_work, |
594 | 599 | }; | |
595 | spin_lock(&sdp->sd_jindex_spin); | ||
596 | 600 | ||
597 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | ||
598 | if (jd->jd_dirty) { | ||
599 | jd->jd_dirty = 0; | ||
600 | found = 1; | ||
601 | break; | ||
602 | } | ||
603 | } | ||
604 | spin_unlock(&sdp->sd_jindex_spin); | ||
605 | |||
606 | if (!found) | ||
607 | jd = NULL; | ||
608 | 601 | ||
609 | return jd; | 602 | static int gfs2_recovery_wait(void *word) |
610 | } | ||
611 | |||
612 | /** | ||
613 | * gfs2_check_journals - Recover any dirty journals | ||
614 | * @sdp: the filesystem | ||
615 | * | ||
616 | */ | ||
617 | |||
618 | static void gfs2_check_journals(struct gfs2_sbd *sdp) | ||
619 | { | 603 | { |
620 | struct gfs2_jdesc *jd; | 604 | schedule(); |
621 | 605 | return 0; | |
622 | for (;;) { | ||
623 | jd = gfs2_jdesc_find_dirty(sdp); | ||
624 | if (!jd) | ||
625 | break; | ||
626 | |||
627 | if (jd != sdp->sd_jdesc) | ||
628 | gfs2_recover_journal(jd); | ||
629 | } | ||
630 | } | 606 | } |
631 | 607 | ||
632 | /** | 608 | int gfs2_recover_journal(struct gfs2_jdesc *jd) |
633 | * gfs2_recoverd - Recover dead machine's journals | ||
634 | * @sdp: Pointer to GFS2 superblock | ||
635 | * | ||
636 | */ | ||
637 | |||
638 | int gfs2_recoverd(void *data) | ||
639 | { | 609 | { |
640 | struct gfs2_sbd *sdp = data; | 610 | int rv; |
641 | unsigned long t; | 611 | rv = slow_work_enqueue(&jd->jd_work); |
642 | 612 | if (rv) | |
643 | while (!kthread_should_stop()) { | 613 | return rv; |
644 | gfs2_check_journals(sdp); | 614 | wait_on_bit(&jd->jd_flags, JDF_RECOVERY, gfs2_recovery_wait, TASK_UNINTERRUPTIBLE); |
645 | t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ; | ||
646 | if (freezing(current)) | ||
647 | refrigerator(); | ||
648 | schedule_timeout_interruptible(t); | ||
649 | } | ||
650 | |||
651 | return 0; | 615 | return 0; |
652 | } | 616 | } |
653 | 617 | ||
diff --git a/fs/gfs2/recovery.h b/fs/gfs2/recovery.h index a8218ea15b57..1616ac22569a 100644 --- a/fs/gfs2/recovery.h +++ b/fs/gfs2/recovery.h | |||
@@ -28,7 +28,7 @@ extern void gfs2_revoke_clean(struct gfs2_sbd *sdp); | |||
28 | extern int gfs2_find_jhead(struct gfs2_jdesc *jd, | 28 | extern int gfs2_find_jhead(struct gfs2_jdesc *jd, |
29 | struct gfs2_log_header_host *head); | 29 | struct gfs2_log_header_host *head); |
30 | extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); | 30 | extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); |
31 | extern int gfs2_recoverd(void *data); | 31 | extern struct slow_work_ops gfs2_recover_ops; |
32 | 32 | ||
33 | #endif /* __RECOVERY_DOT_H__ */ | 33 | #endif /* __RECOVERY_DOT_H__ */ |
34 | 34 | ||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 565038243fa2..de3239731db8 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include "util.h" | 29 | #include "util.h" |
30 | #include "log.h" | 30 | #include "log.h" |
31 | #include "inode.h" | 31 | #include "inode.h" |
32 | #include "ops_address.h" | ||
33 | 32 | ||
34 | #define BFITNOENT ((u32)~0) | 33 | #define BFITNOENT ((u32)~0) |
35 | #define NO_BLOCK ((u64)~0) | 34 | #define NO_BLOCK ((u64)~0) |
@@ -442,6 +441,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) | |||
442 | for (x = 0; x < length; x++) { | 441 | for (x = 0; x < length; x++) { |
443 | bi = rgd->rd_bits + x; | 442 | bi = rgd->rd_bits + x; |
444 | 443 | ||
444 | bi->bi_flags = 0; | ||
445 | /* small rgrp; bitmap stored completely in header block */ | 445 | /* small rgrp; bitmap stored completely in header block */ |
446 | if (length == 1) { | 446 | if (length == 1) { |
447 | bytes = bytes_left; | 447 | bytes = bytes_left; |
@@ -580,7 +580,6 @@ static int read_rindex_entry(struct gfs2_inode *ip, | |||
580 | 580 | ||
581 | rgd->rd_gl->gl_object = rgd; | 581 | rgd->rd_gl->gl_object = rgd; |
582 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; | 582 | rgd->rd_flags &= ~GFS2_RDF_UPTODATE; |
583 | rgd->rd_flags |= GFS2_RDF_CHECK; | ||
584 | return error; | 583 | return error; |
585 | } | 584 | } |
586 | 585 | ||
@@ -701,10 +700,9 @@ static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf) | |||
701 | u32 rg_flags; | 700 | u32 rg_flags; |
702 | 701 | ||
703 | rg_flags = be32_to_cpu(str->rg_flags); | 702 | rg_flags = be32_to_cpu(str->rg_flags); |
704 | if (rg_flags & GFS2_RGF_NOALLOC) | 703 | rg_flags &= ~GFS2_RDF_MASK; |
705 | rgd->rd_flags |= GFS2_RDF_NOALLOC; | 704 | rgd->rd_flags &= GFS2_RDF_MASK; |
706 | else | 705 | rgd->rd_flags |= rg_flags; |
707 | rgd->rd_flags &= ~GFS2_RDF_NOALLOC; | ||
708 | rgd->rd_free = be32_to_cpu(str->rg_free); | 706 | rgd->rd_free = be32_to_cpu(str->rg_free); |
709 | rgd->rd_dinodes = be32_to_cpu(str->rg_dinodes); | 707 | rgd->rd_dinodes = be32_to_cpu(str->rg_dinodes); |
710 | rgd->rd_igeneration = be64_to_cpu(str->rg_igeneration); | 708 | rgd->rd_igeneration = be64_to_cpu(str->rg_igeneration); |
@@ -713,11 +711,8 @@ static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf) | |||
713 | static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) | 711 | static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) |
714 | { | 712 | { |
715 | struct gfs2_rgrp *str = buf; | 713 | struct gfs2_rgrp *str = buf; |
716 | u32 rg_flags = 0; | ||
717 | 714 | ||
718 | if (rgd->rd_flags & GFS2_RDF_NOALLOC) | 715 | str->rg_flags = cpu_to_be32(rgd->rd_flags & ~GFS2_RDF_MASK); |
719 | rg_flags |= GFS2_RGF_NOALLOC; | ||
720 | str->rg_flags = cpu_to_be32(rg_flags); | ||
721 | str->rg_free = cpu_to_be32(rgd->rd_free); | 716 | str->rg_free = cpu_to_be32(rgd->rd_free); |
722 | str->rg_dinodes = cpu_to_be32(rgd->rd_dinodes); | 717 | str->rg_dinodes = cpu_to_be32(rgd->rd_dinodes); |
723 | str->__pad = cpu_to_be32(0); | 718 | str->__pad = cpu_to_be32(0); |
@@ -775,8 +770,10 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
775 | } | 770 | } |
776 | 771 | ||
777 | if (!(rgd->rd_flags & GFS2_RDF_UPTODATE)) { | 772 | if (!(rgd->rd_flags & GFS2_RDF_UPTODATE)) { |
773 | for (x = 0; x < length; x++) | ||
774 | clear_bit(GBF_FULL, &rgd->rd_bits[x].bi_flags); | ||
778 | gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); | 775 | gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); |
779 | rgd->rd_flags |= GFS2_RDF_UPTODATE; | 776 | rgd->rd_flags |= (GFS2_RDF_UPTODATE | GFS2_RDF_CHECK); |
780 | } | 777 | } |
781 | 778 | ||
782 | spin_lock(&sdp->sd_rindex_spin); | 779 | spin_lock(&sdp->sd_rindex_spin); |
@@ -845,7 +842,7 @@ static void gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
845 | struct super_block *sb = sdp->sd_vfs; | 842 | struct super_block *sb = sdp->sd_vfs; |
846 | struct block_device *bdev = sb->s_bdev; | 843 | struct block_device *bdev = sb->s_bdev; |
847 | const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize / | 844 | const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize / |
848 | bdev_hardsect_size(sb->s_bdev); | 845 | bdev_logical_block_size(sb->s_bdev); |
849 | u64 blk; | 846 | u64 blk; |
850 | sector_t start = 0; | 847 | sector_t start = 0; |
851 | sector_t nr_sects = 0; | 848 | sector_t nr_sects = 0; |
@@ -903,6 +900,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) | |||
903 | continue; | 900 | continue; |
904 | if (sdp->sd_args.ar_discard) | 901 | if (sdp->sd_args.ar_discard) |
905 | gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bi); | 902 | gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bi); |
903 | clear_bit(GBF_FULL, &bi->bi_flags); | ||
906 | memcpy(bi->bi_clone + bi->bi_offset, | 904 | memcpy(bi->bi_clone + bi->bi_offset, |
907 | bi->bi_bh->b_data + bi->bi_offset, bi->bi_len); | 905 | bi->bi_bh->b_data + bi->bi_offset, bi->bi_len); |
908 | } | 906 | } |
@@ -942,7 +940,7 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) | |||
942 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 940 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
943 | int ret = 0; | 941 | int ret = 0; |
944 | 942 | ||
945 | if (rgd->rd_flags & GFS2_RDF_NOALLOC) | 943 | if (rgd->rd_flags & (GFS2_RGF_NOALLOC | GFS2_RDF_ERROR)) |
946 | return 0; | 944 | return 0; |
947 | 945 | ||
948 | spin_lock(&sdp->sd_rindex_spin); | 946 | spin_lock(&sdp->sd_rindex_spin); |
@@ -1315,30 +1313,37 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
1315 | { | 1313 | { |
1316 | struct gfs2_bitmap *bi = NULL; | 1314 | struct gfs2_bitmap *bi = NULL; |
1317 | const u32 length = rgd->rd_length; | 1315 | const u32 length = rgd->rd_length; |
1318 | u32 blk = 0; | 1316 | u32 blk = BFITNOENT; |
1319 | unsigned int buf, x; | 1317 | unsigned int buf, x; |
1320 | const unsigned int elen = *n; | 1318 | const unsigned int elen = *n; |
1321 | const u8 *buffer; | 1319 | const u8 *buffer = NULL; |
1322 | 1320 | ||
1323 | *n = 0; | 1321 | *n = 0; |
1324 | /* Find bitmap block that contains bits for goal block */ | 1322 | /* Find bitmap block that contains bits for goal block */ |
1325 | for (buf = 0; buf < length; buf++) { | 1323 | for (buf = 0; buf < length; buf++) { |
1326 | bi = rgd->rd_bits + buf; | 1324 | bi = rgd->rd_bits + buf; |
1327 | if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY) | 1325 | /* Convert scope of "goal" from rgrp-wide to within found bit block */ |
1328 | break; | 1326 | if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY) { |
1327 | goal -= bi->bi_start * GFS2_NBBY; | ||
1328 | goto do_search; | ||
1329 | } | ||
1329 | } | 1330 | } |
1331 | buf = 0; | ||
1332 | goal = 0; | ||
1330 | 1333 | ||
1331 | gfs2_assert(rgd->rd_sbd, buf < length); | 1334 | do_search: |
1332 | |||
1333 | /* Convert scope of "goal" from rgrp-wide to within found bit block */ | ||
1334 | goal -= bi->bi_start * GFS2_NBBY; | ||
1335 | |||
1336 | /* Search (up to entire) bitmap in this rgrp for allocatable block. | 1335 | /* Search (up to entire) bitmap in this rgrp for allocatable block. |
1337 | "x <= length", instead of "x < length", because we typically start | 1336 | "x <= length", instead of "x < length", because we typically start |
1338 | the search in the middle of a bit block, but if we can't find an | 1337 | the search in the middle of a bit block, but if we can't find an |
1339 | allocatable block anywhere else, we want to be able wrap around and | 1338 | allocatable block anywhere else, we want to be able wrap around and |
1340 | search in the first part of our first-searched bit block. */ | 1339 | search in the first part of our first-searched bit block. */ |
1341 | for (x = 0; x <= length; x++) { | 1340 | for (x = 0; x <= length; x++) { |
1341 | bi = rgd->rd_bits + buf; | ||
1342 | |||
1343 | if (test_bit(GBF_FULL, &bi->bi_flags) && | ||
1344 | (old_state == GFS2_BLKST_FREE)) | ||
1345 | goto skip; | ||
1346 | |||
1342 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone | 1347 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone |
1343 | bitmaps, so we must search the originals for that. */ | 1348 | bitmaps, so we must search the originals for that. */ |
1344 | buffer = bi->bi_bh->b_data + bi->bi_offset; | 1349 | buffer = bi->bi_bh->b_data + bi->bi_offset; |
@@ -1349,33 +1354,39 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
1349 | if (blk != BFITNOENT) | 1354 | if (blk != BFITNOENT) |
1350 | break; | 1355 | break; |
1351 | 1356 | ||
1357 | if ((goal == 0) && (old_state == GFS2_BLKST_FREE)) | ||
1358 | set_bit(GBF_FULL, &bi->bi_flags); | ||
1359 | |||
1352 | /* Try next bitmap block (wrap back to rgrp header if at end) */ | 1360 | /* Try next bitmap block (wrap back to rgrp header if at end) */ |
1353 | buf = (buf + 1) % length; | 1361 | skip: |
1354 | bi = rgd->rd_bits + buf; | 1362 | buf++; |
1363 | buf %= length; | ||
1355 | goal = 0; | 1364 | goal = 0; |
1356 | } | 1365 | } |
1357 | 1366 | ||
1358 | if (blk != BFITNOENT && old_state != new_state) { | 1367 | if (blk == BFITNOENT) |
1359 | *n = 1; | 1368 | return blk; |
1360 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1369 | *n = 1; |
1370 | if (old_state == new_state) | ||
1371 | goto out; | ||
1372 | |||
1373 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | ||
1374 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, | ||
1375 | bi->bi_len, blk, new_state); | ||
1376 | goal = blk; | ||
1377 | while (*n < elen) { | ||
1378 | goal++; | ||
1379 | if (goal >= (bi->bi_len * GFS2_NBBY)) | ||
1380 | break; | ||
1381 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != | ||
1382 | GFS2_BLKST_FREE) | ||
1383 | break; | ||
1361 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, | 1384 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, |
1362 | bi->bi_len, blk, new_state); | 1385 | bi->bi_len, goal, new_state); |
1363 | goal = blk; | 1386 | (*n)++; |
1364 | while (*n < elen) { | ||
1365 | goal++; | ||
1366 | if (goal >= (bi->bi_len * GFS2_NBBY)) | ||
1367 | break; | ||
1368 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != | ||
1369 | GFS2_BLKST_FREE) | ||
1370 | break; | ||
1371 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, | ||
1372 | bi->bi_offset, bi->bi_len, goal, | ||
1373 | new_state); | ||
1374 | (*n)++; | ||
1375 | } | ||
1376 | } | 1387 | } |
1377 | 1388 | out: | |
1378 | return (blk == BFITNOENT) ? blk : (bi->bi_start * GFS2_NBBY) + blk; | 1389 | return (bi->bi_start * GFS2_NBBY) + blk; |
1379 | } | 1390 | } |
1380 | 1391 | ||
1381 | /** | 1392 | /** |
@@ -1435,13 +1446,33 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, | |||
1435 | } | 1446 | } |
1436 | 1447 | ||
1437 | /** | 1448 | /** |
1438 | * gfs2_alloc_block - Allocate a block | 1449 | * gfs2_rgrp_dump - print out an rgrp |
1450 | * @seq: The iterator | ||
1451 | * @gl: The glock in question | ||
1452 | * | ||
1453 | */ | ||
1454 | |||
1455 | int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl) | ||
1456 | { | ||
1457 | const struct gfs2_rgrpd *rgd = gl->gl_object; | ||
1458 | if (rgd == NULL) | ||
1459 | return 0; | ||
1460 | gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u\n", | ||
1461 | (unsigned long long)rgd->rd_addr, rgd->rd_flags, | ||
1462 | rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes); | ||
1463 | return 0; | ||
1464 | } | ||
1465 | |||
1466 | /** | ||
1467 | * gfs2_alloc_block - Allocate one or more blocks | ||
1439 | * @ip: the inode to allocate the block for | 1468 | * @ip: the inode to allocate the block for |
1469 | * @bn: Used to return the starting block number | ||
1470 | * @n: requested number of blocks/extent length (value/result) | ||
1440 | * | 1471 | * |
1441 | * Returns: the allocated block | 1472 | * Returns: 0 or error |
1442 | */ | 1473 | */ |
1443 | 1474 | ||
1444 | u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n) | 1475 | int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n) |
1445 | { | 1476 | { |
1446 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1477 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1447 | struct buffer_head *dibh; | 1478 | struct buffer_head *dibh; |
@@ -1457,7 +1488,10 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n) | |||
1457 | goal = rgd->rd_last_alloc; | 1488 | goal = rgd->rd_last_alloc; |
1458 | 1489 | ||
1459 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED, n); | 1490 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED, n); |
1460 | BUG_ON(blk == BFITNOENT); | 1491 | |
1492 | /* Since all blocks are reserved in advance, this shouldn't happen */ | ||
1493 | if (blk == BFITNOENT) | ||
1494 | goto rgrp_error; | ||
1461 | 1495 | ||
1462 | rgd->rd_last_alloc = blk; | 1496 | rgd->rd_last_alloc = blk; |
1463 | block = rgd->rd_data0 + blk; | 1497 | block = rgd->rd_data0 + blk; |
@@ -1469,7 +1503,9 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n) | |||
1469 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_goal); | 1503 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(ip->i_goal); |
1470 | brelse(dibh); | 1504 | brelse(dibh); |
1471 | } | 1505 | } |
1472 | gfs2_assert_withdraw(sdp, rgd->rd_free >= *n); | 1506 | if (rgd->rd_free < *n) |
1507 | goto rgrp_error; | ||
1508 | |||
1473 | rgd->rd_free -= *n; | 1509 | rgd->rd_free -= *n; |
1474 | 1510 | ||
1475 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1511 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
@@ -1484,7 +1520,16 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n) | |||
1484 | rgd->rd_free_clone -= *n; | 1520 | rgd->rd_free_clone -= *n; |
1485 | spin_unlock(&sdp->sd_rindex_spin); | 1521 | spin_unlock(&sdp->sd_rindex_spin); |
1486 | 1522 | ||
1487 | return block; | 1523 | *bn = block; |
1524 | return 0; | ||
1525 | |||
1526 | rgrp_error: | ||
1527 | fs_warn(sdp, "rgrp %llu has an error, marking it readonly until umount\n", | ||
1528 | (unsigned long long)rgd->rd_addr); | ||
1529 | fs_warn(sdp, "umount on all nodes and run fsck.gfs2 to fix the error\n"); | ||
1530 | gfs2_rgrp_dump(NULL, rgd->rd_gl); | ||
1531 | rgd->rd_flags |= GFS2_RDF_ERROR; | ||
1532 | return -EIO; | ||
1488 | } | 1533 | } |
1489 | 1534 | ||
1490 | /** | 1535 | /** |
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index 3181c7e624bf..1e76ff0f3e00 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
@@ -14,22 +14,22 @@ struct gfs2_rgrpd; | |||
14 | struct gfs2_sbd; | 14 | struct gfs2_sbd; |
15 | struct gfs2_holder; | 15 | struct gfs2_holder; |
16 | 16 | ||
17 | void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd); | 17 | extern void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd); |
18 | 18 | ||
19 | struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk); | 19 | struct gfs2_rgrpd *gfs2_blk2rgrpd(struct gfs2_sbd *sdp, u64 blk); |
20 | struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp); | 20 | struct gfs2_rgrpd *gfs2_rgrpd_get_first(struct gfs2_sbd *sdp); |
21 | struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd); | 21 | struct gfs2_rgrpd *gfs2_rgrpd_get_next(struct gfs2_rgrpd *rgd); |
22 | 22 | ||
23 | void gfs2_clear_rgrpd(struct gfs2_sbd *sdp); | 23 | extern void gfs2_clear_rgrpd(struct gfs2_sbd *sdp); |
24 | int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh); | 24 | extern int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh); |
25 | 25 | ||
26 | int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd); | 26 | extern int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd); |
27 | void gfs2_rgrp_bh_hold(struct gfs2_rgrpd *rgd); | 27 | extern void gfs2_rgrp_bh_hold(struct gfs2_rgrpd *rgd); |
28 | void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd); | 28 | extern void gfs2_rgrp_bh_put(struct gfs2_rgrpd *rgd); |
29 | 29 | ||
30 | void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd); | 30 | extern void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd); |
31 | 31 | ||
32 | struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip); | 32 | extern struct gfs2_alloc *gfs2_alloc_get(struct gfs2_inode *ip); |
33 | static inline void gfs2_alloc_put(struct gfs2_inode *ip) | 33 | static inline void gfs2_alloc_put(struct gfs2_inode *ip) |
34 | { | 34 | { |
35 | BUG_ON(ip->i_alloc == NULL); | 35 | BUG_ON(ip->i_alloc == NULL); |
@@ -37,22 +37,22 @@ static inline void gfs2_alloc_put(struct gfs2_inode *ip) | |||
37 | ip->i_alloc = NULL; | 37 | ip->i_alloc = NULL; |
38 | } | 38 | } |
39 | 39 | ||
40 | int gfs2_inplace_reserve_i(struct gfs2_inode *ip, | 40 | extern int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, |
41 | char *file, unsigned int line); | 41 | unsigned int line); |
42 | #define gfs2_inplace_reserve(ip) \ | 42 | #define gfs2_inplace_reserve(ip) \ |
43 | gfs2_inplace_reserve_i((ip), __FILE__, __LINE__) | 43 | gfs2_inplace_reserve_i((ip), __FILE__, __LINE__) |
44 | 44 | ||
45 | void gfs2_inplace_release(struct gfs2_inode *ip); | 45 | extern void gfs2_inplace_release(struct gfs2_inode *ip); |
46 | 46 | ||
47 | unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block); | 47 | extern unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block); |
48 | 48 | ||
49 | u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n); | 49 | extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); |
50 | u64 gfs2_alloc_di(struct gfs2_inode *ip, u64 *generation); | 50 | extern u64 gfs2_alloc_di(struct gfs2_inode *ip, u64 *generation); |
51 | 51 | ||
52 | void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen); | 52 | extern void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen); |
53 | void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); | 53 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); |
54 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); | 54 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); |
55 | void gfs2_unlink_di(struct inode *inode); | 55 | extern void gfs2_unlink_di(struct inode *inode); |
56 | 56 | ||
57 | struct gfs2_rgrp_list { | 57 | struct gfs2_rgrp_list { |
58 | unsigned int rl_rgrps; | 58 | unsigned int rl_rgrps; |
@@ -61,10 +61,11 @@ struct gfs2_rgrp_list { | |||
61 | struct gfs2_holder *rl_ghs; | 61 | struct gfs2_holder *rl_ghs; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, | 64 | extern void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, |
65 | u64 block); | 65 | u64 block); |
66 | void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state); | 66 | extern void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state); |
67 | void gfs2_rlist_free(struct gfs2_rgrp_list *rlist); | 67 | extern void gfs2_rlist_free(struct gfs2_rgrp_list *rlist); |
68 | u64 gfs2_ri_total(struct gfs2_sbd *sdp); | 68 | extern u64 gfs2_ri_total(struct gfs2_sbd *sdp); |
69 | extern int gfs2_rgrp_dump(struct seq_file *seq, const struct gfs2_glock *gl); | ||
69 | 70 | ||
70 | #endif /* __RGRP_DOT_H__ */ | 71 | #endif /* __RGRP_DOT_H__ */ |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 601913e0a482..40bcc37e5a70 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -7,14 +7,20 @@ | |||
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/bio.h> | ||
10 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
12 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
13 | #include <linux/completion.h> | 14 | #include <linux/completion.h> |
14 | #include <linux/buffer_head.h> | 15 | #include <linux/buffer_head.h> |
15 | #include <linux/crc32.h> | 16 | #include <linux/statfs.h> |
17 | #include <linux/seq_file.h> | ||
18 | #include <linux/mount.h> | ||
19 | #include <linux/kthread.h> | ||
20 | #include <linux/delay.h> | ||
16 | #include <linux/gfs2_ondisk.h> | 21 | #include <linux/gfs2_ondisk.h> |
17 | #include <linux/bio.h> | 22 | #include <linux/crc32.h> |
23 | #include <linux/time.h> | ||
18 | 24 | ||
19 | #include "gfs2.h" | 25 | #include "gfs2.h" |
20 | #include "incore.h" | 26 | #include "incore.h" |
@@ -31,6 +37,183 @@ | |||
31 | #include "super.h" | 37 | #include "super.h" |
32 | #include "trans.h" | 38 | #include "trans.h" |
33 | #include "util.h" | 39 | #include "util.h" |
40 | #include "sys.h" | ||
41 | #include "eattr.h" | ||
42 | |||
43 | #define args_neq(a1, a2, x) ((a1)->ar_##x != (a2)->ar_##x) | ||
44 | |||
45 | enum { | ||
46 | Opt_lockproto, | ||
47 | Opt_locktable, | ||
48 | Opt_hostdata, | ||
49 | Opt_spectator, | ||
50 | Opt_ignore_local_fs, | ||
51 | Opt_localflocks, | ||
52 | Opt_localcaching, | ||
53 | Opt_debug, | ||
54 | Opt_nodebug, | ||
55 | Opt_upgrade, | ||
56 | Opt_acl, | ||
57 | Opt_noacl, | ||
58 | Opt_quota_off, | ||
59 | Opt_quota_account, | ||
60 | Opt_quota_on, | ||
61 | Opt_quota, | ||
62 | Opt_noquota, | ||
63 | Opt_suiddir, | ||
64 | Opt_nosuiddir, | ||
65 | Opt_data_writeback, | ||
66 | Opt_data_ordered, | ||
67 | Opt_meta, | ||
68 | Opt_discard, | ||
69 | Opt_nodiscard, | ||
70 | Opt_commit, | ||
71 | Opt_error, | ||
72 | }; | ||
73 | |||
74 | static const match_table_t tokens = { | ||
75 | {Opt_lockproto, "lockproto=%s"}, | ||
76 | {Opt_locktable, "locktable=%s"}, | ||
77 | {Opt_hostdata, "hostdata=%s"}, | ||
78 | {Opt_spectator, "spectator"}, | ||
79 | {Opt_ignore_local_fs, "ignore_local_fs"}, | ||
80 | {Opt_localflocks, "localflocks"}, | ||
81 | {Opt_localcaching, "localcaching"}, | ||
82 | {Opt_debug, "debug"}, | ||
83 | {Opt_nodebug, "nodebug"}, | ||
84 | {Opt_upgrade, "upgrade"}, | ||
85 | {Opt_acl, "acl"}, | ||
86 | {Opt_noacl, "noacl"}, | ||
87 | {Opt_quota_off, "quota=off"}, | ||
88 | {Opt_quota_account, "quota=account"}, | ||
89 | {Opt_quota_on, "quota=on"}, | ||
90 | {Opt_quota, "quota"}, | ||
91 | {Opt_noquota, "noquota"}, | ||
92 | {Opt_suiddir, "suiddir"}, | ||
93 | {Opt_nosuiddir, "nosuiddir"}, | ||
94 | {Opt_data_writeback, "data=writeback"}, | ||
95 | {Opt_data_ordered, "data=ordered"}, | ||
96 | {Opt_meta, "meta"}, | ||
97 | {Opt_discard, "discard"}, | ||
98 | {Opt_nodiscard, "nodiscard"}, | ||
99 | {Opt_commit, "commit=%d"}, | ||
100 | {Opt_error, NULL} | ||
101 | }; | ||
102 | |||
103 | /** | ||
104 | * gfs2_mount_args - Parse mount options | ||
105 | * @sdp: | ||
106 | * @data: | ||
107 | * | ||
108 | * Return: errno | ||
109 | */ | ||
110 | |||
111 | int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) | ||
112 | { | ||
113 | char *o; | ||
114 | int token; | ||
115 | substring_t tmp[MAX_OPT_ARGS]; | ||
116 | int rv; | ||
117 | |||
118 | /* Split the options into tokens with the "," character and | ||
119 | process them */ | ||
120 | |||
121 | while (1) { | ||
122 | o = strsep(&options, ","); | ||
123 | if (o == NULL) | ||
124 | break; | ||
125 | if (*o == '\0') | ||
126 | continue; | ||
127 | |||
128 | token = match_token(o, tokens, tmp); | ||
129 | switch (token) { | ||
130 | case Opt_lockproto: | ||
131 | match_strlcpy(args->ar_lockproto, &tmp[0], | ||
132 | GFS2_LOCKNAME_LEN); | ||
133 | break; | ||
134 | case Opt_locktable: | ||
135 | match_strlcpy(args->ar_locktable, &tmp[0], | ||
136 | GFS2_LOCKNAME_LEN); | ||
137 | break; | ||
138 | case Opt_hostdata: | ||
139 | match_strlcpy(args->ar_hostdata, &tmp[0], | ||
140 | GFS2_LOCKNAME_LEN); | ||
141 | break; | ||
142 | case Opt_spectator: | ||
143 | args->ar_spectator = 1; | ||
144 | break; | ||
145 | case Opt_ignore_local_fs: | ||
146 | args->ar_ignore_local_fs = 1; | ||
147 | break; | ||
148 | case Opt_localflocks: | ||
149 | args->ar_localflocks = 1; | ||
150 | break; | ||
151 | case Opt_localcaching: | ||
152 | args->ar_localcaching = 1; | ||
153 | break; | ||
154 | case Opt_debug: | ||
155 | args->ar_debug = 1; | ||
156 | break; | ||
157 | case Opt_nodebug: | ||
158 | args->ar_debug = 0; | ||
159 | break; | ||
160 | case Opt_upgrade: | ||
161 | args->ar_upgrade = 1; | ||
162 | break; | ||
163 | case Opt_acl: | ||
164 | args->ar_posix_acl = 1; | ||
165 | break; | ||
166 | case Opt_noacl: | ||
167 | args->ar_posix_acl = 0; | ||
168 | break; | ||
169 | case Opt_quota_off: | ||
170 | case Opt_noquota: | ||
171 | args->ar_quota = GFS2_QUOTA_OFF; | ||
172 | break; | ||
173 | case Opt_quota_account: | ||
174 | args->ar_quota = GFS2_QUOTA_ACCOUNT; | ||
175 | break; | ||
176 | case Opt_quota_on: | ||
177 | case Opt_quota: | ||
178 | args->ar_quota = GFS2_QUOTA_ON; | ||
179 | break; | ||
180 | case Opt_suiddir: | ||
181 | args->ar_suiddir = 1; | ||
182 | break; | ||
183 | case Opt_nosuiddir: | ||
184 | args->ar_suiddir = 0; | ||
185 | break; | ||
186 | case Opt_data_writeback: | ||
187 | args->ar_data = GFS2_DATA_WRITEBACK; | ||
188 | break; | ||
189 | case Opt_data_ordered: | ||
190 | args->ar_data = GFS2_DATA_ORDERED; | ||
191 | break; | ||
192 | case Opt_meta: | ||
193 | args->ar_meta = 1; | ||
194 | break; | ||
195 | case Opt_discard: | ||
196 | args->ar_discard = 1; | ||
197 | break; | ||
198 | case Opt_nodiscard: | ||
199 | args->ar_discard = 0; | ||
200 | break; | ||
201 | case Opt_commit: | ||
202 | rv = match_int(&tmp[0], &args->ar_commit); | ||
203 | if (rv || args->ar_commit <= 0) { | ||
204 | fs_info(sdp, "commit mount option requires a positive numeric argument\n"); | ||
205 | return rv ? rv : -EINVAL; | ||
206 | } | ||
207 | break; | ||
208 | case Opt_error: | ||
209 | default: | ||
210 | fs_info(sdp, "invalid mount option: %s\n", o); | ||
211 | return -EINVAL; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | return 0; | ||
216 | } | ||
34 | 217 | ||
35 | /** | 218 | /** |
36 | * gfs2_jindex_free - Clear all the journal index information | 219 | * gfs2_jindex_free - Clear all the journal index information |
@@ -436,3 +619,719 @@ void gfs2_unfreeze_fs(struct gfs2_sbd *sdp) | |||
436 | mutex_unlock(&sdp->sd_freeze_lock); | 619 | mutex_unlock(&sdp->sd_freeze_lock); |
437 | } | 620 | } |
438 | 621 | ||
622 | |||
623 | /** | ||
624 | * gfs2_write_inode - Make sure the inode is stable on the disk | ||
625 | * @inode: The inode | ||
626 | * @sync: synchronous write flag | ||
627 | * | ||
628 | * Returns: errno | ||
629 | */ | ||
630 | |||
631 | static int gfs2_write_inode(struct inode *inode, int sync) | ||
632 | { | ||
633 | struct gfs2_inode *ip = GFS2_I(inode); | ||
634 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
635 | struct gfs2_holder gh; | ||
636 | struct buffer_head *bh; | ||
637 | struct timespec atime; | ||
638 | struct gfs2_dinode *di; | ||
639 | int ret = 0; | ||
640 | |||
641 | /* Check this is a "normal" inode, etc */ | ||
642 | if (!test_bit(GIF_USER, &ip->i_flags) || | ||
643 | (current->flags & PF_MEMALLOC)) | ||
644 | return 0; | ||
645 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
646 | if (ret) | ||
647 | goto do_flush; | ||
648 | ret = gfs2_trans_begin(sdp, RES_DINODE, 0); | ||
649 | if (ret) | ||
650 | goto do_unlock; | ||
651 | ret = gfs2_meta_inode_buffer(ip, &bh); | ||
652 | if (ret == 0) { | ||
653 | di = (struct gfs2_dinode *)bh->b_data; | ||
654 | atime.tv_sec = be64_to_cpu(di->di_atime); | ||
655 | atime.tv_nsec = be32_to_cpu(di->di_atime_nsec); | ||
656 | if (timespec_compare(&inode->i_atime, &atime) > 0) { | ||
657 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | ||
658 | gfs2_dinode_out(ip, bh->b_data); | ||
659 | } | ||
660 | brelse(bh); | ||
661 | } | ||
662 | gfs2_trans_end(sdp); | ||
663 | do_unlock: | ||
664 | gfs2_glock_dq_uninit(&gh); | ||
665 | do_flush: | ||
666 | if (sync != 0) | ||
667 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | ||
668 | return ret; | ||
669 | } | ||
670 | |||
671 | /** | ||
672 | * gfs2_make_fs_ro - Turn a Read-Write FS into a Read-Only one | ||
673 | * @sdp: the filesystem | ||
674 | * | ||
675 | * Returns: errno | ||
676 | */ | ||
677 | |||
678 | static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | ||
679 | { | ||
680 | struct gfs2_holder t_gh; | ||
681 | int error; | ||
682 | |||
683 | gfs2_quota_sync(sdp); | ||
684 | gfs2_statfs_sync(sdp); | ||
685 | |||
686 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, | ||
687 | &t_gh); | ||
688 | if (error && !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
689 | return error; | ||
690 | |||
691 | gfs2_meta_syncfs(sdp); | ||
692 | gfs2_log_shutdown(sdp); | ||
693 | |||
694 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | ||
695 | |||
696 | if (t_gh.gh_gl) | ||
697 | gfs2_glock_dq_uninit(&t_gh); | ||
698 | |||
699 | gfs2_quota_cleanup(sdp); | ||
700 | |||
701 | return error; | ||
702 | } | ||
703 | |||
704 | static int gfs2_umount_recovery_wait(void *word) | ||
705 | { | ||
706 | schedule(); | ||
707 | return 0; | ||
708 | } | ||
709 | |||
710 | /** | ||
711 | * gfs2_put_super - Unmount the filesystem | ||
712 | * @sb: The VFS superblock | ||
713 | * | ||
714 | */ | ||
715 | |||
716 | static void gfs2_put_super(struct super_block *sb) | ||
717 | { | ||
718 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
719 | int error; | ||
720 | struct gfs2_jdesc *jd; | ||
721 | |||
722 | /* Unfreeze the filesystem, if we need to */ | ||
723 | |||
724 | mutex_lock(&sdp->sd_freeze_lock); | ||
725 | if (sdp->sd_freeze_count) | ||
726 | gfs2_glock_dq_uninit(&sdp->sd_freeze_gh); | ||
727 | mutex_unlock(&sdp->sd_freeze_lock); | ||
728 | |||
729 | /* No more recovery requests */ | ||
730 | set_bit(SDF_NORECOVERY, &sdp->sd_flags); | ||
731 | smp_mb(); | ||
732 | |||
733 | /* Wait on outstanding recovery */ | ||
734 | restart: | ||
735 | spin_lock(&sdp->sd_jindex_spin); | ||
736 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | ||
737 | if (!test_bit(JDF_RECOVERY, &jd->jd_flags)) | ||
738 | continue; | ||
739 | spin_unlock(&sdp->sd_jindex_spin); | ||
740 | wait_on_bit(&jd->jd_flags, JDF_RECOVERY, | ||
741 | gfs2_umount_recovery_wait, TASK_UNINTERRUPTIBLE); | ||
742 | goto restart; | ||
743 | } | ||
744 | spin_unlock(&sdp->sd_jindex_spin); | ||
745 | |||
746 | kthread_stop(sdp->sd_quotad_process); | ||
747 | kthread_stop(sdp->sd_logd_process); | ||
748 | |||
749 | if (!(sb->s_flags & MS_RDONLY)) { | ||
750 | error = gfs2_make_fs_ro(sdp); | ||
751 | if (error) | ||
752 | gfs2_io_error(sdp); | ||
753 | } | ||
754 | /* At this point, we're through modifying the disk */ | ||
755 | |||
756 | /* Release stuff */ | ||
757 | |||
758 | iput(sdp->sd_jindex); | ||
759 | iput(sdp->sd_inum_inode); | ||
760 | iput(sdp->sd_statfs_inode); | ||
761 | iput(sdp->sd_rindex); | ||
762 | iput(sdp->sd_quota_inode); | ||
763 | |||
764 | gfs2_glock_put(sdp->sd_rename_gl); | ||
765 | gfs2_glock_put(sdp->sd_trans_gl); | ||
766 | |||
767 | if (!sdp->sd_args.ar_spectator) { | ||
768 | gfs2_glock_dq_uninit(&sdp->sd_journal_gh); | ||
769 | gfs2_glock_dq_uninit(&sdp->sd_jinode_gh); | ||
770 | gfs2_glock_dq_uninit(&sdp->sd_ir_gh); | ||
771 | gfs2_glock_dq_uninit(&sdp->sd_sc_gh); | ||
772 | gfs2_glock_dq_uninit(&sdp->sd_qc_gh); | ||
773 | iput(sdp->sd_ir_inode); | ||
774 | iput(sdp->sd_sc_inode); | ||
775 | iput(sdp->sd_qc_inode); | ||
776 | } | ||
777 | |||
778 | gfs2_glock_dq_uninit(&sdp->sd_live_gh); | ||
779 | gfs2_clear_rgrpd(sdp); | ||
780 | gfs2_jindex_free(sdp); | ||
781 | /* Take apart glock structures and buffer lists */ | ||
782 | gfs2_gl_hash_clear(sdp); | ||
783 | /* Unmount the locking protocol */ | ||
784 | gfs2_lm_unmount(sdp); | ||
785 | |||
786 | /* At this point, we're through participating in the lockspace */ | ||
787 | gfs2_sys_fs_del(sdp); | ||
788 | } | ||
789 | |||
790 | /** | ||
791 | * gfs2_write_super | ||
792 | * @sb: the superblock | ||
793 | * | ||
794 | */ | ||
795 | |||
796 | static void gfs2_write_super(struct super_block *sb) | ||
797 | { | ||
798 | sb->s_dirt = 0; | ||
799 | } | ||
800 | |||
801 | /** | ||
802 | * gfs2_sync_fs - sync the filesystem | ||
803 | * @sb: the superblock | ||
804 | * | ||
805 | * Flushes the log to disk. | ||
806 | */ | ||
807 | |||
808 | static int gfs2_sync_fs(struct super_block *sb, int wait) | ||
809 | { | ||
810 | sb->s_dirt = 0; | ||
811 | if (wait && sb->s_fs_info) | ||
812 | gfs2_log_flush(sb->s_fs_info, NULL); | ||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | /** | ||
817 | * gfs2_freeze - prevent further writes to the filesystem | ||
818 | * @sb: the VFS structure for the filesystem | ||
819 | * | ||
820 | */ | ||
821 | |||
822 | static int gfs2_freeze(struct super_block *sb) | ||
823 | { | ||
824 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
825 | int error; | ||
826 | |||
827 | if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
828 | return -EINVAL; | ||
829 | |||
830 | for (;;) { | ||
831 | error = gfs2_freeze_fs(sdp); | ||
832 | if (!error) | ||
833 | break; | ||
834 | |||
835 | switch (error) { | ||
836 | case -EBUSY: | ||
837 | fs_err(sdp, "waiting for recovery before freeze\n"); | ||
838 | break; | ||
839 | |||
840 | default: | ||
841 | fs_err(sdp, "error freezing FS: %d\n", error); | ||
842 | break; | ||
843 | } | ||
844 | |||
845 | fs_err(sdp, "retrying...\n"); | ||
846 | msleep(1000); | ||
847 | } | ||
848 | return 0; | ||
849 | } | ||
850 | |||
851 | /** | ||
852 | * gfs2_unfreeze - reallow writes to the filesystem | ||
853 | * @sb: the VFS structure for the filesystem | ||
854 | * | ||
855 | */ | ||
856 | |||
857 | static int gfs2_unfreeze(struct super_block *sb) | ||
858 | { | ||
859 | gfs2_unfreeze_fs(sb->s_fs_info); | ||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | /** | ||
864 | * statfs_fill - fill in the sg for a given RG | ||
865 | * @rgd: the RG | ||
866 | * @sc: the sc structure | ||
867 | * | ||
868 | * Returns: 0 on success, -ESTALE if the LVB is invalid | ||
869 | */ | ||
870 | |||
871 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | ||
872 | struct gfs2_statfs_change_host *sc) | ||
873 | { | ||
874 | gfs2_rgrp_verify(rgd); | ||
875 | sc->sc_total += rgd->rd_data; | ||
876 | sc->sc_free += rgd->rd_free; | ||
877 | sc->sc_dinodes += rgd->rd_dinodes; | ||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | /** | ||
882 | * gfs2_statfs_slow - Stat a filesystem using asynchronous locking | ||
883 | * @sdp: the filesystem | ||
884 | * @sc: the sc info that will be returned | ||
885 | * | ||
886 | * Any error (other than a signal) will cause this routine to fall back | ||
887 | * to the synchronous version. | ||
888 | * | ||
889 | * FIXME: This really shouldn't busy wait like this. | ||
890 | * | ||
891 | * Returns: errno | ||
892 | */ | ||
893 | |||
894 | static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
895 | { | ||
896 | struct gfs2_holder ri_gh; | ||
897 | struct gfs2_rgrpd *rgd_next; | ||
898 | struct gfs2_holder *gha, *gh; | ||
899 | unsigned int slots = 64; | ||
900 | unsigned int x; | ||
901 | int done; | ||
902 | int error = 0, err; | ||
903 | |||
904 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); | ||
905 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | ||
906 | if (!gha) | ||
907 | return -ENOMEM; | ||
908 | |||
909 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
910 | if (error) | ||
911 | goto out; | ||
912 | |||
913 | rgd_next = gfs2_rgrpd_get_first(sdp); | ||
914 | |||
915 | for (;;) { | ||
916 | done = 1; | ||
917 | |||
918 | for (x = 0; x < slots; x++) { | ||
919 | gh = gha + x; | ||
920 | |||
921 | if (gh->gh_gl && gfs2_glock_poll(gh)) { | ||
922 | err = gfs2_glock_wait(gh); | ||
923 | if (err) { | ||
924 | gfs2_holder_uninit(gh); | ||
925 | error = err; | ||
926 | } else { | ||
927 | if (!error) | ||
928 | error = statfs_slow_fill( | ||
929 | gh->gh_gl->gl_object, sc); | ||
930 | gfs2_glock_dq_uninit(gh); | ||
931 | } | ||
932 | } | ||
933 | |||
934 | if (gh->gh_gl) | ||
935 | done = 0; | ||
936 | else if (rgd_next && !error) { | ||
937 | error = gfs2_glock_nq_init(rgd_next->rd_gl, | ||
938 | LM_ST_SHARED, | ||
939 | GL_ASYNC, | ||
940 | gh); | ||
941 | rgd_next = gfs2_rgrpd_get_next(rgd_next); | ||
942 | done = 0; | ||
943 | } | ||
944 | |||
945 | if (signal_pending(current)) | ||
946 | error = -ERESTARTSYS; | ||
947 | } | ||
948 | |||
949 | if (done) | ||
950 | break; | ||
951 | |||
952 | yield(); | ||
953 | } | ||
954 | |||
955 | gfs2_glock_dq_uninit(&ri_gh); | ||
956 | |||
957 | out: | ||
958 | kfree(gha); | ||
959 | return error; | ||
960 | } | ||
961 | |||
962 | /** | ||
963 | * gfs2_statfs_i - Do a statfs | ||
964 | * @sdp: the filesystem | ||
965 | * @sg: the sg structure | ||
966 | * | ||
967 | * Returns: errno | ||
968 | */ | ||
969 | |||
970 | static int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
971 | { | ||
972 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
973 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | ||
974 | |||
975 | spin_lock(&sdp->sd_statfs_spin); | ||
976 | |||
977 | *sc = *m_sc; | ||
978 | sc->sc_total += l_sc->sc_total; | ||
979 | sc->sc_free += l_sc->sc_free; | ||
980 | sc->sc_dinodes += l_sc->sc_dinodes; | ||
981 | |||
982 | spin_unlock(&sdp->sd_statfs_spin); | ||
983 | |||
984 | if (sc->sc_free < 0) | ||
985 | sc->sc_free = 0; | ||
986 | if (sc->sc_free > sc->sc_total) | ||
987 | sc->sc_free = sc->sc_total; | ||
988 | if (sc->sc_dinodes < 0) | ||
989 | sc->sc_dinodes = 0; | ||
990 | |||
991 | return 0; | ||
992 | } | ||
993 | |||
994 | /** | ||
995 | * gfs2_statfs - Gather and return stats about the filesystem | ||
996 | * @sb: The superblock | ||
997 | * @statfsbuf: The buffer | ||
998 | * | ||
999 | * Returns: 0 on success or error code | ||
1000 | */ | ||
1001 | |||
1002 | static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | ||
1003 | { | ||
1004 | struct super_block *sb = dentry->d_inode->i_sb; | ||
1005 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
1006 | struct gfs2_statfs_change_host sc; | ||
1007 | int error; | ||
1008 | |||
1009 | if (gfs2_tune_get(sdp, gt_statfs_slow)) | ||
1010 | error = gfs2_statfs_slow(sdp, &sc); | ||
1011 | else | ||
1012 | error = gfs2_statfs_i(sdp, &sc); | ||
1013 | |||
1014 | if (error) | ||
1015 | return error; | ||
1016 | |||
1017 | buf->f_type = GFS2_MAGIC; | ||
1018 | buf->f_bsize = sdp->sd_sb.sb_bsize; | ||
1019 | buf->f_blocks = sc.sc_total; | ||
1020 | buf->f_bfree = sc.sc_free; | ||
1021 | buf->f_bavail = sc.sc_free; | ||
1022 | buf->f_files = sc.sc_dinodes + sc.sc_free; | ||
1023 | buf->f_ffree = sc.sc_free; | ||
1024 | buf->f_namelen = GFS2_FNAMESIZE; | ||
1025 | |||
1026 | return 0; | ||
1027 | } | ||
1028 | |||
1029 | /** | ||
1030 | * gfs2_remount_fs - called when the FS is remounted | ||
1031 | * @sb: the filesystem | ||
1032 | * @flags: the remount flags | ||
1033 | * @data: extra data passed in (not used right now) | ||
1034 | * | ||
1035 | * Returns: errno | ||
1036 | */ | ||
1037 | |||
1038 | static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | ||
1039 | { | ||
1040 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
1041 | struct gfs2_args args = sdp->sd_args; /* Default to current settings */ | ||
1042 | struct gfs2_tune *gt = &sdp->sd_tune; | ||
1043 | int error; | ||
1044 | |||
1045 | spin_lock(>->gt_spin); | ||
1046 | args.ar_commit = gt->gt_log_flush_secs; | ||
1047 | spin_unlock(>->gt_spin); | ||
1048 | error = gfs2_mount_args(sdp, &args, data); | ||
1049 | if (error) | ||
1050 | return error; | ||
1051 | |||
1052 | /* Not allowed to change locking details */ | ||
1053 | if (strcmp(args.ar_lockproto, sdp->sd_args.ar_lockproto) || | ||
1054 | strcmp(args.ar_locktable, sdp->sd_args.ar_locktable) || | ||
1055 | strcmp(args.ar_hostdata, sdp->sd_args.ar_hostdata)) | ||
1056 | return -EINVAL; | ||
1057 | |||
1058 | /* Some flags must not be changed */ | ||
1059 | if (args_neq(&args, &sdp->sd_args, spectator) || | ||
1060 | args_neq(&args, &sdp->sd_args, ignore_local_fs) || | ||
1061 | args_neq(&args, &sdp->sd_args, localflocks) || | ||
1062 | args_neq(&args, &sdp->sd_args, localcaching) || | ||
1063 | args_neq(&args, &sdp->sd_args, meta)) | ||
1064 | return -EINVAL; | ||
1065 | |||
1066 | if (sdp->sd_args.ar_spectator) | ||
1067 | *flags |= MS_RDONLY; | ||
1068 | |||
1069 | if ((sb->s_flags ^ *flags) & MS_RDONLY) { | ||
1070 | if (*flags & MS_RDONLY) | ||
1071 | error = gfs2_make_fs_ro(sdp); | ||
1072 | else | ||
1073 | error = gfs2_make_fs_rw(sdp); | ||
1074 | if (error) | ||
1075 | return error; | ||
1076 | } | ||
1077 | |||
1078 | sdp->sd_args = args; | ||
1079 | if (sdp->sd_args.ar_posix_acl) | ||
1080 | sb->s_flags |= MS_POSIXACL; | ||
1081 | else | ||
1082 | sb->s_flags &= ~MS_POSIXACL; | ||
1083 | spin_lock(>->gt_spin); | ||
1084 | gt->gt_log_flush_secs = args.ar_commit; | ||
1085 | spin_unlock(>->gt_spin); | ||
1086 | |||
1087 | return 0; | ||
1088 | } | ||
1089 | |||
1090 | /** | ||
1091 | * gfs2_drop_inode - Drop an inode (test for remote unlink) | ||
1092 | * @inode: The inode to drop | ||
1093 | * | ||
1094 | * If we've received a callback on an iopen lock then its because a | ||
1095 | * remote node tried to deallocate the inode but failed due to this node | ||
1096 | * still having the inode open. Here we mark the link count zero | ||
1097 | * since we know that it must have reached zero if the GLF_DEMOTE flag | ||
1098 | * is set on the iopen glock. If we didn't do a disk read since the | ||
1099 | * remote node removed the final link then we might otherwise miss | ||
1100 | * this event. This check ensures that this node will deallocate the | ||
1101 | * inode's blocks, or alternatively pass the baton on to another | ||
1102 | * node for later deallocation. | ||
1103 | */ | ||
1104 | |||
1105 | static void gfs2_drop_inode(struct inode *inode) | ||
1106 | { | ||
1107 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1108 | |||
1109 | if (test_bit(GIF_USER, &ip->i_flags) && inode->i_nlink) { | ||
1110 | struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl; | ||
1111 | if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags)) | ||
1112 | clear_nlink(inode); | ||
1113 | } | ||
1114 | generic_drop_inode(inode); | ||
1115 | } | ||
1116 | |||
1117 | /** | ||
1118 | * gfs2_clear_inode - Deallocate an inode when VFS is done with it | ||
1119 | * @inode: The VFS inode | ||
1120 | * | ||
1121 | */ | ||
1122 | |||
1123 | static void gfs2_clear_inode(struct inode *inode) | ||
1124 | { | ||
1125 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1126 | |||
1127 | /* This tells us its a "real" inode and not one which only | ||
1128 | * serves to contain an address space (see rgrp.c, meta_io.c) | ||
1129 | * which therefore doesn't have its own glocks. | ||
1130 | */ | ||
1131 | if (test_bit(GIF_USER, &ip->i_flags)) { | ||
1132 | ip->i_gl->gl_object = NULL; | ||
1133 | gfs2_glock_put(ip->i_gl); | ||
1134 | ip->i_gl = NULL; | ||
1135 | if (ip->i_iopen_gh.gh_gl) { | ||
1136 | ip->i_iopen_gh.gh_gl->gl_object = NULL; | ||
1137 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | ||
1138 | } | ||
1139 | } | ||
1140 | } | ||
1141 | |||
1142 | static int is_ancestor(const struct dentry *d1, const struct dentry *d2) | ||
1143 | { | ||
1144 | do { | ||
1145 | if (d1 == d2) | ||
1146 | return 1; | ||
1147 | d1 = d1->d_parent; | ||
1148 | } while (!IS_ROOT(d1)); | ||
1149 | return 0; | ||
1150 | } | ||
1151 | |||
1152 | /** | ||
1153 | * gfs2_show_options - Show mount options for /proc/mounts | ||
1154 | * @s: seq_file structure | ||
1155 | * @mnt: vfsmount | ||
1156 | * | ||
1157 | * Returns: 0 on success or error code | ||
1158 | */ | ||
1159 | |||
1160 | static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | ||
1161 | { | ||
1162 | struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; | ||
1163 | struct gfs2_args *args = &sdp->sd_args; | ||
1164 | int lfsecs; | ||
1165 | |||
1166 | if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) | ||
1167 | seq_printf(s, ",meta"); | ||
1168 | if (args->ar_lockproto[0]) | ||
1169 | seq_printf(s, ",lockproto=%s", args->ar_lockproto); | ||
1170 | if (args->ar_locktable[0]) | ||
1171 | seq_printf(s, ",locktable=%s", args->ar_locktable); | ||
1172 | if (args->ar_hostdata[0]) | ||
1173 | seq_printf(s, ",hostdata=%s", args->ar_hostdata); | ||
1174 | if (args->ar_spectator) | ||
1175 | seq_printf(s, ",spectator"); | ||
1176 | if (args->ar_ignore_local_fs) | ||
1177 | seq_printf(s, ",ignore_local_fs"); | ||
1178 | if (args->ar_localflocks) | ||
1179 | seq_printf(s, ",localflocks"); | ||
1180 | if (args->ar_localcaching) | ||
1181 | seq_printf(s, ",localcaching"); | ||
1182 | if (args->ar_debug) | ||
1183 | seq_printf(s, ",debug"); | ||
1184 | if (args->ar_upgrade) | ||
1185 | seq_printf(s, ",upgrade"); | ||
1186 | if (args->ar_posix_acl) | ||
1187 | seq_printf(s, ",acl"); | ||
1188 | if (args->ar_quota != GFS2_QUOTA_DEFAULT) { | ||
1189 | char *state; | ||
1190 | switch (args->ar_quota) { | ||
1191 | case GFS2_QUOTA_OFF: | ||
1192 | state = "off"; | ||
1193 | break; | ||
1194 | case GFS2_QUOTA_ACCOUNT: | ||
1195 | state = "account"; | ||
1196 | break; | ||
1197 | case GFS2_QUOTA_ON: | ||
1198 | state = "on"; | ||
1199 | break; | ||
1200 | default: | ||
1201 | state = "unknown"; | ||
1202 | break; | ||
1203 | } | ||
1204 | seq_printf(s, ",quota=%s", state); | ||
1205 | } | ||
1206 | if (args->ar_suiddir) | ||
1207 | seq_printf(s, ",suiddir"); | ||
1208 | if (args->ar_data != GFS2_DATA_DEFAULT) { | ||
1209 | char *state; | ||
1210 | switch (args->ar_data) { | ||
1211 | case GFS2_DATA_WRITEBACK: | ||
1212 | state = "writeback"; | ||
1213 | break; | ||
1214 | case GFS2_DATA_ORDERED: | ||
1215 | state = "ordered"; | ||
1216 | break; | ||
1217 | default: | ||
1218 | state = "unknown"; | ||
1219 | break; | ||
1220 | } | ||
1221 | seq_printf(s, ",data=%s", state); | ||
1222 | } | ||
1223 | if (args->ar_discard) | ||
1224 | seq_printf(s, ",discard"); | ||
1225 | lfsecs = sdp->sd_tune.gt_log_flush_secs; | ||
1226 | if (lfsecs != 60) | ||
1227 | seq_printf(s, ",commit=%d", lfsecs); | ||
1228 | return 0; | ||
1229 | } | ||
1230 | |||
1231 | /* | ||
1232 | * We have to (at the moment) hold the inodes main lock to cover | ||
1233 | * the gap between unlocking the shared lock on the iopen lock and | ||
1234 | * taking the exclusive lock. I'd rather do a shared -> exclusive | ||
1235 | * conversion on the iopen lock, but we can change that later. This | ||
1236 | * is safe, just less efficient. | ||
1237 | */ | ||
1238 | |||
1239 | static void gfs2_delete_inode(struct inode *inode) | ||
1240 | { | ||
1241 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | ||
1242 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1243 | struct gfs2_holder gh; | ||
1244 | int error; | ||
1245 | |||
1246 | if (!test_bit(GIF_USER, &ip->i_flags)) | ||
1247 | goto out; | ||
1248 | |||
1249 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | ||
1250 | if (unlikely(error)) { | ||
1251 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | ||
1252 | goto out; | ||
1253 | } | ||
1254 | |||
1255 | gfs2_glock_dq_wait(&ip->i_iopen_gh); | ||
1256 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); | ||
1257 | error = gfs2_glock_nq(&ip->i_iopen_gh); | ||
1258 | if (error) | ||
1259 | goto out_truncate; | ||
1260 | |||
1261 | if (S_ISDIR(inode->i_mode) && | ||
1262 | (ip->i_diskflags & GFS2_DIF_EXHASH)) { | ||
1263 | error = gfs2_dir_exhash_dealloc(ip); | ||
1264 | if (error) | ||
1265 | goto out_unlock; | ||
1266 | } | ||
1267 | |||
1268 | if (ip->i_eattr) { | ||
1269 | error = gfs2_ea_dealloc(ip); | ||
1270 | if (error) | ||
1271 | goto out_unlock; | ||
1272 | } | ||
1273 | |||
1274 | if (!gfs2_is_stuffed(ip)) { | ||
1275 | error = gfs2_file_dealloc(ip); | ||
1276 | if (error) | ||
1277 | goto out_unlock; | ||
1278 | } | ||
1279 | |||
1280 | error = gfs2_dinode_dealloc(ip); | ||
1281 | if (error) | ||
1282 | goto out_unlock; | ||
1283 | |||
1284 | out_truncate: | ||
1285 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | ||
1286 | if (error) | ||
1287 | goto out_unlock; | ||
1288 | /* Needs to be done before glock release & also in a transaction */ | ||
1289 | truncate_inode_pages(&inode->i_data, 0); | ||
1290 | gfs2_trans_end(sdp); | ||
1291 | |||
1292 | out_unlock: | ||
1293 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) | ||
1294 | gfs2_glock_dq(&ip->i_iopen_gh); | ||
1295 | gfs2_holder_uninit(&ip->i_iopen_gh); | ||
1296 | gfs2_glock_dq_uninit(&gh); | ||
1297 | if (error && error != GLR_TRYFAILED && error != -EROFS) | ||
1298 | fs_warn(sdp, "gfs2_delete_inode: %d\n", error); | ||
1299 | out: | ||
1300 | truncate_inode_pages(&inode->i_data, 0); | ||
1301 | clear_inode(inode); | ||
1302 | } | ||
1303 | |||
1304 | static struct inode *gfs2_alloc_inode(struct super_block *sb) | ||
1305 | { | ||
1306 | struct gfs2_inode *ip; | ||
1307 | |||
1308 | ip = kmem_cache_alloc(gfs2_inode_cachep, GFP_KERNEL); | ||
1309 | if (ip) { | ||
1310 | ip->i_flags = 0; | ||
1311 | ip->i_gl = NULL; | ||
1312 | } | ||
1313 | return &ip->i_inode; | ||
1314 | } | ||
1315 | |||
1316 | static void gfs2_destroy_inode(struct inode *inode) | ||
1317 | { | ||
1318 | kmem_cache_free(gfs2_inode_cachep, inode); | ||
1319 | } | ||
1320 | |||
1321 | const struct super_operations gfs2_super_ops = { | ||
1322 | .alloc_inode = gfs2_alloc_inode, | ||
1323 | .destroy_inode = gfs2_destroy_inode, | ||
1324 | .write_inode = gfs2_write_inode, | ||
1325 | .delete_inode = gfs2_delete_inode, | ||
1326 | .put_super = gfs2_put_super, | ||
1327 | .write_super = gfs2_write_super, | ||
1328 | .sync_fs = gfs2_sync_fs, | ||
1329 | .freeze_fs = gfs2_freeze, | ||
1330 | .unfreeze_fs = gfs2_unfreeze, | ||
1331 | .statfs = gfs2_statfs, | ||
1332 | .remount_fs = gfs2_remount_fs, | ||
1333 | .clear_inode = gfs2_clear_inode, | ||
1334 | .drop_inode = gfs2_drop_inode, | ||
1335 | .show_options = gfs2_show_options, | ||
1336 | }; | ||
1337 | |||
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 7655f5025fec..23419dc3027b 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -26,6 +26,36 @@ | |||
26 | #include "util.h" | 26 | #include "util.h" |
27 | #include "glops.h" | 27 | #include "glops.h" |
28 | 28 | ||
29 | struct gfs2_attr { | ||
30 | struct attribute attr; | ||
31 | ssize_t (*show)(struct gfs2_sbd *, char *); | ||
32 | ssize_t (*store)(struct gfs2_sbd *, const char *, size_t); | ||
33 | }; | ||
34 | |||
35 | static ssize_t gfs2_attr_show(struct kobject *kobj, struct attribute *attr, | ||
36 | char *buf) | ||
37 | { | ||
38 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | ||
39 | struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); | ||
40 | return a->show ? a->show(sdp, buf) : 0; | ||
41 | } | ||
42 | |||
43 | static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr, | ||
44 | const char *buf, size_t len) | ||
45 | { | ||
46 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | ||
47 | struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); | ||
48 | return a->store ? a->store(sdp, buf, len) : len; | ||
49 | } | ||
50 | |||
51 | static struct sysfs_ops gfs2_attr_ops = { | ||
52 | .show = gfs2_attr_show, | ||
53 | .store = gfs2_attr_store, | ||
54 | }; | ||
55 | |||
56 | |||
57 | static struct kset *gfs2_kset; | ||
58 | |||
29 | static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) | 59 | static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) |
30 | { | 60 | { |
31 | return snprintf(buf, PAGE_SIZE, "%u:%u\n", | 61 | return snprintf(buf, PAGE_SIZE, "%u:%u\n", |
@@ -212,11 +242,6 @@ static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len | |||
212 | return len; | 242 | return len; |
213 | } | 243 | } |
214 | 244 | ||
215 | struct gfs2_attr { | ||
216 | struct attribute attr; | ||
217 | ssize_t (*show)(struct gfs2_sbd *, char *); | ||
218 | ssize_t (*store)(struct gfs2_sbd *, const char *, size_t); | ||
219 | }; | ||
220 | 245 | ||
221 | #define GFS2_ATTR(name, mode, show, store) \ | 246 | #define GFS2_ATTR(name, mode, show, store) \ |
222 | static struct gfs2_attr gfs2_attr_##name = __ATTR(name, mode, show, store) | 247 | static struct gfs2_attr gfs2_attr_##name = __ATTR(name, mode, show, store) |
@@ -246,58 +271,11 @@ static struct attribute *gfs2_attrs[] = { | |||
246 | NULL, | 271 | NULL, |
247 | }; | 272 | }; |
248 | 273 | ||
249 | static ssize_t gfs2_attr_show(struct kobject *kobj, struct attribute *attr, | ||
250 | char *buf) | ||
251 | { | ||
252 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | ||
253 | struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); | ||
254 | return a->show ? a->show(sdp, buf) : 0; | ||
255 | } | ||
256 | |||
257 | static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr, | ||
258 | const char *buf, size_t len) | ||
259 | { | ||
260 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | ||
261 | struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); | ||
262 | return a->store ? a->store(sdp, buf, len) : len; | ||
263 | } | ||
264 | |||
265 | static struct sysfs_ops gfs2_attr_ops = { | ||
266 | .show = gfs2_attr_show, | ||
267 | .store = gfs2_attr_store, | ||
268 | }; | ||
269 | |||
270 | static struct kobj_type gfs2_ktype = { | 274 | static struct kobj_type gfs2_ktype = { |
271 | .default_attrs = gfs2_attrs, | 275 | .default_attrs = gfs2_attrs, |
272 | .sysfs_ops = &gfs2_attr_ops, | 276 | .sysfs_ops = &gfs2_attr_ops, |
273 | }; | 277 | }; |
274 | 278 | ||
275 | static struct kset *gfs2_kset; | ||
276 | |||
277 | /* | ||
278 | * display struct lm_lockstruct fields | ||
279 | */ | ||
280 | |||
281 | struct lockstruct_attr { | ||
282 | struct attribute attr; | ||
283 | ssize_t (*show)(struct gfs2_sbd *, char *); | ||
284 | }; | ||
285 | |||
286 | #define LOCKSTRUCT_ATTR(name, fmt) \ | ||
287 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ | ||
288 | { \ | ||
289 | return snprintf(buf, PAGE_SIZE, fmt, sdp->sd_lockstruct.ls_##name); \ | ||
290 | } \ | ||
291 | static struct lockstruct_attr lockstruct_attr_##name = __ATTR_RO(name) | ||
292 | |||
293 | LOCKSTRUCT_ATTR(jid, "%u\n"); | ||
294 | LOCKSTRUCT_ATTR(first, "%u\n"); | ||
295 | |||
296 | static struct attribute *lockstruct_attrs[] = { | ||
297 | &lockstruct_attr_jid.attr, | ||
298 | &lockstruct_attr_first.attr, | ||
299 | NULL, | ||
300 | }; | ||
301 | 279 | ||
302 | /* | 280 | /* |
303 | * lock_module. Originally from lock_dlm | 281 | * lock_module. Originally from lock_dlm |
@@ -359,34 +337,33 @@ static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf) | |||
359 | return sprintf(buf, "%d\n", ls->ls_first_done); | 337 | return sprintf(buf, "%d\n", ls->ls_first_done); |
360 | } | 338 | } |
361 | 339 | ||
362 | static ssize_t recover_show(struct gfs2_sbd *sdp, char *buf) | 340 | static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len) |
363 | { | ||
364 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
365 | return sprintf(buf, "%d\n", ls->ls_recover_jid); | ||
366 | } | ||
367 | |||
368 | static void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid) | ||
369 | { | 341 | { |
342 | unsigned jid; | ||
370 | struct gfs2_jdesc *jd; | 343 | struct gfs2_jdesc *jd; |
344 | int rv; | ||
345 | |||
346 | rv = sscanf(buf, "%u", &jid); | ||
347 | if (rv != 1) | ||
348 | return -EINVAL; | ||
371 | 349 | ||
350 | rv = -ESHUTDOWN; | ||
372 | spin_lock(&sdp->sd_jindex_spin); | 351 | spin_lock(&sdp->sd_jindex_spin); |
352 | if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) | ||
353 | goto out; | ||
354 | rv = -EBUSY; | ||
355 | if (sdp->sd_jdesc->jd_jid == jid) | ||
356 | goto out; | ||
357 | rv = -ENOENT; | ||
373 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | 358 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
374 | if (jd->jd_jid != jid) | 359 | if (jd->jd_jid != jid) |
375 | continue; | 360 | continue; |
376 | jd->jd_dirty = 1; | 361 | rv = slow_work_enqueue(&jd->jd_work); |
377 | break; | 362 | break; |
378 | } | 363 | } |
364 | out: | ||
379 | spin_unlock(&sdp->sd_jindex_spin); | 365 | spin_unlock(&sdp->sd_jindex_spin); |
380 | } | 366 | return rv ? rv : len; |
381 | |||
382 | static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | ||
383 | { | ||
384 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | ||
385 | ls->ls_recover_jid = simple_strtol(buf, NULL, 0); | ||
386 | gfs2_jdesc_make_dirty(sdp, ls->ls_recover_jid); | ||
387 | if (sdp->sd_recoverd_process) | ||
388 | wake_up_process(sdp->sd_recoverd_process); | ||
389 | return len; | ||
390 | } | 367 | } |
391 | 368 | ||
392 | static ssize_t recover_done_show(struct gfs2_sbd *sdp, char *buf) | 369 | static ssize_t recover_done_show(struct gfs2_sbd *sdp, char *buf) |
@@ -401,31 +378,31 @@ static ssize_t recover_status_show(struct gfs2_sbd *sdp, char *buf) | |||
401 | return sprintf(buf, "%d\n", ls->ls_recover_jid_status); | 378 | return sprintf(buf, "%d\n", ls->ls_recover_jid_status); |
402 | } | 379 | } |
403 | 380 | ||
404 | struct gdlm_attr { | 381 | static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf) |
405 | struct attribute attr; | 382 | { |
406 | ssize_t (*show)(struct gfs2_sbd *sdp, char *); | 383 | return sprintf(buf, "%u\n", sdp->sd_lockstruct.ls_jid); |
407 | ssize_t (*store)(struct gfs2_sbd *sdp, const char *, size_t); | 384 | } |
408 | }; | ||
409 | 385 | ||
410 | #define GDLM_ATTR(_name,_mode,_show,_store) \ | 386 | #define GDLM_ATTR(_name,_mode,_show,_store) \ |
411 | static struct gdlm_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) | 387 | static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) |
412 | 388 | ||
413 | GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); | 389 | GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); |
414 | GDLM_ATTR(block, 0644, block_show, block_store); | 390 | GDLM_ATTR(block, 0644, block_show, block_store); |
415 | GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); | 391 | GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); |
416 | GDLM_ATTR(id, 0444, lkid_show, NULL); | 392 | GDLM_ATTR(id, 0444, lkid_show, NULL); |
417 | GDLM_ATTR(first, 0444, lkfirst_show, NULL); | 393 | GDLM_ATTR(jid, 0444, jid_show, NULL); |
418 | GDLM_ATTR(first_done, 0444, first_done_show, NULL); | 394 | GDLM_ATTR(first, 0444, lkfirst_show, NULL); |
419 | GDLM_ATTR(recover, 0644, recover_show, recover_store); | 395 | GDLM_ATTR(first_done, 0444, first_done_show, NULL); |
420 | GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); | 396 | GDLM_ATTR(recover, 0200, NULL, recover_store); |
421 | GDLM_ATTR(recover_status, 0444, recover_status_show, NULL); | 397 | GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); |
398 | GDLM_ATTR(recover_status, 0444, recover_status_show, NULL); | ||
422 | 399 | ||
423 | static struct attribute *lock_module_attrs[] = { | 400 | static struct attribute *lock_module_attrs[] = { |
424 | &gdlm_attr_proto_name.attr, | 401 | &gdlm_attr_proto_name.attr, |
425 | &gdlm_attr_block.attr, | 402 | &gdlm_attr_block.attr, |
426 | &gdlm_attr_withdraw.attr, | 403 | &gdlm_attr_withdraw.attr, |
427 | &gdlm_attr_id.attr, | 404 | &gdlm_attr_id.attr, |
428 | &lockstruct_attr_jid.attr, | 405 | &gdlm_attr_jid.attr, |
429 | &gdlm_attr_first.attr, | 406 | &gdlm_attr_first.attr, |
430 | &gdlm_attr_first_done.attr, | 407 | &gdlm_attr_first_done.attr, |
431 | &gdlm_attr_recover.attr, | 408 | &gdlm_attr_recover.attr, |
@@ -435,53 +412,6 @@ static struct attribute *lock_module_attrs[] = { | |||
435 | }; | 412 | }; |
436 | 413 | ||
437 | /* | 414 | /* |
438 | * display struct gfs2_args fields | ||
439 | */ | ||
440 | |||
441 | struct args_attr { | ||
442 | struct attribute attr; | ||
443 | ssize_t (*show)(struct gfs2_sbd *, char *); | ||
444 | }; | ||
445 | |||
446 | #define ARGS_ATTR(name, fmt) \ | ||
447 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ | ||
448 | { \ | ||
449 | return snprintf(buf, PAGE_SIZE, fmt, sdp->sd_args.ar_##name); \ | ||
450 | } \ | ||
451 | static struct args_attr args_attr_##name = __ATTR_RO(name) | ||
452 | |||
453 | ARGS_ATTR(lockproto, "%s\n"); | ||
454 | ARGS_ATTR(locktable, "%s\n"); | ||
455 | ARGS_ATTR(hostdata, "%s\n"); | ||
456 | ARGS_ATTR(spectator, "%d\n"); | ||
457 | ARGS_ATTR(ignore_local_fs, "%d\n"); | ||
458 | ARGS_ATTR(localcaching, "%d\n"); | ||
459 | ARGS_ATTR(localflocks, "%d\n"); | ||
460 | ARGS_ATTR(debug, "%d\n"); | ||
461 | ARGS_ATTR(upgrade, "%d\n"); | ||
462 | ARGS_ATTR(posix_acl, "%d\n"); | ||
463 | ARGS_ATTR(quota, "%u\n"); | ||
464 | ARGS_ATTR(suiddir, "%d\n"); | ||
465 | ARGS_ATTR(data, "%d\n"); | ||
466 | |||
467 | static struct attribute *args_attrs[] = { | ||
468 | &args_attr_lockproto.attr, | ||
469 | &args_attr_locktable.attr, | ||
470 | &args_attr_hostdata.attr, | ||
471 | &args_attr_spectator.attr, | ||
472 | &args_attr_ignore_local_fs.attr, | ||
473 | &args_attr_localcaching.attr, | ||
474 | &args_attr_localflocks.attr, | ||
475 | &args_attr_debug.attr, | ||
476 | &args_attr_upgrade.attr, | ||
477 | &args_attr_posix_acl.attr, | ||
478 | &args_attr_quota.attr, | ||
479 | &args_attr_suiddir.attr, | ||
480 | &args_attr_data.attr, | ||
481 | NULL, | ||
482 | }; | ||
483 | |||
484 | /* | ||
485 | * get and set struct gfs2_tune fields | 415 | * get and set struct gfs2_tune fields |
486 | */ | 416 | */ |
487 | 417 | ||
@@ -531,14 +461,8 @@ static ssize_t tune_set(struct gfs2_sbd *sdp, unsigned int *field, | |||
531 | return len; | 461 | return len; |
532 | } | 462 | } |
533 | 463 | ||
534 | struct tune_attr { | ||
535 | struct attribute attr; | ||
536 | ssize_t (*show)(struct gfs2_sbd *, char *); | ||
537 | ssize_t (*store)(struct gfs2_sbd *, const char *, size_t); | ||
538 | }; | ||
539 | |||
540 | #define TUNE_ATTR_3(name, show, store) \ | 464 | #define TUNE_ATTR_3(name, show, store) \ |
541 | static struct tune_attr tune_attr_##name = __ATTR(name, 0644, show, store) | 465 | static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store) |
542 | 466 | ||
543 | #define TUNE_ATTR_2(name, store) \ | 467 | #define TUNE_ATTR_2(name, store) \ |
544 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ | 468 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ |
@@ -554,15 +478,6 @@ static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ | |||
554 | } \ | 478 | } \ |
555 | TUNE_ATTR_2(name, name##_store) | 479 | TUNE_ATTR_2(name, name##_store) |
556 | 480 | ||
557 | #define TUNE_ATTR_DAEMON(name, process) \ | ||
558 | static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ | ||
559 | { \ | ||
560 | ssize_t r = tune_set(sdp, &sdp->sd_tune.gt_##name, 1, buf, len); \ | ||
561 | wake_up_process(sdp->sd_##process); \ | ||
562 | return r; \ | ||
563 | } \ | ||
564 | TUNE_ATTR_2(name, name##_store) | ||
565 | |||
566 | TUNE_ATTR(incore_log_blocks, 0); | 481 | TUNE_ATTR(incore_log_blocks, 0); |
567 | TUNE_ATTR(log_flush_secs, 0); | 482 | TUNE_ATTR(log_flush_secs, 0); |
568 | TUNE_ATTR(quota_warn_period, 0); | 483 | TUNE_ATTR(quota_warn_period, 0); |
@@ -574,8 +489,6 @@ TUNE_ATTR(new_files_jdata, 0); | |||
574 | TUNE_ATTR(quota_simul_sync, 1); | 489 | TUNE_ATTR(quota_simul_sync, 1); |
575 | TUNE_ATTR(stall_secs, 1); | 490 | TUNE_ATTR(stall_secs, 1); |
576 | TUNE_ATTR(statfs_quantum, 1); | 491 | TUNE_ATTR(statfs_quantum, 1); |
577 | TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); | ||
578 | TUNE_ATTR_DAEMON(logd_secs, logd_process); | ||
579 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); | 492 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); |
580 | 493 | ||
581 | static struct attribute *tune_attrs[] = { | 494 | static struct attribute *tune_attrs[] = { |
@@ -589,23 +502,11 @@ static struct attribute *tune_attrs[] = { | |||
589 | &tune_attr_quota_simul_sync.attr, | 502 | &tune_attr_quota_simul_sync.attr, |
590 | &tune_attr_stall_secs.attr, | 503 | &tune_attr_stall_secs.attr, |
591 | &tune_attr_statfs_quantum.attr, | 504 | &tune_attr_statfs_quantum.attr, |
592 | &tune_attr_recoverd_secs.attr, | ||
593 | &tune_attr_logd_secs.attr, | ||
594 | &tune_attr_quota_scale.attr, | 505 | &tune_attr_quota_scale.attr, |
595 | &tune_attr_new_files_jdata.attr, | 506 | &tune_attr_new_files_jdata.attr, |
596 | NULL, | 507 | NULL, |
597 | }; | 508 | }; |
598 | 509 | ||
599 | static struct attribute_group lockstruct_group = { | ||
600 | .name = "lockstruct", | ||
601 | .attrs = lockstruct_attrs, | ||
602 | }; | ||
603 | |||
604 | static struct attribute_group args_group = { | ||
605 | .name = "args", | ||
606 | .attrs = args_attrs, | ||
607 | }; | ||
608 | |||
609 | static struct attribute_group tune_group = { | 510 | static struct attribute_group tune_group = { |
610 | .name = "tune", | 511 | .name = "tune", |
611 | .attrs = tune_attrs, | 512 | .attrs = tune_attrs, |
@@ -626,17 +527,9 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | |||
626 | if (error) | 527 | if (error) |
627 | goto fail; | 528 | goto fail; |
628 | 529 | ||
629 | error = sysfs_create_group(&sdp->sd_kobj, &lockstruct_group); | ||
630 | if (error) | ||
631 | goto fail_reg; | ||
632 | |||
633 | error = sysfs_create_group(&sdp->sd_kobj, &args_group); | ||
634 | if (error) | ||
635 | goto fail_lockstruct; | ||
636 | |||
637 | error = sysfs_create_group(&sdp->sd_kobj, &tune_group); | 530 | error = sysfs_create_group(&sdp->sd_kobj, &tune_group); |
638 | if (error) | 531 | if (error) |
639 | goto fail_args; | 532 | goto fail_reg; |
640 | 533 | ||
641 | error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group); | 534 | error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group); |
642 | if (error) | 535 | if (error) |
@@ -647,10 +540,6 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | |||
647 | 540 | ||
648 | fail_tune: | 541 | fail_tune: |
649 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); | 542 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); |
650 | fail_args: | ||
651 | sysfs_remove_group(&sdp->sd_kobj, &args_group); | ||
652 | fail_lockstruct: | ||
653 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); | ||
654 | fail_reg: | 543 | fail_reg: |
655 | kobject_put(&sdp->sd_kobj); | 544 | kobject_put(&sdp->sd_kobj); |
656 | fail: | 545 | fail: |
@@ -661,8 +550,6 @@ fail: | |||
661 | void gfs2_sys_fs_del(struct gfs2_sbd *sdp) | 550 | void gfs2_sys_fs_del(struct gfs2_sbd *sdp) |
662 | { | 551 | { |
663 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); | 552 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); |
664 | sysfs_remove_group(&sdp->sd_kobj, &args_group); | ||
665 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); | ||
666 | sysfs_remove_group(&sdp->sd_kobj, &lock_module_group); | 553 | sysfs_remove_group(&sdp->sd_kobj, &lock_module_group); |
667 | kobject_put(&sdp->sd_kobj); | 554 | kobject_put(&sdp->sd_kobj); |
668 | } | 555 | } |
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 053752d4b27f..4ef0e9fa3549 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c | |||
@@ -33,6 +33,9 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, | |||
33 | BUG_ON(current->journal_info); | 33 | BUG_ON(current->journal_info); |
34 | BUG_ON(blocks == 0 && revokes == 0); | 34 | BUG_ON(blocks == 0 && revokes == 0); |
35 | 35 | ||
36 | if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) | ||
37 | return -EROFS; | ||
38 | |||
36 | tr = kzalloc(sizeof(struct gfs2_trans), GFP_NOFS); | 39 | tr = kzalloc(sizeof(struct gfs2_trans), GFP_NOFS); |
37 | if (!tr) | 40 | if (!tr) |
38 | return -ENOMEM; | 41 | return -ENOMEM; |
@@ -54,12 +57,6 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, | |||
54 | if (error) | 57 | if (error) |
55 | goto fail_holder_uninit; | 58 | goto fail_holder_uninit; |
56 | 59 | ||
57 | if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { | ||
58 | tr->tr_t_gh.gh_flags |= GL_NOCACHE; | ||
59 | error = -EROFS; | ||
60 | goto fail_gunlock; | ||
61 | } | ||
62 | |||
63 | error = gfs2_log_reserve(sdp, tr->tr_reserved); | 60 | error = gfs2_log_reserve(sdp, tr->tr_reserved); |
64 | if (error) | 61 | if (error) |
65 | goto fail_gunlock; | 62 | goto fail_gunlock; |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index c1462d43e721..941c8425c10b 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/dnotify.h> | 30 | #include <linux/dnotify.h> |
31 | #include <linux/statfs.h> | 31 | #include <linux/statfs.h> |
32 | #include <linux/security.h> | 32 | #include <linux/security.h> |
33 | #include <linux/ima.h> | ||
33 | 34 | ||
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
35 | 36 | ||
@@ -986,6 +987,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag) | |||
986 | &hugetlbfs_file_operations); | 987 | &hugetlbfs_file_operations); |
987 | if (!file) | 988 | if (!file) |
988 | goto out_dentry; /* inode is already attached */ | 989 | goto out_dentry; /* inode is already attached */ |
990 | ima_counts_get(file); | ||
989 | 991 | ||
990 | return file; | 992 | return file; |
991 | 993 | ||
diff --git a/fs/ioctl.c b/fs/ioctl.c index 82d9c42b8bac..286f38dfc6c0 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -414,10 +414,6 @@ static int file_ioctl(struct file *filp, unsigned int cmd, | |||
414 | switch (cmd) { | 414 | switch (cmd) { |
415 | case FIBMAP: | 415 | case FIBMAP: |
416 | return ioctl_fibmap(filp, p); | 416 | return ioctl_fibmap(filp, p); |
417 | case FS_IOC_FIEMAP: | ||
418 | return ioctl_fiemap(filp, arg); | ||
419 | case FIGETBSZ: | ||
420 | return put_user(inode->i_sb->s_blocksize, p); | ||
421 | case FIONREAD: | 417 | case FIONREAD: |
422 | return put_user(i_size_read(inode) - filp->f_pos, p); | 418 | return put_user(i_size_read(inode) - filp->f_pos, p); |
423 | } | 419 | } |
@@ -557,6 +553,16 @@ int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, | |||
557 | error = ioctl_fsthaw(filp); | 553 | error = ioctl_fsthaw(filp); |
558 | break; | 554 | break; |
559 | 555 | ||
556 | case FS_IOC_FIEMAP: | ||
557 | return ioctl_fiemap(filp, arg); | ||
558 | |||
559 | case FIGETBSZ: | ||
560 | { | ||
561 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
562 | int __user *p = (int __user *)arg; | ||
563 | return put_user(inode->i_sb->s_blocksize, p); | ||
564 | } | ||
565 | |||
560 | default: | 566 | default: |
561 | if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) | 567 | if (S_ISREG(filp->f_path.dentry->d_inode->i_mode)) |
562 | error = file_ioctl(filp, cmd, arg); | 568 | error = file_ioctl(filp, cmd, arg); |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 58144102bf25..62be7d294ec2 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -1781,7 +1781,7 @@ int jbd2_journal_wipe(journal_t *journal, int write) | |||
1781 | * Journal abort has very specific semantics, which we describe | 1781 | * Journal abort has very specific semantics, which we describe |
1782 | * for journal abort. | 1782 | * for journal abort. |
1783 | * | 1783 | * |
1784 | * Two internal function, which provide abort to te jbd layer | 1784 | * Two internal functions, which provide abort to the jbd layer |
1785 | * itself are here. | 1785 | * itself are here. |
1786 | */ | 1786 | */ |
1787 | 1787 | ||
@@ -1879,7 +1879,7 @@ void jbd2_journal_abort(journal_t *journal, int errno) | |||
1879 | * int jbd2_journal_errno () - returns the journal's error state. | 1879 | * int jbd2_journal_errno () - returns the journal's error state. |
1880 | * @journal: journal to examine. | 1880 | * @journal: journal to examine. |
1881 | * | 1881 | * |
1882 | * This is the errno numbet set with jbd2_journal_abort(), the last | 1882 | * This is the errno number set with jbd2_journal_abort(), the last |
1883 | * time the journal was mounted - if the journal was stopped | 1883 | * time the journal was mounted - if the journal was stopped |
1884 | * without calling abort this will be 0. | 1884 | * without calling abort this will be 0. |
1885 | * | 1885 | * |
@@ -1903,7 +1903,7 @@ int jbd2_journal_errno(journal_t *journal) | |||
1903 | * int jbd2_journal_clear_err () - clears the journal's error state | 1903 | * int jbd2_journal_clear_err () - clears the journal's error state |
1904 | * @journal: journal to act on. | 1904 | * @journal: journal to act on. |
1905 | * | 1905 | * |
1906 | * An error must be cleared or Acked to take a FS out of readonly | 1906 | * An error must be cleared or acked to take a FS out of readonly |
1907 | * mode. | 1907 | * mode. |
1908 | */ | 1908 | */ |
1909 | int jbd2_journal_clear_err(journal_t *journal) | 1909 | int jbd2_journal_clear_err(journal_t *journal) |
@@ -1923,7 +1923,7 @@ int jbd2_journal_clear_err(journal_t *journal) | |||
1923 | * void jbd2_journal_ack_err() - Ack journal err. | 1923 | * void jbd2_journal_ack_err() - Ack journal err. |
1924 | * @journal: journal to act on. | 1924 | * @journal: journal to act on. |
1925 | * | 1925 | * |
1926 | * An error must be cleared or Acked to take a FS out of readonly | 1926 | * An error must be cleared or acked to take a FS out of readonly |
1927 | * mode. | 1927 | * mode. |
1928 | */ | 1928 | */ |
1929 | void jbd2_journal_ack_err(journal_t *journal) | 1929 | void jbd2_journal_ack_err(journal_t *journal) |
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 346057218edc..0fc30407f039 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c | |||
@@ -2571,6 +2571,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) | |||
2571 | 2571 | ||
2572 | txAbort(tid, 0); | 2572 | txAbort(tid, 0); |
2573 | txEnd(tid); | 2573 | txEnd(tid); |
2574 | mutex_unlock(&JFS_IP(ipimap)->commit_mutex); | ||
2574 | 2575 | ||
2575 | /* release the inode map lock */ | 2576 | /* release the inode map lock */ |
2576 | IWRITE_UNLOCK(ipimap); | 2577 | IWRITE_UNLOCK(ipimap); |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 6f21adf9479a..d9b0e92b3602 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -720,8 +720,10 @@ static ssize_t jfs_quota_write(struct super_block *sb, int type, | |||
720 | blk++; | 720 | blk++; |
721 | } | 721 | } |
722 | out: | 722 | out: |
723 | if (len == towrite) | 723 | if (len == towrite) { |
724 | mutex_unlock(&inode->i_mutex); | ||
724 | return err; | 725 | return err; |
726 | } | ||
725 | if (inode->i_size < off+len-towrite) | 727 | if (inode->i_size < off+len-towrite) |
726 | i_size_write(inode, off+len-towrite); | 728 | i_size_write(inode, off+len-towrite); |
727 | inode->i_version++; | 729 | inode->i_version++; |
diff --git a/fs/mpage.c b/fs/mpage.c index 680ba60863ff..42381bd6543b 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
@@ -379,7 +379,8 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages, | |||
379 | struct buffer_head map_bh; | 379 | struct buffer_head map_bh; |
380 | unsigned long first_logical_block = 0; | 380 | unsigned long first_logical_block = 0; |
381 | 381 | ||
382 | clear_buffer_mapped(&map_bh); | 382 | map_bh.b_state = 0; |
383 | map_bh.b_size = 0; | ||
383 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { | 384 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { |
384 | struct page *page = list_entry(pages->prev, struct page, lru); | 385 | struct page *page = list_entry(pages->prev, struct page, lru); |
385 | 386 | ||
@@ -412,7 +413,8 @@ int mpage_readpage(struct page *page, get_block_t get_block) | |||
412 | struct buffer_head map_bh; | 413 | struct buffer_head map_bh; |
413 | unsigned long first_logical_block = 0; | 414 | unsigned long first_logical_block = 0; |
414 | 415 | ||
415 | clear_buffer_mapped(&map_bh); | 416 | map_bh.b_state = 0; |
417 | map_bh.b_size = 0; | ||
416 | bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio, | 418 | bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio, |
417 | &map_bh, &first_logical_block, get_block); | 419 | &map_bh, &first_logical_block, get_block); |
418 | if (bio) | 420 | if (bio) |
diff --git a/fs/namei.c b/fs/namei.c index 967c3db92724..c82805d088e1 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -853,7 +853,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd) | |||
853 | err = inode_permission(nd->path.dentry->d_inode, | 853 | err = inode_permission(nd->path.dentry->d_inode, |
854 | MAY_EXEC); | 854 | MAY_EXEC); |
855 | if (!err) | 855 | if (!err) |
856 | err = ima_path_check(&nd->path, MAY_EXEC); | 856 | err = ima_path_check(&nd->path, MAY_EXEC, |
857 | IMA_COUNT_UPDATE); | ||
857 | if (err) | 858 | if (err) |
858 | break; | 859 | break; |
859 | 860 | ||
@@ -1515,7 +1516,8 @@ int may_open(struct path *path, int acc_mode, int flag) | |||
1515 | return error; | 1516 | return error; |
1516 | 1517 | ||
1517 | error = ima_path_check(path, | 1518 | error = ima_path_check(path, |
1518 | acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); | 1519 | acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC), |
1520 | IMA_COUNT_UPDATE); | ||
1519 | if (error) | 1521 | if (error) |
1520 | return error; | 1522 | return error; |
1521 | /* | 1523 | /* |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index b660435978d2..bd584bcf1d9f 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/security.h> | 55 | #include <linux/security.h> |
56 | #endif /* CONFIG_NFSD_V4 */ | 56 | #endif /* CONFIG_NFSD_V4 */ |
57 | #include <linux/jhash.h> | 57 | #include <linux/jhash.h> |
58 | #include <linux/ima.h> | ||
58 | 59 | ||
59 | #include <asm/uaccess.h> | 60 | #include <asm/uaccess.h> |
60 | 61 | ||
@@ -735,6 +736,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
735 | flags, cred); | 736 | flags, cred); |
736 | if (IS_ERR(*filp)) | 737 | if (IS_ERR(*filp)) |
737 | host_err = PTR_ERR(*filp); | 738 | host_err = PTR_ERR(*filp); |
739 | else | ||
740 | ima_counts_get(*filp); | ||
738 | out_nfserr: | 741 | out_nfserr: |
739 | err = nfserrno(host_err); | 742 | err = nfserrno(host_err); |
740 | out: | 743 | out: |
@@ -2024,6 +2027,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
2024 | struct dentry *dentry, int acc) | 2027 | struct dentry *dentry, int acc) |
2025 | { | 2028 | { |
2026 | struct inode *inode = dentry->d_inode; | 2029 | struct inode *inode = dentry->d_inode; |
2030 | struct path path; | ||
2027 | int err; | 2031 | int err; |
2028 | 2032 | ||
2029 | if (acc == NFSD_MAY_NOP) | 2033 | if (acc == NFSD_MAY_NOP) |
@@ -2096,7 +2100,17 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
2096 | if (err == -EACCES && S_ISREG(inode->i_mode) && | 2100 | if (err == -EACCES && S_ISREG(inode->i_mode) && |
2097 | acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE)) | 2101 | acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE)) |
2098 | err = inode_permission(inode, MAY_EXEC); | 2102 | err = inode_permission(inode, MAY_EXEC); |
2103 | if (err) | ||
2104 | goto nfsd_out; | ||
2099 | 2105 | ||
2106 | /* Do integrity (permission) checking now, but defer incrementing | ||
2107 | * IMA counts to the actual file open. | ||
2108 | */ | ||
2109 | path.mnt = exp->ex_path.mnt; | ||
2110 | path.dentry = dentry; | ||
2111 | err = ima_path_check(&path, acc & (MAY_READ | MAY_WRITE | MAY_EXEC), | ||
2112 | IMA_COUNT_LEAVE); | ||
2113 | nfsd_out: | ||
2100 | return err? nfserrno(err) : 0; | 2114 | return err? nfserrno(err) : 0; |
2101 | } | 2115 | } |
2102 | 2116 | ||
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 7f65b3be4aa9..a91f15b8673c 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
@@ -515,7 +515,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data) | |||
515 | 515 | ||
516 | blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); | 516 | blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); |
517 | if (sb->s_blocksize != blocksize) { | 517 | if (sb->s_blocksize != blocksize) { |
518 | int hw_blocksize = bdev_hardsect_size(sb->s_bdev); | 518 | int hw_blocksize = bdev_logical_block_size(sb->s_bdev); |
519 | 519 | ||
520 | if (blocksize < hw_blocksize) { | 520 | if (blocksize < hw_blocksize) { |
521 | printk(KERN_ERR | 521 | printk(KERN_ERR |
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index f76951dcd4a6..6aa7c4713536 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/blkdev.h> /* For bdev_hardsect_size(). */ | 28 | #include <linux/blkdev.h> /* For bdev_logical_block_size(). */ |
29 | #include <linux/backing-dev.h> | 29 | #include <linux/backing-dev.h> |
30 | #include <linux/buffer_head.h> | 30 | #include <linux/buffer_head.h> |
31 | #include <linux/vfs.h> | 31 | #include <linux/vfs.h> |
@@ -2785,13 +2785,13 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent) | |||
2785 | goto err_out_now; | 2785 | goto err_out_now; |
2786 | 2786 | ||
2787 | /* We support sector sizes up to the PAGE_CACHE_SIZE. */ | 2787 | /* We support sector sizes up to the PAGE_CACHE_SIZE. */ |
2788 | if (bdev_hardsect_size(sb->s_bdev) > PAGE_CACHE_SIZE) { | 2788 | if (bdev_logical_block_size(sb->s_bdev) > PAGE_CACHE_SIZE) { |
2789 | if (!silent) | 2789 | if (!silent) |
2790 | ntfs_error(sb, "Device has unsupported sector size " | 2790 | ntfs_error(sb, "Device has unsupported sector size " |
2791 | "(%i). The maximum supported sector " | 2791 | "(%i). The maximum supported sector " |
2792 | "size on this architecture is %lu " | 2792 | "size on this architecture is %lu " |
2793 | "bytes.", | 2793 | "bytes.", |
2794 | bdev_hardsect_size(sb->s_bdev), | 2794 | bdev_logical_block_size(sb->s_bdev), |
2795 | PAGE_CACHE_SIZE); | 2795 | PAGE_CACHE_SIZE); |
2796 | goto err_out_now; | 2796 | goto err_out_now; |
2797 | } | 2797 | } |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 4f85eceab376..09cc25d04611 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -1371,7 +1371,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1371 | 1371 | ||
1372 | bdevname(reg->hr_bdev, reg->hr_dev_name); | 1372 | bdevname(reg->hr_bdev, reg->hr_dev_name); |
1373 | 1373 | ||
1374 | sectsize = bdev_hardsect_size(reg->hr_bdev); | 1374 | sectsize = bdev_logical_block_size(reg->hr_bdev); |
1375 | if (sectsize != reg->hr_block_bytes) { | 1375 | if (sectsize != reg->hr_block_bytes) { |
1376 | mlog(ML_ERROR, | 1376 | mlog(ML_ERROR, |
1377 | "blocksize %u incorrect for device, expected %d", | 1377 | "blocksize %u incorrect for device, expected %d", |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 79ff8d9d37e0..5c6163f55039 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -713,7 +713,7 @@ static int ocfs2_sb_probe(struct super_block *sb, | |||
713 | *bh = NULL; | 713 | *bh = NULL; |
714 | 714 | ||
715 | /* may be > 512 */ | 715 | /* may be > 512 */ |
716 | *sector_size = bdev_hardsect_size(sb->s_bdev); | 716 | *sector_size = bdev_logical_block_size(sb->s_bdev); |
717 | if (*sector_size > OCFS2_MAX_BLOCKSIZE) { | 717 | if (*sector_size > OCFS2_MAX_BLOCKSIZE) { |
718 | mlog(ML_ERROR, "Hardware sector size too large: %d (max=%d)\n", | 718 | mlog(ML_ERROR, "Hardware sector size too large: %d (max=%d)\n", |
719 | *sector_size, OCFS2_MAX_BLOCKSIZE); | 719 | *sector_size, OCFS2_MAX_BLOCKSIZE); |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 99e33ef40be4..0af36085eb28 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -219,6 +219,13 @@ ssize_t part_size_show(struct device *dev, | |||
219 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); | 219 | return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); |
220 | } | 220 | } |
221 | 221 | ||
222 | ssize_t part_alignment_offset_show(struct device *dev, | ||
223 | struct device_attribute *attr, char *buf) | ||
224 | { | ||
225 | struct hd_struct *p = dev_to_part(dev); | ||
226 | return sprintf(buf, "%llu\n", (unsigned long long)p->alignment_offset); | ||
227 | } | ||
228 | |||
222 | ssize_t part_stat_show(struct device *dev, | 229 | ssize_t part_stat_show(struct device *dev, |
223 | struct device_attribute *attr, char *buf) | 230 | struct device_attribute *attr, char *buf) |
224 | { | 231 | { |
@@ -272,6 +279,7 @@ ssize_t part_fail_store(struct device *dev, | |||
272 | static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL); | 279 | static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL); |
273 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); | 280 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); |
274 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | 281 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); |
282 | static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); | ||
275 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); | 283 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); |
276 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 284 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
277 | static struct device_attribute dev_attr_fail = | 285 | static struct device_attribute dev_attr_fail = |
@@ -282,6 +290,7 @@ static struct attribute *part_attrs[] = { | |||
282 | &dev_attr_partition.attr, | 290 | &dev_attr_partition.attr, |
283 | &dev_attr_start.attr, | 291 | &dev_attr_start.attr, |
284 | &dev_attr_size.attr, | 292 | &dev_attr_size.attr, |
293 | &dev_attr_alignment_offset.attr, | ||
285 | &dev_attr_stat.attr, | 294 | &dev_attr_stat.attr, |
286 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 295 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
287 | &dev_attr_fail.attr, | 296 | &dev_attr_fail.attr, |
@@ -383,6 +392,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
383 | pdev = part_to_dev(p); | 392 | pdev = part_to_dev(p); |
384 | 393 | ||
385 | p->start_sect = start; | 394 | p->start_sect = start; |
395 | p->alignment_offset = queue_sector_alignment_offset(disk->queue, start); | ||
386 | p->nr_sects = len; | 396 | p->nr_sects = len; |
387 | p->partno = partno; | 397 | p->partno = partno; |
388 | p->policy = get_disk_ro(disk); | 398 | p->policy = get_disk_ro(disk); |
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index 46297683cd34..fc71aab08460 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c | |||
@@ -76,7 +76,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
76 | Sector sect; | 76 | Sector sect; |
77 | 77 | ||
78 | res = 0; | 78 | res = 0; |
79 | blocksize = bdev_hardsect_size(bdev); | 79 | blocksize = bdev_logical_block_size(bdev); |
80 | if (blocksize <= 0) | 80 | if (blocksize <= 0) |
81 | goto out_exit; | 81 | goto out_exit; |
82 | i_size = i_size_read(bdev->bd_inode); | 82 | i_size = i_size_read(bdev->bd_inode); |
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 796511886f28..0028d2ef0662 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c | |||
@@ -110,7 +110,7 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev, | |||
110 | Sector sect; | 110 | Sector sect; |
111 | unsigned char *data; | 111 | unsigned char *data; |
112 | u32 this_sector, this_size; | 112 | u32 this_sector, this_size; |
113 | int sector_size = bdev_hardsect_size(bdev) / 512; | 113 | int sector_size = bdev_logical_block_size(bdev) / 512; |
114 | int loopct = 0; /* number of links followed | 114 | int loopct = 0; /* number of links followed |
115 | without finding a data partition */ | 115 | without finding a data partition */ |
116 | int i; | 116 | int i; |
@@ -415,7 +415,7 @@ static struct { | |||
415 | 415 | ||
416 | int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) | 416 | int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) |
417 | { | 417 | { |
418 | int sector_size = bdev_hardsect_size(bdev) / 512; | 418 | int sector_size = bdev_logical_block_size(bdev) / 512; |
419 | Sector sect; | 419 | Sector sect; |
420 | unsigned char *data; | 420 | unsigned char *data; |
421 | struct partition *p; | 421 | struct partition *p; |
@@ -302,6 +302,20 @@ int generic_pipe_buf_confirm(struct pipe_inode_info *info, | |||
302 | return 0; | 302 | return 0; |
303 | } | 303 | } |
304 | 304 | ||
305 | /** | ||
306 | * generic_pipe_buf_release - put a reference to a &struct pipe_buffer | ||
307 | * @pipe: the pipe that the buffer belongs to | ||
308 | * @buf: the buffer to put a reference to | ||
309 | * | ||
310 | * Description: | ||
311 | * This function releases a reference to @buf. | ||
312 | */ | ||
313 | void generic_pipe_buf_release(struct pipe_inode_info *pipe, | ||
314 | struct pipe_buffer *buf) | ||
315 | { | ||
316 | page_cache_release(buf->page); | ||
317 | } | ||
318 | |||
305 | static const struct pipe_buf_operations anon_pipe_buf_ops = { | 319 | static const struct pipe_buf_operations anon_pipe_buf_ops = { |
306 | .can_merge = 1, | 320 | .can_merge = 1, |
307 | .map = generic_pipe_buf_map, | 321 | .map = generic_pipe_buf_map, |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 3326bbf9ab95..1539e630c47d 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2128,9 +2128,15 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, | |||
2128 | if (copy_from_user(page, buf, count)) | 2128 | if (copy_from_user(page, buf, count)) |
2129 | goto out_free; | 2129 | goto out_free; |
2130 | 2130 | ||
2131 | /* Guard against adverse ptrace interaction */ | ||
2132 | length = mutex_lock_interruptible(&task->cred_guard_mutex); | ||
2133 | if (length < 0) | ||
2134 | goto out_free; | ||
2135 | |||
2131 | length = security_setprocattr(task, | 2136 | length = security_setprocattr(task, |
2132 | (char*)file->f_path.dentry->d_name.name, | 2137 | (char*)file->f_path.dentry->d_name.name, |
2133 | (void*)page, count); | 2138 | (void*)page, count); |
2139 | mutex_unlock(&task->cred_guard_mutex); | ||
2134 | out_free: | 2140 | out_free: |
2135 | free_page((unsigned long) page); | 2141 | free_page((unsigned long) page); |
2136 | out: | 2142 | out: |
diff --git a/fs/read_write.c b/fs/read_write.c index 9d1e76bb9ee1..6c8c55dec2bc 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
@@ -805,12 +805,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
805 | goto out; | 805 | goto out; |
806 | if (!(in_file->f_mode & FMODE_READ)) | 806 | if (!(in_file->f_mode & FMODE_READ)) |
807 | goto fput_in; | 807 | goto fput_in; |
808 | retval = -EINVAL; | ||
809 | in_inode = in_file->f_path.dentry->d_inode; | ||
810 | if (!in_inode) | ||
811 | goto fput_in; | ||
812 | if (!in_file->f_op || !in_file->f_op->splice_read) | ||
813 | goto fput_in; | ||
814 | retval = -ESPIPE; | 808 | retval = -ESPIPE; |
815 | if (!ppos) | 809 | if (!ppos) |
816 | ppos = &in_file->f_pos; | 810 | ppos = &in_file->f_pos; |
@@ -834,6 +828,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, | |||
834 | retval = -EINVAL; | 828 | retval = -EINVAL; |
835 | if (!out_file->f_op || !out_file->f_op->sendpage) | 829 | if (!out_file->f_op || !out_file->f_op->sendpage) |
836 | goto fput_out; | 830 | goto fput_out; |
831 | in_inode = in_file->f_path.dentry->d_inode; | ||
837 | out_inode = out_file->f_path.dentry->d_inode; | 832 | out_inode = out_file->f_path.dentry->d_inode; |
838 | retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); | 833 | retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); |
839 | if (retval < 0) | 834 | if (retval < 0) |
diff --git a/fs/splice.c b/fs/splice.c index 666953d59a35..73766d24f97b 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -507,9 +507,131 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, | |||
507 | 507 | ||
508 | return ret; | 508 | return ret; |
509 | } | 509 | } |
510 | |||
511 | EXPORT_SYMBOL(generic_file_splice_read); | 510 | EXPORT_SYMBOL(generic_file_splice_read); |
512 | 511 | ||
512 | static const struct pipe_buf_operations default_pipe_buf_ops = { | ||
513 | .can_merge = 0, | ||
514 | .map = generic_pipe_buf_map, | ||
515 | .unmap = generic_pipe_buf_unmap, | ||
516 | .confirm = generic_pipe_buf_confirm, | ||
517 | .release = generic_pipe_buf_release, | ||
518 | .steal = generic_pipe_buf_steal, | ||
519 | .get = generic_pipe_buf_get, | ||
520 | }; | ||
521 | |||
522 | static ssize_t kernel_readv(struct file *file, const struct iovec *vec, | ||
523 | unsigned long vlen, loff_t offset) | ||
524 | { | ||
525 | mm_segment_t old_fs; | ||
526 | loff_t pos = offset; | ||
527 | ssize_t res; | ||
528 | |||
529 | old_fs = get_fs(); | ||
530 | set_fs(get_ds()); | ||
531 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
532 | res = vfs_readv(file, (const struct iovec __user *)vec, vlen, &pos); | ||
533 | set_fs(old_fs); | ||
534 | |||
535 | return res; | ||
536 | } | ||
537 | |||
538 | static ssize_t kernel_write(struct file *file, const char *buf, size_t count, | ||
539 | loff_t pos) | ||
540 | { | ||
541 | mm_segment_t old_fs; | ||
542 | ssize_t res; | ||
543 | |||
544 | old_fs = get_fs(); | ||
545 | set_fs(get_ds()); | ||
546 | /* The cast to a user pointer is valid due to the set_fs() */ | ||
547 | res = vfs_write(file, (const char __user *)buf, count, &pos); | ||
548 | set_fs(old_fs); | ||
549 | |||
550 | return res; | ||
551 | } | ||
552 | |||
553 | ssize_t default_file_splice_read(struct file *in, loff_t *ppos, | ||
554 | struct pipe_inode_info *pipe, size_t len, | ||
555 | unsigned int flags) | ||
556 | { | ||
557 | unsigned int nr_pages; | ||
558 | unsigned int nr_freed; | ||
559 | size_t offset; | ||
560 | struct page *pages[PIPE_BUFFERS]; | ||
561 | struct partial_page partial[PIPE_BUFFERS]; | ||
562 | struct iovec vec[PIPE_BUFFERS]; | ||
563 | pgoff_t index; | ||
564 | ssize_t res; | ||
565 | size_t this_len; | ||
566 | int error; | ||
567 | int i; | ||
568 | struct splice_pipe_desc spd = { | ||
569 | .pages = pages, | ||
570 | .partial = partial, | ||
571 | .flags = flags, | ||
572 | .ops = &default_pipe_buf_ops, | ||
573 | .spd_release = spd_release_page, | ||
574 | }; | ||
575 | |||
576 | index = *ppos >> PAGE_CACHE_SHIFT; | ||
577 | offset = *ppos & ~PAGE_CACHE_MASK; | ||
578 | nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | ||
579 | |||
580 | for (i = 0; i < nr_pages && i < PIPE_BUFFERS && len; i++) { | ||
581 | struct page *page; | ||
582 | |||
583 | page = alloc_page(GFP_USER); | ||
584 | error = -ENOMEM; | ||
585 | if (!page) | ||
586 | goto err; | ||
587 | |||
588 | this_len = min_t(size_t, len, PAGE_CACHE_SIZE - offset); | ||
589 | vec[i].iov_base = (void __user *) page_address(page); | ||
590 | vec[i].iov_len = this_len; | ||
591 | pages[i] = page; | ||
592 | spd.nr_pages++; | ||
593 | len -= this_len; | ||
594 | offset = 0; | ||
595 | } | ||
596 | |||
597 | res = kernel_readv(in, vec, spd.nr_pages, *ppos); | ||
598 | if (res < 0) { | ||
599 | error = res; | ||
600 | goto err; | ||
601 | } | ||
602 | |||
603 | error = 0; | ||
604 | if (!res) | ||
605 | goto err; | ||
606 | |||
607 | nr_freed = 0; | ||
608 | for (i = 0; i < spd.nr_pages; i++) { | ||
609 | this_len = min_t(size_t, vec[i].iov_len, res); | ||
610 | partial[i].offset = 0; | ||
611 | partial[i].len = this_len; | ||
612 | if (!this_len) { | ||
613 | __free_page(pages[i]); | ||
614 | pages[i] = NULL; | ||
615 | nr_freed++; | ||
616 | } | ||
617 | res -= this_len; | ||
618 | } | ||
619 | spd.nr_pages -= nr_freed; | ||
620 | |||
621 | res = splice_to_pipe(pipe, &spd); | ||
622 | if (res > 0) | ||
623 | *ppos += res; | ||
624 | |||
625 | return res; | ||
626 | |||
627 | err: | ||
628 | for (i = 0; i < spd.nr_pages; i++) | ||
629 | __free_page(pages[i]); | ||
630 | |||
631 | return error; | ||
632 | } | ||
633 | EXPORT_SYMBOL(default_file_splice_read); | ||
634 | |||
513 | /* | 635 | /* |
514 | * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos' | 636 | * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos' |
515 | * using sendpage(). Return the number of bytes sent. | 637 | * using sendpage(). Return the number of bytes sent. |
@@ -881,6 +1003,36 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
881 | 1003 | ||
882 | EXPORT_SYMBOL(generic_file_splice_write); | 1004 | EXPORT_SYMBOL(generic_file_splice_write); |
883 | 1005 | ||
1006 | static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | ||
1007 | struct splice_desc *sd) | ||
1008 | { | ||
1009 | int ret; | ||
1010 | void *data; | ||
1011 | |||
1012 | ret = buf->ops->confirm(pipe, buf); | ||
1013 | if (ret) | ||
1014 | return ret; | ||
1015 | |||
1016 | data = buf->ops->map(pipe, buf, 0); | ||
1017 | ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos); | ||
1018 | buf->ops->unmap(pipe, buf, data); | ||
1019 | |||
1020 | return ret; | ||
1021 | } | ||
1022 | |||
1023 | static ssize_t default_file_splice_write(struct pipe_inode_info *pipe, | ||
1024 | struct file *out, loff_t *ppos, | ||
1025 | size_t len, unsigned int flags) | ||
1026 | { | ||
1027 | ssize_t ret; | ||
1028 | |||
1029 | ret = splice_from_pipe(pipe, out, ppos, len, flags, write_pipe_buf); | ||
1030 | if (ret > 0) | ||
1031 | *ppos += ret; | ||
1032 | |||
1033 | return ret; | ||
1034 | } | ||
1035 | |||
884 | /** | 1036 | /** |
885 | * generic_splice_sendpage - splice data from a pipe to a socket | 1037 | * generic_splice_sendpage - splice data from a pipe to a socket |
886 | * @pipe: pipe to splice from | 1038 | * @pipe: pipe to splice from |
@@ -908,11 +1060,10 @@ EXPORT_SYMBOL(generic_splice_sendpage); | |||
908 | static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, | 1060 | static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, |
909 | loff_t *ppos, size_t len, unsigned int flags) | 1061 | loff_t *ppos, size_t len, unsigned int flags) |
910 | { | 1062 | { |
1063 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, | ||
1064 | loff_t *, size_t, unsigned int); | ||
911 | int ret; | 1065 | int ret; |
912 | 1066 | ||
913 | if (unlikely(!out->f_op || !out->f_op->splice_write)) | ||
914 | return -EINVAL; | ||
915 | |||
916 | if (unlikely(!(out->f_mode & FMODE_WRITE))) | 1067 | if (unlikely(!(out->f_mode & FMODE_WRITE))) |
917 | return -EBADF; | 1068 | return -EBADF; |
918 | 1069 | ||
@@ -923,7 +1074,11 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, | |||
923 | if (unlikely(ret < 0)) | 1074 | if (unlikely(ret < 0)) |
924 | return ret; | 1075 | return ret; |
925 | 1076 | ||
926 | return out->f_op->splice_write(pipe, out, ppos, len, flags); | 1077 | splice_write = out->f_op->splice_write; |
1078 | if (!splice_write) | ||
1079 | splice_write = default_file_splice_write; | ||
1080 | |||
1081 | return splice_write(pipe, out, ppos, len, flags); | ||
927 | } | 1082 | } |
928 | 1083 | ||
929 | /* | 1084 | /* |
@@ -933,11 +1088,10 @@ static long do_splice_to(struct file *in, loff_t *ppos, | |||
933 | struct pipe_inode_info *pipe, size_t len, | 1088 | struct pipe_inode_info *pipe, size_t len, |
934 | unsigned int flags) | 1089 | unsigned int flags) |
935 | { | 1090 | { |
1091 | ssize_t (*splice_read)(struct file *, loff_t *, | ||
1092 | struct pipe_inode_info *, size_t, unsigned int); | ||
936 | int ret; | 1093 | int ret; |
937 | 1094 | ||
938 | if (unlikely(!in->f_op || !in->f_op->splice_read)) | ||
939 | return -EINVAL; | ||
940 | |||
941 | if (unlikely(!(in->f_mode & FMODE_READ))) | 1095 | if (unlikely(!(in->f_mode & FMODE_READ))) |
942 | return -EBADF; | 1096 | return -EBADF; |
943 | 1097 | ||
@@ -945,7 +1099,11 @@ static long do_splice_to(struct file *in, loff_t *ppos, | |||
945 | if (unlikely(ret < 0)) | 1099 | if (unlikely(ret < 0)) |
946 | return ret; | 1100 | return ret; |
947 | 1101 | ||
948 | return in->f_op->splice_read(in, ppos, pipe, len, flags); | 1102 | splice_read = in->f_op->splice_read; |
1103 | if (!splice_read) | ||
1104 | splice_read = default_file_splice_read; | ||
1105 | |||
1106 | return splice_read(in, ppos, pipe, len, flags); | ||
949 | } | 1107 | } |
950 | 1108 | ||
951 | /** | 1109 | /** |
@@ -1112,6 +1270,9 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | |||
1112 | return ret; | 1270 | return ret; |
1113 | } | 1271 | } |
1114 | 1272 | ||
1273 | static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe, | ||
1274 | struct pipe_inode_info *opipe, | ||
1275 | size_t len, unsigned int flags); | ||
1115 | /* | 1276 | /* |
1116 | * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same | 1277 | * After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same |
1117 | * location, so checking ->i_pipe is not enough to verify that this is a | 1278 | * location, so checking ->i_pipe is not enough to verify that this is a |
@@ -1132,12 +1293,32 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1132 | struct file *out, loff_t __user *off_out, | 1293 | struct file *out, loff_t __user *off_out, |
1133 | size_t len, unsigned int flags) | 1294 | size_t len, unsigned int flags) |
1134 | { | 1295 | { |
1135 | struct pipe_inode_info *pipe; | 1296 | struct pipe_inode_info *ipipe; |
1297 | struct pipe_inode_info *opipe; | ||
1136 | loff_t offset, *off; | 1298 | loff_t offset, *off; |
1137 | long ret; | 1299 | long ret; |
1138 | 1300 | ||
1139 | pipe = pipe_info(in->f_path.dentry->d_inode); | 1301 | ipipe = pipe_info(in->f_path.dentry->d_inode); |
1140 | if (pipe) { | 1302 | opipe = pipe_info(out->f_path.dentry->d_inode); |
1303 | |||
1304 | if (ipipe && opipe) { | ||
1305 | if (off_in || off_out) | ||
1306 | return -ESPIPE; | ||
1307 | |||
1308 | if (!(in->f_mode & FMODE_READ)) | ||
1309 | return -EBADF; | ||
1310 | |||
1311 | if (!(out->f_mode & FMODE_WRITE)) | ||
1312 | return -EBADF; | ||
1313 | |||
1314 | /* Splicing to self would be fun, but... */ | ||
1315 | if (ipipe == opipe) | ||
1316 | return -EINVAL; | ||
1317 | |||
1318 | return splice_pipe_to_pipe(ipipe, opipe, len, flags); | ||
1319 | } | ||
1320 | |||
1321 | if (ipipe) { | ||
1141 | if (off_in) | 1322 | if (off_in) |
1142 | return -ESPIPE; | 1323 | return -ESPIPE; |
1143 | if (off_out) { | 1324 | if (off_out) { |
@@ -1149,7 +1330,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1149 | } else | 1330 | } else |
1150 | off = &out->f_pos; | 1331 | off = &out->f_pos; |
1151 | 1332 | ||
1152 | ret = do_splice_from(pipe, out, off, len, flags); | 1333 | ret = do_splice_from(ipipe, out, off, len, flags); |
1153 | 1334 | ||
1154 | if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) | 1335 | if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) |
1155 | ret = -EFAULT; | 1336 | ret = -EFAULT; |
@@ -1157,8 +1338,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1157 | return ret; | 1338 | return ret; |
1158 | } | 1339 | } |
1159 | 1340 | ||
1160 | pipe = pipe_info(out->f_path.dentry->d_inode); | 1341 | if (opipe) { |
1161 | if (pipe) { | ||
1162 | if (off_out) | 1342 | if (off_out) |
1163 | return -ESPIPE; | 1343 | return -ESPIPE; |
1164 | if (off_in) { | 1344 | if (off_in) { |
@@ -1170,7 +1350,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
1170 | } else | 1350 | } else |
1171 | off = &in->f_pos; | 1351 | off = &in->f_pos; |
1172 | 1352 | ||
1173 | ret = do_splice_to(in, off, pipe, len, flags); | 1353 | ret = do_splice_to(in, off, opipe, len, flags); |
1174 | 1354 | ||
1175 | if (off_in && copy_to_user(off_in, off, sizeof(loff_t))) | 1355 | if (off_in && copy_to_user(off_in, off, sizeof(loff_t))) |
1176 | ret = -EFAULT; | 1356 | ret = -EFAULT; |
@@ -1511,7 +1691,7 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, | |||
1511 | * Make sure there's data to read. Wait for input if we can, otherwise | 1691 | * Make sure there's data to read. Wait for input if we can, otherwise |
1512 | * return an appropriate error. | 1692 | * return an appropriate error. |
1513 | */ | 1693 | */ |
1514 | static int link_ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags) | 1694 | static int ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags) |
1515 | { | 1695 | { |
1516 | int ret; | 1696 | int ret; |
1517 | 1697 | ||
@@ -1549,7 +1729,7 @@ static int link_ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags) | |||
1549 | * Make sure there's writeable room. Wait for room if we can, otherwise | 1729 | * Make sure there's writeable room. Wait for room if we can, otherwise |
1550 | * return an appropriate error. | 1730 | * return an appropriate error. |
1551 | */ | 1731 | */ |
1552 | static int link_opipe_prep(struct pipe_inode_info *pipe, unsigned int flags) | 1732 | static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags) |
1553 | { | 1733 | { |
1554 | int ret; | 1734 | int ret; |
1555 | 1735 | ||
@@ -1587,6 +1767,124 @@ static int link_opipe_prep(struct pipe_inode_info *pipe, unsigned int flags) | |||
1587 | } | 1767 | } |
1588 | 1768 | ||
1589 | /* | 1769 | /* |
1770 | * Splice contents of ipipe to opipe. | ||
1771 | */ | ||
1772 | static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe, | ||
1773 | struct pipe_inode_info *opipe, | ||
1774 | size_t len, unsigned int flags) | ||
1775 | { | ||
1776 | struct pipe_buffer *ibuf, *obuf; | ||
1777 | int ret = 0, nbuf; | ||
1778 | bool input_wakeup = false; | ||
1779 | |||
1780 | |||
1781 | retry: | ||
1782 | ret = ipipe_prep(ipipe, flags); | ||
1783 | if (ret) | ||
1784 | return ret; | ||
1785 | |||
1786 | ret = opipe_prep(opipe, flags); | ||
1787 | if (ret) | ||
1788 | return ret; | ||
1789 | |||
1790 | /* | ||
1791 | * Potential ABBA deadlock, work around it by ordering lock | ||
1792 | * grabbing by pipe info address. Otherwise two different processes | ||
1793 | * could deadlock (one doing tee from A -> B, the other from B -> A). | ||
1794 | */ | ||
1795 | pipe_double_lock(ipipe, opipe); | ||
1796 | |||
1797 | do { | ||
1798 | if (!opipe->readers) { | ||
1799 | send_sig(SIGPIPE, current, 0); | ||
1800 | if (!ret) | ||
1801 | ret = -EPIPE; | ||
1802 | break; | ||
1803 | } | ||
1804 | |||
1805 | if (!ipipe->nrbufs && !ipipe->writers) | ||
1806 | break; | ||
1807 | |||
1808 | /* | ||
1809 | * Cannot make any progress, because either the input | ||
1810 | * pipe is empty or the output pipe is full. | ||
1811 | */ | ||
1812 | if (!ipipe->nrbufs || opipe->nrbufs >= PIPE_BUFFERS) { | ||
1813 | /* Already processed some buffers, break */ | ||
1814 | if (ret) | ||
1815 | break; | ||
1816 | |||
1817 | if (flags & SPLICE_F_NONBLOCK) { | ||
1818 | ret = -EAGAIN; | ||
1819 | break; | ||
1820 | } | ||
1821 | |||
1822 | /* | ||
1823 | * We raced with another reader/writer and haven't | ||
1824 | * managed to process any buffers. A zero return | ||
1825 | * value means EOF, so retry instead. | ||
1826 | */ | ||
1827 | pipe_unlock(ipipe); | ||
1828 | pipe_unlock(opipe); | ||
1829 | goto retry; | ||
1830 | } | ||
1831 | |||
1832 | ibuf = ipipe->bufs + ipipe->curbuf; | ||
1833 | nbuf = (opipe->curbuf + opipe->nrbufs) % PIPE_BUFFERS; | ||
1834 | obuf = opipe->bufs + nbuf; | ||
1835 | |||
1836 | if (len >= ibuf->len) { | ||
1837 | /* | ||
1838 | * Simply move the whole buffer from ipipe to opipe | ||
1839 | */ | ||
1840 | *obuf = *ibuf; | ||
1841 | ibuf->ops = NULL; | ||
1842 | opipe->nrbufs++; | ||
1843 | ipipe->curbuf = (ipipe->curbuf + 1) % PIPE_BUFFERS; | ||
1844 | ipipe->nrbufs--; | ||
1845 | input_wakeup = true; | ||
1846 | } else { | ||
1847 | /* | ||
1848 | * Get a reference to this pipe buffer, | ||
1849 | * so we can copy the contents over. | ||
1850 | */ | ||
1851 | ibuf->ops->get(ipipe, ibuf); | ||
1852 | *obuf = *ibuf; | ||
1853 | |||
1854 | /* | ||
1855 | * Don't inherit the gift flag, we need to | ||
1856 | * prevent multiple steals of this page. | ||
1857 | */ | ||
1858 | obuf->flags &= ~PIPE_BUF_FLAG_GIFT; | ||
1859 | |||
1860 | obuf->len = len; | ||
1861 | opipe->nrbufs++; | ||
1862 | ibuf->offset += obuf->len; | ||
1863 | ibuf->len -= obuf->len; | ||
1864 | } | ||
1865 | ret += obuf->len; | ||
1866 | len -= obuf->len; | ||
1867 | } while (len); | ||
1868 | |||
1869 | pipe_unlock(ipipe); | ||
1870 | pipe_unlock(opipe); | ||
1871 | |||
1872 | /* | ||
1873 | * If we put data in the output pipe, wakeup any potential readers. | ||
1874 | */ | ||
1875 | if (ret > 0) { | ||
1876 | smp_mb(); | ||
1877 | if (waitqueue_active(&opipe->wait)) | ||
1878 | wake_up_interruptible(&opipe->wait); | ||
1879 | kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN); | ||
1880 | } | ||
1881 | if (input_wakeup) | ||
1882 | wakeup_pipe_writers(ipipe); | ||
1883 | |||
1884 | return ret; | ||
1885 | } | ||
1886 | |||
1887 | /* | ||
1590 | * Link contents of ipipe to opipe. | 1888 | * Link contents of ipipe to opipe. |
1591 | */ | 1889 | */ |
1592 | static int link_pipe(struct pipe_inode_info *ipipe, | 1890 | static int link_pipe(struct pipe_inode_info *ipipe, |
@@ -1690,9 +1988,9 @@ static long do_tee(struct file *in, struct file *out, size_t len, | |||
1690 | * Keep going, unless we encounter an error. The ipipe/opipe | 1988 | * Keep going, unless we encounter an error. The ipipe/opipe |
1691 | * ordering doesn't really matter. | 1989 | * ordering doesn't really matter. |
1692 | */ | 1990 | */ |
1693 | ret = link_ipipe_prep(ipipe, flags); | 1991 | ret = ipipe_prep(ipipe, flags); |
1694 | if (!ret) { | 1992 | if (!ret) { |
1695 | ret = link_opipe_prep(opipe, flags); | 1993 | ret = opipe_prep(opipe, flags); |
1696 | if (!ret) | 1994 | if (!ret) |
1697 | ret = link_pipe(ipipe, opipe, len, flags); | 1995 | ret = link_pipe(ipipe, opipe, len, flags); |
1698 | } | 1996 | } |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 72348cc855a4..0ba44107d8f1 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1915,7 +1915,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) | |||
1915 | if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) { | 1915 | if (uopt.flags & (1 << UDF_FLAG_BLOCKSIZE_SET)) { |
1916 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); | 1916 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); |
1917 | } else { | 1917 | } else { |
1918 | uopt.blocksize = bdev_hardsect_size(sb->s_bdev); | 1918 | uopt.blocksize = bdev_logical_block_size(sb->s_bdev); |
1919 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); | 1919 | ret = udf_load_vrs(sb, &uopt, silent, &fileset); |
1920 | if (!ret && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) { | 1920 | if (!ret && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) { |
1921 | if (!silent) | 1921 | if (!silent) |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index e28800a9f2b5..1418b916fc27 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -1501,7 +1501,7 @@ xfs_setsize_buftarg_early( | |||
1501 | struct block_device *bdev) | 1501 | struct block_device *bdev) |
1502 | { | 1502 | { |
1503 | return xfs_setsize_buftarg_flags(btp, | 1503 | return xfs_setsize_buftarg_flags(btp, |
1504 | PAGE_CACHE_SIZE, bdev_hardsect_size(bdev), 0); | 1504 | PAGE_CACHE_SIZE, bdev_logical_block_size(bdev), 0); |
1505 | } | 1505 | } |
1506 | 1506 | ||
1507 | int | 1507 | int |