diff options
Diffstat (limited to 'fs')
54 files changed, 463 insertions, 337 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index c017a2dfb909..7a75c3e0fd58 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -2935,6 +2935,7 @@ static void guard_bh_eod(int rw, struct bio *bio, struct buffer_head *bh) | |||
| 2935 | void *kaddr = kmap_atomic(bh->b_page); | 2935 | void *kaddr = kmap_atomic(bh->b_page); |
| 2936 | memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes); | 2936 | memset(kaddr + bh_offset(bh) + bytes, 0, bh->b_size - bytes); |
| 2937 | kunmap_atomic(kaddr); | 2937 | kunmap_atomic(kaddr); |
| 2938 | flush_dcache_page(bh->b_page); | ||
| 2938 | } | 2939 | } |
| 2939 | } | 2940 | } |
| 2940 | 2941 | ||
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index f653835d067b..de7f9168a118 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -228,7 +228,6 @@ cifs_alloc_inode(struct super_block *sb) | |||
| 228 | cifs_set_oplock_level(cifs_inode, 0); | 228 | cifs_set_oplock_level(cifs_inode, 0); |
| 229 | cifs_inode->delete_pending = false; | 229 | cifs_inode->delete_pending = false; |
| 230 | cifs_inode->invalid_mapping = false; | 230 | cifs_inode->invalid_mapping = false; |
| 231 | cifs_inode->leave_pages_clean = false; | ||
| 232 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ | 231 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ |
| 233 | cifs_inode->server_eof = 0; | 232 | cifs_inode->server_eof = 0; |
| 234 | cifs_inode->uniqueid = 0; | 233 | cifs_inode->uniqueid = 0; |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index aea1eec64911..e6899cea1c35 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -386,6 +386,7 @@ struct smb_version_values { | |||
| 386 | unsigned int cap_unix; | 386 | unsigned int cap_unix; |
| 387 | unsigned int cap_nt_find; | 387 | unsigned int cap_nt_find; |
| 388 | unsigned int cap_large_files; | 388 | unsigned int cap_large_files; |
| 389 | unsigned int oplock_read; | ||
| 389 | }; | 390 | }; |
| 390 | 391 | ||
| 391 | #define HEADER_SIZE(server) (server->vals->header_size) | 392 | #define HEADER_SIZE(server) (server->vals->header_size) |
| @@ -1030,7 +1031,6 @@ struct cifsInodeInfo { | |||
| 1030 | bool clientCanCacheAll; /* read and writebehind oplock */ | 1031 | bool clientCanCacheAll; /* read and writebehind oplock */ |
| 1031 | bool delete_pending; /* DELETE_ON_CLOSE is set */ | 1032 | bool delete_pending; /* DELETE_ON_CLOSE is set */ |
| 1032 | bool invalid_mapping; /* pagecache is invalid */ | 1033 | bool invalid_mapping; /* pagecache is invalid */ |
| 1033 | bool leave_pages_clean; /* protected by i_mutex, not set pages dirty */ | ||
| 1034 | unsigned long time; /* jiffies of last update of inode */ | 1034 | unsigned long time; /* jiffies of last update of inode */ |
| 1035 | u64 server_eof; /* current file size on server -- protected by i_lock */ | 1035 | u64 server_eof; /* current file size on server -- protected by i_lock */ |
| 1036 | u64 uniqueid; /* server inode number */ | 1036 | u64 uniqueid; /* server inode number */ |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0a6677ba212b..8ea6ca50a665 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -238,6 +238,23 @@ out: | |||
| 238 | return rc; | 238 | return rc; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | static bool | ||
| 242 | cifs_has_mand_locks(struct cifsInodeInfo *cinode) | ||
| 243 | { | ||
| 244 | struct cifs_fid_locks *cur; | ||
| 245 | bool has_locks = false; | ||
| 246 | |||
| 247 | down_read(&cinode->lock_sem); | ||
| 248 | list_for_each_entry(cur, &cinode->llist, llist) { | ||
| 249 | if (!list_empty(&cur->locks)) { | ||
| 250 | has_locks = true; | ||
| 251 | break; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | up_read(&cinode->lock_sem); | ||
| 255 | return has_locks; | ||
| 256 | } | ||
| 257 | |||
| 241 | struct cifsFileInfo * | 258 | struct cifsFileInfo * |
| 242 | cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, | 259 | cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, |
| 243 | struct tcon_link *tlink, __u32 oplock) | 260 | struct tcon_link *tlink, __u32 oplock) |
| @@ -248,6 +265,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, | |||
| 248 | struct cifsFileInfo *cfile; | 265 | struct cifsFileInfo *cfile; |
| 249 | struct cifs_fid_locks *fdlocks; | 266 | struct cifs_fid_locks *fdlocks; |
| 250 | struct cifs_tcon *tcon = tlink_tcon(tlink); | 267 | struct cifs_tcon *tcon = tlink_tcon(tlink); |
| 268 | struct TCP_Server_Info *server = tcon->ses->server; | ||
| 251 | 269 | ||
| 252 | cfile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); | 270 | cfile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); |
| 253 | if (cfile == NULL) | 271 | if (cfile == NULL) |
| @@ -276,12 +294,22 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, | |||
| 276 | INIT_WORK(&cfile->oplock_break, cifs_oplock_break); | 294 | INIT_WORK(&cfile->oplock_break, cifs_oplock_break); |
| 277 | mutex_init(&cfile->fh_mutex); | 295 | mutex_init(&cfile->fh_mutex); |
| 278 | 296 | ||
| 297 | /* | ||
| 298 | * If the server returned a read oplock and we have mandatory brlocks, | ||
| 299 | * set oplock level to None. | ||
| 300 | */ | ||
| 301 | if (oplock == server->vals->oplock_read && | ||
| 302 | cifs_has_mand_locks(cinode)) { | ||
| 303 | cFYI(1, "Reset oplock val from read to None due to mand locks"); | ||
| 304 | oplock = 0; | ||
| 305 | } | ||
| 306 | |||
| 279 | spin_lock(&cifs_file_list_lock); | 307 | spin_lock(&cifs_file_list_lock); |
| 280 | if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE) | 308 | if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE && oplock) |
| 281 | oplock = fid->pending_open->oplock; | 309 | oplock = fid->pending_open->oplock; |
| 282 | list_del(&fid->pending_open->olist); | 310 | list_del(&fid->pending_open->olist); |
| 283 | 311 | ||
| 284 | tlink_tcon(tlink)->ses->server->ops->set_fid(cfile, fid, oplock); | 312 | server->ops->set_fid(cfile, fid, oplock); |
| 285 | 313 | ||
| 286 | list_add(&cfile->tlist, &tcon->openFileList); | 314 | list_add(&cfile->tlist, &tcon->openFileList); |
| 287 | /* if readable file instance put first in list*/ | 315 | /* if readable file instance put first in list*/ |
| @@ -1422,6 +1450,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, | |||
| 1422 | struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; | 1450 | struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; |
| 1423 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 1451 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
| 1424 | struct TCP_Server_Info *server = tcon->ses->server; | 1452 | struct TCP_Server_Info *server = tcon->ses->server; |
| 1453 | struct inode *inode = cfile->dentry->d_inode; | ||
| 1425 | 1454 | ||
| 1426 | if (posix_lck) { | 1455 | if (posix_lck) { |
| 1427 | int posix_lock_type; | 1456 | int posix_lock_type; |
| @@ -1459,6 +1488,21 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, | |||
| 1459 | if (!rc) | 1488 | if (!rc) |
| 1460 | goto out; | 1489 | goto out; |
| 1461 | 1490 | ||
| 1491 | /* | ||
| 1492 | * Windows 7 server can delay breaking lease from read to None | ||
| 1493 | * if we set a byte-range lock on a file - break it explicitly | ||
| 1494 | * before sending the lock to the server to be sure the next | ||
| 1495 | * read won't conflict with non-overlapted locks due to | ||
| 1496 | * pagereading. | ||
| 1497 | */ | ||
| 1498 | if (!CIFS_I(inode)->clientCanCacheAll && | ||
| 1499 | CIFS_I(inode)->clientCanCacheRead) { | ||
| 1500 | cifs_invalidate_mapping(inode); | ||
| 1501 | cFYI(1, "Set no oplock for inode=%p due to mand locks", | ||
| 1502 | inode); | ||
| 1503 | CIFS_I(inode)->clientCanCacheRead = false; | ||
| 1504 | } | ||
| 1505 | |||
| 1462 | rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, | 1506 | rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, |
| 1463 | type, 1, 0, wait_flag); | 1507 | type, 1, 0, wait_flag); |
| 1464 | if (rc) { | 1508 | if (rc) { |
| @@ -2103,15 +2147,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, | |||
| 2103 | } else { | 2147 | } else { |
| 2104 | rc = copied; | 2148 | rc = copied; |
| 2105 | pos += copied; | 2149 | pos += copied; |
| 2106 | /* | 2150 | set_page_dirty(page); |
| 2107 | * When we use strict cache mode and cifs_strict_writev was run | ||
| 2108 | * with level II oplock (indicated by leave_pages_clean field of | ||
| 2109 | * CIFS_I(inode)), we can leave pages clean - cifs_strict_writev | ||
| 2110 | * sent the data to the server itself. | ||
| 2111 | */ | ||
| 2112 | if (!CIFS_I(inode)->leave_pages_clean || | ||
| 2113 | !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)) | ||
| 2114 | set_page_dirty(page); | ||
| 2115 | } | 2151 | } |
| 2116 | 2152 | ||
| 2117 | if (rc > 0) { | 2153 | if (rc > 0) { |
| @@ -2462,8 +2498,8 @@ ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov, | |||
| 2462 | } | 2498 | } |
| 2463 | 2499 | ||
| 2464 | static ssize_t | 2500 | static ssize_t |
| 2465 | cifs_pagecache_writev(struct kiocb *iocb, const struct iovec *iov, | 2501 | cifs_writev(struct kiocb *iocb, const struct iovec *iov, |
| 2466 | unsigned long nr_segs, loff_t pos, bool cache_ex) | 2502 | unsigned long nr_segs, loff_t pos) |
| 2467 | { | 2503 | { |
| 2468 | struct file *file = iocb->ki_filp; | 2504 | struct file *file = iocb->ki_filp; |
| 2469 | struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; | 2505 | struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; |
| @@ -2485,12 +2521,8 @@ cifs_pagecache_writev(struct kiocb *iocb, const struct iovec *iov, | |||
| 2485 | server->vals->exclusive_lock_type, NULL, | 2521 | server->vals->exclusive_lock_type, NULL, |
| 2486 | CIFS_WRITE_OP)) { | 2522 | CIFS_WRITE_OP)) { |
| 2487 | mutex_lock(&inode->i_mutex); | 2523 | mutex_lock(&inode->i_mutex); |
| 2488 | if (!cache_ex) | ||
| 2489 | cinode->leave_pages_clean = true; | ||
| 2490 | rc = __generic_file_aio_write(iocb, iov, nr_segs, | 2524 | rc = __generic_file_aio_write(iocb, iov, nr_segs, |
| 2491 | &iocb->ki_pos); | 2525 | &iocb->ki_pos); |
| 2492 | if (!cache_ex) | ||
| 2493 | cinode->leave_pages_clean = false; | ||
| 2494 | mutex_unlock(&inode->i_mutex); | 2526 | mutex_unlock(&inode->i_mutex); |
| 2495 | } | 2527 | } |
| 2496 | 2528 | ||
| @@ -2517,60 +2549,32 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, | |||
| 2517 | struct cifsFileInfo *cfile = (struct cifsFileInfo *) | 2549 | struct cifsFileInfo *cfile = (struct cifsFileInfo *) |
| 2518 | iocb->ki_filp->private_data; | 2550 | iocb->ki_filp->private_data; |
| 2519 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 2551 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
| 2520 | ssize_t written, written2; | 2552 | ssize_t written; |
| 2521 | /* | ||
| 2522 | * We need to store clientCanCacheAll here to prevent race | ||
| 2523 | * conditions - this value can be changed during an execution | ||
| 2524 | * of generic_file_aio_write. For CIFS it can be changed from | ||
| 2525 | * true to false only, but for SMB2 it can be changed both from | ||
| 2526 | * true to false and vice versa. So, we can end up with a data | ||
| 2527 | * stored in the cache, not marked dirty and not sent to the | ||
| 2528 | * server if this value changes its state from false to true | ||
| 2529 | * after cifs_write_end. | ||
| 2530 | */ | ||
| 2531 | bool cache_ex = cinode->clientCanCacheAll; | ||
| 2532 | bool cache_read = cinode->clientCanCacheRead; | ||
| 2533 | int rc; | ||
| 2534 | loff_t saved_pos; | ||
| 2535 | 2553 | ||
| 2536 | if (cache_ex) { | 2554 | if (cinode->clientCanCacheAll) { |
| 2537 | if (cap_unix(tcon->ses) && | 2555 | if (cap_unix(tcon->ses) && |
| 2538 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) && | 2556 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) |
| 2539 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu( | 2557 | && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) |
| 2540 | tcon->fsUnixInfo.Capability))) | ||
| 2541 | return generic_file_aio_write(iocb, iov, nr_segs, pos); | 2558 | return generic_file_aio_write(iocb, iov, nr_segs, pos); |
| 2542 | return cifs_pagecache_writev(iocb, iov, nr_segs, pos, cache_ex); | 2559 | return cifs_writev(iocb, iov, nr_segs, pos); |
| 2543 | } | 2560 | } |
| 2544 | |||
| 2545 | /* | 2561 | /* |
| 2546 | * For files without exclusive oplock in strict cache mode we need to | 2562 | * For non-oplocked files in strict cache mode we need to write the data |
| 2547 | * write the data to the server exactly from the pos to pos+len-1 rather | 2563 | * to the server exactly from the pos to pos+len-1 rather than flush all |
| 2548 | * than flush all affected pages because it may cause a error with | 2564 | * affected pages because it may cause a error with mandatory locks on |
| 2549 | * mandatory locks on these pages but not on the region from pos to | 2565 | * these pages but not on the region from pos to ppos+len-1. |
| 2550 | * ppos+len-1. | ||
| 2551 | */ | 2566 | */ |
| 2552 | written = cifs_user_writev(iocb, iov, nr_segs, pos); | 2567 | written = cifs_user_writev(iocb, iov, nr_segs, pos); |
| 2553 | if (!cache_read || written <= 0) | 2568 | if (written > 0 && cinode->clientCanCacheRead) { |
| 2554 | return written; | 2569 | /* |
| 2555 | 2570 | * Windows 7 server can delay breaking level2 oplock if a write | |
| 2556 | saved_pos = iocb->ki_pos; | 2571 | * request comes - break it on the client to prevent reading |
| 2557 | iocb->ki_pos = pos; | 2572 | * an old data. |
| 2558 | /* we have a read oplock - need to store a data in the page cache */ | 2573 | */ |
| 2559 | if (cap_unix(tcon->ses) && | 2574 | cifs_invalidate_mapping(inode); |
| 2560 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) && | 2575 | cFYI(1, "Set no oplock for inode=%p after a write operation", |
| 2561 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu( | 2576 | inode); |
| 2562 | tcon->fsUnixInfo.Capability))) | 2577 | cinode->clientCanCacheRead = false; |
| 2563 | written2 = generic_file_aio_write(iocb, iov, nr_segs, pos); | ||
| 2564 | else | ||
| 2565 | written2 = cifs_pagecache_writev(iocb, iov, nr_segs, pos, | ||
| 2566 | cache_ex); | ||
| 2567 | /* errors occured during writing - invalidate the page cache */ | ||
| 2568 | if (written2 < 0) { | ||
| 2569 | rc = cifs_invalidate_mapping(inode); | ||
| 2570 | if (rc) | ||
| 2571 | written = (ssize_t)rc; | ||
| 2572 | else | ||
| 2573 | iocb->ki_pos = saved_pos; | ||
| 2574 | } | 2578 | } |
| 2575 | return written; | 2579 | return written; |
| 2576 | } | 2580 | } |
| @@ -3577,6 +3581,13 @@ void cifs_oplock_break(struct work_struct *work) | |||
| 3577 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); | 3581 | struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
| 3578 | int rc = 0; | 3582 | int rc = 0; |
| 3579 | 3583 | ||
| 3584 | if (!cinode->clientCanCacheAll && cinode->clientCanCacheRead && | ||
| 3585 | cifs_has_mand_locks(cinode)) { | ||
| 3586 | cFYI(1, "Reset oplock to None for inode=%p due to mand locks", | ||
| 3587 | inode); | ||
| 3588 | cinode->clientCanCacheRead = false; | ||
| 3589 | } | ||
| 3590 | |||
| 3580 | if (inode && S_ISREG(inode->i_mode)) { | 3591 | if (inode && S_ISREG(inode->i_mode)) { |
| 3581 | if (cinode->clientCanCacheRead) | 3592 | if (cinode->clientCanCacheRead) |
| 3582 | break_lease(inode, O_RDONLY); | 3593 | break_lease(inode, O_RDONLY); |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index a5d234c8d5d9..47bc5a87f94e 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
| @@ -53,6 +53,13 @@ send_nt_cancel(struct TCP_Server_Info *server, void *buf, | |||
| 53 | mutex_unlock(&server->srv_mutex); | 53 | mutex_unlock(&server->srv_mutex); |
| 54 | return rc; | 54 | return rc; |
| 55 | } | 55 | } |
| 56 | |||
| 57 | /* | ||
| 58 | * The response to this call was already factored into the sequence | ||
| 59 | * number when the call went out, so we must adjust it back downward | ||
| 60 | * after signing here. | ||
| 61 | */ | ||
| 62 | --server->sequence_number; | ||
| 56 | rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); | 63 | rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); |
| 57 | mutex_unlock(&server->srv_mutex); | 64 | mutex_unlock(&server->srv_mutex); |
| 58 | 65 | ||
| @@ -952,4 +959,5 @@ struct smb_version_values smb1_values = { | |||
| 952 | .cap_unix = CAP_UNIX, | 959 | .cap_unix = CAP_UNIX, |
| 953 | .cap_nt_find = CAP_NT_SMBS | CAP_NT_FIND, | 960 | .cap_nt_find = CAP_NT_SMBS | CAP_NT_FIND, |
| 954 | .cap_large_files = CAP_LARGE_FILES, | 961 | .cap_large_files = CAP_LARGE_FILES, |
| 962 | .oplock_read = OPLOCK_READ, | ||
| 955 | }; | 963 | }; |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index d79de7bc4435..c9c7aa7ed966 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
| @@ -708,6 +708,7 @@ struct smb_version_values smb20_values = { | |||
| 708 | .cap_unix = 0, | 708 | .cap_unix = 0, |
| 709 | .cap_nt_find = SMB2_NT_FIND, | 709 | .cap_nt_find = SMB2_NT_FIND, |
| 710 | .cap_large_files = SMB2_LARGE_FILES, | 710 | .cap_large_files = SMB2_LARGE_FILES, |
| 711 | .oplock_read = SMB2_OPLOCK_LEVEL_II, | ||
| 711 | }; | 712 | }; |
| 712 | 713 | ||
| 713 | struct smb_version_values smb21_values = { | 714 | struct smb_version_values smb21_values = { |
| @@ -725,6 +726,7 @@ struct smb_version_values smb21_values = { | |||
| 725 | .cap_unix = 0, | 726 | .cap_unix = 0, |
| 726 | .cap_nt_find = SMB2_NT_FIND, | 727 | .cap_nt_find = SMB2_NT_FIND, |
| 727 | .cap_large_files = SMB2_LARGE_FILES, | 728 | .cap_large_files = SMB2_LARGE_FILES, |
| 729 | .oplock_read = SMB2_OPLOCK_LEVEL_II, | ||
| 728 | }; | 730 | }; |
| 729 | 731 | ||
| 730 | struct smb_version_values smb30_values = { | 732 | struct smb_version_values smb30_values = { |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 76d974c952fe..1a528680ec5a 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -144,9 +144,6 @@ smb_send_kvec(struct TCP_Server_Info *server, struct kvec *iov, size_t n_vec, | |||
| 144 | 144 | ||
| 145 | *sent = 0; | 145 | *sent = 0; |
| 146 | 146 | ||
| 147 | if (ssocket == NULL) | ||
| 148 | return -ENOTSOCK; /* BB eventually add reconnect code here */ | ||
| 149 | |||
| 150 | smb_msg.msg_name = (struct sockaddr *) &server->dstaddr; | 147 | smb_msg.msg_name = (struct sockaddr *) &server->dstaddr; |
| 151 | smb_msg.msg_namelen = sizeof(struct sockaddr); | 148 | smb_msg.msg_namelen = sizeof(struct sockaddr); |
| 152 | smb_msg.msg_control = NULL; | 149 | smb_msg.msg_control = NULL; |
| @@ -291,6 +288,9 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) | |||
| 291 | struct socket *ssocket = server->ssocket; | 288 | struct socket *ssocket = server->ssocket; |
| 292 | int val = 1; | 289 | int val = 1; |
| 293 | 290 | ||
| 291 | if (ssocket == NULL) | ||
| 292 | return -ENOTSOCK; | ||
| 293 | |||
| 294 | cFYI(1, "Sending smb: smb_len=%u", smb_buf_length); | 294 | cFYI(1, "Sending smb: smb_len=%u", smb_buf_length); |
| 295 | dump_smb(iov[0].iov_base, iov[0].iov_len); | 295 | dump_smb(iov[0].iov_base, iov[0].iov_len); |
| 296 | 296 | ||
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 153bb1e42e63..a5f12b7e228d 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
| @@ -176,7 +176,7 @@ static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts) | |||
| 176 | opts->uid = uid; | 176 | opts->uid = uid; |
| 177 | break; | 177 | break; |
| 178 | case Opt_gid: | 178 | case Opt_gid: |
| 179 | if (match_octal(&args[0], &option)) | 179 | if (match_int(&args[0], &option)) |
| 180 | return -EINVAL; | 180 | return -EINVAL; |
| 181 | gid = make_kgid(current_user_ns(), option); | 181 | gid = make_kgid(current_user_ns(), option); |
| 182 | if (!gid_valid(gid)) | 182 | if (!gid_valid(gid)) |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index ea9931281557..a7b0c2dfb3db 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -1935,7 +1935,7 @@ static const unsigned char filename_rev_map[256] = { | |||
| 1935 | * @src: Source location for the filename to encode | 1935 | * @src: Source location for the filename to encode |
| 1936 | * @src_size: Size of the source in bytes | 1936 | * @src_size: Size of the source in bytes |
| 1937 | */ | 1937 | */ |
| 1938 | void ecryptfs_encode_for_filename(unsigned char *dst, size_t *dst_size, | 1938 | static void ecryptfs_encode_for_filename(unsigned char *dst, size_t *dst_size, |
| 1939 | unsigned char *src, size_t src_size) | 1939 | unsigned char *src, size_t src_size) |
| 1940 | { | 1940 | { |
| 1941 | size_t num_blocks; | 1941 | size_t num_blocks; |
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c index 809e67d05ca3..f1ea610362c6 100644 --- a/fs/ecryptfs/kthread.c +++ b/fs/ecryptfs/kthread.c | |||
| @@ -102,12 +102,12 @@ int __init ecryptfs_init_kthread(void) | |||
| 102 | 102 | ||
| 103 | void ecryptfs_destroy_kthread(void) | 103 | void ecryptfs_destroy_kthread(void) |
| 104 | { | 104 | { |
| 105 | struct ecryptfs_open_req *req; | 105 | struct ecryptfs_open_req *req, *tmp; |
| 106 | 106 | ||
| 107 | mutex_lock(&ecryptfs_kthread_ctl.mux); | 107 | mutex_lock(&ecryptfs_kthread_ctl.mux); |
| 108 | ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE; | 108 | ecryptfs_kthread_ctl.flags |= ECRYPTFS_KTHREAD_ZOMBIE; |
| 109 | list_for_each_entry(req, &ecryptfs_kthread_ctl.req_list, | 109 | list_for_each_entry_safe(req, tmp, &ecryptfs_kthread_ctl.req_list, |
| 110 | kthread_ctl_list) { | 110 | kthread_ctl_list) { |
| 111 | list_del(&req->kthread_ctl_list); | 111 | list_del(&req->kthread_ctl_list); |
| 112 | *req->lower_file = ERR_PTR(-EIO); | 112 | *req->lower_file = ERR_PTR(-EIO); |
| 113 | complete(&req->done); | 113 | complete(&req->done); |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index bd1d57f98f74..564a1fa34b99 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
| @@ -338,7 +338,8 @@ static int ecryptfs_write_begin(struct file *file, | |||
| 338 | if (prev_page_end_size | 338 | if (prev_page_end_size |
| 339 | >= i_size_read(page->mapping->host)) { | 339 | >= i_size_read(page->mapping->host)) { |
| 340 | zero_user(page, 0, PAGE_CACHE_SIZE); | 340 | zero_user(page, 0, PAGE_CACHE_SIZE); |
| 341 | } else { | 341 | SetPageUptodate(page); |
| 342 | } else if (len < PAGE_CACHE_SIZE) { | ||
| 342 | rc = ecryptfs_decrypt_page(page); | 343 | rc = ecryptfs_decrypt_page(page); |
| 343 | if (rc) { | 344 | if (rc) { |
| 344 | printk(KERN_ERR "%s: Error decrypting " | 345 | printk(KERN_ERR "%s: Error decrypting " |
| @@ -348,8 +349,8 @@ static int ecryptfs_write_begin(struct file *file, | |||
| 348 | ClearPageUptodate(page); | 349 | ClearPageUptodate(page); |
| 349 | goto out; | 350 | goto out; |
| 350 | } | 351 | } |
| 352 | SetPageUptodate(page); | ||
| 351 | } | 353 | } |
| 352 | SetPageUptodate(page); | ||
| 353 | } | 354 | } |
| 354 | } | 355 | } |
| 355 | /* If creating a page or more of holes, zero them out via truncate. | 356 | /* If creating a page or more of holes, zero them out via truncate. |
| @@ -499,6 +500,13 @@ static int ecryptfs_write_end(struct file *file, | |||
| 499 | } | 500 | } |
| 500 | goto out; | 501 | goto out; |
| 501 | } | 502 | } |
| 503 | if (!PageUptodate(page)) { | ||
| 504 | if (copied < PAGE_CACHE_SIZE) { | ||
| 505 | rc = 0; | ||
| 506 | goto out; | ||
| 507 | } | ||
| 508 | SetPageUptodate(page); | ||
| 509 | } | ||
| 502 | /* Fills in zeros if 'to' goes beyond inode size */ | 510 | /* Fills in zeros if 'to' goes beyond inode size */ |
| 503 | rc = fill_zeros_to_end_of_page(page, to); | 511 | rc = fill_zeros_to_end_of_page(page, to); |
| 504 | if (rc) { | 512 | if (rc) { |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index be56b21435f8..9fec1836057a 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
| @@ -1313,7 +1313,7 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even | |||
| 1313 | * otherwise we might miss an event that happens between the | 1313 | * otherwise we might miss an event that happens between the |
| 1314 | * f_op->poll() call and the new event set registering. | 1314 | * f_op->poll() call and the new event set registering. |
| 1315 | */ | 1315 | */ |
| 1316 | epi->event.events = event->events; | 1316 | epi->event.events = event->events; /* need barrier below */ |
| 1317 | pt._key = event->events; | 1317 | pt._key = event->events; |
| 1318 | epi->event.data = event->data; /* protected by mtx */ | 1318 | epi->event.data = event->data; /* protected by mtx */ |
| 1319 | if (epi->event.events & EPOLLWAKEUP) { | 1319 | if (epi->event.events & EPOLLWAKEUP) { |
| @@ -1324,6 +1324,26 @@ static int ep_modify(struct eventpoll *ep, struct epitem *epi, struct epoll_even | |||
| 1324 | } | 1324 | } |
| 1325 | 1325 | ||
| 1326 | /* | 1326 | /* |
| 1327 | * The following barrier has two effects: | ||
| 1328 | * | ||
| 1329 | * 1) Flush epi changes above to other CPUs. This ensures | ||
| 1330 | * we do not miss events from ep_poll_callback if an | ||
| 1331 | * event occurs immediately after we call f_op->poll(). | ||
| 1332 | * We need this because we did not take ep->lock while | ||
| 1333 | * changing epi above (but ep_poll_callback does take | ||
| 1334 | * ep->lock). | ||
| 1335 | * | ||
| 1336 | * 2) We also need to ensure we do not miss _past_ events | ||
| 1337 | * when calling f_op->poll(). This barrier also | ||
| 1338 | * pairs with the barrier in wq_has_sleeper (see | ||
| 1339 | * comments for wq_has_sleeper). | ||
| 1340 | * | ||
| 1341 | * This barrier will now guarantee ep_poll_callback or f_op->poll | ||
| 1342 | * (or both) will notice the readiness of an item. | ||
| 1343 | */ | ||
| 1344 | smp_mb(); | ||
| 1345 | |||
| 1346 | /* | ||
| 1327 | * Get current event bits. We can safely use the file* here because | 1347 | * Get current event bits. We can safely use the file* here because |
| 1328 | * its usage count has been increased by the caller of this function. | 1348 | * its usage count has been increased by the caller of this function. |
| 1329 | */ | 1349 | */ |
| @@ -434,8 +434,9 @@ static int count(struct user_arg_ptr argv, int max) | |||
| 434 | if (IS_ERR(p)) | 434 | if (IS_ERR(p)) |
| 435 | return -EFAULT; | 435 | return -EFAULT; |
| 436 | 436 | ||
| 437 | if (i++ >= max) | 437 | if (i >= max) |
| 438 | return -E2BIG; | 438 | return -E2BIG; |
| 439 | ++i; | ||
| 439 | 440 | ||
| 440 | if (fatal_signal_pending(current)) | 441 | if (fatal_signal_pending(current)) |
| 441 | return -ERESTARTNOHAND; | 442 | return -ERESTARTNOHAND; |
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index 0a475c881852..987358740cb9 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig | |||
| @@ -41,6 +41,7 @@ config EXT4_USE_FOR_EXT23 | |||
| 41 | 41 | ||
| 42 | config EXT4_FS_POSIX_ACL | 42 | config EXT4_FS_POSIX_ACL |
| 43 | bool "Ext4 POSIX Access Control Lists" | 43 | bool "Ext4 POSIX Access Control Lists" |
| 44 | depends on EXT4_FS | ||
| 44 | select FS_POSIX_ACL | 45 | select FS_POSIX_ACL |
| 45 | help | 46 | help |
| 46 | POSIX Access Control Lists (ACLs) support permissions for users and | 47 | POSIX Access Control Lists (ACLs) support permissions for users and |
| @@ -53,6 +54,7 @@ config EXT4_FS_POSIX_ACL | |||
| 53 | 54 | ||
| 54 | config EXT4_FS_SECURITY | 55 | config EXT4_FS_SECURITY |
| 55 | bool "Ext4 Security Labels" | 56 | bool "Ext4 Security Labels" |
| 57 | depends on EXT4_FS | ||
| 56 | help | 58 | help |
| 57 | Security labels support alternative access control models | 59 | Security labels support alternative access control models |
| 58 | implemented by security modules like SELinux. This option | 60 | implemented by security modules like SELinux. This option |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 26af22832a84..5ae1674ec12f 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -2226,13 +2226,14 @@ errout: | |||
| 2226 | * removes index from the index block. | 2226 | * removes index from the index block. |
| 2227 | */ | 2227 | */ |
| 2228 | static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, | 2228 | static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, |
| 2229 | struct ext4_ext_path *path) | 2229 | struct ext4_ext_path *path, int depth) |
| 2230 | { | 2230 | { |
| 2231 | int err; | 2231 | int err; |
| 2232 | ext4_fsblk_t leaf; | 2232 | ext4_fsblk_t leaf; |
| 2233 | 2233 | ||
| 2234 | /* free index block */ | 2234 | /* free index block */ |
| 2235 | path--; | 2235 | depth--; |
| 2236 | path = path + depth; | ||
| 2236 | leaf = ext4_idx_pblock(path->p_idx); | 2237 | leaf = ext4_idx_pblock(path->p_idx); |
| 2237 | if (unlikely(path->p_hdr->eh_entries == 0)) { | 2238 | if (unlikely(path->p_hdr->eh_entries == 0)) { |
| 2238 | EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0"); | 2239 | EXT4_ERROR_INODE(inode, "path->p_hdr->eh_entries == 0"); |
| @@ -2257,6 +2258,19 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, | |||
| 2257 | 2258 | ||
| 2258 | ext4_free_blocks(handle, inode, NULL, leaf, 1, | 2259 | ext4_free_blocks(handle, inode, NULL, leaf, 1, |
| 2259 | EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET); | 2260 | EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET); |
| 2261 | |||
| 2262 | while (--depth >= 0) { | ||
| 2263 | if (path->p_idx != EXT_FIRST_INDEX(path->p_hdr)) | ||
| 2264 | break; | ||
| 2265 | path--; | ||
| 2266 | err = ext4_ext_get_access(handle, inode, path); | ||
| 2267 | if (err) | ||
| 2268 | break; | ||
| 2269 | path->p_idx->ei_block = (path+1)->p_idx->ei_block; | ||
| 2270 | err = ext4_ext_dirty(handle, inode, path); | ||
| 2271 | if (err) | ||
| 2272 | break; | ||
| 2273 | } | ||
| 2260 | return err; | 2274 | return err; |
| 2261 | } | 2275 | } |
| 2262 | 2276 | ||
| @@ -2599,7 +2613,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, | |||
| 2599 | /* if this leaf is free, then we should | 2613 | /* if this leaf is free, then we should |
| 2600 | * remove it from index block above */ | 2614 | * remove it from index block above */ |
| 2601 | if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL) | 2615 | if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL) |
| 2602 | err = ext4_ext_rm_idx(handle, inode, path + depth); | 2616 | err = ext4_ext_rm_idx(handle, inode, path, depth); |
| 2603 | 2617 | ||
| 2604 | out: | 2618 | out: |
| 2605 | return err; | 2619 | return err; |
| @@ -2802,7 +2816,7 @@ again: | |||
| 2802 | /* index is empty, remove it; | 2816 | /* index is empty, remove it; |
| 2803 | * handle must be already prepared by the | 2817 | * handle must be already prepared by the |
| 2804 | * truncatei_leaf() */ | 2818 | * truncatei_leaf() */ |
| 2805 | err = ext4_ext_rm_idx(handle, inode, path + i); | 2819 | err = ext4_ext_rm_idx(handle, inode, path, i); |
| 2806 | } | 2820 | } |
| 2807 | /* root level has p_bh == NULL, brelse() eats this */ | 2821 | /* root level has p_bh == NULL, brelse() eats this */ |
| 2808 | brelse(path[i].p_bh); | 2822 | brelse(path[i].p_bh); |
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index d07c27ca594a..405565a62277 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
| @@ -108,14 +108,6 @@ ext4_file_dio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 108 | 108 | ||
| 109 | /* Unaligned direct AIO must be serialized; see comment above */ | 109 | /* Unaligned direct AIO must be serialized; see comment above */ |
| 110 | if (unaligned_aio) { | 110 | if (unaligned_aio) { |
| 111 | static unsigned long unaligned_warn_time; | ||
| 112 | |||
| 113 | /* Warn about this once per day */ | ||
| 114 | if (printk_timed_ratelimit(&unaligned_warn_time, 60*60*24*HZ)) | ||
| 115 | ext4_msg(inode->i_sb, KERN_WARNING, | ||
| 116 | "Unaligned AIO/DIO on inode %ld by %s; " | ||
| 117 | "performance will be poor.", | ||
| 118 | inode->i_ino, current->comm); | ||
| 119 | mutex_lock(ext4_aio_mutex(inode)); | 111 | mutex_lock(ext4_aio_mutex(inode)); |
| 120 | ext4_unwritten_wait(inode); | 112 | ext4_unwritten_wait(inode); |
| 121 | } | 113 | } |
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index dfbc1fe96674..3278e64e57b6 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c | |||
| @@ -109,8 +109,6 @@ static int __sync_inode(struct inode *inode, int datasync) | |||
| 109 | * | 109 | * |
| 110 | * What we do is just kick off a commit and wait on it. This will snapshot the | 110 | * What we do is just kick off a commit and wait on it. This will snapshot the |
| 111 | * inode to disk. | 111 | * inode to disk. |
| 112 | * | ||
| 113 | * i_mutex lock is held when entering and exiting this function | ||
| 114 | */ | 112 | */ |
| 115 | 113 | ||
| 116 | int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | 114 | int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index cb1c1ab2720b..cbfe13bf5b2a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -2880,8 +2880,6 @@ static void ext4_invalidatepage_free_endio(struct page *page, unsigned long offs | |||
| 2880 | 2880 | ||
| 2881 | static void ext4_invalidatepage(struct page *page, unsigned long offset) | 2881 | static void ext4_invalidatepage(struct page *page, unsigned long offset) |
| 2882 | { | 2882 | { |
| 2883 | journal_t *journal = EXT4_JOURNAL(page->mapping->host); | ||
| 2884 | |||
| 2885 | trace_ext4_invalidatepage(page, offset); | 2883 | trace_ext4_invalidatepage(page, offset); |
| 2886 | 2884 | ||
| 2887 | /* | 2885 | /* |
| @@ -2889,16 +2887,34 @@ static void ext4_invalidatepage(struct page *page, unsigned long offset) | |||
| 2889 | */ | 2887 | */ |
| 2890 | if (ext4_should_dioread_nolock(page->mapping->host)) | 2888 | if (ext4_should_dioread_nolock(page->mapping->host)) |
| 2891 | ext4_invalidatepage_free_endio(page, offset); | 2889 | ext4_invalidatepage_free_endio(page, offset); |
| 2890 | |||
| 2891 | /* No journalling happens on data buffers when this function is used */ | ||
| 2892 | WARN_ON(page_has_buffers(page) && buffer_jbd(page_buffers(page))); | ||
| 2893 | |||
| 2894 | block_invalidatepage(page, offset); | ||
| 2895 | } | ||
| 2896 | |||
| 2897 | static int __ext4_journalled_invalidatepage(struct page *page, | ||
| 2898 | unsigned long offset) | ||
| 2899 | { | ||
| 2900 | journal_t *journal = EXT4_JOURNAL(page->mapping->host); | ||
| 2901 | |||
| 2902 | trace_ext4_journalled_invalidatepage(page, offset); | ||
| 2903 | |||
| 2892 | /* | 2904 | /* |
| 2893 | * If it's a full truncate we just forget about the pending dirtying | 2905 | * If it's a full truncate we just forget about the pending dirtying |
| 2894 | */ | 2906 | */ |
| 2895 | if (offset == 0) | 2907 | if (offset == 0) |
| 2896 | ClearPageChecked(page); | 2908 | ClearPageChecked(page); |
| 2897 | 2909 | ||
| 2898 | if (journal) | 2910 | return jbd2_journal_invalidatepage(journal, page, offset); |
| 2899 | jbd2_journal_invalidatepage(journal, page, offset); | 2911 | } |
| 2900 | else | 2912 | |
| 2901 | block_invalidatepage(page, offset); | 2913 | /* Wrapper for aops... */ |
| 2914 | static void ext4_journalled_invalidatepage(struct page *page, | ||
| 2915 | unsigned long offset) | ||
| 2916 | { | ||
| 2917 | WARN_ON(__ext4_journalled_invalidatepage(page, offset) < 0); | ||
| 2902 | } | 2918 | } |
| 2903 | 2919 | ||
| 2904 | static int ext4_releasepage(struct page *page, gfp_t wait) | 2920 | static int ext4_releasepage(struct page *page, gfp_t wait) |
| @@ -3264,7 +3280,7 @@ static const struct address_space_operations ext4_journalled_aops = { | |||
| 3264 | .write_end = ext4_journalled_write_end, | 3280 | .write_end = ext4_journalled_write_end, |
| 3265 | .set_page_dirty = ext4_journalled_set_page_dirty, | 3281 | .set_page_dirty = ext4_journalled_set_page_dirty, |
| 3266 | .bmap = ext4_bmap, | 3282 | .bmap = ext4_bmap, |
| 3267 | .invalidatepage = ext4_invalidatepage, | 3283 | .invalidatepage = ext4_journalled_invalidatepage, |
| 3268 | .releasepage = ext4_releasepage, | 3284 | .releasepage = ext4_releasepage, |
| 3269 | .direct_IO = ext4_direct_IO, | 3285 | .direct_IO = ext4_direct_IO, |
| 3270 | .is_partially_uptodate = block_is_partially_uptodate, | 3286 | .is_partially_uptodate = block_is_partially_uptodate, |
| @@ -4305,6 +4321,47 @@ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 4305 | } | 4321 | } |
| 4306 | 4322 | ||
| 4307 | /* | 4323 | /* |
| 4324 | * In data=journal mode ext4_journalled_invalidatepage() may fail to invalidate | ||
| 4325 | * buffers that are attached to a page stradding i_size and are undergoing | ||
| 4326 | * commit. In that case we have to wait for commit to finish and try again. | ||
| 4327 | */ | ||
| 4328 | static void ext4_wait_for_tail_page_commit(struct inode *inode) | ||
| 4329 | { | ||
| 4330 | struct page *page; | ||
| 4331 | unsigned offset; | ||
| 4332 | journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; | ||
| 4333 | tid_t commit_tid = 0; | ||
| 4334 | int ret; | ||
| 4335 | |||
| 4336 | offset = inode->i_size & (PAGE_CACHE_SIZE - 1); | ||
| 4337 | /* | ||
| 4338 | * All buffers in the last page remain valid? Then there's nothing to | ||
| 4339 | * do. We do the check mainly to optimize the common PAGE_CACHE_SIZE == | ||
| 4340 | * blocksize case | ||
| 4341 | */ | ||
| 4342 | if (offset > PAGE_CACHE_SIZE - (1 << inode->i_blkbits)) | ||
| 4343 | return; | ||
| 4344 | while (1) { | ||
| 4345 | page = find_lock_page(inode->i_mapping, | ||
| 4346 | inode->i_size >> PAGE_CACHE_SHIFT); | ||
| 4347 | if (!page) | ||
| 4348 | return; | ||
| 4349 | ret = __ext4_journalled_invalidatepage(page, offset); | ||
| 4350 | unlock_page(page); | ||
| 4351 | page_cache_release(page); | ||
| 4352 | if (ret != -EBUSY) | ||
| 4353 | return; | ||
| 4354 | commit_tid = 0; | ||
| 4355 | read_lock(&journal->j_state_lock); | ||
| 4356 | if (journal->j_committing_transaction) | ||
| 4357 | commit_tid = journal->j_committing_transaction->t_tid; | ||
| 4358 | read_unlock(&journal->j_state_lock); | ||
| 4359 | if (commit_tid) | ||
| 4360 | jbd2_log_wait_commit(journal, commit_tid); | ||
| 4361 | } | ||
| 4362 | } | ||
| 4363 | |||
| 4364 | /* | ||
| 4308 | * ext4_setattr() | 4365 | * ext4_setattr() |
| 4309 | * | 4366 | * |
| 4310 | * Called from notify_change. | 4367 | * Called from notify_change. |
| @@ -4417,16 +4474,28 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 4417 | } | 4474 | } |
| 4418 | 4475 | ||
| 4419 | if (attr->ia_valid & ATTR_SIZE) { | 4476 | if (attr->ia_valid & ATTR_SIZE) { |
| 4420 | if (attr->ia_size != i_size_read(inode)) { | 4477 | if (attr->ia_size != inode->i_size) { |
| 4421 | truncate_setsize(inode, attr->ia_size); | 4478 | loff_t oldsize = inode->i_size; |
| 4422 | /* Inode size will be reduced, wait for dio in flight. | 4479 | |
| 4423 | * Temporarily disable dioread_nolock to prevent | 4480 | i_size_write(inode, attr->ia_size); |
| 4424 | * livelock. */ | 4481 | /* |
| 4482 | * Blocks are going to be removed from the inode. Wait | ||
| 4483 | * for dio in flight. Temporarily disable | ||
| 4484 | * dioread_nolock to prevent livelock. | ||
| 4485 | */ | ||
| 4425 | if (orphan) { | 4486 | if (orphan) { |
| 4426 | ext4_inode_block_unlocked_dio(inode); | 4487 | if (!ext4_should_journal_data(inode)) { |
| 4427 | inode_dio_wait(inode); | 4488 | ext4_inode_block_unlocked_dio(inode); |
| 4428 | ext4_inode_resume_unlocked_dio(inode); | 4489 | inode_dio_wait(inode); |
| 4490 | ext4_inode_resume_unlocked_dio(inode); | ||
| 4491 | } else | ||
| 4492 | ext4_wait_for_tail_page_commit(inode); | ||
| 4429 | } | 4493 | } |
| 4494 | /* | ||
| 4495 | * Truncate pagecache after we've waited for commit | ||
| 4496 | * in data=journal mode to make pages freeable. | ||
| 4497 | */ | ||
| 4498 | truncate_pagecache(inode, oldsize, inode->i_size); | ||
| 4430 | } | 4499 | } |
| 4431 | ext4_truncate(inode); | 4500 | ext4_truncate(inode); |
| 4432 | } | 4501 | } |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index cac448282331..f9ed946a448e 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
| @@ -722,7 +722,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir, | |||
| 722 | ext4_warning(dir->i_sb, "Node failed checksum"); | 722 | ext4_warning(dir->i_sb, "Node failed checksum"); |
| 723 | brelse(bh); | 723 | brelse(bh); |
| 724 | *err = ERR_BAD_DX_DIR; | 724 | *err = ERR_BAD_DX_DIR; |
| 725 | goto fail; | 725 | goto fail2; |
| 726 | } | 726 | } |
| 727 | set_buffer_verified(bh); | 727 | set_buffer_verified(bh); |
| 728 | 728 | ||
| @@ -2368,7 +2368,6 @@ static int ext4_init_new_dir(handle_t *handle, struct inode *dir, | |||
| 2368 | } | 2368 | } |
| 2369 | 2369 | ||
| 2370 | inode->i_size = EXT4_I(inode)->i_disksize = blocksize; | 2370 | inode->i_size = EXT4_I(inode)->i_disksize = blocksize; |
| 2371 | dir_block = ext4_bread(handle, inode, 0, 1, &err); | ||
| 2372 | if (!(dir_block = ext4_bread(handle, inode, 0, 1, &err))) { | 2371 | if (!(dir_block = ext4_bread(handle, inode, 0, 1, &err))) { |
| 2373 | if (!err) { | 2372 | if (!err) { |
| 2374 | err = -EIO; | 2373 | err = -EIO; |
| @@ -2648,7 +2647,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) | |||
| 2648 | struct ext4_iloc iloc; | 2647 | struct ext4_iloc iloc; |
| 2649 | int err = 0; | 2648 | int err = 0; |
| 2650 | 2649 | ||
| 2651 | if (!EXT4_SB(inode->i_sb)->s_journal) | 2650 | if ((!EXT4_SB(inode->i_sb)->s_journal) && |
| 2651 | !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) | ||
| 2652 | return 0; | 2652 | return 0; |
| 2653 | 2653 | ||
| 2654 | mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); | 2654 | mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 3cdb0a2fc648..3d4fb81bacd5 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
| @@ -1645,9 +1645,7 @@ static int parse_options(char *options, struct super_block *sb, | |||
| 1645 | unsigned int *journal_ioprio, | 1645 | unsigned int *journal_ioprio, |
| 1646 | int is_remount) | 1646 | int is_remount) |
| 1647 | { | 1647 | { |
| 1648 | #ifdef CONFIG_QUOTA | ||
| 1649 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1648 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
| 1650 | #endif | ||
| 1651 | char *p; | 1649 | char *p; |
| 1652 | substring_t args[MAX_OPT_ARGS]; | 1650 | substring_t args[MAX_OPT_ARGS]; |
| 1653 | int token; | 1651 | int token; |
| @@ -1696,6 +1694,16 @@ static int parse_options(char *options, struct super_block *sb, | |||
| 1696 | } | 1694 | } |
| 1697 | } | 1695 | } |
| 1698 | #endif | 1696 | #endif |
| 1697 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
| 1698 | int blocksize = | ||
| 1699 | BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size); | ||
| 1700 | |||
| 1701 | if (blocksize < PAGE_CACHE_SIZE) { | ||
| 1702 | ext4_msg(sb, KERN_ERR, "can't mount with " | ||
| 1703 | "dioread_nolock if block size != PAGE_SIZE"); | ||
| 1704 | return 0; | ||
| 1705 | } | ||
| 1706 | } | ||
| 1699 | return 1; | 1707 | return 1; |
| 1700 | } | 1708 | } |
| 1701 | 1709 | ||
| @@ -2212,7 +2220,9 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
| 2212 | __func__, inode->i_ino, inode->i_size); | 2220 | __func__, inode->i_ino, inode->i_size); |
| 2213 | jbd_debug(2, "truncating inode %lu to %lld bytes\n", | 2221 | jbd_debug(2, "truncating inode %lu to %lld bytes\n", |
| 2214 | inode->i_ino, inode->i_size); | 2222 | inode->i_ino, inode->i_size); |
| 2223 | mutex_lock(&inode->i_mutex); | ||
| 2215 | ext4_truncate(inode); | 2224 | ext4_truncate(inode); |
| 2225 | mutex_unlock(&inode->i_mutex); | ||
| 2216 | nr_truncates++; | 2226 | nr_truncates++; |
| 2217 | } else { | 2227 | } else { |
| 2218 | ext4_msg(sb, KERN_DEBUG, | 2228 | ext4_msg(sb, KERN_DEBUG, |
| @@ -3223,6 +3233,10 @@ int ext4_calculate_overhead(struct super_block *sb) | |||
| 3223 | memset(buf, 0, PAGE_SIZE); | 3233 | memset(buf, 0, PAGE_SIZE); |
| 3224 | cond_resched(); | 3234 | cond_resched(); |
| 3225 | } | 3235 | } |
| 3236 | /* Add the journal blocks as well */ | ||
| 3237 | if (sbi->s_journal) | ||
| 3238 | overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen); | ||
| 3239 | |||
| 3226 | sbi->s_overhead = overhead; | 3240 | sbi->s_overhead = overhead; |
| 3227 | smp_wmb(); | 3241 | smp_wmb(); |
| 3228 | free_page((unsigned long) buf); | 3242 | free_page((unsigned long) buf); |
| @@ -3436,15 +3450,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 3436 | clear_opt(sb, DELALLOC); | 3450 | clear_opt(sb, DELALLOC); |
| 3437 | } | 3451 | } |
| 3438 | 3452 | ||
| 3439 | blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size); | ||
| 3440 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
| 3441 | if (blocksize < PAGE_SIZE) { | ||
| 3442 | ext4_msg(sb, KERN_ERR, "can't mount with " | ||
| 3443 | "dioread_nolock if block size != PAGE_SIZE"); | ||
| 3444 | goto failed_mount; | ||
| 3445 | } | ||
| 3446 | } | ||
| 3447 | |||
| 3448 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 3453 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
| 3449 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); | 3454 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
| 3450 | 3455 | ||
| @@ -3486,6 +3491,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
| 3486 | if (!ext4_feature_set_ok(sb, (sb->s_flags & MS_RDONLY))) | 3491 | if (!ext4_feature_set_ok(sb, (sb->s_flags & MS_RDONLY))) |
| 3487 | goto failed_mount; | 3492 | goto failed_mount; |
| 3488 | 3493 | ||
| 3494 | blocksize = BLOCK_SIZE << le32_to_cpu(es->s_log_block_size); | ||
| 3489 | if (blocksize < EXT4_MIN_BLOCK_SIZE || | 3495 | if (blocksize < EXT4_MIN_BLOCK_SIZE || |
| 3490 | blocksize > EXT4_MAX_BLOCK_SIZE) { | 3496 | blocksize > EXT4_MAX_BLOCK_SIZE) { |
| 3491 | ext4_msg(sb, KERN_ERR, | 3497 | ext4_msg(sb, KERN_ERR, |
| @@ -4725,7 +4731,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
| 4725 | } | 4731 | } |
| 4726 | 4732 | ||
| 4727 | ext4_setup_system_zone(sb); | 4733 | ext4_setup_system_zone(sb); |
| 4728 | if (sbi->s_journal == NULL) | 4734 | if (sbi->s_journal == NULL && !(old_sb_flags & MS_RDONLY)) |
| 4729 | ext4_commit_super(sb, 1); | 4735 | ext4_commit_super(sb, 1); |
| 4730 | 4736 | ||
| 4731 | #ifdef CONFIG_QUOTA | 4737 | #ifdef CONFIG_QUOTA |
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index fed74d193ffb..e95b94945d5f 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c | |||
| @@ -82,7 +82,6 @@ static struct posix_acl *f2fs_acl_from_disk(const char *value, size_t size) | |||
| 82 | case ACL_GROUP_OBJ: | 82 | case ACL_GROUP_OBJ: |
| 83 | case ACL_MASK: | 83 | case ACL_MASK: |
| 84 | case ACL_OTHER: | 84 | case ACL_OTHER: |
| 85 | acl->a_entries[i].e_id = ACL_UNDEFINED_ID; | ||
| 86 | entry = (struct f2fs_acl_entry *)((char *)entry + | 85 | entry = (struct f2fs_acl_entry *)((char *)entry + |
| 87 | sizeof(struct f2fs_acl_entry_short)); | 86 | sizeof(struct f2fs_acl_entry_short)); |
| 88 | break; | 87 | break; |
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 655aeabc1dd4..3aa5ce7cab83 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/backing-dev.h> | 16 | #include <linux/backing-dev.h> |
| 17 | #include <linux/blkdev.h> | 17 | #include <linux/blkdev.h> |
| 18 | #include <linux/bio.h> | 18 | #include <linux/bio.h> |
| 19 | #include <linux/prefetch.h> | ||
| 19 | 20 | ||
| 20 | #include "f2fs.h" | 21 | #include "f2fs.h" |
| 21 | #include "node.h" | 22 | #include "node.h" |
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index b4e24f32b54e..951ed52748f6 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
| 12 | #include <linux/f2fs_fs.h> | 12 | #include <linux/f2fs_fs.h> |
| 13 | #include "f2fs.h" | 13 | #include "f2fs.h" |
| 14 | #include "node.h" | ||
| 14 | #include "acl.h" | 15 | #include "acl.h" |
| 15 | 16 | ||
| 16 | static unsigned long dir_blocks(struct inode *inode) | 17 | static unsigned long dir_blocks(struct inode *inode) |
| @@ -74,7 +75,7 @@ static unsigned long dir_block_index(unsigned int level, unsigned int idx) | |||
| 74 | return bidx; | 75 | return bidx; |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | static bool early_match_name(const char *name, int namelen, | 78 | static bool early_match_name(const char *name, size_t namelen, |
| 78 | f2fs_hash_t namehash, struct f2fs_dir_entry *de) | 79 | f2fs_hash_t namehash, struct f2fs_dir_entry *de) |
| 79 | { | 80 | { |
| 80 | if (le16_to_cpu(de->name_len) != namelen) | 81 | if (le16_to_cpu(de->name_len) != namelen) |
| @@ -87,7 +88,7 @@ static bool early_match_name(const char *name, int namelen, | |||
| 87 | } | 88 | } |
| 88 | 89 | ||
| 89 | static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, | 90 | static struct f2fs_dir_entry *find_in_block(struct page *dentry_page, |
| 90 | const char *name, int namelen, int *max_slots, | 91 | const char *name, size_t namelen, int *max_slots, |
| 91 | f2fs_hash_t namehash, struct page **res_page) | 92 | f2fs_hash_t namehash, struct page **res_page) |
| 92 | { | 93 | { |
| 93 | struct f2fs_dir_entry *de; | 94 | struct f2fs_dir_entry *de; |
| @@ -126,7 +127,7 @@ found: | |||
| 126 | } | 127 | } |
| 127 | 128 | ||
| 128 | static struct f2fs_dir_entry *find_in_level(struct inode *dir, | 129 | static struct f2fs_dir_entry *find_in_level(struct inode *dir, |
| 129 | unsigned int level, const char *name, int namelen, | 130 | unsigned int level, const char *name, size_t namelen, |
| 130 | f2fs_hash_t namehash, struct page **res_page) | 131 | f2fs_hash_t namehash, struct page **res_page) |
| 131 | { | 132 | { |
| 132 | int s = GET_DENTRY_SLOTS(namelen); | 133 | int s = GET_DENTRY_SLOTS(namelen); |
| @@ -181,7 +182,7 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir, | |||
| 181 | struct qstr *child, struct page **res_page) | 182 | struct qstr *child, struct page **res_page) |
| 182 | { | 183 | { |
| 183 | const char *name = child->name; | 184 | const char *name = child->name; |
| 184 | int namelen = child->len; | 185 | size_t namelen = child->len; |
| 185 | unsigned long npages = dir_blocks(dir); | 186 | unsigned long npages = dir_blocks(dir); |
| 186 | struct f2fs_dir_entry *de = NULL; | 187 | struct f2fs_dir_entry *de = NULL; |
| 187 | f2fs_hash_t name_hash; | 188 | f2fs_hash_t name_hash; |
| @@ -308,6 +309,7 @@ static int init_inode_metadata(struct inode *inode, struct dentry *dentry) | |||
| 308 | ipage = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); | 309 | ipage = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino); |
| 309 | if (IS_ERR(ipage)) | 310 | if (IS_ERR(ipage)) |
| 310 | return PTR_ERR(ipage); | 311 | return PTR_ERR(ipage); |
| 312 | set_cold_node(inode, ipage); | ||
| 311 | init_dent_inode(dentry, ipage); | 313 | init_dent_inode(dentry, ipage); |
| 312 | f2fs_put_page(ipage, 1); | 314 | f2fs_put_page(ipage, 1); |
| 313 | } | 315 | } |
| @@ -381,7 +383,7 @@ int f2fs_add_link(struct dentry *dentry, struct inode *inode) | |||
| 381 | struct inode *dir = dentry->d_parent->d_inode; | 383 | struct inode *dir = dentry->d_parent->d_inode; |
| 382 | struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); | 384 | struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb); |
| 383 | const char *name = dentry->d_name.name; | 385 | const char *name = dentry->d_name.name; |
| 384 | int namelen = dentry->d_name.len; | 386 | size_t namelen = dentry->d_name.len; |
| 385 | struct page *dentry_page = NULL; | 387 | struct page *dentry_page = NULL; |
| 386 | struct f2fs_dentry_block *dentry_blk = NULL; | 388 | struct f2fs_dentry_block *dentry_blk = NULL; |
| 387 | int slots = GET_DENTRY_SLOTS(namelen); | 389 | int slots = GET_DENTRY_SLOTS(namelen); |
| @@ -540,13 +542,13 @@ int f2fs_make_empty(struct inode *inode, struct inode *parent) | |||
| 540 | 542 | ||
| 541 | de = &dentry_blk->dentry[0]; | 543 | de = &dentry_blk->dentry[0]; |
| 542 | de->name_len = cpu_to_le16(1); | 544 | de->name_len = cpu_to_le16(1); |
| 543 | de->hash_code = 0; | 545 | de->hash_code = f2fs_dentry_hash(".", 1); |
| 544 | de->ino = cpu_to_le32(inode->i_ino); | 546 | de->ino = cpu_to_le32(inode->i_ino); |
| 545 | memcpy(dentry_blk->filename[0], ".", 1); | 547 | memcpy(dentry_blk->filename[0], ".", 1); |
| 546 | set_de_type(de, inode); | 548 | set_de_type(de, inode); |
| 547 | 549 | ||
| 548 | de = &dentry_blk->dentry[1]; | 550 | de = &dentry_blk->dentry[1]; |
| 549 | de->hash_code = 0; | 551 | de->hash_code = f2fs_dentry_hash("..", 2); |
| 550 | de->name_len = cpu_to_le16(2); | 552 | de->name_len = cpu_to_le16(2); |
| 551 | de->ino = cpu_to_le32(parent->i_ino); | 553 | de->ino = cpu_to_le32(parent->i_ino); |
| 552 | memcpy(dentry_blk->filename[1], "..", 2); | 554 | memcpy(dentry_blk->filename[1], "..", 2); |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a18d63db2fb6..13c6dfbb7183 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
| @@ -881,7 +881,7 @@ int f2fs_sync_fs(struct super_block *, int); | |||
| 881 | /* | 881 | /* |
| 882 | * hash.c | 882 | * hash.c |
| 883 | */ | 883 | */ |
| 884 | f2fs_hash_t f2fs_dentry_hash(const char *, int); | 884 | f2fs_hash_t f2fs_dentry_hash(const char *, size_t); |
| 885 | 885 | ||
| 886 | /* | 886 | /* |
| 887 | * node.c | 887 | * node.c |
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index f9e085dfb1f0..7f9ea9271ebe 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c | |||
| @@ -160,15 +160,17 @@ int f2fs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 160 | if (need_to_sync_dir(sbi, inode)) | 160 | if (need_to_sync_dir(sbi, inode)) |
| 161 | need_cp = true; | 161 | need_cp = true; |
| 162 | 162 | ||
| 163 | f2fs_write_inode(inode, NULL); | ||
| 164 | |||
| 165 | if (need_cp) { | 163 | if (need_cp) { |
| 166 | /* all the dirty node pages should be flushed for POR */ | 164 | /* all the dirty node pages should be flushed for POR */ |
| 167 | ret = f2fs_sync_fs(inode->i_sb, 1); | 165 | ret = f2fs_sync_fs(inode->i_sb, 1); |
| 168 | clear_inode_flag(F2FS_I(inode), FI_NEED_CP); | 166 | clear_inode_flag(F2FS_I(inode), FI_NEED_CP); |
| 169 | } else { | 167 | } else { |
| 170 | while (sync_node_pages(sbi, inode->i_ino, &wbc) == 0) | 168 | /* if there is no written node page, write its inode page */ |
| 171 | f2fs_write_inode(inode, NULL); | 169 | while (!sync_node_pages(sbi, inode->i_ino, &wbc)) { |
| 170 | ret = f2fs_write_inode(inode, NULL); | ||
| 171 | if (ret) | ||
| 172 | goto out; | ||
| 173 | } | ||
| 172 | filemap_fdatawait_range(sbi->node_inode->i_mapping, | 174 | filemap_fdatawait_range(sbi->node_inode->i_mapping, |
| 173 | 0, LONG_MAX); | 175 | 0, LONG_MAX); |
| 174 | } | 176 | } |
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 644aa3808273..b0ec721e984a 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c | |||
| @@ -390,9 +390,7 @@ next_step: | |||
| 390 | } | 390 | } |
| 391 | 391 | ||
| 392 | err = check_valid_map(sbi, segno, off); | 392 | err = check_valid_map(sbi, segno, off); |
| 393 | if (err == GC_ERROR) | 393 | if (err == GC_NEXT) |
| 394 | return err; | ||
| 395 | else if (err == GC_NEXT) | ||
| 396 | continue; | 394 | continue; |
| 397 | 395 | ||
| 398 | if (initial) { | 396 | if (initial) { |
| @@ -430,28 +428,22 @@ next_step: | |||
| 430 | */ | 428 | */ |
| 431 | block_t start_bidx_of_node(unsigned int node_ofs) | 429 | block_t start_bidx_of_node(unsigned int node_ofs) |
| 432 | { | 430 | { |
| 433 | block_t start_bidx; | 431 | unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4; |
| 434 | unsigned int bidx, indirect_blks; | 432 | unsigned int bidx; |
| 435 | int dec; | ||
| 436 | 433 | ||
| 437 | indirect_blks = 2 * NIDS_PER_BLOCK + 4; | 434 | if (node_ofs == 0) |
| 435 | return 0; | ||
| 438 | 436 | ||
| 439 | start_bidx = 1; | 437 | if (node_ofs <= 2) { |
| 440 | if (node_ofs == 0) { | ||
| 441 | start_bidx = 0; | ||
| 442 | } else if (node_ofs <= 2) { | ||
| 443 | bidx = node_ofs - 1; | 438 | bidx = node_ofs - 1; |
| 444 | } else if (node_ofs <= indirect_blks) { | 439 | } else if (node_ofs <= indirect_blks) { |
| 445 | dec = (node_ofs - 4) / (NIDS_PER_BLOCK + 1); | 440 | int dec = (node_ofs - 4) / (NIDS_PER_BLOCK + 1); |
| 446 | bidx = node_ofs - 2 - dec; | 441 | bidx = node_ofs - 2 - dec; |
| 447 | } else { | 442 | } else { |
| 448 | dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1); | 443 | int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1); |
| 449 | bidx = node_ofs - 5 - dec; | 444 | bidx = node_ofs - 5 - dec; |
| 450 | } | 445 | } |
| 451 | 446 | return bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE; | |
| 452 | if (start_bidx) | ||
| 453 | start_bidx = bidx * ADDRS_PER_BLOCK + ADDRS_PER_INODE; | ||
| 454 | return start_bidx; | ||
| 455 | } | 447 | } |
| 456 | 448 | ||
| 457 | static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, | 449 | static int check_dnode(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, |
| @@ -556,9 +548,7 @@ next_step: | |||
| 556 | } | 548 | } |
| 557 | 549 | ||
| 558 | err = check_valid_map(sbi, segno, off); | 550 | err = check_valid_map(sbi, segno, off); |
| 559 | if (err == GC_ERROR) | 551 | if (err == GC_NEXT) |
| 560 | goto stop; | ||
| 561 | else if (err == GC_NEXT) | ||
| 562 | continue; | 552 | continue; |
| 563 | 553 | ||
| 564 | if (phase == 0) { | 554 | if (phase == 0) { |
| @@ -568,9 +558,7 @@ next_step: | |||
| 568 | 558 | ||
| 569 | /* Get an inode by ino with checking validity */ | 559 | /* Get an inode by ino with checking validity */ |
| 570 | err = check_dnode(sbi, entry, &dni, start_addr + off, &nofs); | 560 | err = check_dnode(sbi, entry, &dni, start_addr + off, &nofs); |
| 571 | if (err == GC_ERROR) | 561 | if (err == GC_NEXT) |
| 572 | goto stop; | ||
| 573 | else if (err == GC_NEXT) | ||
| 574 | continue; | 562 | continue; |
| 575 | 563 | ||
| 576 | if (phase == 1) { | 564 | if (phase == 1) { |
diff --git a/fs/f2fs/hash.c b/fs/f2fs/hash.c index a60f04200f8b..6eb8d269b53b 100644 --- a/fs/f2fs/hash.c +++ b/fs/f2fs/hash.c | |||
| @@ -42,7 +42,7 @@ static void TEA_transform(unsigned int buf[4], unsigned int const in[]) | |||
| 42 | buf[1] += b1; | 42 | buf[1] += b1; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static void str2hashbuf(const char *msg, int len, unsigned int *buf, int num) | 45 | static void str2hashbuf(const char *msg, size_t len, unsigned int *buf, int num) |
| 46 | { | 46 | { |
| 47 | unsigned pad, val; | 47 | unsigned pad, val; |
| 48 | int i; | 48 | int i; |
| @@ -69,13 +69,17 @@ static void str2hashbuf(const char *msg, int len, unsigned int *buf, int num) | |||
| 69 | *buf++ = pad; | 69 | *buf++ = pad; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | f2fs_hash_t f2fs_dentry_hash(const char *name, int len) | 72 | f2fs_hash_t f2fs_dentry_hash(const char *name, size_t len) |
| 73 | { | 73 | { |
| 74 | __u32 hash, minor_hash; | 74 | __u32 hash; |
| 75 | f2fs_hash_t f2fs_hash; | 75 | f2fs_hash_t f2fs_hash; |
| 76 | const char *p; | 76 | const char *p; |
| 77 | __u32 in[8], buf[4]; | 77 | __u32 in[8], buf[4]; |
| 78 | 78 | ||
| 79 | if ((len <= 2) && (name[0] == '.') && | ||
| 80 | (name[1] == '.' || name[1] == '\0')) | ||
| 81 | return 0; | ||
| 82 | |||
| 79 | /* Initialize the default seed for the hash checksum functions */ | 83 | /* Initialize the default seed for the hash checksum functions */ |
| 80 | buf[0] = 0x67452301; | 84 | buf[0] = 0x67452301; |
| 81 | buf[1] = 0xefcdab89; | 85 | buf[1] = 0xefcdab89; |
| @@ -83,15 +87,15 @@ f2fs_hash_t f2fs_dentry_hash(const char *name, int len) | |||
| 83 | buf[3] = 0x10325476; | 87 | buf[3] = 0x10325476; |
| 84 | 88 | ||
| 85 | p = name; | 89 | p = name; |
| 86 | while (len > 0) { | 90 | while (1) { |
| 87 | str2hashbuf(p, len, in, 4); | 91 | str2hashbuf(p, len, in, 4); |
| 88 | TEA_transform(buf, in); | 92 | TEA_transform(buf, in); |
| 89 | len -= 16; | ||
| 90 | p += 16; | 93 | p += 16; |
| 94 | if (len <= 16) | ||
| 95 | break; | ||
| 96 | len -= 16; | ||
| 91 | } | 97 | } |
| 92 | hash = buf[0]; | 98 | hash = buf[0]; |
| 93 | minor_hash = buf[1]; | ||
| 94 | |||
| 95 | f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT); | 99 | f2fs_hash = cpu_to_le32(hash & ~F2FS_HASH_COL_BIT); |
| 96 | return f2fs_hash; | 100 | return f2fs_hash; |
| 97 | } | 101 | } |
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index df5fb381ebf1..bf20b4d03214 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c | |||
| @@ -203,6 +203,7 @@ void update_inode(struct inode *inode, struct page *node_page) | |||
| 203 | ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags); | 203 | ri->i_flags = cpu_to_le32(F2FS_I(inode)->i_flags); |
| 204 | ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino); | 204 | ri->i_pino = cpu_to_le32(F2FS_I(inode)->i_pino); |
| 205 | ri->i_generation = cpu_to_le32(inode->i_generation); | 205 | ri->i_generation = cpu_to_le32(inode->i_generation); |
| 206 | set_cold_node(inode, node_page); | ||
| 206 | set_page_dirty(node_page); | 207 | set_page_dirty(node_page); |
| 207 | } | 208 | } |
| 208 | 209 | ||
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 89b7675dc377..1a49b881bac0 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
| @@ -77,8 +77,8 @@ fail: | |||
| 77 | 77 | ||
| 78 | static int is_multimedia_file(const unsigned char *s, const char *sub) | 78 | static int is_multimedia_file(const unsigned char *s, const char *sub) |
| 79 | { | 79 | { |
| 80 | int slen = strlen(s); | 80 | size_t slen = strlen(s); |
| 81 | int sublen = strlen(sub); | 81 | size_t sublen = strlen(sub); |
| 82 | int ret; | 82 | int ret; |
| 83 | 83 | ||
| 84 | if (sublen > slen) | 84 | if (sublen > slen) |
| @@ -123,6 +123,8 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
| 123 | nid_t ino = 0; | 123 | nid_t ino = 0; |
| 124 | int err; | 124 | int err; |
| 125 | 125 | ||
| 126 | f2fs_balance_fs(sbi); | ||
| 127 | |||
| 126 | inode = f2fs_new_inode(dir, mode); | 128 | inode = f2fs_new_inode(dir, mode); |
| 127 | if (IS_ERR(inode)) | 129 | if (IS_ERR(inode)) |
| 128 | return PTR_ERR(inode); | 130 | return PTR_ERR(inode); |
| @@ -144,8 +146,6 @@ static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode, | |||
| 144 | if (!sbi->por_doing) | 146 | if (!sbi->por_doing) |
| 145 | d_instantiate(dentry, inode); | 147 | d_instantiate(dentry, inode); |
| 146 | unlock_new_inode(inode); | 148 | unlock_new_inode(inode); |
| 147 | |||
| 148 | f2fs_balance_fs(sbi); | ||
| 149 | return 0; | 149 | return 0; |
| 150 | out: | 150 | out: |
| 151 | clear_nlink(inode); | 151 | clear_nlink(inode); |
| @@ -163,6 +163,8 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 163 | struct f2fs_sb_info *sbi = F2FS_SB(sb); | 163 | struct f2fs_sb_info *sbi = F2FS_SB(sb); |
| 164 | int err; | 164 | int err; |
| 165 | 165 | ||
| 166 | f2fs_balance_fs(sbi); | ||
| 167 | |||
| 166 | inode->i_ctime = CURRENT_TIME; | 168 | inode->i_ctime = CURRENT_TIME; |
| 167 | atomic_inc(&inode->i_count); | 169 | atomic_inc(&inode->i_count); |
| 168 | 170 | ||
| @@ -172,8 +174,6 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 172 | goto out; | 174 | goto out; |
| 173 | 175 | ||
| 174 | d_instantiate(dentry, inode); | 176 | d_instantiate(dentry, inode); |
| 175 | |||
| 176 | f2fs_balance_fs(sbi); | ||
| 177 | return 0; | 177 | return 0; |
| 178 | out: | 178 | out: |
| 179 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); | 179 | clear_inode_flag(F2FS_I(inode), FI_INC_LINK); |
| @@ -223,6 +223,8 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 223 | struct page *page; | 223 | struct page *page; |
| 224 | int err = -ENOENT; | 224 | int err = -ENOENT; |
| 225 | 225 | ||
| 226 | f2fs_balance_fs(sbi); | ||
| 227 | |||
| 226 | de = f2fs_find_entry(dir, &dentry->d_name, &page); | 228 | de = f2fs_find_entry(dir, &dentry->d_name, &page); |
| 227 | if (!de) | 229 | if (!de) |
| 228 | goto fail; | 230 | goto fail; |
| @@ -238,7 +240,6 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 238 | 240 | ||
| 239 | /* In order to evict this inode, we set it dirty */ | 241 | /* In order to evict this inode, we set it dirty */ |
| 240 | mark_inode_dirty(inode); | 242 | mark_inode_dirty(inode); |
| 241 | f2fs_balance_fs(sbi); | ||
| 242 | fail: | 243 | fail: |
| 243 | return err; | 244 | return err; |
| 244 | } | 245 | } |
| @@ -249,9 +250,11 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 249 | struct super_block *sb = dir->i_sb; | 250 | struct super_block *sb = dir->i_sb; |
| 250 | struct f2fs_sb_info *sbi = F2FS_SB(sb); | 251 | struct f2fs_sb_info *sbi = F2FS_SB(sb); |
| 251 | struct inode *inode; | 252 | struct inode *inode; |
| 252 | unsigned symlen = strlen(symname) + 1; | 253 | size_t symlen = strlen(symname) + 1; |
| 253 | int err; | 254 | int err; |
| 254 | 255 | ||
| 256 | f2fs_balance_fs(sbi); | ||
| 257 | |||
| 255 | inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO); | 258 | inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO); |
| 256 | if (IS_ERR(inode)) | 259 | if (IS_ERR(inode)) |
| 257 | return PTR_ERR(inode); | 260 | return PTR_ERR(inode); |
| @@ -268,9 +271,6 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 268 | 271 | ||
| 269 | d_instantiate(dentry, inode); | 272 | d_instantiate(dentry, inode); |
| 270 | unlock_new_inode(inode); | 273 | unlock_new_inode(inode); |
| 271 | |||
| 272 | f2fs_balance_fs(sbi); | ||
| 273 | |||
| 274 | return err; | 274 | return err; |
| 275 | out: | 275 | out: |
| 276 | clear_nlink(inode); | 276 | clear_nlink(inode); |
| @@ -286,6 +286,8 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 286 | struct inode *inode; | 286 | struct inode *inode; |
| 287 | int err; | 287 | int err; |
| 288 | 288 | ||
| 289 | f2fs_balance_fs(sbi); | ||
| 290 | |||
| 289 | inode = f2fs_new_inode(dir, S_IFDIR | mode); | 291 | inode = f2fs_new_inode(dir, S_IFDIR | mode); |
| 290 | if (IS_ERR(inode)) | 292 | if (IS_ERR(inode)) |
| 291 | return PTR_ERR(inode); | 293 | return PTR_ERR(inode); |
| @@ -305,7 +307,6 @@ static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
| 305 | d_instantiate(dentry, inode); | 307 | d_instantiate(dentry, inode); |
| 306 | unlock_new_inode(inode); | 308 | unlock_new_inode(inode); |
| 307 | 309 | ||
| 308 | f2fs_balance_fs(sbi); | ||
| 309 | return 0; | 310 | return 0; |
| 310 | 311 | ||
| 311 | out_fail: | 312 | out_fail: |
| @@ -336,6 +337,8 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 336 | if (!new_valid_dev(rdev)) | 337 | if (!new_valid_dev(rdev)) |
| 337 | return -EINVAL; | 338 | return -EINVAL; |
| 338 | 339 | ||
| 340 | f2fs_balance_fs(sbi); | ||
| 341 | |||
| 339 | inode = f2fs_new_inode(dir, mode); | 342 | inode = f2fs_new_inode(dir, mode); |
| 340 | if (IS_ERR(inode)) | 343 | if (IS_ERR(inode)) |
| 341 | return PTR_ERR(inode); | 344 | return PTR_ERR(inode); |
| @@ -350,9 +353,6 @@ static int f2fs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 350 | alloc_nid_done(sbi, inode->i_ino); | 353 | alloc_nid_done(sbi, inode->i_ino); |
| 351 | d_instantiate(dentry, inode); | 354 | d_instantiate(dentry, inode); |
| 352 | unlock_new_inode(inode); | 355 | unlock_new_inode(inode); |
| 353 | |||
| 354 | f2fs_balance_fs(sbi); | ||
| 355 | |||
| 356 | return 0; | 356 | return 0; |
| 357 | out: | 357 | out: |
| 358 | clear_nlink(inode); | 358 | clear_nlink(inode); |
| @@ -376,6 +376,8 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 376 | struct f2fs_dir_entry *new_entry; | 376 | struct f2fs_dir_entry *new_entry; |
| 377 | int err = -ENOENT; | 377 | int err = -ENOENT; |
| 378 | 378 | ||
| 379 | f2fs_balance_fs(sbi); | ||
| 380 | |||
| 379 | old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); | 381 | old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
| 380 | if (!old_entry) | 382 | if (!old_entry) |
| 381 | goto out; | 383 | goto out; |
| @@ -441,8 +443,6 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 441 | } | 443 | } |
| 442 | 444 | ||
| 443 | mutex_unlock_op(sbi, RENAME); | 445 | mutex_unlock_op(sbi, RENAME); |
| 444 | |||
| 445 | f2fs_balance_fs(sbi); | ||
| 446 | return 0; | 446 | return 0; |
| 447 | 447 | ||
| 448 | out_dir: | 448 | out_dir: |
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 19870361497e..5066bfd256c9 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c | |||
| @@ -484,12 +484,14 @@ static void truncate_node(struct dnode_of_data *dn) | |||
| 484 | struct node_info ni; | 484 | struct node_info ni; |
| 485 | 485 | ||
| 486 | get_node_info(sbi, dn->nid, &ni); | 486 | get_node_info(sbi, dn->nid, &ni); |
| 487 | if (dn->inode->i_blocks == 0) { | ||
| 488 | BUG_ON(ni.blk_addr != NULL_ADDR); | ||
| 489 | goto invalidate; | ||
| 490 | } | ||
| 487 | BUG_ON(ni.blk_addr == NULL_ADDR); | 491 | BUG_ON(ni.blk_addr == NULL_ADDR); |
| 488 | 492 | ||
| 489 | if (ni.blk_addr != NULL_ADDR) | ||
| 490 | invalidate_blocks(sbi, ni.blk_addr); | ||
| 491 | |||
| 492 | /* Deallocate node address */ | 493 | /* Deallocate node address */ |
| 494 | invalidate_blocks(sbi, ni.blk_addr); | ||
| 493 | dec_valid_node_count(sbi, dn->inode, 1); | 495 | dec_valid_node_count(sbi, dn->inode, 1); |
| 494 | set_node_addr(sbi, &ni, NULL_ADDR); | 496 | set_node_addr(sbi, &ni, NULL_ADDR); |
| 495 | 497 | ||
| @@ -499,7 +501,7 @@ static void truncate_node(struct dnode_of_data *dn) | |||
| 499 | } else { | 501 | } else { |
| 500 | sync_inode_page(dn); | 502 | sync_inode_page(dn); |
| 501 | } | 503 | } |
| 502 | 504 | invalidate: | |
| 503 | clear_node_page_dirty(dn->node_page); | 505 | clear_node_page_dirty(dn->node_page); |
| 504 | F2FS_SET_SB_DIRT(sbi); | 506 | F2FS_SET_SB_DIRT(sbi); |
| 505 | 507 | ||
| @@ -768,20 +770,12 @@ int remove_inode_page(struct inode *inode) | |||
| 768 | dn.inode_page_locked = 1; | 770 | dn.inode_page_locked = 1; |
| 769 | truncate_node(&dn); | 771 | truncate_node(&dn); |
| 770 | } | 772 | } |
| 771 | if (inode->i_blocks == 1) { | ||
| 772 | /* inernally call f2fs_put_page() */ | ||
| 773 | set_new_dnode(&dn, inode, page, page, ino); | ||
| 774 | truncate_node(&dn); | ||
| 775 | } else if (inode->i_blocks == 0) { | ||
| 776 | struct node_info ni; | ||
| 777 | get_node_info(sbi, inode->i_ino, &ni); | ||
| 778 | 773 | ||
| 779 | /* called after f2fs_new_inode() is failed */ | 774 | /* 0 is possible, after f2fs_new_inode() is failed */ |
| 780 | BUG_ON(ni.blk_addr != NULL_ADDR); | 775 | BUG_ON(inode->i_blocks != 0 && inode->i_blocks != 1); |
| 781 | f2fs_put_page(page, 1); | 776 | set_new_dnode(&dn, inode, page, page, ino); |
| 782 | } else { | 777 | truncate_node(&dn); |
| 783 | BUG(); | 778 | |
| 784 | } | ||
| 785 | mutex_unlock_op(sbi, NODE_TRUNC); | 779 | mutex_unlock_op(sbi, NODE_TRUNC); |
| 786 | return 0; | 780 | return 0; |
| 787 | } | 781 | } |
| @@ -834,17 +828,18 @@ struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs) | |||
| 834 | goto fail; | 828 | goto fail; |
| 835 | } | 829 | } |
| 836 | set_node_addr(sbi, &new_ni, NEW_ADDR); | 830 | set_node_addr(sbi, &new_ni, NEW_ADDR); |
| 831 | set_cold_node(dn->inode, page); | ||
| 837 | 832 | ||
| 838 | dn->node_page = page; | 833 | dn->node_page = page; |
| 839 | sync_inode_page(dn); | 834 | sync_inode_page(dn); |
| 840 | set_page_dirty(page); | 835 | set_page_dirty(page); |
| 841 | set_cold_node(dn->inode, page); | ||
| 842 | if (ofs == 0) | 836 | if (ofs == 0) |
| 843 | inc_valid_inode_count(sbi); | 837 | inc_valid_inode_count(sbi); |
| 844 | 838 | ||
| 845 | return page; | 839 | return page; |
| 846 | 840 | ||
| 847 | fail: | 841 | fail: |
| 842 | clear_node_page_dirty(page); | ||
| 848 | f2fs_put_page(page, 1); | 843 | f2fs_put_page(page, 1); |
| 849 | return ERR_PTR(err); | 844 | return ERR_PTR(err); |
| 850 | } | 845 | } |
| @@ -1093,7 +1088,6 @@ static int f2fs_write_node_page(struct page *page, | |||
| 1093 | { | 1088 | { |
| 1094 | struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb); | 1089 | struct f2fs_sb_info *sbi = F2FS_SB(page->mapping->host->i_sb); |
| 1095 | nid_t nid; | 1090 | nid_t nid; |
| 1096 | unsigned int nofs; | ||
| 1097 | block_t new_addr; | 1091 | block_t new_addr; |
| 1098 | struct node_info ni; | 1092 | struct node_info ni; |
| 1099 | 1093 | ||
| @@ -1110,7 +1104,6 @@ static int f2fs_write_node_page(struct page *page, | |||
| 1110 | 1104 | ||
| 1111 | /* get old block addr of this node page */ | 1105 | /* get old block addr of this node page */ |
| 1112 | nid = nid_of_node(page); | 1106 | nid = nid_of_node(page); |
| 1113 | nofs = ofs_of_node(page); | ||
| 1114 | BUG_ON(page->index != nid); | 1107 | BUG_ON(page->index != nid); |
| 1115 | 1108 | ||
| 1116 | get_node_info(sbi, nid, &ni); | 1109 | get_node_info(sbi, nid, &ni); |
| @@ -1571,7 +1564,7 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
| 1571 | nid_t nid; | 1564 | nid_t nid; |
| 1572 | struct f2fs_nat_entry raw_ne; | 1565 | struct f2fs_nat_entry raw_ne; |
| 1573 | int offset = -1; | 1566 | int offset = -1; |
| 1574 | block_t old_blkaddr, new_blkaddr; | 1567 | block_t new_blkaddr; |
| 1575 | 1568 | ||
| 1576 | ne = list_entry(cur, struct nat_entry, list); | 1569 | ne = list_entry(cur, struct nat_entry, list); |
| 1577 | nid = nat_get_nid(ne); | 1570 | nid = nat_get_nid(ne); |
| @@ -1585,7 +1578,6 @@ void flush_nat_entries(struct f2fs_sb_info *sbi) | |||
| 1585 | offset = lookup_journal_in_cursum(sum, NAT_JOURNAL, nid, 1); | 1578 | offset = lookup_journal_in_cursum(sum, NAT_JOURNAL, nid, 1); |
| 1586 | if (offset >= 0) { | 1579 | if (offset >= 0) { |
| 1587 | raw_ne = nat_in_journal(sum, offset); | 1580 | raw_ne = nat_in_journal(sum, offset); |
| 1588 | old_blkaddr = le32_to_cpu(raw_ne.block_addr); | ||
| 1589 | goto flush_now; | 1581 | goto flush_now; |
| 1590 | } | 1582 | } |
| 1591 | to_nat_page: | 1583 | to_nat_page: |
| @@ -1607,7 +1599,6 @@ to_nat_page: | |||
| 1607 | 1599 | ||
| 1608 | BUG_ON(!nat_blk); | 1600 | BUG_ON(!nat_blk); |
| 1609 | raw_ne = nat_blk->entries[nid - start_nid]; | 1601 | raw_ne = nat_blk->entries[nid - start_nid]; |
| 1610 | old_blkaddr = le32_to_cpu(raw_ne.block_addr); | ||
| 1611 | flush_now: | 1602 | flush_now: |
| 1612 | new_blkaddr = nat_get_blkaddr(ne); | 1603 | new_blkaddr = nat_get_blkaddr(ne); |
| 1613 | 1604 | ||
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index b07e9b6ef376..b571fee677d5 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c | |||
| @@ -144,14 +144,15 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head) | |||
| 144 | goto out; | 144 | goto out; |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | INIT_LIST_HEAD(&entry->list); | ||
| 148 | list_add_tail(&entry->list, head); | ||
| 149 | |||
| 150 | entry->inode = f2fs_iget(sbi->sb, ino_of_node(page)); | 147 | entry->inode = f2fs_iget(sbi->sb, ino_of_node(page)); |
| 151 | if (IS_ERR(entry->inode)) { | 148 | if (IS_ERR(entry->inode)) { |
| 152 | err = PTR_ERR(entry->inode); | 149 | err = PTR_ERR(entry->inode); |
| 150 | kmem_cache_free(fsync_entry_slab, entry); | ||
| 153 | goto out; | 151 | goto out; |
| 154 | } | 152 | } |
| 153 | |||
| 154 | INIT_LIST_HEAD(&entry->list); | ||
| 155 | list_add_tail(&entry->list, head); | ||
| 155 | entry->blkaddr = blkaddr; | 156 | entry->blkaddr = blkaddr; |
| 156 | } | 157 | } |
| 157 | if (IS_INODE(page)) { | 158 | if (IS_INODE(page)) { |
| @@ -228,6 +229,9 @@ static void check_index_in_prev_nodes(struct f2fs_sb_info *sbi, | |||
| 228 | 229 | ||
| 229 | /* Deallocate previous index in the node page */ | 230 | /* Deallocate previous index in the node page */ |
| 230 | inode = f2fs_iget_nowait(sbi->sb, ino); | 231 | inode = f2fs_iget_nowait(sbi->sb, ino); |
| 232 | if (IS_ERR(inode)) | ||
| 233 | return; | ||
| 234 | |||
| 231 | truncate_hole(inode, bidx, bidx + 1); | 235 | truncate_hole(inode, bidx, bidx + 1); |
| 232 | iput(inode); | 236 | iput(inode); |
| 233 | } | 237 | } |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 1b26e4ea1016..de6240922b0a 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
| @@ -12,54 +12,23 @@ | |||
| 12 | #include <linux/f2fs_fs.h> | 12 | #include <linux/f2fs_fs.h> |
| 13 | #include <linux/bio.h> | 13 | #include <linux/bio.h> |
| 14 | #include <linux/blkdev.h> | 14 | #include <linux/blkdev.h> |
| 15 | #include <linux/prefetch.h> | ||
| 15 | #include <linux/vmalloc.h> | 16 | #include <linux/vmalloc.h> |
| 16 | 17 | ||
| 17 | #include "f2fs.h" | 18 | #include "f2fs.h" |
| 18 | #include "segment.h" | 19 | #include "segment.h" |
| 19 | #include "node.h" | 20 | #include "node.h" |
| 20 | 21 | ||
| 21 | static int need_to_flush(struct f2fs_sb_info *sbi) | ||
| 22 | { | ||
| 23 | unsigned int pages_per_sec = (1 << sbi->log_blocks_per_seg) * | ||
| 24 | sbi->segs_per_sec; | ||
| 25 | int node_secs = ((get_pages(sbi, F2FS_DIRTY_NODES) + pages_per_sec - 1) | ||
| 26 | >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; | ||
| 27 | int dent_secs = ((get_pages(sbi, F2FS_DIRTY_DENTS) + pages_per_sec - 1) | ||
| 28 | >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; | ||
| 29 | |||
| 30 | if (sbi->por_doing) | ||
| 31 | return 0; | ||
| 32 | |||
| 33 | if (free_sections(sbi) <= (node_secs + 2 * dent_secs + | ||
| 34 | reserved_sections(sbi))) | ||
| 35 | return 1; | ||
| 36 | return 0; | ||
| 37 | } | ||
| 38 | |||
| 39 | /* | 22 | /* |
| 40 | * This function balances dirty node and dentry pages. | 23 | * This function balances dirty node and dentry pages. |
| 41 | * In addition, it controls garbage collection. | 24 | * In addition, it controls garbage collection. |
| 42 | */ | 25 | */ |
| 43 | void f2fs_balance_fs(struct f2fs_sb_info *sbi) | 26 | void f2fs_balance_fs(struct f2fs_sb_info *sbi) |
| 44 | { | 27 | { |
| 45 | struct writeback_control wbc = { | ||
| 46 | .sync_mode = WB_SYNC_ALL, | ||
| 47 | .nr_to_write = LONG_MAX, | ||
| 48 | .for_reclaim = 0, | ||
| 49 | }; | ||
| 50 | |||
| 51 | if (sbi->por_doing) | ||
| 52 | return; | ||
| 53 | |||
| 54 | /* | 28 | /* |
| 55 | * We should do checkpoint when there are so many dirty node pages | 29 | * We should do GC or end up with checkpoint, if there are so many dirty |
| 56 | * with enough free segments. After then, we should do GC. | 30 | * dir/node pages without enough free segments. |
| 57 | */ | 31 | */ |
| 58 | if (need_to_flush(sbi)) { | ||
| 59 | sync_dirty_dir_inodes(sbi); | ||
| 60 | sync_node_pages(sbi, 0, &wbc); | ||
| 61 | } | ||
| 62 | |||
| 63 | if (has_not_enough_free_secs(sbi)) { | 32 | if (has_not_enough_free_secs(sbi)) { |
| 64 | mutex_lock(&sbi->gc_mutex); | 33 | mutex_lock(&sbi->gc_mutex); |
| 65 | f2fs_gc(sbi, 1); | 34 | f2fs_gc(sbi, 1); |
| @@ -631,7 +600,6 @@ static void f2fs_end_io_write(struct bio *bio, int err) | |||
| 631 | if (page->mapping) | 600 | if (page->mapping) |
| 632 | set_bit(AS_EIO, &page->mapping->flags); | 601 | set_bit(AS_EIO, &page->mapping->flags); |
| 633 | set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG); | 602 | set_ckpt_flags(p->sbi->ckpt, CP_ERROR_FLAG); |
| 634 | set_page_dirty(page); | ||
| 635 | } | 603 | } |
| 636 | end_page_writeback(page); | 604 | end_page_writeback(page); |
| 637 | dec_page_count(p->sbi, F2FS_WRITEBACK); | 605 | dec_page_count(p->sbi, F2FS_WRITEBACK); |
| @@ -791,11 +759,10 @@ static int __get_segment_type(struct page *page, enum page_type p_type) | |||
| 791 | return __get_segment_type_2(page, p_type); | 759 | return __get_segment_type_2(page, p_type); |
| 792 | case 4: | 760 | case 4: |
| 793 | return __get_segment_type_4(page, p_type); | 761 | return __get_segment_type_4(page, p_type); |
| 794 | case 6: | ||
| 795 | return __get_segment_type_6(page, p_type); | ||
| 796 | default: | ||
| 797 | BUG(); | ||
| 798 | } | 762 | } |
| 763 | /* NR_CURSEG_TYPE(6) logs by default */ | ||
| 764 | BUG_ON(sbi->active_logs != NR_CURSEG_TYPE); | ||
| 765 | return __get_segment_type_6(page, p_type); | ||
| 799 | } | 766 | } |
| 800 | 767 | ||
| 801 | static void do_write_page(struct f2fs_sb_info *sbi, struct page *page, | 768 | static void do_write_page(struct f2fs_sb_info *sbi, struct page *page, |
| @@ -1608,7 +1575,6 @@ static int build_dirty_segmap(struct f2fs_sb_info *sbi) | |||
| 1608 | 1575 | ||
| 1609 | for (i = 0; i < NR_DIRTY_TYPE; i++) { | 1576 | for (i = 0; i < NR_DIRTY_TYPE; i++) { |
| 1610 | dirty_i->dirty_segmap[i] = kzalloc(bitmap_size, GFP_KERNEL); | 1577 | dirty_i->dirty_segmap[i] = kzalloc(bitmap_size, GFP_KERNEL); |
| 1611 | dirty_i->nr_dirty[i] = 0; | ||
| 1612 | if (!dirty_i->dirty_segmap[i]) | 1578 | if (!dirty_i->dirty_segmap[i]) |
| 1613 | return -ENOMEM; | 1579 | return -ENOMEM; |
| 1614 | } | 1580 | } |
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 0948405af6f5..66a288a52fd3 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h | |||
| @@ -459,7 +459,20 @@ static inline int get_ssr_segment(struct f2fs_sb_info *sbi, int type) | |||
| 459 | 459 | ||
| 460 | static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi) | 460 | static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi) |
| 461 | { | 461 | { |
| 462 | return free_sections(sbi) <= reserved_sections(sbi); | 462 | unsigned int pages_per_sec = (1 << sbi->log_blocks_per_seg) * |
| 463 | sbi->segs_per_sec; | ||
| 464 | int node_secs = ((get_pages(sbi, F2FS_DIRTY_NODES) + pages_per_sec - 1) | ||
| 465 | >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; | ||
| 466 | int dent_secs = ((get_pages(sbi, F2FS_DIRTY_DENTS) + pages_per_sec - 1) | ||
| 467 | >> sbi->log_blocks_per_seg) / sbi->segs_per_sec; | ||
| 468 | |||
| 469 | if (sbi->por_doing) | ||
| 470 | return false; | ||
| 471 | |||
| 472 | if (free_sections(sbi) <= (node_secs + 2 * dent_secs + | ||
| 473 | reserved_sections(sbi))) | ||
| 474 | return true; | ||
| 475 | return false; | ||
| 463 | } | 476 | } |
| 464 | 477 | ||
| 465 | static inline int utilization(struct f2fs_sb_info *sbi) | 478 | static inline int utilization(struct f2fs_sb_info *sbi) |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 13867322cf5a..08a94c814bdc 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
| @@ -119,7 +119,6 @@ static void f2fs_put_super(struct super_block *sb) | |||
| 119 | int f2fs_sync_fs(struct super_block *sb, int sync) | 119 | int f2fs_sync_fs(struct super_block *sb, int sync) |
| 120 | { | 120 | { |
| 121 | struct f2fs_sb_info *sbi = F2FS_SB(sb); | 121 | struct f2fs_sb_info *sbi = F2FS_SB(sb); |
| 122 | int ret = 0; | ||
| 123 | 122 | ||
| 124 | if (!sbi->s_dirty && !get_pages(sbi, F2FS_DIRTY_NODES)) | 123 | if (!sbi->s_dirty && !get_pages(sbi, F2FS_DIRTY_NODES)) |
| 125 | return 0; | 124 | return 0; |
| @@ -127,7 +126,7 @@ int f2fs_sync_fs(struct super_block *sb, int sync) | |||
| 127 | if (sync) | 126 | if (sync) |
| 128 | write_checkpoint(sbi, false, false); | 127 | write_checkpoint(sbi, false, false); |
| 129 | 128 | ||
| 130 | return ret; | 129 | return 0; |
| 131 | } | 130 | } |
| 132 | 131 | ||
| 133 | static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) | 132 | static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) |
| @@ -148,8 +147,8 @@ static int f2fs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
| 148 | buf->f_bfree = buf->f_blocks - valid_user_blocks(sbi) - ovp_count; | 147 | buf->f_bfree = buf->f_blocks - valid_user_blocks(sbi) - ovp_count; |
| 149 | buf->f_bavail = user_block_count - valid_user_blocks(sbi); | 148 | buf->f_bavail = user_block_count - valid_user_blocks(sbi); |
| 150 | 149 | ||
| 151 | buf->f_files = valid_inode_count(sbi); | 150 | buf->f_files = sbi->total_node_count; |
| 152 | buf->f_ffree = sbi->total_node_count - valid_node_count(sbi); | 151 | buf->f_ffree = sbi->total_node_count - valid_inode_count(sbi); |
| 153 | 152 | ||
| 154 | buf->f_namelen = F2FS_MAX_NAME_LEN; | 153 | buf->f_namelen = F2FS_MAX_NAME_LEN; |
| 155 | buf->f_fsid.val[0] = (u32)id; | 154 | buf->f_fsid.val[0] = (u32)id; |
| @@ -302,7 +301,7 @@ static int parse_options(struct f2fs_sb_info *sbi, char *options) | |||
| 302 | case Opt_active_logs: | 301 | case Opt_active_logs: |
| 303 | if (args->from && match_int(args, &arg)) | 302 | if (args->from && match_int(args, &arg)) |
| 304 | return -EINVAL; | 303 | return -EINVAL; |
| 305 | if (arg != 2 && arg != 4 && arg != 6) | 304 | if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE) |
| 306 | return -EINVAL; | 305 | return -EINVAL; |
| 307 | sbi->active_logs = arg; | 306 | sbi->active_logs = arg; |
| 308 | break; | 307 | break; |
| @@ -528,8 +527,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 528 | 527 | ||
| 529 | /* if there are nt orphan nodes free them */ | 528 | /* if there are nt orphan nodes free them */ |
| 530 | err = -EINVAL; | 529 | err = -EINVAL; |
| 531 | if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG) && | 530 | if (recover_orphan_inodes(sbi)) |
| 532 | recover_orphan_inodes(sbi)) | ||
| 533 | goto free_node_inode; | 531 | goto free_node_inode; |
| 534 | 532 | ||
| 535 | /* read root inode and dentry */ | 533 | /* read root inode and dentry */ |
| @@ -548,8 +546,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 548 | } | 546 | } |
| 549 | 547 | ||
| 550 | /* recover fsynced data */ | 548 | /* recover fsynced data */ |
| 551 | if (!is_set_ckpt_flags(F2FS_CKPT(sbi), CP_UMOUNT_FLAG) && | 549 | if (!test_opt(sbi, DISABLE_ROLL_FORWARD)) |
| 552 | !test_opt(sbi, DISABLE_ROLL_FORWARD)) | ||
| 553 | recover_fsync_data(sbi); | 550 | recover_fsync_data(sbi); |
| 554 | 551 | ||
| 555 | /* After POR, we can run background GC thread */ | 552 | /* After POR, we can run background GC thread */ |
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index 7d52e8dc0c59..940136a3d3a6 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c | |||
| @@ -208,7 +208,7 @@ int f2fs_getxattr(struct inode *inode, int name_index, const char *name, | |||
| 208 | struct page *page; | 208 | struct page *page; |
| 209 | void *base_addr; | 209 | void *base_addr; |
| 210 | int error = 0, found = 0; | 210 | int error = 0, found = 0; |
| 211 | int value_len, name_len; | 211 | size_t value_len, name_len; |
| 212 | 212 | ||
| 213 | if (name == NULL) | 213 | if (name == NULL) |
| 214 | return -EINVAL; | 214 | return -EINVAL; |
| @@ -304,7 +304,8 @@ int f2fs_setxattr(struct inode *inode, int name_index, const char *name, | |||
| 304 | struct f2fs_xattr_entry *here, *last; | 304 | struct f2fs_xattr_entry *here, *last; |
| 305 | struct page *page; | 305 | struct page *page; |
| 306 | void *base_addr; | 306 | void *base_addr; |
| 307 | int error, found, free, name_len, newsize; | 307 | int error, found, free, newsize; |
| 308 | size_t name_len; | ||
| 308 | char *pval; | 309 | char *pval; |
| 309 | 310 | ||
| 310 | if (name == NULL) | 311 | if (name == NULL) |
| @@ -490,7 +490,7 @@ void exit_files(struct task_struct *tsk) | |||
| 490 | } | 490 | } |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | static void __devinit fdtable_defer_list_init(int cpu) | 493 | static void fdtable_defer_list_init(int cpu) |
| 494 | { | 494 | { |
| 495 | struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); | 495 | struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); |
| 496 | spin_lock_init(&fddef->lock); | 496 | spin_lock_init(&fddef->lock); |
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index 8dad6b093716..b906ed17a839 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c | |||
| @@ -241,6 +241,7 @@ static u32 make_flags(struct gfs2_glock *gl, const unsigned int gfs_flags, | |||
| 241 | 241 | ||
| 242 | static void gfs2_reverse_hex(char *c, u64 value) | 242 | static void gfs2_reverse_hex(char *c, u64 value) |
| 243 | { | 243 | { |
| 244 | *c = '0'; | ||
| 244 | while (value) { | 245 | while (value) { |
| 245 | *c-- = hex_asc[value & 0x0f]; | 246 | *c-- = hex_asc[value & 0x0f]; |
| 246 | value >>= 4; | 247 | value >>= 4; |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 37ee061d899e..b7eff078fe90 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -350,10 +350,14 @@ static u32 gfs2_free_extlen(const struct gfs2_rbm *rrbm, u32 len) | |||
| 350 | BUG_ON(len < chunk_size); | 350 | BUG_ON(len < chunk_size); |
| 351 | len -= chunk_size; | 351 | len -= chunk_size; |
| 352 | block = gfs2_rbm_to_block(&rbm); | 352 | block = gfs2_rbm_to_block(&rbm); |
| 353 | gfs2_rbm_from_block(&rbm, block + chunk_size); | 353 | if (gfs2_rbm_from_block(&rbm, block + chunk_size)) { |
| 354 | n_unaligned = 3; | 354 | n_unaligned = 0; |
| 355 | if (ptr) | ||
| 356 | break; | 355 | break; |
| 356 | } | ||
| 357 | if (ptr) { | ||
| 358 | n_unaligned = 3; | ||
| 359 | break; | ||
| 360 | } | ||
| 357 | n_unaligned = len & 3; | 361 | n_unaligned = len & 3; |
| 358 | } | 362 | } |
| 359 | 363 | ||
| @@ -557,22 +561,20 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) | |||
| 557 | */ | 561 | */ |
| 558 | int gfs2_rs_alloc(struct gfs2_inode *ip) | 562 | int gfs2_rs_alloc(struct gfs2_inode *ip) |
| 559 | { | 563 | { |
| 560 | struct gfs2_blkreserv *res; | 564 | int error = 0; |
| 561 | 565 | ||
| 566 | down_write(&ip->i_rw_mutex); | ||
| 562 | if (ip->i_res) | 567 | if (ip->i_res) |
| 563 | return 0; | 568 | goto out; |
| 564 | |||
| 565 | res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); | ||
| 566 | if (!res) | ||
| 567 | return -ENOMEM; | ||
| 568 | 569 | ||
| 569 | RB_CLEAR_NODE(&res->rs_node); | 570 | ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); |
| 571 | if (!ip->i_res) { | ||
| 572 | error = -ENOMEM; | ||
| 573 | goto out; | ||
| 574 | } | ||
| 570 | 575 | ||
| 571 | down_write(&ip->i_rw_mutex); | 576 | RB_CLEAR_NODE(&ip->i_res->rs_node); |
| 572 | if (ip->i_res) | 577 | out: |
| 573 | kmem_cache_free(gfs2_rsrv_cachep, res); | ||
| 574 | else | ||
| 575 | ip->i_res = res; | ||
| 576 | up_write(&ip->i_rw_mutex); | 578 | up_write(&ip->i_rw_mutex); |
| 577 | return 0; | 579 | return 0; |
| 578 | } | 580 | } |
| @@ -1424,6 +1426,9 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, | |||
| 1424 | rs->rs_free = extlen; | 1426 | rs->rs_free = extlen; |
| 1425 | rs->rs_inum = ip->i_no_addr; | 1427 | rs->rs_inum = ip->i_no_addr; |
| 1426 | rs_insert(ip); | 1428 | rs_insert(ip); |
| 1429 | } else { | ||
| 1430 | if (goal == rgd->rd_last_alloc + rgd->rd_data0) | ||
| 1431 | rgd->rd_last_alloc = 0; | ||
| 1427 | } | 1432 | } |
| 1428 | } | 1433 | } |
| 1429 | 1434 | ||
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index a2862339323b..81cc7eaff863 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
| @@ -446,7 +446,8 @@ int __log_start_commit(journal_t *journal, tid_t target) | |||
| 446 | * currently running transaction (if it exists). Otherwise, | 446 | * currently running transaction (if it exists). Otherwise, |
| 447 | * the target tid must be an old one. | 447 | * the target tid must be an old one. |
| 448 | */ | 448 | */ |
| 449 | if (journal->j_running_transaction && | 449 | if (journal->j_commit_request != target && |
| 450 | journal->j_running_transaction && | ||
| 450 | journal->j_running_transaction->t_tid == target) { | 451 | journal->j_running_transaction->t_tid == target) { |
| 451 | /* | 452 | /* |
| 452 | * We want a new commit: OK, mark the request and wakeup the | 453 | * We want a new commit: OK, mark the request and wakeup the |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 42f6615af0ac..df9f29760efa 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -209,7 +209,8 @@ repeat: | |||
| 209 | if (!new_transaction) | 209 | if (!new_transaction) |
| 210 | goto alloc_transaction; | 210 | goto alloc_transaction; |
| 211 | write_lock(&journal->j_state_lock); | 211 | write_lock(&journal->j_state_lock); |
| 212 | if (!journal->j_running_transaction) { | 212 | if (!journal->j_running_transaction && |
| 213 | !journal->j_barrier_count) { | ||
| 213 | jbd2_get_transaction(journal, new_transaction); | 214 | jbd2_get_transaction(journal, new_transaction); |
| 214 | new_transaction = NULL; | 215 | new_transaction = NULL; |
| 215 | } | 216 | } |
| @@ -1839,7 +1840,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, | |||
| 1839 | 1840 | ||
| 1840 | BUFFER_TRACE(bh, "entry"); | 1841 | BUFFER_TRACE(bh, "entry"); |
| 1841 | 1842 | ||
| 1842 | retry: | ||
| 1843 | /* | 1843 | /* |
| 1844 | * It is safe to proceed here without the j_list_lock because the | 1844 | * It is safe to proceed here without the j_list_lock because the |
| 1845 | * buffers cannot be stolen by try_to_free_buffers as long as we are | 1845 | * buffers cannot be stolen by try_to_free_buffers as long as we are |
| @@ -1934,14 +1934,11 @@ retry: | |||
| 1934 | * for commit and try again. | 1934 | * for commit and try again. |
| 1935 | */ | 1935 | */ |
| 1936 | if (partial_page) { | 1936 | if (partial_page) { |
| 1937 | tid_t tid = journal->j_committing_transaction->t_tid; | ||
| 1938 | |||
| 1939 | jbd2_journal_put_journal_head(jh); | 1937 | jbd2_journal_put_journal_head(jh); |
| 1940 | spin_unlock(&journal->j_list_lock); | 1938 | spin_unlock(&journal->j_list_lock); |
| 1941 | jbd_unlock_bh_state(bh); | 1939 | jbd_unlock_bh_state(bh); |
| 1942 | write_unlock(&journal->j_state_lock); | 1940 | write_unlock(&journal->j_state_lock); |
| 1943 | jbd2_log_wait_commit(journal, tid); | 1941 | return -EBUSY; |
| 1944 | goto retry; | ||
| 1945 | } | 1942 | } |
| 1946 | /* | 1943 | /* |
| 1947 | * OK, buffer won't be reachable after truncate. We just set | 1944 | * OK, buffer won't be reachable after truncate. We just set |
| @@ -2002,21 +1999,23 @@ zap_buffer_unlocked: | |||
| 2002 | * @page: page to flush | 1999 | * @page: page to flush |
| 2003 | * @offset: length of page to invalidate. | 2000 | * @offset: length of page to invalidate. |
| 2004 | * | 2001 | * |
| 2005 | * Reap page buffers containing data after offset in page. | 2002 | * Reap page buffers containing data after offset in page. Can return -EBUSY |
| 2006 | * | 2003 | * if buffers are part of the committing transaction and the page is straddling |
| 2004 | * i_size. Caller then has to wait for current commit and try again. | ||
| 2007 | */ | 2005 | */ |
| 2008 | void jbd2_journal_invalidatepage(journal_t *journal, | 2006 | int jbd2_journal_invalidatepage(journal_t *journal, |
| 2009 | struct page *page, | 2007 | struct page *page, |
| 2010 | unsigned long offset) | 2008 | unsigned long offset) |
| 2011 | { | 2009 | { |
| 2012 | struct buffer_head *head, *bh, *next; | 2010 | struct buffer_head *head, *bh, *next; |
| 2013 | unsigned int curr_off = 0; | 2011 | unsigned int curr_off = 0; |
| 2014 | int may_free = 1; | 2012 | int may_free = 1; |
| 2013 | int ret = 0; | ||
| 2015 | 2014 | ||
| 2016 | if (!PageLocked(page)) | 2015 | if (!PageLocked(page)) |
| 2017 | BUG(); | 2016 | BUG(); |
| 2018 | if (!page_has_buffers(page)) | 2017 | if (!page_has_buffers(page)) |
| 2019 | return; | 2018 | return 0; |
| 2020 | 2019 | ||
| 2021 | /* We will potentially be playing with lists other than just the | 2020 | /* We will potentially be playing with lists other than just the |
| 2022 | * data lists (especially for journaled data mode), so be | 2021 | * data lists (especially for journaled data mode), so be |
| @@ -2030,9 +2029,11 @@ void jbd2_journal_invalidatepage(journal_t *journal, | |||
| 2030 | if (offset <= curr_off) { | 2029 | if (offset <= curr_off) { |
| 2031 | /* This block is wholly outside the truncation point */ | 2030 | /* This block is wholly outside the truncation point */ |
| 2032 | lock_buffer(bh); | 2031 | lock_buffer(bh); |
| 2033 | may_free &= journal_unmap_buffer(journal, bh, | 2032 | ret = journal_unmap_buffer(journal, bh, offset > 0); |
| 2034 | offset > 0); | ||
| 2035 | unlock_buffer(bh); | 2033 | unlock_buffer(bh); |
| 2034 | if (ret < 0) | ||
| 2035 | return ret; | ||
| 2036 | may_free &= ret; | ||
| 2036 | } | 2037 | } |
| 2037 | curr_off = next_off; | 2038 | curr_off = next_off; |
| 2038 | bh = next; | 2039 | bh = next; |
| @@ -2043,6 +2044,7 @@ void jbd2_journal_invalidatepage(journal_t *journal, | |||
| 2043 | if (may_free && try_to_free_buffers(page)) | 2044 | if (may_free && try_to_free_buffers(page)) |
| 2044 | J_ASSERT(!page_has_buffers(page)); | 2045 | J_ASSERT(!page_has_buffers(page)); |
| 2045 | } | 2046 | } |
| 2047 | return 0; | ||
| 2046 | } | 2048 | } |
| 2047 | 2049 | ||
| 2048 | /* | 2050 | /* |
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index c89b26bc9759..264d1aa935f2 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
| @@ -206,7 +206,7 @@ static u32 initiate_bulk_draining(struct nfs_client *clp, | |||
| 206 | 206 | ||
| 207 | list_for_each_entry(lo, &server->layouts, plh_layouts) { | 207 | list_for_each_entry(lo, &server->layouts, plh_layouts) { |
| 208 | ino = igrab(lo->plh_inode); | 208 | ino = igrab(lo->plh_inode); |
| 209 | if (ino) | 209 | if (!ino) |
| 210 | continue; | 210 | continue; |
| 211 | spin_lock(&ino->i_lock); | 211 | spin_lock(&ino->i_lock); |
| 212 | /* Is this layout in the process of being freed? */ | 212 | /* Is this layout in the process of being freed? */ |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 32e6c53520e2..1b2d7eb93796 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -2153,12 +2153,16 @@ static int nfs_open_permission_mask(int openflags) | |||
| 2153 | { | 2153 | { |
| 2154 | int mask = 0; | 2154 | int mask = 0; |
| 2155 | 2155 | ||
| 2156 | if ((openflags & O_ACCMODE) != O_WRONLY) | 2156 | if (openflags & __FMODE_EXEC) { |
| 2157 | mask |= MAY_READ; | 2157 | /* ONLY check exec rights */ |
| 2158 | if ((openflags & O_ACCMODE) != O_RDONLY) | 2158 | mask = MAY_EXEC; |
| 2159 | mask |= MAY_WRITE; | 2159 | } else { |
| 2160 | if (openflags & __FMODE_EXEC) | 2160 | if ((openflags & O_ACCMODE) != O_WRONLY) |
| 2161 | mask |= MAY_EXEC; | 2161 | mask |= MAY_READ; |
| 2162 | if ((openflags & O_ACCMODE) != O_RDONLY) | ||
| 2163 | mask |= MAY_WRITE; | ||
| 2164 | } | ||
| 2165 | |||
| 2162 | return mask; | 2166 | return mask; |
| 2163 | } | 2167 | } |
| 2164 | 2168 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5d864fb36578..cf747ef86650 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -1626,7 +1626,8 @@ static int _nfs4_recover_proc_open(struct nfs4_opendata *data) | |||
| 1626 | 1626 | ||
| 1627 | static int nfs4_opendata_access(struct rpc_cred *cred, | 1627 | static int nfs4_opendata_access(struct rpc_cred *cred, |
| 1628 | struct nfs4_opendata *opendata, | 1628 | struct nfs4_opendata *opendata, |
| 1629 | struct nfs4_state *state, fmode_t fmode) | 1629 | struct nfs4_state *state, fmode_t fmode, |
| 1630 | int openflags) | ||
| 1630 | { | 1631 | { |
| 1631 | struct nfs_access_entry cache; | 1632 | struct nfs_access_entry cache; |
| 1632 | u32 mask; | 1633 | u32 mask; |
| @@ -1638,11 +1639,14 @@ static int nfs4_opendata_access(struct rpc_cred *cred, | |||
| 1638 | 1639 | ||
| 1639 | mask = 0; | 1640 | mask = 0; |
| 1640 | /* don't check MAY_WRITE - a newly created file may not have | 1641 | /* don't check MAY_WRITE - a newly created file may not have |
| 1641 | * write mode bits, but POSIX allows the creating process to write */ | 1642 | * write mode bits, but POSIX allows the creating process to write. |
| 1642 | if (fmode & FMODE_READ) | 1643 | * use openflags to check for exec, because fmode won't |
| 1643 | mask |= MAY_READ; | 1644 | * always have FMODE_EXEC set when file open for exec. */ |
| 1644 | if (fmode & FMODE_EXEC) | 1645 | if (openflags & __FMODE_EXEC) { |
| 1645 | mask |= MAY_EXEC; | 1646 | /* ONLY check for exec rights */ |
| 1647 | mask = MAY_EXEC; | ||
| 1648 | } else if (fmode & FMODE_READ) | ||
| 1649 | mask = MAY_READ; | ||
| 1646 | 1650 | ||
| 1647 | cache.cred = cred; | 1651 | cache.cred = cred; |
| 1648 | cache.jiffies = jiffies; | 1652 | cache.jiffies = jiffies; |
| @@ -1896,7 +1900,7 @@ static int _nfs4_do_open(struct inode *dir, | |||
| 1896 | if (server->caps & NFS_CAP_POSIX_LOCK) | 1900 | if (server->caps & NFS_CAP_POSIX_LOCK) |
| 1897 | set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); | 1901 | set_bit(NFS_STATE_POSIX_LOCKS, &state->flags); |
| 1898 | 1902 | ||
| 1899 | status = nfs4_opendata_access(cred, opendata, state, fmode); | 1903 | status = nfs4_opendata_access(cred, opendata, state, fmode, flags); |
| 1900 | if (status != 0) | 1904 | if (status != 0) |
| 1901 | goto err_opendata_put; | 1905 | goto err_opendata_put; |
| 1902 | 1906 | ||
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index e7165d915362..d00260b08103 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
| @@ -254,7 +254,7 @@ static void | |||
| 254 | pnfs_layout_set_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit) | 254 | pnfs_layout_set_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit) |
| 255 | { | 255 | { |
| 256 | lo->plh_retry_timestamp = jiffies; | 256 | lo->plh_retry_timestamp = jiffies; |
| 257 | if (test_and_set_bit(fail_bit, &lo->plh_flags)) | 257 | if (!test_and_set_bit(fail_bit, &lo->plh_flags)) |
| 258 | atomic_inc(&lo->plh_refcount); | 258 | atomic_inc(&lo->plh_refcount); |
| 259 | } | 259 | } |
| 260 | 260 | ||
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index b6bdb18e892c..a5e5d9899d56 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
| @@ -91,12 +91,16 @@ void nfs_readdata_release(struct nfs_read_data *rdata) | |||
| 91 | put_nfs_open_context(rdata->args.context); | 91 | put_nfs_open_context(rdata->args.context); |
| 92 | if (rdata->pages.pagevec != rdata->pages.page_array) | 92 | if (rdata->pages.pagevec != rdata->pages.page_array) |
| 93 | kfree(rdata->pages.pagevec); | 93 | kfree(rdata->pages.pagevec); |
| 94 | if (rdata != &read_header->rpc_data) | 94 | if (rdata == &read_header->rpc_data) { |
| 95 | kfree(rdata); | ||
| 96 | else | ||
| 97 | rdata->header = NULL; | 95 | rdata->header = NULL; |
| 96 | rdata = NULL; | ||
| 97 | } | ||
| 98 | if (atomic_dec_and_test(&hdr->refcnt)) | 98 | if (atomic_dec_and_test(&hdr->refcnt)) |
| 99 | hdr->completion_ops->completion(hdr); | 99 | hdr->completion_ops->completion(hdr); |
| 100 | /* Note: we only free the rpc_task after callbacks are done. | ||
| 101 | * See the comment in rpc_free_task() for why | ||
| 102 | */ | ||
| 103 | kfree(rdata); | ||
| 100 | } | 104 | } |
| 101 | EXPORT_SYMBOL_GPL(nfs_readdata_release); | 105 | EXPORT_SYMBOL_GPL(nfs_readdata_release); |
| 102 | 106 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index c25cadf8f8c4..2e7e8c878e5d 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -1152,7 +1152,7 @@ static int nfs_get_option_str(substring_t args[], char **option) | |||
| 1152 | { | 1152 | { |
| 1153 | kfree(*option); | 1153 | kfree(*option); |
| 1154 | *option = match_strdup(args); | 1154 | *option = match_strdup(args); |
| 1155 | return !option; | 1155 | return !*option; |
| 1156 | } | 1156 | } |
| 1157 | 1157 | ||
| 1158 | static int nfs_get_option_ul(substring_t args[], unsigned long *option) | 1158 | static int nfs_get_option_ul(substring_t args[], unsigned long *option) |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index b673be31590e..c483cc50b82e 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -126,12 +126,16 @@ void nfs_writedata_release(struct nfs_write_data *wdata) | |||
| 126 | put_nfs_open_context(wdata->args.context); | 126 | put_nfs_open_context(wdata->args.context); |
| 127 | if (wdata->pages.pagevec != wdata->pages.page_array) | 127 | if (wdata->pages.pagevec != wdata->pages.page_array) |
| 128 | kfree(wdata->pages.pagevec); | 128 | kfree(wdata->pages.pagevec); |
| 129 | if (wdata != &write_header->rpc_data) | 129 | if (wdata == &write_header->rpc_data) { |
| 130 | kfree(wdata); | ||
| 131 | else | ||
| 132 | wdata->header = NULL; | 130 | wdata->header = NULL; |
| 131 | wdata = NULL; | ||
| 132 | } | ||
| 133 | if (atomic_dec_and_test(&hdr->refcnt)) | 133 | if (atomic_dec_and_test(&hdr->refcnt)) |
| 134 | hdr->completion_ops->completion(hdr); | 134 | hdr->completion_ops->completion(hdr); |
| 135 | /* Note: we only free the rpc_task after callbacks are done. | ||
| 136 | * See the comment in rpc_free_task() for why | ||
| 137 | */ | ||
| 138 | kfree(wdata); | ||
| 135 | } | 139 | } |
| 136 | EXPORT_SYMBOL_GPL(nfs_writedata_release); | 140 | EXPORT_SYMBOL_GPL(nfs_writedata_release); |
| 137 | 141 | ||
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index e064f562b1f7..76ddae83daa5 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
| @@ -352,18 +352,18 @@ retry: | |||
| 352 | if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL)) | 352 | if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL)) |
| 353 | return -ENOMEM; | 353 | return -ENOMEM; |
| 354 | 354 | ||
| 355 | spin_lock_bh(&proc_inum_lock); | 355 | spin_lock_irq(&proc_inum_lock); |
| 356 | error = ida_get_new(&proc_inum_ida, &i); | 356 | error = ida_get_new(&proc_inum_ida, &i); |
| 357 | spin_unlock_bh(&proc_inum_lock); | 357 | spin_unlock_irq(&proc_inum_lock); |
| 358 | if (error == -EAGAIN) | 358 | if (error == -EAGAIN) |
| 359 | goto retry; | 359 | goto retry; |
| 360 | else if (error) | 360 | else if (error) |
| 361 | return error; | 361 | return error; |
| 362 | 362 | ||
| 363 | if (i > UINT_MAX - PROC_DYNAMIC_FIRST) { | 363 | if (i > UINT_MAX - PROC_DYNAMIC_FIRST) { |
| 364 | spin_lock_bh(&proc_inum_lock); | 364 | spin_lock_irq(&proc_inum_lock); |
| 365 | ida_remove(&proc_inum_ida, i); | 365 | ida_remove(&proc_inum_ida, i); |
| 366 | spin_unlock_bh(&proc_inum_lock); | 366 | spin_unlock_irq(&proc_inum_lock); |
| 367 | return -ENOSPC; | 367 | return -ENOSPC; |
| 368 | } | 368 | } |
| 369 | *inum = PROC_DYNAMIC_FIRST + i; | 369 | *inum = PROC_DYNAMIC_FIRST + i; |
| @@ -372,9 +372,10 @@ retry: | |||
| 372 | 372 | ||
| 373 | void proc_free_inum(unsigned int inum) | 373 | void proc_free_inum(unsigned int inum) |
| 374 | { | 374 | { |
| 375 | spin_lock_bh(&proc_inum_lock); | 375 | unsigned long flags; |
| 376 | spin_lock_irqsave(&proc_inum_lock, flags); | ||
| 376 | ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); | 377 | ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST); |
| 377 | spin_unlock_bh(&proc_inum_lock); | 378 | spin_unlock_irqrestore(&proc_inum_lock, flags); |
| 378 | } | 379 | } |
| 379 | 380 | ||
| 380 | static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) | 381 | static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 448455b7fd91..ca5ce7f9f800 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
| @@ -1278,7 +1278,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) | |||
| 1278 | walk.mm = mm; | 1278 | walk.mm = mm; |
| 1279 | 1279 | ||
| 1280 | pol = get_vma_policy(task, vma, vma->vm_start); | 1280 | pol = get_vma_policy(task, vma, vma->vm_start); |
| 1281 | mpol_to_str(buffer, sizeof(buffer), pol, 0); | 1281 | mpol_to_str(buffer, sizeof(buffer), pol); |
| 1282 | mpol_cond_put(pol); | 1282 | mpol_cond_put(pol); |
| 1283 | 1283 | ||
| 1284 | seq_printf(m, "%08lx %s", vma->vm_start, buffer); | 1284 | seq_printf(m, "%08lx %s", vma->vm_start, buffer); |
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index f883e7e74305..7003e5266f25 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c | |||
| @@ -291,9 +291,8 @@ static void ramoops_free_przs(struct ramoops_context *cxt) | |||
| 291 | kfree(cxt->przs); | 291 | kfree(cxt->przs); |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | static int __devinit ramoops_init_przs(struct device *dev, | 294 | static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt, |
| 295 | struct ramoops_context *cxt, | 295 | phys_addr_t *paddr, size_t dump_mem_sz) |
| 296 | phys_addr_t *paddr, size_t dump_mem_sz) | ||
| 297 | { | 296 | { |
| 298 | int err = -ENOMEM; | 297 | int err = -ENOMEM; |
| 299 | int i; | 298 | int i; |
| @@ -336,10 +335,9 @@ fail_prz: | |||
| 336 | return err; | 335 | return err; |
| 337 | } | 336 | } |
| 338 | 337 | ||
| 339 | static int __devinit ramoops_init_prz(struct device *dev, | 338 | static int ramoops_init_prz(struct device *dev, struct ramoops_context *cxt, |
| 340 | struct ramoops_context *cxt, | 339 | struct persistent_ram_zone **prz, |
| 341 | struct persistent_ram_zone **prz, | 340 | phys_addr_t *paddr, size_t sz, u32 sig) |
| 342 | phys_addr_t *paddr, size_t sz, u32 sig) | ||
| 343 | { | 341 | { |
| 344 | if (!sz) | 342 | if (!sz) |
| 345 | return 0; | 343 | return 0; |
| @@ -367,7 +365,7 @@ static int __devinit ramoops_init_prz(struct device *dev, | |||
| 367 | return 0; | 365 | return 0; |
| 368 | } | 366 | } |
| 369 | 367 | ||
| 370 | static int __devinit ramoops_probe(struct platform_device *pdev) | 368 | static int ramoops_probe(struct platform_device *pdev) |
| 371 | { | 369 | { |
| 372 | struct device *dev = &pdev->dev; | 370 | struct device *dev = &pdev->dev; |
| 373 | struct ramoops_platform_data *pdata = pdev->dev.platform_data; | 371 | struct ramoops_platform_data *pdata = pdev->dev.platform_data; |
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index eecd2a8a84dd..0306303be372 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c | |||
| @@ -390,8 +390,8 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size, | |||
| 390 | return 0; | 390 | return 0; |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | static int __devinit persistent_ram_post_init(struct persistent_ram_zone *prz, | 393 | static int persistent_ram_post_init(struct persistent_ram_zone *prz, u32 sig, |
| 394 | u32 sig, int ecc_size) | 394 | int ecc_size) |
| 395 | { | 395 | { |
| 396 | int ret; | 396 | int ret; |
| 397 | 397 | ||
| @@ -443,9 +443,8 @@ void persistent_ram_free(struct persistent_ram_zone *prz) | |||
| 443 | kfree(prz); | 443 | kfree(prz); |
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | struct persistent_ram_zone * __devinit persistent_ram_new(phys_addr_t start, | 446 | struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size, |
| 447 | size_t size, u32 sig, | 447 | u32 sig, int ecc_size) |
| 448 | int ecc_size) | ||
| 449 | { | 448 | { |
| 450 | struct persistent_ram_zone *prz; | 449 | struct persistent_ram_zone *prz; |
| 451 | int ret = -ENOMEM; | 450 | int ret = -ENOMEM; |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 9d863fb501f9..f2bc3dfd0b88 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
| @@ -296,7 +296,7 @@ EXPORT_SYMBOL(seq_read); | |||
| 296 | * seq_lseek - ->llseek() method for sequential files. | 296 | * seq_lseek - ->llseek() method for sequential files. |
| 297 | * @file: the file in question | 297 | * @file: the file in question |
| 298 | * @offset: new position | 298 | * @offset: new position |
| 299 | * @origin: 0 for absolute, 1 for relative position | 299 | * @whence: 0 for absolute, 1 for relative position |
| 300 | * | 300 | * |
| 301 | * Ready-made ->f_op->llseek() | 301 | * Ready-made ->f_op->llseek() |
| 302 | */ | 302 | */ |
diff --git a/fs/splice.c b/fs/splice.c index 8890604e3fcd..6909d89d0da5 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
| @@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, | |||
| 696 | return -EINVAL; | 696 | return -EINVAL; |
| 697 | 697 | ||
| 698 | more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0; | 698 | more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0; |
| 699 | if (sd->len < sd->total_len) | 699 | |
| 700 | if (sd->len < sd->total_len && pipe->nrbufs > 1) | ||
| 700 | more |= MSG_SENDPAGE_NOTLAST; | 701 | more |= MSG_SENDPAGE_NOTLAST; |
| 702 | |||
| 701 | return file->f_op->sendpage(file, buf->page, buf->offset, | 703 | return file->f_op->sendpage(file, buf->page, buf->offset, |
| 702 | sd->len, &pos, more); | 704 | sd->len, &pos, more); |
| 703 | } | 705 | } |
diff --git a/fs/udf/super.c b/fs/udf/super.c index d44fb568abe1..e9be396a558d 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
| @@ -307,7 +307,8 @@ static void udf_sb_free_partitions(struct super_block *sb) | |||
| 307 | { | 307 | { |
| 308 | struct udf_sb_info *sbi = UDF_SB(sb); | 308 | struct udf_sb_info *sbi = UDF_SB(sb); |
| 309 | int i; | 309 | int i; |
| 310 | 310 | if (sbi->s_partmaps == NULL) | |
| 311 | return; | ||
| 311 | for (i = 0; i < sbi->s_partitions; i++) | 312 | for (i = 0; i < sbi->s_partitions; i++) |
| 312 | udf_free_partition(&sbi->s_partmaps[i]); | 313 | udf_free_partition(&sbi->s_partmaps[i]); |
| 313 | kfree(sbi->s_partmaps); | 314 | kfree(sbi->s_partmaps); |
