aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/vfs_inode.c2
-rw-r--r--fs/cifs/CHANGES8
-rw-r--r--fs/cifs/README30
-rw-r--r--fs/cifs/TODO4
-rw-r--r--fs/cifs/cifsfs.c23
-rw-r--r--fs/cifs/cifssmb.c25
-rw-r--r--fs/cifs/dir.c34
-rw-r--r--fs/cifs/inode.c50
-rw-r--r--fs/cifs/misc.c17
-rw-r--r--fs/cifs/netmisc.c4
-rw-r--r--fs/cifs/transport.c1
-rw-r--r--fs/dquot.c6
-rw-r--r--fs/exec.c12
-rw-r--r--fs/ext3/resize.c1
-rw-r--r--fs/fuse/dir.c37
-rw-r--r--fs/hfsplus/hfsplus_fs.h1
-rw-r--r--fs/hfsplus/hfsplus_raw.h12
-rw-r--r--fs/hfsplus/options.c6
-rw-r--r--fs/hfsplus/super.c20
-rw-r--r--fs/jffs2/fs.c2
-rw-r--r--fs/jffs2/super.c2
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nfs/inode.c81
-rw-r--r--fs/nfs/nfs4proc.c17
-rw-r--r--fs/nfs/nfs4state.c20
-rw-r--r--fs/nfs/proc.c1
-rw-r--r--fs/nfs/write.c6
-rw-r--r--fs/proc/task_mmu.c7
-rw-r--r--fs/reiserfs/inode.c2
-rw-r--r--fs/reiserfs/journal.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c13
-rw-r--r--fs/xfs/xfs_attr_leaf.c11
-rw-r--r--fs/xfs/xfs_fsops.c2
-rw-r--r--fs/xfs/xfs_iomap.h2
-rw-r--r--fs/xfs/xfs_log_priv.h36
-rw-r--r--fs/xfs/xfs_vnodeops.c5
36 files changed, 336 insertions, 176 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index be7288184fa..0ea965c3bb7 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -427,6 +427,8 @@ v9fs_create(struct inode *dir,
427 427
428 v9fs_mistat2inode(fcall->params.rstat.stat, file_inode, sb); 428 v9fs_mistat2inode(fcall->params.rstat.stat, file_inode, sb);
429 kfree(fcall); 429 kfree(fcall);
430 fcall = NULL;
431 file_dentry->d_op = &v9fs_dentry_operations;
430 d_instantiate(file_dentry, file_inode); 432 d_instantiate(file_dentry, file_inode);
431 433
432 if (perm & V9FS_DMDIR) { 434 if (perm & V9FS_DMDIR) {
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 6bded10c0d5..943ef9b8224 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,10 +1,12 @@
1Version 1.39 1Version 1.39
2------------ 2------------
3Defer close of a file handle slightly if pending writes depend on that file handle 3Defer close of a file handle slightly if pending writes depend on that handle
4(this reduces the EBADF bad file handle errors that can be logged under heavy 4(this reduces the EBADF bad file handle errors that can be logged under heavy
5stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 5stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2
6Fix SFU style symlinks and mknod needed for servers which do not support the CIFS 6Fix SFU style symlinks and mknod needed for servers which do not support the
7Unix Extensions. Fix setfacl/getfacl on bigendian. 7CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative
8dentries so files that the client sees as deleted but that later get created
9on the server will be recognized. Add client side permission check on setattr.
8 10
9Version 1.38 11Version 1.38
10------------ 12------------
diff --git a/fs/cifs/README b/fs/cifs/README
index bb90941826a..e5d09a2fc7a 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -278,7 +278,9 @@ A partial list of the supported mount options follows:
278 (such as Windows), permissions can also be checked at the 278 (such as Windows), permissions can also be checked at the
279 client, and a crude form of client side permission checking 279 client, and a crude form of client side permission checking
280 can be enabled by specifying file_mode and dir_mode on 280 can be enabled by specifying file_mode and dir_mode on
281 the client 281 the client. Note that the mount.cifs helper must be
282 at version 1.10 or higher to support specifying the uid
283 (or gid) in non-numberic form.
282 gid If CIFS Unix extensions are not supported by the server 284 gid If CIFS Unix extensions are not supported by the server
283 this overrides the default gid for inodes. 285 this overrides the default gid for inodes.
284 file_mode If CIFS Unix extensions are not supported by the server 286 file_mode If CIFS Unix extensions are not supported by the server
@@ -345,7 +347,10 @@ A partial list of the supported mount options follows:
345 client system. It is typically only needed when the server 347 client system. It is typically only needed when the server
346 supports the CIFS Unix Extensions but the UIDs/GIDs on the 348 supports the CIFS Unix Extensions but the UIDs/GIDs on the
347 client and server system do not match closely enough to allow 349 client and server system do not match closely enough to allow
348 access by the user doing the mount. 350 access by the user doing the mount, but it may be useful with
351 non CIFS Unix Extension mounts for cases in which the default
352 mode is specified on the mount but is not to be enforced on the
353 client (e.g. perhaps when MultiUserMount is enabled)
349 Note that this does not affect the normal ACL check on the 354 Note that this does not affect the normal ACL check on the
350 target machine done by the server software (of the server 355 target machine done by the server software (of the server
351 ACL against the user name provided at mount time). 356 ACL against the user name provided at mount time).
@@ -368,15 +373,21 @@ A partial list of the supported mount options follows:
368 setuids If the CIFS Unix extensions are negotiated with the server 373 setuids If the CIFS Unix extensions are negotiated with the server
369 the client will attempt to set the effective uid and gid of 374 the client will attempt to set the effective uid and gid of
370 the local process on newly created files, directories, and 375 the local process on newly created files, directories, and
371 devices (create, mkdir, mknod). 376 devices (create, mkdir, mknod). If the CIFS Unix Extensions
377 are not negotiated, for newly created files and directories
378 instead of using the default uid and gid specified on the
379 the mount, cache the new file's uid and gid locally which means
380 that the uid for the file can change when the inode is
381 reloaded (or the user remounts the share).
372 nosetuids The client will not attempt to set the uid and gid on 382 nosetuids The client will not attempt to set the uid and gid on
373 on newly created files, directories, and devices (create, 383 on newly created files, directories, and devices (create,
374 mkdir, mknod) which will result in the server setting the 384 mkdir, mknod) which will result in the server setting the
375 uid and gid to the default (usually the server uid of the 385 uid and gid to the default (usually the server uid of the
376 user who mounted the share). Letting the server (rather than 386 user who mounted the share). Letting the server (rather than
377 the client) set the uid and gid is the default. This 387 the client) set the uid and gid is the default. If the CIFS
378 parameter has no effect if the CIFS Unix Extensions are not 388 Unix Extensions are not negotiated then the uid and gid for
379 negotiated. 389 new files will appear to be the uid (gid) of the mounter or the
390 uid (gid) parameter specified on the mount.
380 netbiosname When mounting to servers via port 139, specifies the RFC1001 391 netbiosname When mounting to servers via port 139, specifies the RFC1001
381 source name to use to represent the client netbios machine 392 source name to use to represent the client netbios machine
382 name when doing the RFC1001 netbios session initialize. 393 name when doing the RFC1001 netbios session initialize.
@@ -418,6 +429,13 @@ A partial list of the supported mount options follows:
418 byte range locks). 429 byte range locks).
419 remount remount the share (often used to change from ro to rw mounts 430 remount remount the share (often used to change from ro to rw mounts
420 or vice versa) 431 or vice versa)
432 sfu When the CIFS Unix Extensions are not negotiated, attempt to
433 create device files and fifos in a format compatible with
434 Services for Unix (SFU). In addition retrieve bits 10-12
435 of the mode via the SETFILEBITS extended attribute (as
436 SFU does). In the future the bottom 9 bits of the mode
437 mode also will be emulated using queries of the security
438 descriptor (ACL).
421 439
422The mount.cifs mount helper also accepts a few mount options before -o 440The mount.cifs mount helper also accepts a few mount options before -o
423including: 441including:
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index c909298d11e..fc34c74ec4b 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -1,4 +1,4 @@
1version 1.37 October 9, 2005 1Version 1.39 November 30, 2005
2 2
3A Partial List of Missing Features 3A Partial List of Missing Features
4================================== 4==================================
@@ -58,7 +58,7 @@ o) Improve performance of readpages by sending more than one read
58at a time when 8 pages or more are requested. In conjuntion 58at a time when 8 pages or more are requested. In conjuntion
59add support for async_cifs_readpages. 59add support for async_cifs_readpages.
60 60
61p) Add support for storing symlink and fifo info to Windows servers 61p) Add support for storing symlink info to Windows servers
62in the Extended Attribute format their SFU clients would recognize. 62in the Extended Attribute format their SFU clients would recognize.
63 63
64q) Finish fcntl D_NOTIFY support so kde and gnome file list windows 64q) Finish fcntl D_NOTIFY support so kde and gnome file list windows
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 51548ed2e9c..2a13a2bac8f 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -32,6 +32,7 @@
32#include <linux/seq_file.h> 32#include <linux/seq_file.h>
33#include <linux/vfs.h> 33#include <linux/vfs.h>
34#include <linux/mempool.h> 34#include <linux/mempool.h>
35#include <linux/delay.h>
35#include "cifsfs.h" 36#include "cifsfs.h"
36#include "cifspdu.h" 37#include "cifspdu.h"
37#define DECLARE_GLOBALS_HERE 38#define DECLARE_GLOBALS_HERE
@@ -429,6 +430,11 @@ static void cifs_umount_begin(struct super_block * sblock)
429 { 430 {
430 cFYI(1,("wake up tasks now - umount begin not complete")); 431 cFYI(1,("wake up tasks now - umount begin not complete"));
431 wake_up_all(&tcon->ses->server->request_q); 432 wake_up_all(&tcon->ses->server->request_q);
433 wake_up_all(&tcon->ses->server->response_q);
434 msleep(1); /* yield */
435 /* we have to kick the requests once more */
436 wake_up_all(&tcon->ses->server->response_q);
437 msleep(1);
432 } 438 }
433/* BB FIXME - finish add checks for tidStatus BB */ 439/* BB FIXME - finish add checks for tidStatus BB */
434 440
@@ -895,6 +901,9 @@ static int cifs_oplock_thread(void * dummyarg)
895 901
896static int cifs_dnotify_thread(void * dummyarg) 902static int cifs_dnotify_thread(void * dummyarg)
897{ 903{
904 struct list_head *tmp;
905 struct cifsSesInfo *ses;
906
898 daemonize("cifsdnotifyd"); 907 daemonize("cifsdnotifyd");
899 allow_signal(SIGTERM); 908 allow_signal(SIGTERM);
900 909
@@ -903,7 +912,19 @@ static int cifs_dnotify_thread(void * dummyarg)
903 if(try_to_freeze()) 912 if(try_to_freeze())
904 continue; 913 continue;
905 set_current_state(TASK_INTERRUPTIBLE); 914 set_current_state(TASK_INTERRUPTIBLE);
906 schedule_timeout(39*HZ); 915 schedule_timeout(15*HZ);
916 read_lock(&GlobalSMBSeslock);
917 /* check if any stuck requests that need
918 to be woken up and wakeq so the
919 thread can wake up and error out */
920 list_for_each(tmp, &GlobalSMBSessionList) {
921 ses = list_entry(tmp, struct cifsSesInfo,
922 cifsSessionList);
923 if(ses && ses->server &&
924 atomic_read(&ses->server->inFlight))
925 wake_up_all(&ses->server->response_q);
926 }
927 read_unlock(&GlobalSMBSeslock);
907 } while(!signal_pending(current)); 928 } while(!signal_pending(current));
908 complete_and_exit (&cifs_dnotify_exited, 0); 929 complete_and_exit (&cifs_dnotify_exited, 0);
909} 930}
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index d179b0c3eee..6867e556d37 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -90,6 +90,18 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
90 check for tcp and smb session status done differently 90 check for tcp and smb session status done differently
91 for those three - in the calling routine */ 91 for those three - in the calling routine */
92 if(tcon) { 92 if(tcon) {
93 if(tcon->tidStatus == CifsExiting) {
94 /* only tree disconnect, open, and write,
95 (and ulogoff which does not have tcon)
96 are allowed as we start force umount */
97 if((smb_command != SMB_COM_WRITE_ANDX) &&
98 (smb_command != SMB_COM_OPEN_ANDX) &&
99 (smb_command != SMB_COM_TREE_DISCONNECT)) {
100 cFYI(1,("can not send cmd %d while umounting",
101 smb_command));
102 return -ENODEV;
103 }
104 }
93 if((tcon->ses) && (tcon->ses->status != CifsExiting) && 105 if((tcon->ses) && (tcon->ses->status != CifsExiting) &&
94 (tcon->ses->server)){ 106 (tcon->ses->server)){
95 struct nls_table *nls_codepage; 107 struct nls_table *nls_codepage;
@@ -187,6 +199,19 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
187 check for tcp and smb session status done differently 199 check for tcp and smb session status done differently
188 for those three - in the calling routine */ 200 for those three - in the calling routine */
189 if(tcon) { 201 if(tcon) {
202 if(tcon->tidStatus == CifsExiting) {
203 /* only tree disconnect, open, and write,
204 (and ulogoff which does not have tcon)
205 are allowed as we start force umount */
206 if((smb_command != SMB_COM_WRITE_ANDX) &&
207 (smb_command != SMB_COM_OPEN_ANDX) &&
208 (smb_command != SMB_COM_TREE_DISCONNECT)) {
209 cFYI(1,("can not send cmd %d while umounting",
210 smb_command));
211 return -ENODEV;
212 }
213 }
214
190 if((tcon->ses) && (tcon->ses->status != CifsExiting) && 215 if((tcon->ses) && (tcon->ses->status != CifsExiting) &&
191 (tcon->ses->server)){ 216 (tcon->ses->server)){
192 struct nls_table *nls_codepage; 217 struct nls_table *nls_codepage;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 16b21522e8f..32cc96cafa3 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -228,8 +228,15 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
228 else { 228 else {
229 rc = cifs_get_inode_info(&newinode, full_path, 229 rc = cifs_get_inode_info(&newinode, full_path,
230 buf, inode->i_sb,xid); 230 buf, inode->i_sb,xid);
231 if(newinode) 231 if(newinode) {
232 newinode->i_mode = mode; 232 newinode->i_mode = mode;
233 if((oplock & CIFS_CREATE_ACTION) &&
234 (cifs_sb->mnt_cifs_flags &
235 CIFS_MOUNT_SET_UID)) {
236 newinode->i_uid = current->fsuid;
237 newinode->i_gid = current->fsgid;
238 }
239 }
233 } 240 }
234 241
235 if (rc != 0) { 242 if (rc != 0) {
@@ -465,12 +472,20 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
465 direntry->d_op = &cifs_dentry_ops; 472 direntry->d_op = &cifs_dentry_ops;
466 d_add(direntry, newInode); 473 d_add(direntry, newInode);
467 474
468 /* since paths are not looked up by component - the parent directories are presumed to be good here */ 475 /* since paths are not looked up by component - the parent
476 directories are presumed to be good here */
469 renew_parental_timestamps(direntry); 477 renew_parental_timestamps(direntry);
470 478
471 } else if (rc == -ENOENT) { 479 } else if (rc == -ENOENT) {
472 rc = 0; 480 rc = 0;
481 direntry->d_time = jiffies;
482 if (pTcon->nocase)
483 direntry->d_op = &cifs_ci_dentry_ops;
484 else
485 direntry->d_op = &cifs_dentry_ops;
473 d_add(direntry, NULL); 486 d_add(direntry, NULL);
487 /* if it was once a directory (but how can we tell?) we could do
488 shrink_dcache_parent(direntry); */
474 } else { 489 } else {
475 cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", 490 cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
476 rc,full_path)); 491 rc,full_path));
@@ -489,21 +504,20 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
489{ 504{
490 int isValid = 1; 505 int isValid = 1;
491 506
492/* lock_kernel(); *//* surely we do not want to lock the kernel for a whole network round trip which could take seconds */
493
494 if (direntry->d_inode) { 507 if (direntry->d_inode) {
495 if (cifs_revalidate(direntry)) { 508 if (cifs_revalidate(direntry)) {
496 /* unlock_kernel(); */
497 return 0; 509 return 0;
498 } 510 }
499 } else { 511 } else {
500 cFYI(1, 512 cFYI(1, ("neg dentry 0x%p name = %s",
501 ("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p", 513 direntry, direntry->d_name.name));
502 direntry->d_name.name, direntry)); 514 if(time_after(jiffies, direntry->d_time + HZ) ||
515 !lookupCacheEnabled) {
516 d_drop(direntry);
517 isValid = 0;
518 }
503 } 519 }
504 520
505/* unlock_kernel(); */
506
507 return isValid; 521 return isValid;
508} 522}
509 523
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 05b525812ad..411c1f7f84d 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -710,7 +710,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
710 char *full_path = NULL; 710 char *full_path = NULL;
711 struct inode *newinode = NULL; 711 struct inode *newinode = NULL;
712 712
713 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p ", mode, inode)); 713 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
714 714
715 xid = GetXid(); 715 xid = GetXid();
716 716
@@ -768,6 +768,17 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
768 /* BB to be implemented via Windows secrty descriptors 768 /* BB to be implemented via Windows secrty descriptors
769 eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, 769 eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
770 -1, -1, local_nls); */ 770 -1, -1, local_nls); */
771 if(direntry->d_inode) {
772 direntry->d_inode->i_mode = mode;
773 direntry->d_inode->i_mode |= S_IFDIR;
774 if(cifs_sb->mnt_cifs_flags &
775 CIFS_MOUNT_SET_UID) {
776 direntry->d_inode->i_uid =
777 current->fsuid;
778 direntry->d_inode->i_gid =
779 current->fsgid;
780 }
781 }
771 } 782 }
772 } 783 }
773 kfree(full_path); 784 kfree(full_path);
@@ -1039,14 +1050,20 @@ int cifs_revalidate(struct dentry *direntry)
1039 filemap_fdatawrite(direntry->d_inode->i_mapping); 1050 filemap_fdatawrite(direntry->d_inode->i_mapping);
1040 } 1051 }
1041 if (invalidate_inode) { 1052 if (invalidate_inode) {
1042 if (direntry->d_inode->i_mapping) 1053 /* shrink_dcache not necessary now that cifs dentry ops
1043 filemap_fdatawait(direntry->d_inode->i_mapping); 1054 are exported for negative dentries */
1044 /* may eventually have to do this for open files too */ 1055/* if(S_ISDIR(direntry->d_inode->i_mode))
1045 if (list_empty(&(cifsInode->openFileList))) { 1056 shrink_dcache_parent(direntry); */
1046 /* Has changed on server - flush read ahead pages */ 1057 if (S_ISREG(direntry->d_inode->i_mode)) {
1047 cFYI(1, ("Invalidating read ahead data on " 1058 if (direntry->d_inode->i_mapping)
1048 "closed file")); 1059 filemap_fdatawait(direntry->d_inode->i_mapping);
1049 invalidate_remote_inode(direntry->d_inode); 1060 /* may eventually have to do this for open files too */
1061 if (list_empty(&(cifsInode->openFileList))) {
1062 /* changed on server - flush read ahead pages */
1063 cFYI(1, ("Invalidating read ahead data on "
1064 "closed file"));
1065 invalidate_remote_inode(direntry->d_inode);
1066 }
1050 } 1067 }
1051 } 1068 }
1052/* up(&direntry->d_inode->i_sem); */ 1069/* up(&direntry->d_inode->i_sem); */
@@ -1105,9 +1122,20 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1105 1122
1106 cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ", 1123 cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
1107 direntry->d_name.name, attrs->ia_valid)); 1124 direntry->d_name.name, attrs->ia_valid));
1125
1108 cifs_sb = CIFS_SB(direntry->d_inode->i_sb); 1126 cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
1109 pTcon = cifs_sb->tcon; 1127 pTcon = cifs_sb->tcon;
1110 1128
1129 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1130 /* check if we have permission to change attrs */
1131 rc = inode_change_ok(direntry->d_inode, attrs);
1132 if(rc < 0) {
1133 FreeXid(xid);
1134 return rc;
1135 } else
1136 rc = 0;
1137 }
1138
1111 down(&direntry->d_sb->s_vfs_rename_sem); 1139 down(&direntry->d_sb->s_vfs_rename_sem);
1112 full_path = build_path_from_dentry(direntry); 1140 full_path = build_path_from_dentry(direntry);
1113 up(&direntry->d_sb->s_vfs_rename_sem); 1141 up(&direntry->d_sb->s_vfs_rename_sem);
@@ -1147,7 +1175,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1147 1 /* 45 seconds */); 1175 1 /* 45 seconds */);
1148 cFYI(1,("Wrt seteof rc %d", rc)); 1176 cFYI(1,("Wrt seteof rc %d", rc));
1149 } 1177 }
1150 } 1178 } else
1179 rc = -EINVAL;
1180
1151 if (rc != 0) { 1181 if (rc != 0) {
1152 /* Set file size by pathname rather than by handle 1182 /* Set file size by pathname rather than by handle
1153 either because no valid, writeable file handle for 1183 either because no valid, writeable file handle for
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index ca27a82c54c..94baf6c8ecb 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -397,12 +397,12 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
397 if(smb->Command == SMB_COM_LOCKING_ANDX) 397 if(smb->Command == SMB_COM_LOCKING_ANDX)
398 return 0; 398 return 0;
399 else 399 else
400 cERROR(1, ("Rcvd Request not response ")); 400 cERROR(1, ("Rcvd Request not response"));
401 } 401 }
402 } else { /* bad signature or mid */ 402 } else { /* bad signature or mid */
403 if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) 403 if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
404 cERROR(1, 404 cERROR(1,
405 ("Bad protocol string signature header %x ", 405 ("Bad protocol string signature header %x",
406 *(unsigned int *) smb->Protocol)); 406 *(unsigned int *) smb->Protocol));
407 if (mid != smb->Mid) 407 if (mid != smb->Mid)
408 cERROR(1, ("Mids do not match")); 408 cERROR(1, ("Mids do not match"));
@@ -417,7 +417,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
417 __u32 len = smb->smb_buf_length; 417 __u32 len = smb->smb_buf_length;
418 __u32 clc_len; /* calculated length */ 418 __u32 clc_len; /* calculated length */
419 cFYI(0, 419 cFYI(0,
420 ("Entering checkSMB with Length: %x, smb_buf_length: %x ", 420 ("Entering checkSMB with Length: %x, smb_buf_length: %x",
421 length, len)); 421 length, len));
422 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || 422 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
423 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { 423 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
@@ -451,9 +451,16 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
451 cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); 451 cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid));
452 /* Windows XP can return a few bytes too much, presumably 452 /* Windows XP can return a few bytes too much, presumably
453 an illegal pad, at the end of byte range lock responses 453 an illegal pad, at the end of byte range lock responses
454 so we allow for up to eight byte pad, as long as actual 454 so we allow for that three byte pad, as long as actual
455 received length is as long or longer than calculated length */ 455 received length is as long or longer than calculated length */
456 if((4+len > clc_len) && (len <= clc_len + 3)) 456 /* We have now had to extend this more, since there is a
457 case in which it needs to be bigger still to handle a
458 malformed response to transact2 findfirst from WinXP when
459 access denied is returned and thus bcc and wct are zero
460 but server says length is 0x21 bytes too long as if the server
461 forget to reset the smb rfc1001 length when it reset the
462 wct and bcc to minimum size and drop the t2 parms and data */
463 if((4+len > clc_len) && (len <= clc_len + 512))
457 return 0; 464 return 0;
458 else 465 else
459 return 1; 466 return 1;
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index f7814689844..5de74d216fd 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -330,7 +330,7 @@ static const struct {
330 ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, { 330 ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {
331 ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, { 331 ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, {
332 ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, { 332 ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, {
333 ERRSRV, 2242, NT_STATUS_PASSWORD_EXPIRED}, { 333 ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, {
334 ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, { 334 ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, {
335 ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, { 335 ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, {
336 ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, { 336 ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {
@@ -676,7 +676,7 @@ static const struct {
676 ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, { 676 ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, {
677 ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, { 677 ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, {
678 ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, { 678 ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, {
679 ERRSRV, 2242, NT_STATUS_PASSWORD_MUST_CHANGE}, { 679 ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_MUST_CHANGE}, {
680 ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, { 680 ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, {
681 ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, { 681 ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, {
682 ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, { 682 ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, {
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 41a9659c16b..f8871196098 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -515,6 +515,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
515 *pbytes_returned = in_buf->smb_buf_length; 515 *pbytes_returned = in_buf->smb_buf_length;
516 516
517 /* BB special case reconnect tid and uid here? */ 517 /* BB special case reconnect tid and uid here? */
518 /* BB special case Errbadpassword and pwdexpired here */
518 rc = map_smb_to_linux_error(in_buf); 519 rc = map_smb_to_linux_error(in_buf);
519 520
520 /* convert ByteCount if necessary */ 521 /* convert ByteCount if necessary */
diff --git a/fs/dquot.c b/fs/dquot.c
index 05b60283c9c..2a62b3dc20e 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1513,10 +1513,16 @@ int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
1513 if (IS_ERR(dentry)) 1513 if (IS_ERR(dentry))
1514 return PTR_ERR(dentry); 1514 return PTR_ERR(dentry);
1515 1515
1516 if (!dentry->d_inode) {
1517 error = -ENOENT;
1518 goto out;
1519 }
1520
1516 error = security_quota_on(dentry); 1521 error = security_quota_on(dentry);
1517 if (!error) 1522 if (!error)
1518 error = vfs_quota_on_inode(dentry->d_inode, type, format_id); 1523 error = vfs_quota_on_inode(dentry->d_inode, type, format_id);
1519 1524
1525out:
1520 dput(dentry); 1526 dput(dentry);
1521 return error; 1527 return error;
1522} 1528}
diff --git a/fs/exec.c b/fs/exec.c
index 1f8a9fd2c9e..22533cce061 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -306,9 +306,6 @@ void install_arg_page(struct vm_area_struct *vma,
306 struct page *page, unsigned long address) 306 struct page *page, unsigned long address)
307{ 307{
308 struct mm_struct *mm = vma->vm_mm; 308 struct mm_struct *mm = vma->vm_mm;
309 pgd_t * pgd;
310 pud_t * pud;
311 pmd_t * pmd;
312 pte_t * pte; 309 pte_t * pte;
313 spinlock_t *ptl; 310 spinlock_t *ptl;
314 311
@@ -316,14 +313,7 @@ void install_arg_page(struct vm_area_struct *vma,
316 goto out; 313 goto out;
317 314
318 flush_dcache_page(page); 315 flush_dcache_page(page);
319 pgd = pgd_offset(mm, address); 316 pte = get_locked_pte(mm, address, &ptl);
320 pud = pud_alloc(mm, pgd, address);
321 if (!pud)
322 goto out;
323 pmd = pmd_alloc(mm, pud, address);
324 if (!pmd)
325 goto out;
326 pte = pte_alloc_map_lock(mm, pmd, address, &ptl);
327 if (!pte) 317 if (!pte)
328 goto out; 318 goto out;
329 if (!pte_none(*pte)) { 319 if (!pte_none(*pte)) {
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 1be78b4b4de..6104ad31050 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -767,6 +767,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
767 if (input->group != EXT3_SB(sb)->s_groups_count) { 767 if (input->group != EXT3_SB(sb)->s_groups_count) {
768 ext3_warning(sb, __FUNCTION__, 768 ext3_warning(sb, __FUNCTION__,
769 "multiple resizers run on filesystem!\n"); 769 "multiple resizers run on filesystem!\n");
770 err = -EBUSY;
770 goto exit_journal; 771 goto exit_journal;
771 } 772 }
772 773
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index c045cc70c74..51f5da65277 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -74,6 +74,24 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
74 return 1; 74 return 1;
75} 75}
76 76
77static int dir_alias(struct inode *inode)
78{
79 if (S_ISDIR(inode->i_mode)) {
80 /* Don't allow creating an alias to a directory */
81 struct dentry *alias = d_find_alias(inode);
82 if (alias) {
83 dput(alias);
84 return 1;
85 }
86 }
87 return 0;
88}
89
90static inline int invalid_nodeid(u64 nodeid)
91{
92 return !nodeid || nodeid == FUSE_ROOT_ID;
93}
94
77static struct dentry_operations fuse_dentry_operations = { 95static struct dentry_operations fuse_dentry_operations = {
78 .d_revalidate = fuse_dentry_revalidate, 96 .d_revalidate = fuse_dentry_revalidate,
79}; 97};
@@ -97,7 +115,7 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
97 fuse_lookup_init(req, dir, entry, &outarg); 115 fuse_lookup_init(req, dir, entry, &outarg);
98 request_send(fc, req); 116 request_send(fc, req);
99 err = req->out.h.error; 117 err = req->out.h.error;
100 if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID)) 118 if (!err && invalid_nodeid(outarg.nodeid))
101 err = -EIO; 119 err = -EIO;
102 if (!err) { 120 if (!err) {
103 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, 121 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
@@ -193,7 +211,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
193 } 211 }
194 212
195 err = -EIO; 213 err = -EIO;
196 if (!S_ISREG(outentry.attr.mode)) 214 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
197 goto out_free_ff; 215 goto out_free_ff;
198 216
199 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, 217 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
@@ -250,7 +268,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
250 fuse_put_request(fc, req); 268 fuse_put_request(fc, req);
251 return err; 269 return err;
252 } 270 }
253 if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) { 271 if (invalid_nodeid(outarg.nodeid)) {
254 fuse_put_request(fc, req); 272 fuse_put_request(fc, req);
255 return -EIO; 273 return -EIO;
256 } 274 }
@@ -263,7 +281,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
263 fuse_put_request(fc, req); 281 fuse_put_request(fc, req);
264 282
265 /* Don't allow userspace to do really stupid things... */ 283 /* Don't allow userspace to do really stupid things... */
266 if ((inode->i_mode ^ mode) & S_IFMT) { 284 if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
267 iput(inode); 285 iput(inode);
268 return -EIO; 286 return -EIO;
269 } 287 }
@@ -874,14 +892,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
874 err = fuse_lookup_iget(dir, entry, &inode); 892 err = fuse_lookup_iget(dir, entry, &inode);
875 if (err) 893 if (err)
876 return ERR_PTR(err); 894 return ERR_PTR(err);
877 if (inode && S_ISDIR(inode->i_mode)) { 895 if (inode && dir_alias(inode)) {
878 /* Don't allow creating an alias to a directory */ 896 iput(inode);
879 struct dentry *alias = d_find_alias(inode); 897 return ERR_PTR(-EIO);
880 if (alias) {
881 dput(alias);
882 iput(inode);
883 return ERR_PTR(-EIO);
884 }
885 } 898 }
886 d_add(entry, inode); 899 d_add(entry, inode);
887 return NULL; 900 return NULL;
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index c60e5635498..df16fcbff3f 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -151,6 +151,7 @@ struct hfsplus_sb_info {
151 151
152#define HFSPLUS_SB_WRITEBACKUP 0x0001 152#define HFSPLUS_SB_WRITEBACKUP 0x0001
153#define HFSPLUS_SB_NODECOMPOSE 0x0002 153#define HFSPLUS_SB_NODECOMPOSE 0x0002
154#define HFSPLUS_SB_FORCE 0x0004
154 155
155 156
156struct hfsplus_inode_info { 157struct hfsplus_inode_info {
diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h
index 5bad37cfdb2..b4fbed63321 100644
--- a/fs/hfsplus/hfsplus_raw.h
+++ b/fs/hfsplus/hfsplus_raw.h
@@ -123,11 +123,13 @@ struct hfsplus_vh {
123} __packed; 123} __packed;
124 124
125/* HFS+ volume attributes */ 125/* HFS+ volume attributes */
126#define HFSPLUS_VOL_UNMNT (1 << 8) 126#define HFSPLUS_VOL_UNMNT (1 << 8)
127#define HFSPLUS_VOL_SPARE_BLK (1 << 9) 127#define HFSPLUS_VOL_SPARE_BLK (1 << 9)
128#define HFSPLUS_VOL_NOCACHE (1 << 10) 128#define HFSPLUS_VOL_NOCACHE (1 << 10)
129#define HFSPLUS_VOL_INCNSTNT (1 << 11) 129#define HFSPLUS_VOL_INCNSTNT (1 << 11)
130#define HFSPLUS_VOL_SOFTLOCK (1 << 15) 130#define HFSPLUS_VOL_NODEID_REUSED (1 << 12)
131#define HFSPLUS_VOL_JOURNALED (1 << 13)
132#define HFSPLUS_VOL_SOFTLOCK (1 << 15)
131 133
132/* HFS+ BTree node descriptor */ 134/* HFS+ BTree node descriptor */
133struct hfs_bnode_desc { 135struct hfs_bnode_desc {
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c
index cca0818aa4c..935dafba007 100644
--- a/fs/hfsplus/options.c
+++ b/fs/hfsplus/options.c
@@ -22,7 +22,7 @@ enum {
22 opt_umask, opt_uid, opt_gid, 22 opt_umask, opt_uid, opt_gid,
23 opt_part, opt_session, opt_nls, 23 opt_part, opt_session, opt_nls,
24 opt_nodecompose, opt_decompose, 24 opt_nodecompose, opt_decompose,
25 opt_err 25 opt_force, opt_err
26}; 26};
27 27
28static match_table_t tokens = { 28static match_table_t tokens = {
@@ -36,6 +36,7 @@ static match_table_t tokens = {
36 { opt_nls, "nls=%s" }, 36 { opt_nls, "nls=%s" },
37 { opt_decompose, "decompose" }, 37 { opt_decompose, "decompose" },
38 { opt_nodecompose, "nodecompose" }, 38 { opt_nodecompose, "nodecompose" },
39 { opt_force, "force" },
39 { opt_err, NULL } 40 { opt_err, NULL }
40}; 41};
41 42
@@ -145,6 +146,9 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi)
145 case opt_nodecompose: 146 case opt_nodecompose:
146 sbi->flags |= HFSPLUS_SB_NODECOMPOSE; 147 sbi->flags |= HFSPLUS_SB_NODECOMPOSE;
147 break; 148 break;
149 case opt_force:
150 sbi->flags |= HFSPLUS_SB_FORCE;
151 break;
148 default: 152 default:
149 return 0; 153 return 0;
150 } 154 }
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 0ce1c455ae5..8093351bd7c 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -251,16 +251,28 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data)
251 return 0; 251 return 0;
252 if (!(*flags & MS_RDONLY)) { 252 if (!(*flags & MS_RDONLY)) {
253 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; 253 struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
254 struct hfsplus_sb_info sbi;
255
256 memset(&sbi, 0, sizeof(struct hfsplus_sb_info));
257 sbi.nls = HFSPLUS_SB(sb).nls;
258 if (!hfsplus_parse_options(data, &sbi))
259 return -EINVAL;
254 260
255 if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { 261 if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) {
256 printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " 262 printk("HFS+-fs warning: Filesystem was not cleanly unmounted, "
257 "running fsck.hfsplus is recommended. leaving read-only.\n"); 263 "running fsck.hfsplus is recommended. leaving read-only.\n");
258 sb->s_flags |= MS_RDONLY; 264 sb->s_flags |= MS_RDONLY;
259 *flags |= MS_RDONLY; 265 *flags |= MS_RDONLY;
266 } else if (sbi.flags & HFSPLUS_SB_FORCE) {
267 /* nothing */
260 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { 268 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
261 printk("HFS+-fs: Filesystem is marked locked, leaving read-only.\n"); 269 printk("HFS+-fs: Filesystem is marked locked, leaving read-only.\n");
262 sb->s_flags |= MS_RDONLY; 270 sb->s_flags |= MS_RDONLY;
263 *flags |= MS_RDONLY; 271 *flags |= MS_RDONLY;
272 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
273 printk("HFS+-fs: Filesystem is marked journaled, leaving read-only.\n");
274 sb->s_flags |= MS_RDONLY;
275 *flags |= MS_RDONLY;
264 } 276 }
265 } 277 }
266 return 0; 278 return 0;
@@ -352,11 +364,19 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
352 printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " 364 printk("HFS+-fs warning: Filesystem was not cleanly unmounted, "
353 "running fsck.hfsplus is recommended. mounting read-only.\n"); 365 "running fsck.hfsplus is recommended. mounting read-only.\n");
354 sb->s_flags |= MS_RDONLY; 366 sb->s_flags |= MS_RDONLY;
367 } else if (sbi->flags & HFSPLUS_SB_FORCE) {
368 /* nothing */
355 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { 369 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
356 if (!silent) 370 if (!silent)
357 printk("HFS+-fs: Filesystem is marked locked, mounting read-only.\n"); 371 printk("HFS+-fs: Filesystem is marked locked, mounting read-only.\n");
358 sb->s_flags |= MS_RDONLY; 372 sb->s_flags |= MS_RDONLY;
373 } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
374 if (!silent)
375 printk("HFS+-fs: write access to a jounaled filesystem is not supported, "
376 "use the force option at your own risk, mounting read-only.\n");
377 sb->s_flags |= MS_RDONLY;
359 } 378 }
379 sbi->flags &= ~HFSPLUS_SB_FORCE;
360 380
361 /* Load metadata objects (B*Trees) */ 381 /* Load metadata objects (B*Trees) */
362 HFSPLUS_SB(sb).ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); 382 HFSPLUS_SB(sb).ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID);
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 543420665c5..d0fcc5f3497 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -234,6 +234,7 @@ void jffs2_read_inode (struct inode *inode)
234 c = JFFS2_SB_INFO(inode->i_sb); 234 c = JFFS2_SB_INFO(inode->i_sb);
235 235
236 jffs2_init_inode_info(f); 236 jffs2_init_inode_info(f);
237 down(&f->sem);
237 238
238 ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); 239 ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
239 240
@@ -400,6 +401,7 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
400 401
401 f = JFFS2_INODE_INFO(inode); 402 f = JFFS2_INODE_INFO(inode);
402 jffs2_init_inode_info(f); 403 jffs2_init_inode_info(f);
404 down(&f->sem);
403 405
404 memset(ri, 0, sizeof(*ri)); 406 memset(ri, 0, sizeof(*ri));
405 /* Set OS-specific defaults for new inodes */ 407 /* Set OS-specific defaults for new inodes */
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 9e0b5458d9c..93883817cbd 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -51,7 +51,7 @@ static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long f
51 51
52 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == 52 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
53 SLAB_CTOR_CONSTRUCTOR) { 53 SLAB_CTOR_CONSTRUCTOR) {
54 init_MUTEX_LOCKED(&ei->sem); 54 init_MUTEX(&ei->sem);
55 inode_init_once(&ei->vfs_inode); 55 inode_init_once(&ei->vfs_inode);
56 } 56 }
57} 57}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7370583b61e..c0d1a214572 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1287,6 +1287,7 @@ dentry->d_parent->d_name.name, dentry->d_name.name);
1287 nfs_begin_data_update(dentry->d_inode); 1287 nfs_begin_data_update(dentry->d_inode);
1288 error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, 1288 error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
1289 dir, &qsilly); 1289 dir, &qsilly);
1290 nfs_mark_for_revalidate(dentry->d_inode);
1290 nfs_end_data_update(dentry->d_inode); 1291 nfs_end_data_update(dentry->d_inode);
1291 } else 1292 } else
1292 error = NFS_PROTO(dir)->rename(dir, &dentry->d_name, 1293 error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
@@ -1334,6 +1335,7 @@ static int nfs_safe_remove(struct dentry *dentry)
1334 /* The VFS may want to delete this inode */ 1335 /* The VFS may want to delete this inode */
1335 if (error == 0) 1336 if (error == 0)
1336 inode->i_nlink--; 1337 inode->i_nlink--;
1338 nfs_mark_for_revalidate(inode);
1337 nfs_end_data_update(inode); 1339 nfs_end_data_update(inode);
1338 } else 1340 } else
1339 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name); 1341 error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
@@ -1556,6 +1558,7 @@ go_ahead:
1556 nfs_begin_data_update(old_inode); 1558 nfs_begin_data_update(old_inode);
1557 error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, 1559 error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name,
1558 new_dir, &new_dentry->d_name); 1560 new_dir, &new_dentry->d_name);
1561 nfs_mark_for_revalidate(old_inode);
1559 nfs_end_data_update(old_inode); 1562 nfs_end_data_update(old_inode);
1560 nfs_end_data_update(new_dir); 1563 nfs_end_data_update(new_dir);
1561 nfs_end_data_update(old_dir); 1564 nfs_end_data_update(old_dir);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 6391d896421..afd75d0463f 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -54,7 +54,7 @@
54#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1) 54#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
55 55
56static void nfs_invalidate_inode(struct inode *); 56static void nfs_invalidate_inode(struct inode *);
57static int nfs_update_inode(struct inode *, struct nfs_fattr *, unsigned long); 57static int nfs_update_inode(struct inode *, struct nfs_fattr *);
58 58
59static struct inode *nfs_alloc_inode(struct super_block *sb); 59static struct inode *nfs_alloc_inode(struct super_block *sb);
60static void nfs_destroy_inode(struct inode *); 60static void nfs_destroy_inode(struct inode *);
@@ -643,14 +643,11 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
643/* 643/*
644 * Invalidate the local caches 644 * Invalidate the local caches
645 */ 645 */
646void 646static void nfs_zap_caches_locked(struct inode *inode)
647nfs_zap_caches(struct inode *inode)
648{ 647{
649 struct nfs_inode *nfsi = NFS_I(inode); 648 struct nfs_inode *nfsi = NFS_I(inode);
650 int mode = inode->i_mode; 649 int mode = inode->i_mode;
651 650
652 spin_lock(&inode->i_lock);
653
654 NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); 651 NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode);
655 NFS_ATTRTIMEO_UPDATE(inode) = jiffies; 652 NFS_ATTRTIMEO_UPDATE(inode) = jiffies;
656 653
@@ -659,7 +656,12 @@ nfs_zap_caches(struct inode *inode)
659 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; 656 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
660 else 657 else
661 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; 658 nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE;
659}
662 660
661void nfs_zap_caches(struct inode *inode)
662{
663 spin_lock(&inode->i_lock);
664 nfs_zap_caches_locked(inode);
663 spin_unlock(&inode->i_lock); 665 spin_unlock(&inode->i_lock);
664} 666}
665 667
@@ -676,16 +678,13 @@ static void nfs_zap_acl_cache(struct inode *inode)
676} 678}
677 679
678/* 680/*
679 * Invalidate, but do not unhash, the inode 681 * Invalidate, but do not unhash, the inode.
682 * NB: must be called with inode->i_lock held!
680 */ 683 */
681static void 684static void nfs_invalidate_inode(struct inode *inode)
682nfs_invalidate_inode(struct inode *inode)
683{ 685{
684 umode_t save_mode = inode->i_mode; 686 set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
685 687 nfs_zap_caches_locked(inode);
686 make_bad_inode(inode);
687 inode->i_mode = save_mode;
688 nfs_zap_caches(inode);
689} 688}
690 689
691struct nfs_find_desc { 690struct nfs_find_desc {
@@ -1081,8 +1080,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1081 int status = -ESTALE; 1080 int status = -ESTALE;
1082 struct nfs_fattr fattr; 1081 struct nfs_fattr fattr;
1083 struct nfs_inode *nfsi = NFS_I(inode); 1082 struct nfs_inode *nfsi = NFS_I(inode);
1084 unsigned long verifier;
1085 unsigned long cache_validity;
1086 1083
1087 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", 1084 dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n",
1088 inode->i_sb->s_id, (long long)NFS_FILEID(inode)); 1085 inode->i_sb->s_id, (long long)NFS_FILEID(inode));
@@ -1107,8 +1104,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1107 } 1104 }
1108 } 1105 }
1109 1106
1110 /* Protect against RPC races by saving the change attribute */
1111 verifier = nfs_save_change_attribute(inode);
1112 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr); 1107 status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
1113 if (status != 0) { 1108 if (status != 0) {
1114 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n", 1109 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
@@ -1123,7 +1118,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1123 } 1118 }
1124 1119
1125 spin_lock(&inode->i_lock); 1120 spin_lock(&inode->i_lock);
1126 status = nfs_update_inode(inode, &fattr, verifier); 1121 status = nfs_update_inode(inode, &fattr);
1127 if (status) { 1122 if (status) {
1128 spin_unlock(&inode->i_lock); 1123 spin_unlock(&inode->i_lock);
1129 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n", 1124 dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
@@ -1131,20 +1126,11 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1131 (long long)NFS_FILEID(inode), status); 1126 (long long)NFS_FILEID(inode), status);
1132 goto out; 1127 goto out;
1133 } 1128 }
1134 cache_validity = nfsi->cache_validity;
1135 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
1136
1137 /*
1138 * We may need to keep the attributes marked as invalid if
1139 * we raced with nfs_end_attr_update().
1140 */
1141 if (time_after_eq(verifier, nfsi->cache_change_attribute))
1142 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
1143 spin_unlock(&inode->i_lock); 1129 spin_unlock(&inode->i_lock);
1144 1130
1145 nfs_revalidate_mapping(inode, inode->i_mapping); 1131 nfs_revalidate_mapping(inode, inode->i_mapping);
1146 1132
1147 if (cache_validity & NFS_INO_INVALID_ACL) 1133 if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
1148 nfs_zap_acl_cache(inode); 1134 nfs_zap_acl_cache(inode);
1149 1135
1150 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", 1136 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
@@ -1347,10 +1333,8 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
1347 return 0; 1333 return 0;
1348 spin_lock(&inode->i_lock); 1334 spin_lock(&inode->i_lock);
1349 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; 1335 nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
1350 if (nfs_verify_change_attribute(inode, fattr->time_start))
1351 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
1352 if (time_after(fattr->time_start, nfsi->last_updated)) 1336 if (time_after(fattr->time_start, nfsi->last_updated))
1353 status = nfs_update_inode(inode, fattr, fattr->time_start); 1337 status = nfs_update_inode(inode, fattr);
1354 else 1338 else
1355 status = nfs_check_inode_attributes(inode, fattr); 1339 status = nfs_check_inode_attributes(inode, fattr);
1356 1340
@@ -1376,10 +1360,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1376 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; 1360 nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
1377 goto out; 1361 goto out;
1378 } 1362 }
1379 status = nfs_update_inode(inode, fattr, fattr->time_start); 1363 status = nfs_update_inode(inode, fattr);
1380 if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute))
1381 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
1382 nfsi->cache_change_attribute = jiffies;
1383out: 1364out:
1384 spin_unlock(&inode->i_lock); 1365 spin_unlock(&inode->i_lock);
1385 return status; 1366 return status;
@@ -1397,12 +1378,12 @@ out:
1397 * 1378 *
1398 * A very similar scenario holds for the dir cache. 1379 * A very similar scenario holds for the dir cache.
1399 */ 1380 */
1400static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier) 1381static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1401{ 1382{
1402 struct nfs_inode *nfsi = NFS_I(inode); 1383 struct nfs_inode *nfsi = NFS_I(inode);
1403 loff_t cur_isize, new_isize; 1384 loff_t cur_isize, new_isize;
1404 unsigned int invalid = 0; 1385 unsigned int invalid = 0;
1405 int data_unstable; 1386 int data_stable;
1406 1387
1407 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n", 1388 dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
1408 __FUNCTION__, inode->i_sb->s_id, inode->i_ino, 1389 __FUNCTION__, inode->i_sb->s_id, inode->i_ino,
@@ -1433,8 +1414,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1433 nfsi->last_updated = jiffies; 1414 nfsi->last_updated = jiffies;
1434 1415
1435 /* Are we racing with known updates of the metadata on the server? */ 1416 /* Are we racing with known updates of the metadata on the server? */
1436 data_unstable = ! (nfs_verify_change_attribute(inode, verifier) || 1417 data_stable = nfs_verify_change_attribute(inode, fattr->time_start);
1437 (nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)); 1418 if (data_stable)
1419 nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
1438 1420
1439 /* Check if our cached file size is stale */ 1421 /* Check if our cached file size is stale */
1440 new_isize = nfs_size_to_loff_t(fattr->size); 1422 new_isize = nfs_size_to_loff_t(fattr->size);
@@ -1443,7 +1425,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1443 /* Do we perhaps have any outstanding writes? */ 1425 /* Do we perhaps have any outstanding writes? */
1444 if (nfsi->npages == 0) { 1426 if (nfsi->npages == 0) {
1445 /* No, but did we race with nfs_end_data_update()? */ 1427 /* No, but did we race with nfs_end_data_update()? */
1446 if (time_after_eq(verifier, nfsi->cache_change_attribute)) { 1428 if (data_stable) {
1447 inode->i_size = new_isize; 1429 inode->i_size = new_isize;
1448 invalid |= NFS_INO_INVALID_DATA; 1430 invalid |= NFS_INO_INVALID_DATA;
1449 } 1431 }
@@ -1452,6 +1434,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1452 inode->i_size = new_isize; 1434 inode->i_size = new_isize;
1453 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1435 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1454 } 1436 }
1437 nfsi->cache_change_attribute = jiffies;
1455 dprintk("NFS: isize change on server for file %s/%ld\n", 1438 dprintk("NFS: isize change on server for file %s/%ld\n",
1456 inode->i_sb->s_id, inode->i_ino); 1439 inode->i_sb->s_id, inode->i_ino);
1457 } 1440 }
@@ -1461,8 +1444,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1461 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); 1444 memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
1462 dprintk("NFS: mtime change on server for file %s/%ld\n", 1445 dprintk("NFS: mtime change on server for file %s/%ld\n",
1463 inode->i_sb->s_id, inode->i_ino); 1446 inode->i_sb->s_id, inode->i_ino);
1464 if (!data_unstable) 1447 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1465 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1448 nfsi->cache_change_attribute = jiffies;
1466 } 1449 }
1467 1450
1468 if ((fattr->valid & NFS_ATTR_FATTR_V4) 1451 if ((fattr->valid & NFS_ATTR_FATTR_V4)
@@ -1470,15 +1453,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1470 dprintk("NFS: change_attr change on server for file %s/%ld\n", 1453 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1471 inode->i_sb->s_id, inode->i_ino); 1454 inode->i_sb->s_id, inode->i_ino);
1472 nfsi->change_attr = fattr->change_attr; 1455 nfsi->change_attr = fattr->change_attr;
1473 if (!data_unstable) 1456 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1474 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1457 nfsi->cache_change_attribute = jiffies;
1475 } 1458 }
1476 1459
1477 /* If ctime has changed we should definitely clear access+acl caches */ 1460 /* If ctime has changed we should definitely clear access+acl caches */
1478 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) { 1461 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
1479 if (!data_unstable) 1462 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1480 invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1481 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); 1463 memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
1464 nfsi->cache_change_attribute = jiffies;
1482 } 1465 }
1483 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime)); 1466 memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
1484 1467
@@ -1516,6 +1499,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1516 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) 1499 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
1517 || S_ISLNK(inode->i_mode))) 1500 || S_ISLNK(inode->i_mode)))
1518 invalid &= ~NFS_INO_INVALID_DATA; 1501 invalid &= ~NFS_INO_INVALID_DATA;
1502 if (data_stable)
1503 invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
1519 if (!nfs_have_delegation(inode, FMODE_READ)) 1504 if (!nfs_have_delegation(inode, FMODE_READ))
1520 nfsi->cache_validity |= invalid; 1505 nfsi->cache_validity |= invalid;
1521 1506
@@ -1528,14 +1513,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1528 printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n", 1513 printk(KERN_DEBUG "%s: inode %ld mode changed, %07o to %07o\n",
1529 __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode); 1514 __FUNCTION__, inode->i_ino, inode->i_mode, fattr->mode);
1530#endif 1515#endif
1516 out_err:
1531 /* 1517 /*
1532 * No need to worry about unhashing the dentry, as the 1518 * No need to worry about unhashing the dentry, as the
1533 * lookup validation will know that the inode is bad. 1519 * lookup validation will know that the inode is bad.
1534 * (But we fall through to invalidate the caches.) 1520 * (But we fall through to invalidate the caches.)
1535 */ 1521 */
1536 nfs_invalidate_inode(inode); 1522 nfs_invalidate_inode(inode);
1537 out_err:
1538 set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
1539 return -ESTALE; 1523 return -ESTALE;
1540} 1524}
1541 1525
@@ -2068,6 +2052,7 @@ static struct inode *nfs_alloc_inode(struct super_block *sb)
2068 return NULL; 2052 return NULL;
2069 nfsi->flags = 0UL; 2053 nfsi->flags = 0UL;
2070 nfsi->cache_validity = 0UL; 2054 nfsi->cache_validity = 0UL;
2055 nfsi->cache_change_attribute = jiffies;
2071#ifdef CONFIG_NFS_V3_ACL 2056#ifdef CONFIG_NFS_V3_ACL
2072 nfsi->acl_access = ERR_PTR(-EAGAIN); 2057 nfsi->acl_access = ERR_PTR(-EAGAIN);
2073 nfsi->acl_default = ERR_PTR(-EAGAIN); 2058 nfsi->acl_default = ERR_PTR(-EAGAIN);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 21482b2518f..f988a9417b1 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1506,10 +1506,15 @@ static int _nfs4_proc_write(struct nfs_write_data *wdata)
1506 dprintk("NFS call write %d @ %Ld\n", wdata->args.count, 1506 dprintk("NFS call write %d @ %Ld\n", wdata->args.count,
1507 (long long) wdata->args.offset); 1507 (long long) wdata->args.offset);
1508 1508
1509 wdata->args.bitmask = server->attr_bitmask;
1510 wdata->res.server = server;
1509 nfs_fattr_init(fattr); 1511 nfs_fattr_init(fattr);
1510 status = rpc_call_sync(server->client, &msg, rpcflags); 1512 status = rpc_call_sync(server->client, &msg, rpcflags);
1511 dprintk("NFS reply write: %d\n", status); 1513 dprintk("NFS reply write: %d\n", status);
1512 return status; 1514 if (status < 0)
1515 return status;
1516 nfs_post_op_update_inode(inode, fattr);
1517 return wdata->res.count;
1513} 1518}
1514 1519
1515static int nfs4_proc_write(struct nfs_write_data *wdata) 1520static int nfs4_proc_write(struct nfs_write_data *wdata)
@@ -1540,9 +1545,13 @@ static int _nfs4_proc_commit(struct nfs_write_data *cdata)
1540 dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, 1545 dprintk("NFS call commit %d @ %Ld\n", cdata->args.count,
1541 (long long) cdata->args.offset); 1546 (long long) cdata->args.offset);
1542 1547
1548 cdata->args.bitmask = server->attr_bitmask;
1549 cdata->res.server = server;
1543 nfs_fattr_init(fattr); 1550 nfs_fattr_init(fattr);
1544 status = rpc_call_sync(server->client, &msg, 0); 1551 status = rpc_call_sync(server->client, &msg, 0);
1545 dprintk("NFS reply commit: %d\n", status); 1552 dprintk("NFS reply commit: %d\n", status);
1553 if (status >= 0)
1554 nfs_post_op_update_inode(inode, fattr);
1546 return status; 1555 return status;
1547} 1556}
1548 1557
@@ -3071,15 +3080,15 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
3071 struct nfs4_client *clp = state->owner->so_client; 3080 struct nfs4_client *clp = state->owner->so_client;
3072 int status; 3081 int status;
3073 3082
3074 down_read(&clp->cl_sem);
3075 /* Is this a delegated open? */ 3083 /* Is this a delegated open? */
3076 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) { 3084 if (NFS_I(state->inode)->delegation_state != 0) {
3077 /* Yes: cache locks! */ 3085 /* Yes: cache locks! */
3078 status = do_vfs_lock(request->fl_file, request); 3086 status = do_vfs_lock(request->fl_file, request);
3079 /* ...but avoid races with delegation recall... */ 3087 /* ...but avoid races with delegation recall... */
3080 if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags)) 3088 if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags))
3081 goto out; 3089 return status;
3082 } 3090 }
3091 down_read(&clp->cl_sem);
3083 status = nfs4_set_lock_state(state, request); 3092 status = nfs4_set_lock_state(state, request);
3084 if (status != 0) 3093 if (status != 0)
3085 goto out; 3094 goto out;
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 0675f3215e0..5ef4c57618f 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -644,12 +644,15 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
644 644
645struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) 645struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter)
646{ 646{
647 struct rpc_sequence *sequence = counter->sequence;
647 struct nfs_seqid *new; 648 struct nfs_seqid *new;
648 649
649 new = kmalloc(sizeof(*new), GFP_KERNEL); 650 new = kmalloc(sizeof(*new), GFP_KERNEL);
650 if (new != NULL) { 651 if (new != NULL) {
651 new->sequence = counter; 652 new->sequence = counter;
652 INIT_LIST_HEAD(&new->list); 653 spin_lock(&sequence->lock);
654 list_add_tail(&new->list, &sequence->list);
655 spin_unlock(&sequence->lock);
653 } 656 }
654 return new; 657 return new;
655} 658}
@@ -658,12 +661,10 @@ void nfs_free_seqid(struct nfs_seqid *seqid)
658{ 661{
659 struct rpc_sequence *sequence = seqid->sequence->sequence; 662 struct rpc_sequence *sequence = seqid->sequence->sequence;
660 663
661 if (!list_empty(&seqid->list)) { 664 spin_lock(&sequence->lock);
662 spin_lock(&sequence->lock); 665 list_del(&seqid->list);
663 list_del(&seqid->list); 666 spin_unlock(&sequence->lock);
664 spin_unlock(&sequence->lock); 667 rpc_wake_up(&sequence->wait);
665 }
666 rpc_wake_up_next(&sequence->wait);
667 kfree(seqid); 668 kfree(seqid);
668} 669}
669 670
@@ -722,11 +723,10 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
722 if (sequence->list.next == &seqid->list) 723 if (sequence->list.next == &seqid->list)
723 goto out; 724 goto out;
724 spin_lock(&sequence->lock); 725 spin_lock(&sequence->lock);
725 if (!list_empty(&sequence->list)) { 726 if (sequence->list.next != &seqid->list) {
726 rpc_sleep_on(&sequence->wait, task, NULL, NULL); 727 rpc_sleep_on(&sequence->wait, task, NULL, NULL);
727 status = -EAGAIN; 728 status = -EAGAIN;
728 } else 729 }
729 list_add(&seqid->list, &sequence->list);
730 spin_unlock(&sequence->lock); 730 spin_unlock(&sequence->lock);
731out: 731out:
732 return status; 732 return status;
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index a48a003242c..e1e3ca5d746 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -375,6 +375,7 @@ nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
375 375
376 dprintk("NFS call link %s\n", name->name); 376 dprintk("NFS call link %s\n", name->name);
377 status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0); 377 status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0);
378 nfs_mark_for_revalidate(inode);
378 nfs_mark_for_revalidate(dir); 379 nfs_mark_for_revalidate(dir);
379 dprintk("NFS reply link: %d\n", status); 380 dprintk("NFS reply link: %d\n", status);
380 return status; 381 return status;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 8f71e766cc5..3107908e5f3 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -189,6 +189,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode,
189 (long long)NFS_FILEID(inode), 189 (long long)NFS_FILEID(inode),
190 count, (long long)(page_offset(page) + offset)); 190 count, (long long)(page_offset(page) + offset));
191 191
192 set_page_writeback(page);
192 nfs_begin_data_update(inode); 193 nfs_begin_data_update(inode);
193 do { 194 do {
194 if (count < wsize) 195 if (count < wsize)
@@ -221,6 +222,7 @@ static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode,
221 222
222io_error: 223io_error:
223 nfs_end_data_update(inode); 224 nfs_end_data_update(inode);
225 end_page_writeback(page);
224 nfs_writedata_free(wdata); 226 nfs_writedata_free(wdata);
225 return written ? written : result; 227 return written ? written : result;
226} 228}
@@ -929,7 +931,7 @@ static int nfs_flush_multi(struct list_head *head, struct inode *inode, int how)
929 atomic_set(&req->wb_complete, requests); 931 atomic_set(&req->wb_complete, requests);
930 932
931 ClearPageError(page); 933 ClearPageError(page);
932 SetPageWriteback(page); 934 set_page_writeback(page);
933 offset = 0; 935 offset = 0;
934 nbytes = req->wb_bytes; 936 nbytes = req->wb_bytes;
935 do { 937 do {
@@ -992,7 +994,7 @@ static int nfs_flush_one(struct list_head *head, struct inode *inode, int how)
992 nfs_list_remove_request(req); 994 nfs_list_remove_request(req);
993 nfs_list_add_request(req, &data->pages); 995 nfs_list_add_request(req, &data->pages);
994 ClearPageError(req->wb_page); 996 ClearPageError(req->wb_page);
995 SetPageWriteback(req->wb_page); 997 set_page_writeback(req->wb_page);
996 *pages++ = req->wb_page; 998 *pages++ = req->wb_page;
997 count += req->wb_bytes; 999 count += req->wb_bytes;
998 } 1000 }
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 9ab97cef0da..50bd5a8f044 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -402,12 +402,11 @@ struct numa_maps {
402/* 402/*
403 * Calculate numa node maps for a vma 403 * Calculate numa node maps for a vma
404 */ 404 */
405static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma) 405static struct numa_maps *get_numa_maps(struct vm_area_struct *vma)
406{ 406{
407 int i;
407 struct page *page; 408 struct page *page;
408 unsigned long vaddr; 409 unsigned long vaddr;
409 struct mm_struct *mm = vma->vm_mm;
410 int i;
411 struct numa_maps *md = kmalloc(sizeof(struct numa_maps), GFP_KERNEL); 410 struct numa_maps *md = kmalloc(sizeof(struct numa_maps), GFP_KERNEL);
412 411
413 if (!md) 412 if (!md)
@@ -420,7 +419,7 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma)
420 md->node[i] =0; 419 md->node[i] =0;
421 420
422 for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) { 421 for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
423 page = follow_page(mm, vaddr, 0); 422 page = follow_page(vma, vaddr, 0);
424 if (page) { 423 if (page) {
425 int count = page_mapcount(page); 424 int count = page_mapcount(page);
426 425
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 5f82352b97e..0a044ad9888 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2194,7 +2194,7 @@ static int map_block_for_writepage(struct inode *inode,
2194 INITIALIZE_PATH(path); 2194 INITIALIZE_PATH(path);
2195 int pos_in_item; 2195 int pos_in_item;
2196 int jbegin_count = JOURNAL_PER_BALANCE_CNT; 2196 int jbegin_count = JOURNAL_PER_BALANCE_CNT;
2197 loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1; 2197 loff_t byte_offset = ((loff_t)block << inode->i_sb->s_blocksize_bits)+1;
2198 int retval; 2198 int retval;
2199 int use_get_block = 0; 2199 int use_get_block = 0;
2200 int bytes_copied = 0; 2200 int bytes_copied = 0;
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 4b15761434b..68b7b78638f 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2757,6 +2757,15 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name,
2757 journal->j_cnode_used = 0; 2757 journal->j_cnode_used = 0;
2758 journal->j_must_wait = 0; 2758 journal->j_must_wait = 0;
2759 2759
2760 if (journal->j_cnode_free == 0) {
2761 reiserfs_warning(p_s_sb, "journal-2004: Journal cnode memory "
2762 "allocation failed (%ld bytes). Journal is "
2763 "too large for available memory. Usually "
2764 "this is due to a journal that is too large.",
2765 sizeof (struct reiserfs_journal_cnode) * num_cnodes);
2766 goto free_and_return;
2767 }
2768
2760 init_journal_hash(p_s_sb); 2769 init_journal_hash(p_s_sb);
2761 jl = journal->j_current_jl; 2770 jl = journal->j_current_jl;
2762 jl->j_list_bitmap = get_list_bitmap(p_s_sb, jl); 2771 jl->j_list_bitmap = get_list_bitmap(p_s_sb, jl);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index c6108971b4e..94d3cdfbf9b 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -941,13 +941,12 @@ __linvfs_get_block(
941 int retpbbm = 1; 941 int retpbbm = 1;
942 int error; 942 int error;
943 943
944 if (blocks) {
945 offset = blocks << inode->i_blkbits; /* 64 bit goodness */
946 size = (ssize_t) min_t(xfs_off_t, offset, LONG_MAX);
947 } else {
948 size = 1 << inode->i_blkbits;
949 }
950 offset = (xfs_off_t)iblock << inode->i_blkbits; 944 offset = (xfs_off_t)iblock << inode->i_blkbits;
945 if (blocks)
946 size = (ssize_t) min_t(xfs_off_t, LONG_MAX,
947 (xfs_off_t)blocks << inode->i_blkbits);
948 else
949 size = 1 << inode->i_blkbits;
951 950
952 VOP_BMAP(vp, offset, size, 951 VOP_BMAP(vp, offset, size,
953 create ? flags : BMAPI_READ, &iomap, &retpbbm, error); 952 create ? flags : BMAPI_READ, &iomap, &retpbbm, error);
@@ -1007,7 +1006,7 @@ __linvfs_get_block(
1007 ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0); 1006 ASSERT(iomap.iomap_bsize - iomap.iomap_delta > 0);
1008 offset = min_t(xfs_off_t, 1007 offset = min_t(xfs_off_t,
1009 iomap.iomap_bsize - iomap.iomap_delta, 1008 iomap.iomap_bsize - iomap.iomap_delta,
1010 blocks << inode->i_blkbits); 1009 (xfs_off_t)blocks << inode->i_blkbits);
1011 bh_result->b_size = (u32) min_t(xfs_off_t, UINT_MAX, offset); 1010 bh_result->b_size = (u32) min_t(xfs_off_t, UINT_MAX, offset);
1012 } 1011 }
1013 1012
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 35e557b00db..1c7421840c1 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -310,7 +310,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
310 * Fix up the start offset of the attribute fork 310 * Fix up the start offset of the attribute fork
311 */ 311 */
312 totsize -= size; 312 totsize -= size;
313 if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname) { 313 if (totsize == sizeof(xfs_attr_sf_hdr_t) && !args->addname &&
314 !(mp->m_flags & XFS_MOUNT_COMPAT_ATTR)) {
314 /* 315 /*
315 * Last attribute now removed, revert to original 316 * Last attribute now removed, revert to original
316 * inode format making all literal area available 317 * inode format making all literal area available
@@ -328,7 +329,8 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
328 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); 329 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
329 dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize); 330 dp->i_d.di_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
330 ASSERT(dp->i_d.di_forkoff); 331 ASSERT(dp->i_d.di_forkoff);
331 ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname); 332 ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) || args->addname ||
333 (mp->m_flags & XFS_MOUNT_COMPAT_ATTR));
332 dp->i_afp->if_ext_max = 334 dp->i_afp->if_ext_max =
333 XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t); 335 XFS_IFORK_ASIZE(dp) / (uint)sizeof(xfs_bmbt_rec_t);
334 dp->i_df.if_ext_max = 336 dp->i_df.if_ext_max =
@@ -737,7 +739,8 @@ xfs_attr_shortform_allfit(xfs_dabuf_t *bp, xfs_inode_t *dp)
737 + name_loc->namelen 739 + name_loc->namelen
738 + INT_GET(name_loc->valuelen, ARCH_CONVERT); 740 + INT_GET(name_loc->valuelen, ARCH_CONVERT);
739 } 741 }
740 if (bytes == sizeof(struct xfs_attr_sf_hdr)) 742 if (!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR) &&
743 (bytes == sizeof(struct xfs_attr_sf_hdr)))
741 return(-1); 744 return(-1);
742 return(xfs_attr_shortform_bytesfit(dp, bytes)); 745 return(xfs_attr_shortform_bytesfit(dp, bytes));
743} 746}
@@ -775,6 +778,8 @@ xfs_attr_leaf_to_shortform(xfs_dabuf_t *bp, xfs_da_args_t *args, int forkoff)
775 goto out; 778 goto out;
776 779
777 if (forkoff == -1) { 780 if (forkoff == -1) {
781 ASSERT(!(dp->i_mount->m_flags & XFS_MOUNT_COMPAT_ATTR));
782
778 /* 783 /*
779 * Last attribute was removed, revert to original 784 * Last attribute was removed, revert to original
780 * inode format making all literal area available 785 * inode format making all literal area available
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 7ceabd0e2d9..d1236d6f404 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -550,7 +550,7 @@ xfs_fs_goingdown(
550 struct vfs *vfsp = XFS_MTOVFS(mp); 550 struct vfs *vfsp = XFS_MTOVFS(mp);
551 struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev); 551 struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
552 552
553 if (sb) { 553 if (sb && !IS_ERR(sb)) {
554 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT); 554 xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
555 thaw_bdev(sb->s_bdev, sb); 555 thaw_bdev(sb->s_bdev, sb);
556 } 556 }
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index fcd6d63bb68..3ce204a524b 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -69,7 +69,7 @@ typedef struct xfs_iomap {
69 xfs_buftarg_t *iomap_target; 69 xfs_buftarg_t *iomap_target;
70 xfs_off_t iomap_offset; /* offset of mapping, bytes */ 70 xfs_off_t iomap_offset; /* offset of mapping, bytes */
71 xfs_off_t iomap_bsize; /* size of mapping, bytes */ 71 xfs_off_t iomap_bsize; /* size of mapping, bytes */
72 size_t iomap_delta; /* offset into mapping, bytes */ 72 xfs_off_t iomap_delta; /* offset into mapping, bytes */
73 iomap_flags_t iomap_flags; 73 iomap_flags_t iomap_flags;
74} xfs_iomap_t; 74} xfs_iomap_t;
75 75
diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
index 8f285149681..4518b188ade 100644
--- a/fs/xfs/xfs_log_priv.h
+++ b/fs/xfs/xfs_log_priv.h
@@ -494,10 +494,8 @@ typedef struct log {
494 494
495#define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) 495#define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR)
496 496
497#define XLOG_GRANT_SUB_SPACE(log,bytes,type) \ 497#define XLOG_GRANT_SUB_SPACE(log,bytes,type) \
498 xlog_grant_sub_space(log,bytes,type) 498 { \
499static inline void xlog_grant_sub_space(struct log *log, int bytes, int type)
500{
501 if (type == 'w') { \ 499 if (type == 'w') { \
502 (log)->l_grant_write_bytes -= (bytes); \ 500 (log)->l_grant_write_bytes -= (bytes); \
503 if ((log)->l_grant_write_bytes < 0) { \ 501 if ((log)->l_grant_write_bytes < 0) { \
@@ -511,13 +509,9 @@ static inline void xlog_grant_sub_space(struct log *log, int bytes, int type)
511 (log)->l_grant_reserve_cycle--; \ 509 (log)->l_grant_reserve_cycle--; \
512 } \ 510 } \
513 } \ 511 } \
514} 512 }
515 513#define XLOG_GRANT_ADD_SPACE(log,bytes,type) \
516#define XLOG_GRANT_ADD_SPACE(log,bytes,type) \ 514 { \
517 xlog_grant_add_space(log,bytes,type)
518static inline void
519xlog_grant_add_space(struct log *log, int bytes, int type)
520{
521 if (type == 'w') { \ 515 if (type == 'w') { \
522 (log)->l_grant_write_bytes += (bytes); \ 516 (log)->l_grant_write_bytes += (bytes); \
523 if ((log)->l_grant_write_bytes > (log)->l_logsize) { \ 517 if ((log)->l_grant_write_bytes > (log)->l_logsize) { \
@@ -531,12 +525,9 @@ xlog_grant_add_space(struct log *log, int bytes, int type)
531 (log)->l_grant_reserve_cycle++; \ 525 (log)->l_grant_reserve_cycle++; \
532 } \ 526 } \
533 } \ 527 } \
534} 528 }
535 529#define XLOG_INS_TICKETQ(q, tic) \
536#define XLOG_INS_TICKETQ(q, tic) xlog_ins_ticketq(q, tic) 530 { \
537static inline void
538xlog_ins_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
539{ \
540 if (q) { \ 531 if (q) { \
541 (tic)->t_next = (q); \ 532 (tic)->t_next = (q); \
542 (tic)->t_prev = (q)->t_prev; \ 533 (tic)->t_prev = (q)->t_prev; \
@@ -547,12 +538,9 @@ xlog_ins_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
547 (q) = (tic); \ 538 (q) = (tic); \
548 } \ 539 } \
549 (tic)->t_flags |= XLOG_TIC_IN_Q; \ 540 (tic)->t_flags |= XLOG_TIC_IN_Q; \
550} 541 }
551 542#define XLOG_DEL_TICKETQ(q, tic) \
552#define XLOG_DEL_TICKETQ(q, tic) xlog_del_ticketq(q, tic) 543 { \
553static inline void
554xlog_del_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
555{ \
556 if ((tic) == (tic)->t_next) { \ 544 if ((tic) == (tic)->t_next) { \
557 (q) = NULL; \ 545 (q) = NULL; \
558 } else { \ 546 } else { \
@@ -562,7 +550,7 @@ xlog_del_ticketq(struct xlog_ticket *q, struct xlog_ticket *tic)
562 } \ 550 } \
563 (tic)->t_next = (tic)->t_prev = NULL; \ 551 (tic)->t_next = (tic)->t_prev = NULL; \
564 (tic)->t_flags &= ~XLOG_TIC_IN_Q; \ 552 (tic)->t_flags &= ~XLOG_TIC_IN_Q; \
565} 553 }
566 554
567/* common routines */ 555/* common routines */
568extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp); 556extern xfs_lsn_t xlog_assign_tail_lsn(struct xfs_mount *mp);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 7c1f7453146..e03fa2a3d5e 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -3958,8 +3958,9 @@ xfs_finish_reclaim_all(xfs_mount_t *mp, int noblock)
3958 } 3958 }
3959 } 3959 }
3960 XFS_MOUNT_IUNLOCK(mp); 3960 XFS_MOUNT_IUNLOCK(mp);
3961 xfs_finish_reclaim(ip, noblock, 3961 if (xfs_finish_reclaim(ip, noblock,
3962 XFS_IFLUSH_DELWRI_ELSE_ASYNC); 3962 XFS_IFLUSH_DELWRI_ELSE_ASYNC))
3963 delay(1);
3963 purged = 1; 3964 purged = 1;
3964 break; 3965 break;
3965 } 3966 }