diff options
author | Ingo Molnar <mingo@elte.hu> | 2010-07-01 02:49:28 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-07-01 03:31:25 -0400 |
commit | 0a54cec0c25cc49e3b68b14c205f1f6cff13f5e1 (patch) | |
tree | eb4e63ee9ae1fcaf9aa53a1668e55c09516052d9 /fs | |
parent | ec8c27e04f89a7575ca2c4facb99152e03d6a99c (diff) | |
parent | 980019d74e4b2428362b36a0506519d6d9460800 (diff) |
Merge branch 'linus' into core/rcu
Conflicts:
fs/fs-writeback.c
Merge reason: Resolve the conflict
Note, i picked the version from Linus's tree, which effectively reverts
the fs-writeback.c bits of:
b97181f: fs: remove all rcu head initializations, except on_stack initializations
As the upstream changes to this file changed this code heavily and the
first attempt to resolve the conflict resulted in a non-booting kernel.
It's safer to re-try this portion of the commit cleanly.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/binfmt_flat.c | 6 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 16 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 1 | ||||
-rw-r--r-- | fs/cifs/dir.c | 76 | ||||
-rw-r--r-- | fs/cifs/file.c | 100 | ||||
-rw-r--r-- | fs/cifs/inode.c | 4 | ||||
-rw-r--r-- | fs/cifs/sess.c | 10 | ||||
-rw-r--r-- | fs/dcache.c | 2 | ||||
-rw-r--r-- | fs/ext2/acl.c | 1 | ||||
-rw-r--r-- | fs/ext3/acl.c | 1 | ||||
-rw-r--r-- | fs/fcntl.c | 6 | ||||
-rw-r--r-- | fs/fs-writeback.c | 279 | ||||
-rw-r--r-- | fs/nfs/client.c | 122 | ||||
-rw-r--r-- | fs/nfs/getroot.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 4 | ||||
-rw-r--r-- | fs/nfs/super.c | 22 | ||||
-rw-r--r-- | fs/ocfs2/reservations.c | 1 | ||||
-rw-r--r-- | fs/proc/proc_devtree.c | 3 | ||||
-rw-r--r-- | fs/proc/task_nommu.c | 20 | ||||
-rw-r--r-- | fs/super.c | 6 | ||||
-rw-r--r-- | fs/sysv/ialloc.c | 6 | ||||
-rw-r--r-- | fs/ubifs/budget.c | 2 |
22 files changed, 319 insertions, 371 deletions
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index b6ab27ccf214..811384bec8de 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -68,11 +68,7 @@ | |||
68 | * Here we can be a bit looser than the data sections since this | 68 | * Here we can be a bit looser than the data sections since this |
69 | * needs to only meet arch ABI requirements. | 69 | * needs to only meet arch ABI requirements. |
70 | */ | 70 | */ |
71 | #ifdef ARCH_SLAB_MINALIGN | 71 | #define FLAT_STACK_ALIGN max_t(unsigned long, sizeof(void *), ARCH_SLAB_MINALIGN) |
72 | #define FLAT_STACK_ALIGN (ARCH_SLAB_MINALIGN) | ||
73 | #else | ||
74 | #define FLAT_STACK_ALIGN (sizeof(void *)) | ||
75 | #endif | ||
76 | 72 | ||
77 | #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ | 73 | #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ |
78 | #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ | 74 | #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 78c02eb4cb1f..484e52bb40bb 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -473,14 +473,24 @@ static int cifs_remount(struct super_block *sb, int *flags, char *data) | |||
473 | return 0; | 473 | return 0; |
474 | } | 474 | } |
475 | 475 | ||
476 | void cifs_drop_inode(struct inode *inode) | ||
477 | { | ||
478 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
479 | |||
480 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) | ||
481 | return generic_drop_inode(inode); | ||
482 | |||
483 | return generic_delete_inode(inode); | ||
484 | } | ||
485 | |||
476 | static const struct super_operations cifs_super_ops = { | 486 | static const struct super_operations cifs_super_ops = { |
477 | .put_super = cifs_put_super, | 487 | .put_super = cifs_put_super, |
478 | .statfs = cifs_statfs, | 488 | .statfs = cifs_statfs, |
479 | .alloc_inode = cifs_alloc_inode, | 489 | .alloc_inode = cifs_alloc_inode, |
480 | .destroy_inode = cifs_destroy_inode, | 490 | .destroy_inode = cifs_destroy_inode, |
481 | /* .drop_inode = generic_delete_inode, | 491 | .drop_inode = cifs_drop_inode, |
482 | .delete_inode = cifs_delete_inode, */ /* Do not need above two | 492 | /* .delete_inode = cifs_delete_inode, */ /* Do not need above |
483 | functions unless later we add lazy close of inodes or unless the | 493 | function unless later we add lazy close of inodes or unless the |
484 | kernel forgets to call us with the same number of releases (closes) | 494 | kernel forgets to call us with the same number of releases (closes) |
485 | as opens */ | 495 | as opens */ |
486 | .show_options = cifs_show_options, | 496 | .show_options = cifs_show_options, |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index fb1657e0fdb8..fb6318b81509 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -106,7 +106,6 @@ extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, | |||
106 | __u16 fileHandle, struct file *file, | 106 | __u16 fileHandle, struct file *file, |
107 | struct vfsmount *mnt, unsigned int oflags); | 107 | struct vfsmount *mnt, unsigned int oflags); |
108 | extern int cifs_posix_open(char *full_path, struct inode **pinode, | 108 | extern int cifs_posix_open(char *full_path, struct inode **pinode, |
109 | struct vfsmount *mnt, | ||
110 | struct super_block *sb, | 109 | struct super_block *sb, |
111 | int mode, int oflags, | 110 | int mode, int oflags, |
112 | __u32 *poplock, __u16 *pnetfid, int xid); | 111 | __u32 *poplock, __u16 *pnetfid, int xid); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 391816b461ca..e7ae78b66fa1 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/namei.h> | 26 | #include <linux/namei.h> |
27 | #include <linux/mount.h> | 27 | #include <linux/mount.h> |
28 | #include <linux/file.h> | ||
28 | #include "cifsfs.h" | 29 | #include "cifsfs.h" |
29 | #include "cifspdu.h" | 30 | #include "cifspdu.h" |
30 | #include "cifsglob.h" | 31 | #include "cifsglob.h" |
@@ -184,12 +185,13 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, | |||
184 | } | 185 | } |
185 | write_unlock(&GlobalSMBSeslock); | 186 | write_unlock(&GlobalSMBSeslock); |
186 | 187 | ||
188 | file->private_data = pCifsFile; | ||
189 | |||
187 | return pCifsFile; | 190 | return pCifsFile; |
188 | } | 191 | } |
189 | 192 | ||
190 | int cifs_posix_open(char *full_path, struct inode **pinode, | 193 | int cifs_posix_open(char *full_path, struct inode **pinode, |
191 | struct vfsmount *mnt, struct super_block *sb, | 194 | struct super_block *sb, int mode, int oflags, |
192 | int mode, int oflags, | ||
193 | __u32 *poplock, __u16 *pnetfid, int xid) | 195 | __u32 *poplock, __u16 *pnetfid, int xid) |
194 | { | 196 | { |
195 | int rc; | 197 | int rc; |
@@ -258,19 +260,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode, | |||
258 | cifs_fattr_to_inode(*pinode, &fattr); | 260 | cifs_fattr_to_inode(*pinode, &fattr); |
259 | } | 261 | } |
260 | 262 | ||
261 | /* | ||
262 | * cifs_fill_filedata() takes care of setting cifsFileInfo pointer to | ||
263 | * file->private_data. | ||
264 | */ | ||
265 | if (mnt) { | ||
266 | struct cifsFileInfo *pfile_info; | ||
267 | |||
268 | pfile_info = cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, | ||
269 | oflags); | ||
270 | if (pfile_info == NULL) | ||
271 | rc = -ENOMEM; | ||
272 | } | ||
273 | |||
274 | posix_open_ret: | 263 | posix_open_ret: |
275 | kfree(presp_data); | 264 | kfree(presp_data); |
276 | return rc; | 265 | return rc; |
@@ -298,7 +287,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
298 | int create_options = CREATE_NOT_DIR; | 287 | int create_options = CREATE_NOT_DIR; |
299 | __u32 oplock = 0; | 288 | __u32 oplock = 0; |
300 | int oflags; | 289 | int oflags; |
301 | bool posix_create = false; | ||
302 | /* | 290 | /* |
303 | * BB below access is probably too much for mknod to request | 291 | * BB below access is probably too much for mknod to request |
304 | * but we have to do query and setpathinfo so requesting | 292 | * but we have to do query and setpathinfo so requesting |
@@ -339,7 +327,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
339 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | 327 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
340 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 328 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
341 | rc = cifs_posix_open(full_path, &newinode, | 329 | rc = cifs_posix_open(full_path, &newinode, |
342 | nd ? nd->path.mnt : NULL, | ||
343 | inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); | 330 | inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); |
344 | /* EIO could indicate that (posix open) operation is not | 331 | /* EIO could indicate that (posix open) operation is not |
345 | supported, despite what server claimed in capability | 332 | supported, despite what server claimed in capability |
@@ -347,7 +334,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
347 | handled in posix open */ | 334 | handled in posix open */ |
348 | 335 | ||
349 | if (rc == 0) { | 336 | if (rc == 0) { |
350 | posix_create = true; | ||
351 | if (newinode == NULL) /* query inode info */ | 337 | if (newinode == NULL) /* query inode info */ |
352 | goto cifs_create_get_file_info; | 338 | goto cifs_create_get_file_info; |
353 | else /* success, no need to query */ | 339 | else /* success, no need to query */ |
@@ -478,21 +464,28 @@ cifs_create_set_dentry: | |||
478 | else | 464 | else |
479 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); | 465 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); |
480 | 466 | ||
481 | /* nfsd case - nfs srv does not set nd */ | 467 | if (newinode && nd && (nd->flags & LOOKUP_OPEN)) { |
482 | if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { | ||
483 | /* mknod case - do not leave file open */ | ||
484 | CIFSSMBClose(xid, tcon, fileHandle); | ||
485 | } else if (!(posix_create) && (newinode)) { | ||
486 | struct cifsFileInfo *pfile_info; | 468 | struct cifsFileInfo *pfile_info; |
487 | /* | 469 | struct file *filp; |
488 | * cifs_fill_filedata() takes care of setting cifsFileInfo | 470 | |
489 | * pointer to file->private_data. | 471 | filp = lookup_instantiate_filp(nd, direntry, generic_file_open); |
490 | */ | 472 | if (IS_ERR(filp)) { |
491 | pfile_info = cifs_new_fileinfo(newinode, fileHandle, NULL, | 473 | rc = PTR_ERR(filp); |
474 | CIFSSMBClose(xid, tcon, fileHandle); | ||
475 | goto cifs_create_out; | ||
476 | } | ||
477 | |||
478 | pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, | ||
492 | nd->path.mnt, oflags); | 479 | nd->path.mnt, oflags); |
493 | if (pfile_info == NULL) | 480 | if (pfile_info == NULL) { |
481 | fput(filp); | ||
482 | CIFSSMBClose(xid, tcon, fileHandle); | ||
494 | rc = -ENOMEM; | 483 | rc = -ENOMEM; |
484 | } | ||
485 | } else { | ||
486 | CIFSSMBClose(xid, tcon, fileHandle); | ||
495 | } | 487 | } |
488 | |||
496 | cifs_create_out: | 489 | cifs_create_out: |
497 | kfree(buf); | 490 | kfree(buf); |
498 | kfree(full_path); | 491 | kfree(full_path); |
@@ -636,6 +629,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
636 | bool posix_open = false; | 629 | bool posix_open = false; |
637 | struct cifs_sb_info *cifs_sb; | 630 | struct cifs_sb_info *cifs_sb; |
638 | struct cifsTconInfo *pTcon; | 631 | struct cifsTconInfo *pTcon; |
632 | struct cifsFileInfo *cfile; | ||
639 | struct inode *newInode = NULL; | 633 | struct inode *newInode = NULL; |
640 | char *full_path = NULL; | 634 | char *full_path = NULL; |
641 | struct file *filp; | 635 | struct file *filp; |
@@ -703,7 +697,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
703 | if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && | 697 | if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && |
704 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && | 698 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && |
705 | (nd->intent.open.flags & O_CREAT)) { | 699 | (nd->intent.open.flags & O_CREAT)) { |
706 | rc = cifs_posix_open(full_path, &newInode, nd->path.mnt, | 700 | rc = cifs_posix_open(full_path, &newInode, |
707 | parent_dir_inode->i_sb, | 701 | parent_dir_inode->i_sb, |
708 | nd->intent.open.create_mode, | 702 | nd->intent.open.create_mode, |
709 | nd->intent.open.flags, &oplock, | 703 | nd->intent.open.flags, &oplock, |
@@ -733,8 +727,25 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
733 | else | 727 | else |
734 | direntry->d_op = &cifs_dentry_ops; | 728 | direntry->d_op = &cifs_dentry_ops; |
735 | d_add(direntry, newInode); | 729 | d_add(direntry, newInode); |
736 | if (posix_open) | 730 | if (posix_open) { |
737 | filp = lookup_instantiate_filp(nd, direntry, NULL); | 731 | filp = lookup_instantiate_filp(nd, direntry, |
732 | generic_file_open); | ||
733 | if (IS_ERR(filp)) { | ||
734 | rc = PTR_ERR(filp); | ||
735 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
736 | goto lookup_out; | ||
737 | } | ||
738 | |||
739 | cfile = cifs_new_fileinfo(newInode, fileHandle, filp, | ||
740 | nd->path.mnt, | ||
741 | nd->intent.open.flags); | ||
742 | if (cfile == NULL) { | ||
743 | fput(filp); | ||
744 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
745 | rc = -ENOMEM; | ||
746 | goto lookup_out; | ||
747 | } | ||
748 | } | ||
738 | /* since paths are not looked up by component - the parent | 749 | /* since paths are not looked up by component - the parent |
739 | directories are presumed to be good here */ | 750 | directories are presumed to be good here */ |
740 | renew_parental_timestamps(direntry); | 751 | renew_parental_timestamps(direntry); |
@@ -755,6 +766,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
755 | is a common return code */ | 766 | is a common return code */ |
756 | } | 767 | } |
757 | 768 | ||
769 | lookup_out: | ||
758 | kfree(full_path); | 770 | kfree(full_path); |
759 | FreeXid(xid); | 771 | FreeXid(xid); |
760 | return ERR_PTR(rc); | 772 | return ERR_PTR(rc); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 75541af4b3db..409e4f523e61 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -162,44 +162,12 @@ psx_client_can_cache: | |||
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | static struct cifsFileInfo * | ||
166 | cifs_fill_filedata(struct file *file) | ||
167 | { | ||
168 | struct list_head *tmp; | ||
169 | struct cifsFileInfo *pCifsFile = NULL; | ||
170 | struct cifsInodeInfo *pCifsInode = NULL; | ||
171 | |||
172 | /* search inode for this file and fill in file->private_data */ | ||
173 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | ||
174 | read_lock(&GlobalSMBSeslock); | ||
175 | list_for_each(tmp, &pCifsInode->openFileList) { | ||
176 | pCifsFile = list_entry(tmp, struct cifsFileInfo, flist); | ||
177 | if ((pCifsFile->pfile == NULL) && | ||
178 | (pCifsFile->pid == current->tgid)) { | ||
179 | /* mode set in cifs_create */ | ||
180 | |||
181 | /* needed for writepage */ | ||
182 | pCifsFile->pfile = file; | ||
183 | file->private_data = pCifsFile; | ||
184 | break; | ||
185 | } | ||
186 | } | ||
187 | read_unlock(&GlobalSMBSeslock); | ||
188 | |||
189 | if (file->private_data != NULL) { | ||
190 | return pCifsFile; | ||
191 | } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) | ||
192 | cERROR(1, "could not find file instance for " | ||
193 | "new file %p", file); | ||
194 | return NULL; | ||
195 | } | ||
196 | |||
197 | /* all arguments to this function must be checked for validity in caller */ | 165 | /* all arguments to this function must be checked for validity in caller */ |
198 | static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | 166 | static inline int cifs_open_inode_helper(struct inode *inode, |
199 | struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, | ||
200 | struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf, | 167 | struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf, |
201 | char *full_path, int xid) | 168 | char *full_path, int xid) |
202 | { | 169 | { |
170 | struct cifsInodeInfo *pCifsInode = CIFS_I(inode); | ||
203 | struct timespec temp; | 171 | struct timespec temp; |
204 | int rc; | 172 | int rc; |
205 | 173 | ||
@@ -213,36 +181,35 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, | |||
213 | /* if not oplocked, invalidate inode pages if mtime or file | 181 | /* if not oplocked, invalidate inode pages if mtime or file |
214 | size changed */ | 182 | size changed */ |
215 | temp = cifs_NTtimeToUnix(buf->LastWriteTime); | 183 | temp = cifs_NTtimeToUnix(buf->LastWriteTime); |
216 | if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && | 184 | if (timespec_equal(&inode->i_mtime, &temp) && |
217 | (file->f_path.dentry->d_inode->i_size == | 185 | (inode->i_size == |
218 | (loff_t)le64_to_cpu(buf->EndOfFile))) { | 186 | (loff_t)le64_to_cpu(buf->EndOfFile))) { |
219 | cFYI(1, "inode unchanged on server"); | 187 | cFYI(1, "inode unchanged on server"); |
220 | } else { | 188 | } else { |
221 | if (file->f_path.dentry->d_inode->i_mapping) { | 189 | if (inode->i_mapping) { |
222 | /* BB no need to lock inode until after invalidate | 190 | /* BB no need to lock inode until after invalidate |
223 | since namei code should already have it locked? */ | 191 | since namei code should already have it locked? */ |
224 | rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); | 192 | rc = filemap_write_and_wait(inode->i_mapping); |
225 | if (rc != 0) | 193 | if (rc != 0) |
226 | CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc; | 194 | pCifsInode->write_behind_rc = rc; |
227 | } | 195 | } |
228 | cFYI(1, "invalidating remote inode since open detected it " | 196 | cFYI(1, "invalidating remote inode since open detected it " |
229 | "changed"); | 197 | "changed"); |
230 | invalidate_remote_inode(file->f_path.dentry->d_inode); | 198 | invalidate_remote_inode(inode); |
231 | } | 199 | } |
232 | 200 | ||
233 | client_can_cache: | 201 | client_can_cache: |
234 | if (pTcon->unix_ext) | 202 | if (pTcon->unix_ext) |
235 | rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, | 203 | rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, |
236 | full_path, inode->i_sb, xid); | 204 | xid); |
237 | else | 205 | else |
238 | rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, | 206 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, |
239 | full_path, buf, inode->i_sb, xid, NULL); | 207 | xid, NULL); |
240 | 208 | ||
241 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 209 | if ((*oplock & 0xF) == OPLOCK_EXCLUSIVE) { |
242 | pCifsInode->clientCanCacheAll = true; | 210 | pCifsInode->clientCanCacheAll = true; |
243 | pCifsInode->clientCanCacheRead = true; | 211 | pCifsInode->clientCanCacheRead = true; |
244 | cFYI(1, "Exclusive Oplock granted on inode %p", | 212 | cFYI(1, "Exclusive Oplock granted on inode %p", inode); |
245 | file->f_path.dentry->d_inode); | ||
246 | } else if ((*oplock & 0xF) == OPLOCK_READ) | 213 | } else if ((*oplock & 0xF) == OPLOCK_READ) |
247 | pCifsInode->clientCanCacheRead = true; | 214 | pCifsInode->clientCanCacheRead = true; |
248 | 215 | ||
@@ -256,7 +223,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
256 | __u32 oplock; | 223 | __u32 oplock; |
257 | struct cifs_sb_info *cifs_sb; | 224 | struct cifs_sb_info *cifs_sb; |
258 | struct cifsTconInfo *tcon; | 225 | struct cifsTconInfo *tcon; |
259 | struct cifsFileInfo *pCifsFile; | 226 | struct cifsFileInfo *pCifsFile = NULL; |
260 | struct cifsInodeInfo *pCifsInode; | 227 | struct cifsInodeInfo *pCifsInode; |
261 | char *full_path = NULL; | 228 | char *full_path = NULL; |
262 | int desiredAccess; | 229 | int desiredAccess; |
@@ -270,12 +237,6 @@ int cifs_open(struct inode *inode, struct file *file) | |||
270 | tcon = cifs_sb->tcon; | 237 | tcon = cifs_sb->tcon; |
271 | 238 | ||
272 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | 239 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
273 | pCifsFile = cifs_fill_filedata(file); | ||
274 | if (pCifsFile) { | ||
275 | rc = 0; | ||
276 | FreeXid(xid); | ||
277 | return rc; | ||
278 | } | ||
279 | 240 | ||
280 | full_path = build_path_from_dentry(file->f_path.dentry); | 241 | full_path = build_path_from_dentry(file->f_path.dentry); |
281 | if (full_path == NULL) { | 242 | if (full_path == NULL) { |
@@ -299,8 +260,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
299 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); | 260 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); |
300 | oflags |= SMB_O_CREAT; | 261 | oflags |= SMB_O_CREAT; |
301 | /* can not refresh inode info since size could be stale */ | 262 | /* can not refresh inode info since size could be stale */ |
302 | rc = cifs_posix_open(full_path, &inode, file->f_path.mnt, | 263 | rc = cifs_posix_open(full_path, &inode, inode->i_sb, |
303 | inode->i_sb, | ||
304 | cifs_sb->mnt_file_mode /* ignored */, | 264 | cifs_sb->mnt_file_mode /* ignored */, |
305 | oflags, &oplock, &netfid, xid); | 265 | oflags, &oplock, &netfid, xid); |
306 | if (rc == 0) { | 266 | if (rc == 0) { |
@@ -308,9 +268,20 @@ int cifs_open(struct inode *inode, struct file *file) | |||
308 | /* no need for special case handling of setting mode | 268 | /* no need for special case handling of setting mode |
309 | on read only files needed here */ | 269 | on read only files needed here */ |
310 | 270 | ||
311 | pCifsFile = cifs_fill_filedata(file); | 271 | rc = cifs_posix_open_inode_helper(inode, file, |
312 | cifs_posix_open_inode_helper(inode, file, pCifsInode, | 272 | pCifsInode, oplock, netfid); |
313 | oplock, netfid); | 273 | if (rc != 0) { |
274 | CIFSSMBClose(xid, tcon, netfid); | ||
275 | goto out; | ||
276 | } | ||
277 | |||
278 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, | ||
279 | file->f_path.mnt, | ||
280 | oflags); | ||
281 | if (pCifsFile == NULL) { | ||
282 | CIFSSMBClose(xid, tcon, netfid); | ||
283 | rc = -ENOMEM; | ||
284 | } | ||
314 | goto out; | 285 | goto out; |
315 | } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | 286 | } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { |
316 | if (tcon->ses->serverNOS) | 287 | if (tcon->ses->serverNOS) |
@@ -391,17 +362,17 @@ int cifs_open(struct inode *inode, struct file *file) | |||
391 | goto out; | 362 | goto out; |
392 | } | 363 | } |
393 | 364 | ||
365 | rc = cifs_open_inode_helper(inode, tcon, &oplock, buf, full_path, xid); | ||
366 | if (rc != 0) | ||
367 | goto out; | ||
368 | |||
394 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, | 369 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, |
395 | file->f_flags); | 370 | file->f_flags); |
396 | file->private_data = pCifsFile; | 371 | if (pCifsFile == NULL) { |
397 | if (file->private_data == NULL) { | ||
398 | rc = -ENOMEM; | 372 | rc = -ENOMEM; |
399 | goto out; | 373 | goto out; |
400 | } | 374 | } |
401 | 375 | ||
402 | rc = cifs_open_inode_helper(inode, file, pCifsInode, pCifsFile, tcon, | ||
403 | &oplock, buf, full_path, xid); | ||
404 | |||
405 | if (oplock & CIFS_CREATE_ACTION) { | 376 | if (oplock & CIFS_CREATE_ACTION) { |
406 | /* time to set mode which we can not set earlier due to | 377 | /* time to set mode which we can not set earlier due to |
407 | problems creating new read-only files */ | 378 | problems creating new read-only files */ |
@@ -513,8 +484,7 @@ reopen_error_exit: | |||
513 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 484 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
514 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); | 485 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); |
515 | /* can not refresh inode info since size could be stale */ | 486 | /* can not refresh inode info since size could be stale */ |
516 | rc = cifs_posix_open(full_path, NULL, file->f_path.mnt, | 487 | rc = cifs_posix_open(full_path, NULL, inode->i_sb, |
517 | inode->i_sb, | ||
518 | cifs_sb->mnt_file_mode /* ignored */, | 488 | cifs_sb->mnt_file_mode /* ignored */, |
519 | oflags, &oplock, &netfid, xid); | 489 | oflags, &oplock, &netfid, xid); |
520 | if (rc == 0) { | 490 | if (rc == 0) { |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 62b324f26a56..6f0683c68952 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1401,6 +1401,10 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, | |||
1401 | if (rc == 0 || rc != -ETXTBSY) | 1401 | if (rc == 0 || rc != -ETXTBSY) |
1402 | return rc; | 1402 | return rc; |
1403 | 1403 | ||
1404 | /* open-file renames don't work across directories */ | ||
1405 | if (to_dentry->d_parent != from_dentry->d_parent) | ||
1406 | return rc; | ||
1407 | |||
1404 | /* open the file to be renamed -- we need DELETE perms */ | 1408 | /* open the file to be renamed -- we need DELETE perms */ |
1405 | rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, | 1409 | rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, |
1406 | CREATE_NOT_DIR, &srcfid, &oplock, NULL, | 1410 | CREATE_NOT_DIR, &srcfid, &oplock, NULL, |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 7707389bdf2c..0a57cb7db5dd 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -730,15 +730,7 @@ ssetup_ntlmssp_authenticate: | |||
730 | 730 | ||
731 | /* calculate session key */ | 731 | /* calculate session key */ |
732 | setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); | 732 | setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); |
733 | if (first_time) /* should this be moved into common code | 733 | /* FIXME: calculate MAC key */ |
734 | with similar ntlmv2 path? */ | ||
735 | /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key, | ||
736 | response BB FIXME, v2_sess_key); */ | ||
737 | |||
738 | /* copy session key */ | ||
739 | |||
740 | /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE); | ||
741 | bcc_ptr += LM2_SESS_KEY_SIZE; */ | ||
742 | memcpy(bcc_ptr, (char *)v2_sess_key, | 734 | memcpy(bcc_ptr, (char *)v2_sess_key, |
743 | sizeof(struct ntlmv2_resp)); | 735 | sizeof(struct ntlmv2_resp)); |
744 | bcc_ptr += sizeof(struct ntlmv2_resp); | 736 | bcc_ptr += sizeof(struct ntlmv2_resp); |
diff --git a/fs/dcache.c b/fs/dcache.c index d96047b4a633..c8c78ba07827 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -590,6 +590,8 @@ static void prune_dcache(int count) | |||
590 | up_read(&sb->s_umount); | 590 | up_read(&sb->s_umount); |
591 | } | 591 | } |
592 | spin_lock(&sb_lock); | 592 | spin_lock(&sb_lock); |
593 | /* lock was dropped, must reset next */ | ||
594 | list_safe_reset_next(sb, n, s_list); | ||
593 | count -= pruned; | 595 | count -= pruned; |
594 | __put_super(sb); | 596 | __put_super(sb); |
595 | /* more work left to do? */ | 597 | /* more work left to do? */ |
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index ca7e2a0ed98a..2bcc0431bada 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
@@ -200,6 +200,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
200 | return error; | 200 | return error; |
201 | else { | 201 | else { |
202 | inode->i_mode = mode; | 202 | inode->i_mode = mode; |
203 | inode->i_ctime = CURRENT_TIME_SEC; | ||
203 | mark_inode_dirty(inode); | 204 | mark_inode_dirty(inode); |
204 | if (error == 0) | 205 | if (error == 0) |
205 | acl = NULL; | 206 | acl = NULL; |
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 01552abbca3c..8a11fe212183 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
@@ -205,6 +205,7 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, | |||
205 | return error; | 205 | return error; |
206 | else { | 206 | else { |
207 | inode->i_mode = mode; | 207 | inode->i_mode = mode; |
208 | inode->i_ctime = CURRENT_TIME_SEC; | ||
208 | ext3_mark_inode_dirty(handle, inode); | 209 | ext3_mark_inode_dirty(handle, inode); |
209 | if (error == 0) | 210 | if (error == 0) |
210 | acl = NULL; | 211 | acl = NULL; |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 51e11bf5708f..9d175d623aab 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -733,12 +733,14 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band) | |||
733 | { | 733 | { |
734 | while (fa) { | 734 | while (fa) { |
735 | struct fown_struct *fown; | 735 | struct fown_struct *fown; |
736 | unsigned long flags; | ||
737 | |||
736 | if (fa->magic != FASYNC_MAGIC) { | 738 | if (fa->magic != FASYNC_MAGIC) { |
737 | printk(KERN_ERR "kill_fasync: bad magic number in " | 739 | printk(KERN_ERR "kill_fasync: bad magic number in " |
738 | "fasync_struct!\n"); | 740 | "fasync_struct!\n"); |
739 | return; | 741 | return; |
740 | } | 742 | } |
741 | spin_lock(&fa->fa_lock); | 743 | spin_lock_irqsave(&fa->fa_lock, flags); |
742 | if (fa->fa_file) { | 744 | if (fa->fa_file) { |
743 | fown = &fa->fa_file->f_owner; | 745 | fown = &fa->fa_file->f_owner; |
744 | /* Don't send SIGURG to processes which have not set a | 746 | /* Don't send SIGURG to processes which have not set a |
@@ -747,7 +749,7 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band) | |||
747 | if (!(sig == SIGURG && fown->signum == 0)) | 749 | if (!(sig == SIGURG && fown->signum == 0)) |
748 | send_sigio(fown, fa->fa_fd, band); | 750 | send_sigio(fown, fa->fa_fd, band); |
749 | } | 751 | } |
750 | spin_unlock(&fa->fa_lock); | 752 | spin_unlock_irqrestore(&fa->fa_lock, flags); |
751 | fa = rcu_dereference(fa->fa_next); | 753 | fa = rcu_dereference(fa->fa_next); |
752 | } | 754 | } |
753 | } | 755 | } |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index af92100a7411..0609607d3955 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -63,45 +63,16 @@ struct bdi_work { | |||
63 | }; | 63 | }; |
64 | 64 | ||
65 | enum { | 65 | enum { |
66 | WS_USED_B = 0, | 66 | WS_INPROGRESS = 0, |
67 | WS_ONSTACK_B, | 67 | WS_ONSTACK, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | #define WS_USED (1 << WS_USED_B) | ||
71 | #define WS_ONSTACK (1 << WS_ONSTACK_B) | ||
72 | |||
73 | static inline bool bdi_work_on_stack(struct bdi_work *work) | ||
74 | { | ||
75 | return test_bit(WS_ONSTACK_B, &work->state); | ||
76 | } | ||
77 | |||
78 | static inline void __bdi_work_init(struct bdi_work *work, | ||
79 | struct wb_writeback_args *args, | ||
80 | int on_stack) | ||
81 | { | ||
82 | work->args = *args; | ||
83 | work->state = WS_USED; | ||
84 | if (on_stack) { | ||
85 | work->state |= WS_ONSTACK; | ||
86 | init_rcu_head_on_stack(&work->rcu_head); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | static inline void bdi_work_init(struct bdi_work *work, | 70 | static inline void bdi_work_init(struct bdi_work *work, |
91 | struct wb_writeback_args *args) | 71 | struct wb_writeback_args *args) |
92 | { | 72 | { |
93 | __bdi_work_init(work, args, false); | 73 | INIT_RCU_HEAD(&work->rcu_head); |
94 | } | 74 | work->args = *args; |
95 | 75 | __set_bit(WS_INPROGRESS, &work->state); | |
96 | static inline void bdi_work_init_on_stack(struct bdi_work *work, | ||
97 | struct wb_writeback_args *args) | ||
98 | { | ||
99 | __bdi_work_init(work, args, true); | ||
100 | } | ||
101 | |||
102 | static inline void bdi_destroy_work_on_stack(struct bdi_work *work) | ||
103 | { | ||
104 | destroy_rcu_head_on_stack(&work->rcu_head); | ||
105 | } | 76 | } |
106 | 77 | ||
107 | /** | 78 | /** |
@@ -116,43 +87,16 @@ int writeback_in_progress(struct backing_dev_info *bdi) | |||
116 | return !list_empty(&bdi->work_list); | 87 | return !list_empty(&bdi->work_list); |
117 | } | 88 | } |
118 | 89 | ||
119 | static void bdi_work_clear(struct bdi_work *work) | ||
120 | { | ||
121 | clear_bit(WS_USED_B, &work->state); | ||
122 | smp_mb__after_clear_bit(); | ||
123 | /* | ||
124 | * work can have disappeared at this point. bit waitq functions | ||
125 | * should be able to tolerate this, provided bdi_sched_wait does | ||
126 | * not dereference it's pointer argument. | ||
127 | */ | ||
128 | wake_up_bit(&work->state, WS_USED_B); | ||
129 | } | ||
130 | |||
131 | static void bdi_work_free(struct rcu_head *head) | 90 | static void bdi_work_free(struct rcu_head *head) |
132 | { | 91 | { |
133 | struct bdi_work *work = container_of(head, struct bdi_work, rcu_head); | 92 | struct bdi_work *work = container_of(head, struct bdi_work, rcu_head); |
134 | 93 | ||
135 | if (!bdi_work_on_stack(work)) | 94 | clear_bit(WS_INPROGRESS, &work->state); |
136 | kfree(work); | 95 | smp_mb__after_clear_bit(); |
137 | else | 96 | wake_up_bit(&work->state, WS_INPROGRESS); |
138 | bdi_work_clear(work); | ||
139 | } | ||
140 | |||
141 | static void wb_work_complete(struct bdi_work *work) | ||
142 | { | ||
143 | const enum writeback_sync_modes sync_mode = work->args.sync_mode; | ||
144 | int onstack = bdi_work_on_stack(work); | ||
145 | 97 | ||
146 | /* | 98 | if (!test_bit(WS_ONSTACK, &work->state)) |
147 | * For allocated work, we can clear the done/seen bit right here. | 99 | kfree(work); |
148 | * For on-stack work, we need to postpone both the clear and free | ||
149 | * to after the RCU grace period, since the stack could be invalidated | ||
150 | * as soon as bdi_work_clear() has done the wakeup. | ||
151 | */ | ||
152 | if (!onstack) | ||
153 | bdi_work_clear(work); | ||
154 | if (sync_mode == WB_SYNC_NONE || onstack) | ||
155 | call_rcu(&work->rcu_head, bdi_work_free); | ||
156 | } | 100 | } |
157 | 101 | ||
158 | static void wb_clear_pending(struct bdi_writeback *wb, struct bdi_work *work) | 102 | static void wb_clear_pending(struct bdi_writeback *wb, struct bdi_work *work) |
@@ -168,7 +112,7 @@ static void wb_clear_pending(struct bdi_writeback *wb, struct bdi_work *work) | |||
168 | list_del_rcu(&work->list); | 112 | list_del_rcu(&work->list); |
169 | spin_unlock(&bdi->wb_lock); | 113 | spin_unlock(&bdi->wb_lock); |
170 | 114 | ||
171 | wb_work_complete(work); | 115 | call_rcu(&work->rcu_head, bdi_work_free); |
172 | } | 116 | } |
173 | } | 117 | } |
174 | 118 | ||
@@ -206,9 +150,9 @@ static void bdi_queue_work(struct backing_dev_info *bdi, struct bdi_work *work) | |||
206 | * Used for on-stack allocated work items. The caller needs to wait until | 150 | * Used for on-stack allocated work items. The caller needs to wait until |
207 | * the wb threads have acked the work before it's safe to continue. | 151 | * the wb threads have acked the work before it's safe to continue. |
208 | */ | 152 | */ |
209 | static void bdi_wait_on_work_clear(struct bdi_work *work) | 153 | static void bdi_wait_on_work_done(struct bdi_work *work) |
210 | { | 154 | { |
211 | wait_on_bit(&work->state, WS_USED_B, bdi_sched_wait, | 155 | wait_on_bit(&work->state, WS_INPROGRESS, bdi_sched_wait, |
212 | TASK_UNINTERRUPTIBLE); | 156 | TASK_UNINTERRUPTIBLE); |
213 | } | 157 | } |
214 | 158 | ||
@@ -234,37 +178,28 @@ static void bdi_alloc_queue_work(struct backing_dev_info *bdi, | |||
234 | } | 178 | } |
235 | 179 | ||
236 | /** | 180 | /** |
237 | * bdi_sync_writeback - start and wait for writeback | 181 | * bdi_queue_work_onstack - start and wait for writeback |
238 | * @bdi: the backing device to write from | ||
239 | * @sb: write inodes from this super_block | 182 | * @sb: write inodes from this super_block |
240 | * | 183 | * |
241 | * Description: | 184 | * Description: |
242 | * This does WB_SYNC_ALL data integrity writeback and waits for the | 185 | * This function initiates writeback and waits for the operation to |
243 | * IO to complete. Callers must hold the sb s_umount semaphore for | 186 | * complete. Callers must hold the sb s_umount semaphore for |
244 | * reading, to avoid having the super disappear before we are done. | 187 | * reading, to avoid having the super disappear before we are done. |
245 | */ | 188 | */ |
246 | static void bdi_sync_writeback(struct backing_dev_info *bdi, | 189 | static void bdi_queue_work_onstack(struct wb_writeback_args *args) |
247 | struct super_block *sb) | ||
248 | { | 190 | { |
249 | struct wb_writeback_args args = { | ||
250 | .sb = sb, | ||
251 | .sync_mode = WB_SYNC_ALL, | ||
252 | .nr_pages = LONG_MAX, | ||
253 | .range_cyclic = 0, | ||
254 | }; | ||
255 | struct bdi_work work; | 191 | struct bdi_work work; |
256 | 192 | ||
257 | bdi_work_init_on_stack(&work, &args); | 193 | bdi_work_init(&work, args); |
194 | __set_bit(WS_ONSTACK, &work.state); | ||
258 | 195 | ||
259 | bdi_queue_work(bdi, &work); | 196 | bdi_queue_work(args->sb->s_bdi, &work); |
260 | bdi_wait_on_work_clear(&work); | 197 | bdi_wait_on_work_done(&work); |
261 | bdi_destroy_work_on_stack(&work); | ||
262 | } | 198 | } |
263 | 199 | ||
264 | /** | 200 | /** |
265 | * bdi_start_writeback - start writeback | 201 | * bdi_start_writeback - start writeback |
266 | * @bdi: the backing device to write from | 202 | * @bdi: the backing device to write from |
267 | * @sb: write inodes from this super_block | ||
268 | * @nr_pages: the number of pages to write | 203 | * @nr_pages: the number of pages to write |
269 | * | 204 | * |
270 | * Description: | 205 | * Description: |
@@ -273,25 +208,34 @@ static void bdi_sync_writeback(struct backing_dev_info *bdi, | |||
273 | * completion. Caller need not hold sb s_umount semaphore. | 208 | * completion. Caller need not hold sb s_umount semaphore. |
274 | * | 209 | * |
275 | */ | 210 | */ |
276 | void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, | 211 | void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages) |
277 | long nr_pages) | ||
278 | { | 212 | { |
279 | struct wb_writeback_args args = { | 213 | struct wb_writeback_args args = { |
280 | .sb = sb, | ||
281 | .sync_mode = WB_SYNC_NONE, | 214 | .sync_mode = WB_SYNC_NONE, |
282 | .nr_pages = nr_pages, | 215 | .nr_pages = nr_pages, |
283 | .range_cyclic = 1, | 216 | .range_cyclic = 1, |
284 | }; | 217 | }; |
285 | 218 | ||
286 | /* | 219 | bdi_alloc_queue_work(bdi, &args); |
287 | * We treat @nr_pages=0 as the special case to do background writeback, | 220 | } |
288 | * ie. to sync pages until the background dirty threshold is reached. | ||
289 | */ | ||
290 | if (!nr_pages) { | ||
291 | args.nr_pages = LONG_MAX; | ||
292 | args.for_background = 1; | ||
293 | } | ||
294 | 221 | ||
222 | /** | ||
223 | * bdi_start_background_writeback - start background writeback | ||
224 | * @bdi: the backing device to write from | ||
225 | * | ||
226 | * Description: | ||
227 | * This does WB_SYNC_NONE background writeback. The IO is only | ||
228 | * started when this function returns, we make no guarentees on | ||
229 | * completion. Caller need not hold sb s_umount semaphore. | ||
230 | */ | ||
231 | void bdi_start_background_writeback(struct backing_dev_info *bdi) | ||
232 | { | ||
233 | struct wb_writeback_args args = { | ||
234 | .sync_mode = WB_SYNC_NONE, | ||
235 | .nr_pages = LONG_MAX, | ||
236 | .for_background = 1, | ||
237 | .range_cyclic = 1, | ||
238 | }; | ||
295 | bdi_alloc_queue_work(bdi, &args); | 239 | bdi_alloc_queue_work(bdi, &args); |
296 | } | 240 | } |
297 | 241 | ||
@@ -582,48 +526,30 @@ select_queue: | |||
582 | return ret; | 526 | return ret; |
583 | } | 527 | } |
584 | 528 | ||
585 | static void unpin_sb_for_writeback(struct super_block *sb) | ||
586 | { | ||
587 | up_read(&sb->s_umount); | ||
588 | put_super(sb); | ||
589 | } | ||
590 | |||
591 | enum sb_pin_state { | ||
592 | SB_PINNED, | ||
593 | SB_NOT_PINNED, | ||
594 | SB_PIN_FAILED | ||
595 | }; | ||
596 | |||
597 | /* | 529 | /* |
598 | * For WB_SYNC_NONE writeback, the caller does not have the sb pinned | 530 | * For background writeback the caller does not have the sb pinned |
599 | * before calling writeback. So make sure that we do pin it, so it doesn't | 531 | * before calling writeback. So make sure that we do pin it, so it doesn't |
600 | * go away while we are writing inodes from it. | 532 | * go away while we are writing inodes from it. |
601 | */ | 533 | */ |
602 | static enum sb_pin_state pin_sb_for_writeback(struct writeback_control *wbc, | 534 | static bool pin_sb_for_writeback(struct super_block *sb) |
603 | struct super_block *sb) | ||
604 | { | 535 | { |
605 | /* | ||
606 | * Caller must already hold the ref for this | ||
607 | */ | ||
608 | if (wbc->sync_mode == WB_SYNC_ALL) { | ||
609 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); | ||
610 | return SB_NOT_PINNED; | ||
611 | } | ||
612 | spin_lock(&sb_lock); | 536 | spin_lock(&sb_lock); |
537 | if (list_empty(&sb->s_instances)) { | ||
538 | spin_unlock(&sb_lock); | ||
539 | return false; | ||
540 | } | ||
541 | |||
613 | sb->s_count++; | 542 | sb->s_count++; |
543 | spin_unlock(&sb_lock); | ||
544 | |||
614 | if (down_read_trylock(&sb->s_umount)) { | 545 | if (down_read_trylock(&sb->s_umount)) { |
615 | if (sb->s_root) { | 546 | if (sb->s_root) |
616 | spin_unlock(&sb_lock); | 547 | return true; |
617 | return SB_PINNED; | ||
618 | } | ||
619 | /* | ||
620 | * umounted, drop rwsem again and fall through to failure | ||
621 | */ | ||
622 | up_read(&sb->s_umount); | 548 | up_read(&sb->s_umount); |
623 | } | 549 | } |
624 | sb->s_count--; | 550 | |
625 | spin_unlock(&sb_lock); | 551 | put_super(sb); |
626 | return SB_PIN_FAILED; | 552 | return false; |
627 | } | 553 | } |
628 | 554 | ||
629 | /* | 555 | /* |
@@ -702,24 +628,31 @@ static void writeback_inodes_wb(struct bdi_writeback *wb, | |||
702 | struct inode *inode = list_entry(wb->b_io.prev, | 628 | struct inode *inode = list_entry(wb->b_io.prev, |
703 | struct inode, i_list); | 629 | struct inode, i_list); |
704 | struct super_block *sb = inode->i_sb; | 630 | struct super_block *sb = inode->i_sb; |
705 | enum sb_pin_state state; | ||
706 | 631 | ||
707 | if (wbc->sb && sb != wbc->sb) { | 632 | if (wbc->sb) { |
708 | /* super block given and doesn't | 633 | /* |
709 | match, skip this inode */ | 634 | * We are requested to write out inodes for a specific |
710 | redirty_tail(inode); | 635 | * superblock. This means we already have s_umount |
711 | continue; | 636 | * taken by the caller which also waits for us to |
712 | } | 637 | * complete the writeout. |
713 | state = pin_sb_for_writeback(wbc, sb); | 638 | */ |
639 | if (sb != wbc->sb) { | ||
640 | redirty_tail(inode); | ||
641 | continue; | ||
642 | } | ||
714 | 643 | ||
715 | if (state == SB_PIN_FAILED) { | 644 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); |
716 | requeue_io(inode); | 645 | |
717 | continue; | 646 | ret = writeback_sb_inodes(sb, wb, wbc); |
647 | } else { | ||
648 | if (!pin_sb_for_writeback(sb)) { | ||
649 | requeue_io(inode); | ||
650 | continue; | ||
651 | } | ||
652 | ret = writeback_sb_inodes(sb, wb, wbc); | ||
653 | drop_super(sb); | ||
718 | } | 654 | } |
719 | ret = writeback_sb_inodes(sb, wb, wbc); | ||
720 | 655 | ||
721 | if (state == SB_PINNED) | ||
722 | unpin_sb_for_writeback(sb); | ||
723 | if (ret) | 656 | if (ret) |
724 | break; | 657 | break; |
725 | } | 658 | } |
@@ -932,7 +865,7 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
932 | * If this isn't a data integrity operation, just notify | 865 | * If this isn't a data integrity operation, just notify |
933 | * that we have seen this work and we are now starting it. | 866 | * that we have seen this work and we are now starting it. |
934 | */ | 867 | */ |
935 | if (args.sync_mode == WB_SYNC_NONE) | 868 | if (!test_bit(WS_ONSTACK, &work->state)) |
936 | wb_clear_pending(wb, work); | 869 | wb_clear_pending(wb, work); |
937 | 870 | ||
938 | wrote += wb_writeback(wb, &args); | 871 | wrote += wb_writeback(wb, &args); |
@@ -941,7 +874,7 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait) | |||
941 | * This is a data integrity writeback, so only do the | 874 | * This is a data integrity writeback, so only do the |
942 | * notification when we have completed the work. | 875 | * notification when we have completed the work. |
943 | */ | 876 | */ |
944 | if (args.sync_mode == WB_SYNC_ALL) | 877 | if (test_bit(WS_ONSTACK, &work->state)) |
945 | wb_clear_pending(wb, work); | 878 | wb_clear_pending(wb, work); |
946 | } | 879 | } |
947 | 880 | ||
@@ -999,42 +932,32 @@ int bdi_writeback_task(struct bdi_writeback *wb) | |||
999 | } | 932 | } |
1000 | 933 | ||
1001 | /* | 934 | /* |
1002 | * Schedule writeback for all backing devices. This does WB_SYNC_NONE | 935 | * Start writeback of `nr_pages' pages. If `nr_pages' is zero, write back |
1003 | * writeback, for integrity writeback see bdi_sync_writeback(). | 936 | * the whole world. |
1004 | */ | 937 | */ |
1005 | static void bdi_writeback_all(struct super_block *sb, long nr_pages) | 938 | void wakeup_flusher_threads(long nr_pages) |
1006 | { | 939 | { |
940 | struct backing_dev_info *bdi; | ||
1007 | struct wb_writeback_args args = { | 941 | struct wb_writeback_args args = { |
1008 | .sb = sb, | ||
1009 | .nr_pages = nr_pages, | ||
1010 | .sync_mode = WB_SYNC_NONE, | 942 | .sync_mode = WB_SYNC_NONE, |
1011 | }; | 943 | }; |
1012 | struct backing_dev_info *bdi; | ||
1013 | 944 | ||
1014 | rcu_read_lock(); | 945 | if (nr_pages) { |
946 | args.nr_pages = nr_pages; | ||
947 | } else { | ||
948 | args.nr_pages = global_page_state(NR_FILE_DIRTY) + | ||
949 | global_page_state(NR_UNSTABLE_NFS); | ||
950 | } | ||
1015 | 951 | ||
952 | rcu_read_lock(); | ||
1016 | list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) { | 953 | list_for_each_entry_rcu(bdi, &bdi_list, bdi_list) { |
1017 | if (!bdi_has_dirty_io(bdi)) | 954 | if (!bdi_has_dirty_io(bdi)) |
1018 | continue; | 955 | continue; |
1019 | |||
1020 | bdi_alloc_queue_work(bdi, &args); | 956 | bdi_alloc_queue_work(bdi, &args); |
1021 | } | 957 | } |
1022 | |||
1023 | rcu_read_unlock(); | 958 | rcu_read_unlock(); |
1024 | } | 959 | } |
1025 | 960 | ||
1026 | /* | ||
1027 | * Start writeback of `nr_pages' pages. If `nr_pages' is zero, write back | ||
1028 | * the whole world. | ||
1029 | */ | ||
1030 | void wakeup_flusher_threads(long nr_pages) | ||
1031 | { | ||
1032 | if (nr_pages == 0) | ||
1033 | nr_pages = global_page_state(NR_FILE_DIRTY) + | ||
1034 | global_page_state(NR_UNSTABLE_NFS); | ||
1035 | bdi_writeback_all(NULL, nr_pages); | ||
1036 | } | ||
1037 | |||
1038 | static noinline void block_dump___mark_inode_dirty(struct inode *inode) | 961 | static noinline void block_dump___mark_inode_dirty(struct inode *inode) |
1039 | { | 962 | { |
1040 | if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) { | 963 | if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) { |
@@ -1239,12 +1162,17 @@ void writeback_inodes_sb(struct super_block *sb) | |||
1239 | { | 1162 | { |
1240 | unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); | 1163 | unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); |
1241 | unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); | 1164 | unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); |
1242 | long nr_to_write; | 1165 | struct wb_writeback_args args = { |
1166 | .sb = sb, | ||
1167 | .sync_mode = WB_SYNC_NONE, | ||
1168 | }; | ||
1243 | 1169 | ||
1244 | nr_to_write = nr_dirty + nr_unstable + | 1170 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); |
1171 | |||
1172 | args.nr_pages = nr_dirty + nr_unstable + | ||
1245 | (inodes_stat.nr_inodes - inodes_stat.nr_unused); | 1173 | (inodes_stat.nr_inodes - inodes_stat.nr_unused); |
1246 | 1174 | ||
1247 | bdi_start_writeback(sb->s_bdi, sb, nr_to_write); | 1175 | bdi_queue_work_onstack(&args); |
1248 | } | 1176 | } |
1249 | EXPORT_SYMBOL(writeback_inodes_sb); | 1177 | EXPORT_SYMBOL(writeback_inodes_sb); |
1250 | 1178 | ||
@@ -1258,7 +1186,9 @@ EXPORT_SYMBOL(writeback_inodes_sb); | |||
1258 | int writeback_inodes_sb_if_idle(struct super_block *sb) | 1186 | int writeback_inodes_sb_if_idle(struct super_block *sb) |
1259 | { | 1187 | { |
1260 | if (!writeback_in_progress(sb->s_bdi)) { | 1188 | if (!writeback_in_progress(sb->s_bdi)) { |
1189 | down_read(&sb->s_umount); | ||
1261 | writeback_inodes_sb(sb); | 1190 | writeback_inodes_sb(sb); |
1191 | up_read(&sb->s_umount); | ||
1262 | return 1; | 1192 | return 1; |
1263 | } else | 1193 | } else |
1264 | return 0; | 1194 | return 0; |
@@ -1274,7 +1204,16 @@ EXPORT_SYMBOL(writeback_inodes_sb_if_idle); | |||
1274 | */ | 1204 | */ |
1275 | void sync_inodes_sb(struct super_block *sb) | 1205 | void sync_inodes_sb(struct super_block *sb) |
1276 | { | 1206 | { |
1277 | bdi_sync_writeback(sb->s_bdi, sb); | 1207 | struct wb_writeback_args args = { |
1208 | .sb = sb, | ||
1209 | .sync_mode = WB_SYNC_ALL, | ||
1210 | .nr_pages = LONG_MAX, | ||
1211 | .range_cyclic = 0, | ||
1212 | }; | ||
1213 | |||
1214 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); | ||
1215 | |||
1216 | bdi_queue_work_onstack(&args); | ||
1278 | wait_sb_inodes(sb); | 1217 | wait_sb_inodes(sb); |
1279 | } | 1218 | } |
1280 | EXPORT_SYMBOL(sync_inodes_sb); | 1219 | EXPORT_SYMBOL(sync_inodes_sb); |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 7ec9b34a59f8..d25b5257b7a1 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -1286,6 +1286,55 @@ static void nfs4_session_set_rwsize(struct nfs_server *server) | |||
1286 | #endif /* CONFIG_NFS_V4_1 */ | 1286 | #endif /* CONFIG_NFS_V4_1 */ |
1287 | } | 1287 | } |
1288 | 1288 | ||
1289 | static int nfs4_server_common_setup(struct nfs_server *server, | ||
1290 | struct nfs_fh *mntfh) | ||
1291 | { | ||
1292 | struct nfs_fattr *fattr; | ||
1293 | int error; | ||
1294 | |||
1295 | BUG_ON(!server->nfs_client); | ||
1296 | BUG_ON(!server->nfs_client->rpc_ops); | ||
1297 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | ||
1298 | |||
1299 | fattr = nfs_alloc_fattr(); | ||
1300 | if (fattr == NULL) | ||
1301 | return -ENOMEM; | ||
1302 | |||
1303 | /* We must ensure the session is initialised first */ | ||
1304 | error = nfs4_init_session(server); | ||
1305 | if (error < 0) | ||
1306 | goto out; | ||
1307 | |||
1308 | /* Probe the root fh to retrieve its FSID and filehandle */ | ||
1309 | error = nfs4_get_rootfh(server, mntfh); | ||
1310 | if (error < 0) | ||
1311 | goto out; | ||
1312 | |||
1313 | dprintk("Server FSID: %llx:%llx\n", | ||
1314 | (unsigned long long) server->fsid.major, | ||
1315 | (unsigned long long) server->fsid.minor); | ||
1316 | dprintk("Mount FH: %d\n", mntfh->size); | ||
1317 | |||
1318 | nfs4_session_set_rwsize(server); | ||
1319 | |||
1320 | error = nfs_probe_fsinfo(server, mntfh, fattr); | ||
1321 | if (error < 0) | ||
1322 | goto out; | ||
1323 | |||
1324 | if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) | ||
1325 | server->namelen = NFS4_MAXNAMLEN; | ||
1326 | |||
1327 | spin_lock(&nfs_client_lock); | ||
1328 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
1329 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
1330 | spin_unlock(&nfs_client_lock); | ||
1331 | |||
1332 | server->mount_time = jiffies; | ||
1333 | out: | ||
1334 | nfs_free_fattr(fattr); | ||
1335 | return error; | ||
1336 | } | ||
1337 | |||
1289 | /* | 1338 | /* |
1290 | * Create a version 4 volume record | 1339 | * Create a version 4 volume record |
1291 | */ | 1340 | */ |
@@ -1346,7 +1395,6 @@ error: | |||
1346 | struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, | 1395 | struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, |
1347 | struct nfs_fh *mntfh) | 1396 | struct nfs_fh *mntfh) |
1348 | { | 1397 | { |
1349 | struct nfs_fattr *fattr; | ||
1350 | struct nfs_server *server; | 1398 | struct nfs_server *server; |
1351 | int error; | 1399 | int error; |
1352 | 1400 | ||
@@ -1356,55 +1404,19 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, | |||
1356 | if (!server) | 1404 | if (!server) |
1357 | return ERR_PTR(-ENOMEM); | 1405 | return ERR_PTR(-ENOMEM); |
1358 | 1406 | ||
1359 | error = -ENOMEM; | ||
1360 | fattr = nfs_alloc_fattr(); | ||
1361 | if (fattr == NULL) | ||
1362 | goto error; | ||
1363 | |||
1364 | /* set up the general RPC client */ | 1407 | /* set up the general RPC client */ |
1365 | error = nfs4_init_server(server, data); | 1408 | error = nfs4_init_server(server, data); |
1366 | if (error < 0) | 1409 | if (error < 0) |
1367 | goto error; | 1410 | goto error; |
1368 | 1411 | ||
1369 | BUG_ON(!server->nfs_client); | 1412 | error = nfs4_server_common_setup(server, mntfh); |
1370 | BUG_ON(!server->nfs_client->rpc_ops); | ||
1371 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | ||
1372 | |||
1373 | error = nfs4_init_session(server); | ||
1374 | if (error < 0) | ||
1375 | goto error; | ||
1376 | |||
1377 | /* Probe the root fh to retrieve its FSID */ | ||
1378 | error = nfs4_get_rootfh(server, mntfh); | ||
1379 | if (error < 0) | 1413 | if (error < 0) |
1380 | goto error; | 1414 | goto error; |
1381 | 1415 | ||
1382 | dprintk("Server FSID: %llx:%llx\n", | ||
1383 | (unsigned long long) server->fsid.major, | ||
1384 | (unsigned long long) server->fsid.minor); | ||
1385 | dprintk("Mount FH: %d\n", mntfh->size); | ||
1386 | |||
1387 | nfs4_session_set_rwsize(server); | ||
1388 | |||
1389 | error = nfs_probe_fsinfo(server, mntfh, fattr); | ||
1390 | if (error < 0) | ||
1391 | goto error; | ||
1392 | |||
1393 | if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) | ||
1394 | server->namelen = NFS4_MAXNAMLEN; | ||
1395 | |||
1396 | spin_lock(&nfs_client_lock); | ||
1397 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
1398 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
1399 | spin_unlock(&nfs_client_lock); | ||
1400 | |||
1401 | server->mount_time = jiffies; | ||
1402 | dprintk("<-- nfs4_create_server() = %p\n", server); | 1416 | dprintk("<-- nfs4_create_server() = %p\n", server); |
1403 | nfs_free_fattr(fattr); | ||
1404 | return server; | 1417 | return server; |
1405 | 1418 | ||
1406 | error: | 1419 | error: |
1407 | nfs_free_fattr(fattr); | ||
1408 | nfs_free_server(server); | 1420 | nfs_free_server(server); |
1409 | dprintk("<-- nfs4_create_server() = error %d\n", error); | 1421 | dprintk("<-- nfs4_create_server() = error %d\n", error); |
1410 | return ERR_PTR(error); | 1422 | return ERR_PTR(error); |
@@ -1418,7 +1430,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, | |||
1418 | { | 1430 | { |
1419 | struct nfs_client *parent_client; | 1431 | struct nfs_client *parent_client; |
1420 | struct nfs_server *server, *parent_server; | 1432 | struct nfs_server *server, *parent_server; |
1421 | struct nfs_fattr *fattr; | ||
1422 | int error; | 1433 | int error; |
1423 | 1434 | ||
1424 | dprintk("--> nfs4_create_referral_server()\n"); | 1435 | dprintk("--> nfs4_create_referral_server()\n"); |
@@ -1427,11 +1438,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, | |||
1427 | if (!server) | 1438 | if (!server) |
1428 | return ERR_PTR(-ENOMEM); | 1439 | return ERR_PTR(-ENOMEM); |
1429 | 1440 | ||
1430 | error = -ENOMEM; | ||
1431 | fattr = nfs_alloc_fattr(); | ||
1432 | if (fattr == NULL) | ||
1433 | goto error; | ||
1434 | |||
1435 | parent_server = NFS_SB(data->sb); | 1441 | parent_server = NFS_SB(data->sb); |
1436 | parent_client = parent_server->nfs_client; | 1442 | parent_client = parent_server->nfs_client; |
1437 | 1443 | ||
@@ -1456,40 +1462,14 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, | |||
1456 | if (error < 0) | 1462 | if (error < 0) |
1457 | goto error; | 1463 | goto error; |
1458 | 1464 | ||
1459 | BUG_ON(!server->nfs_client); | 1465 | error = nfs4_server_common_setup(server, mntfh); |
1460 | BUG_ON(!server->nfs_client->rpc_ops); | ||
1461 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | ||
1462 | |||
1463 | /* Probe the root fh to retrieve its FSID and filehandle */ | ||
1464 | error = nfs4_get_rootfh(server, mntfh); | ||
1465 | if (error < 0) | ||
1466 | goto error; | ||
1467 | |||
1468 | /* probe the filesystem info for this server filesystem */ | ||
1469 | error = nfs_probe_fsinfo(server, mntfh, fattr); | ||
1470 | if (error < 0) | 1466 | if (error < 0) |
1471 | goto error; | 1467 | goto error; |
1472 | 1468 | ||
1473 | if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) | ||
1474 | server->namelen = NFS4_MAXNAMLEN; | ||
1475 | |||
1476 | dprintk("Referral FSID: %llx:%llx\n", | ||
1477 | (unsigned long long) server->fsid.major, | ||
1478 | (unsigned long long) server->fsid.minor); | ||
1479 | |||
1480 | spin_lock(&nfs_client_lock); | ||
1481 | list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); | ||
1482 | list_add_tail(&server->master_link, &nfs_volume_list); | ||
1483 | spin_unlock(&nfs_client_lock); | ||
1484 | |||
1485 | server->mount_time = jiffies; | ||
1486 | |||
1487 | nfs_free_fattr(fattr); | ||
1488 | dprintk("<-- nfs_create_referral_server() = %p\n", server); | 1469 | dprintk("<-- nfs_create_referral_server() = %p\n", server); |
1489 | return server; | 1470 | return server; |
1490 | 1471 | ||
1491 | error: | 1472 | error: |
1492 | nfs_free_fattr(fattr); | ||
1493 | nfs_free_server(server); | 1473 | nfs_free_server(server); |
1494 | dprintk("<-- nfs4_create_referral_server() = error %d\n", error); | 1474 | dprintk("<-- nfs4_create_referral_server() = error %d\n", error); |
1495 | return ERR_PTR(error); | 1475 | return ERR_PTR(error); |
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 7428f7d6273b..a70e446e1605 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c | |||
@@ -146,7 +146,7 @@ int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh) | |||
146 | goto out; | 146 | goto out; |
147 | } | 147 | } |
148 | 148 | ||
149 | if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_MODE) | 149 | if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_TYPE) |
150 | || !S_ISDIR(fsinfo.fattr->mode)) { | 150 | || !S_ISDIR(fsinfo.fattr->mode)) { |
151 | printk(KERN_ERR "nfs4_get_rootfh:" | 151 | printk(KERN_ERR "nfs4_get_rootfh:" |
152 | " getroot encountered non-directory\n"); | 152 | " getroot encountered non-directory\n"); |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 6bdef28efa33..65c8dae4b267 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -862,8 +862,8 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const | |||
862 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; | 862 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; |
863 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); | 863 | *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); |
864 | *p++ = cpu_to_be32(0); | 864 | *p++ = cpu_to_be32(0); |
865 | *p++ = cpu_to_be32(iap->ia_mtime.tv_sec); | 865 | *p++ = cpu_to_be32(iap->ia_atime.tv_sec); |
866 | *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec); | 866 | *p++ = cpu_to_be32(iap->ia_atime.tv_nsec); |
867 | } | 867 | } |
868 | else if (iap->ia_valid & ATTR_ATIME) { | 868 | else if (iap->ia_valid & ATTR_ATIME) { |
869 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; | 869 | bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 04214fc5c304..f9df16de4a56 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -570,6 +570,22 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, | |||
570 | nfs_show_mountd_netid(m, nfss, showdefaults); | 570 | nfs_show_mountd_netid(m, nfss, showdefaults); |
571 | } | 571 | } |
572 | 572 | ||
573 | #ifdef CONFIG_NFS_V4 | ||
574 | static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss, | ||
575 | int showdefaults) | ||
576 | { | ||
577 | struct nfs_client *clp = nfss->nfs_client; | ||
578 | |||
579 | seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr); | ||
580 | seq_printf(m, ",minorversion=%u", clp->cl_minorversion); | ||
581 | } | ||
582 | #else | ||
583 | static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss, | ||
584 | int showdefaults) | ||
585 | { | ||
586 | } | ||
587 | #endif | ||
588 | |||
573 | /* | 589 | /* |
574 | * Describe the mount options in force on this server representation | 590 | * Describe the mount options in force on this server representation |
575 | */ | 591 | */ |
@@ -631,11 +647,9 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, | |||
631 | 647 | ||
632 | if (version != 4) | 648 | if (version != 4) |
633 | nfs_show_mountd_options(m, nfss, showdefaults); | 649 | nfs_show_mountd_options(m, nfss, showdefaults); |
650 | else | ||
651 | nfs_show_nfsv4_options(m, nfss, showdefaults); | ||
634 | 652 | ||
635 | #ifdef CONFIG_NFS_V4 | ||
636 | if (clp->rpc_ops->version == 4) | ||
637 | seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr); | ||
638 | #endif | ||
639 | if (nfss->options & NFS_OPTION_FSCACHE) | 653 | if (nfss->options & NFS_OPTION_FSCACHE) |
640 | seq_printf(m, ",fsc"); | 654 | seq_printf(m, ",fsc"); |
641 | } | 655 | } |
diff --git a/fs/ocfs2/reservations.c b/fs/ocfs2/reservations.c index 40650021fc24..d8b6e4259b80 100644 --- a/fs/ocfs2/reservations.c +++ b/fs/ocfs2/reservations.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/slab.h> | ||
30 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
31 | #include <linux/bitops.h> | 30 | #include <linux/bitops.h> |
32 | #include <linux/list.h> | 31 | #include <linux/list.h> |
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index ce94801f48ca..d9396a4fc7ff 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c | |||
@@ -209,6 +209,9 @@ void proc_device_tree_add_node(struct device_node *np, | |||
209 | for (pp = np->properties; pp != NULL; pp = pp->next) { | 209 | for (pp = np->properties; pp != NULL; pp = pp->next) { |
210 | p = pp->name; | 210 | p = pp->name; |
211 | 211 | ||
212 | if (strchr(p, '/')) | ||
213 | continue; | ||
214 | |||
212 | if (duplicate_name(de, p)) | 215 | if (duplicate_name(de, p)) |
213 | p = fixup_name(np, de, p); | 216 | p = fixup_name(np, de, p); |
214 | 217 | ||
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 46d4b5d72bd3..cb6306e63843 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -122,11 +122,20 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, | |||
122 | return size; | 122 | return size; |
123 | } | 123 | } |
124 | 124 | ||
125 | static void pad_len_spaces(struct seq_file *m, int len) | ||
126 | { | ||
127 | len = 25 + sizeof(void*) * 6 - len; | ||
128 | if (len < 1) | ||
129 | len = 1; | ||
130 | seq_printf(m, "%*c", len, ' '); | ||
131 | } | ||
132 | |||
125 | /* | 133 | /* |
126 | * display a single VMA to a sequenced file | 134 | * display a single VMA to a sequenced file |
127 | */ | 135 | */ |
128 | static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) | 136 | static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) |
129 | { | 137 | { |
138 | struct mm_struct *mm = vma->vm_mm; | ||
130 | unsigned long ino = 0; | 139 | unsigned long ino = 0; |
131 | struct file *file; | 140 | struct file *file; |
132 | dev_t dev = 0; | 141 | dev_t dev = 0; |
@@ -155,11 +164,14 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) | |||
155 | MAJOR(dev), MINOR(dev), ino, &len); | 164 | MAJOR(dev), MINOR(dev), ino, &len); |
156 | 165 | ||
157 | if (file) { | 166 | if (file) { |
158 | len = 25 + sizeof(void *) * 6 - len; | 167 | pad_len_spaces(m, len); |
159 | if (len < 1) | ||
160 | len = 1; | ||
161 | seq_printf(m, "%*c", len, ' '); | ||
162 | seq_path(m, &file->f_path, ""); | 168 | seq_path(m, &file->f_path, ""); |
169 | } else if (mm) { | ||
170 | if (vma->vm_start <= mm->start_stack && | ||
171 | vma->vm_end >= mm->start_stack) { | ||
172 | pad_len_spaces(m, len); | ||
173 | seq_puts(m, "[stack]"); | ||
174 | } | ||
163 | } | 175 | } |
164 | 176 | ||
165 | seq_putc(m, '\n'); | 177 | seq_putc(m, '\n'); |
diff --git a/fs/super.c b/fs/super.c index 5c35bc7a499e..938119ab8dcb 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -374,6 +374,8 @@ void sync_supers(void) | |||
374 | up_read(&sb->s_umount); | 374 | up_read(&sb->s_umount); |
375 | 375 | ||
376 | spin_lock(&sb_lock); | 376 | spin_lock(&sb_lock); |
377 | /* lock was dropped, must reset next */ | ||
378 | list_safe_reset_next(sb, n, s_list); | ||
377 | __put_super(sb); | 379 | __put_super(sb); |
378 | } | 380 | } |
379 | } | 381 | } |
@@ -405,6 +407,8 @@ void iterate_supers(void (*f)(struct super_block *, void *), void *arg) | |||
405 | up_read(&sb->s_umount); | 407 | up_read(&sb->s_umount); |
406 | 408 | ||
407 | spin_lock(&sb_lock); | 409 | spin_lock(&sb_lock); |
410 | /* lock was dropped, must reset next */ | ||
411 | list_safe_reset_next(sb, n, s_list); | ||
408 | __put_super(sb); | 412 | __put_super(sb); |
409 | } | 413 | } |
410 | spin_unlock(&sb_lock); | 414 | spin_unlock(&sb_lock); |
@@ -585,6 +589,8 @@ static void do_emergency_remount(struct work_struct *work) | |||
585 | } | 589 | } |
586 | up_write(&sb->s_umount); | 590 | up_write(&sb->s_umount); |
587 | spin_lock(&sb_lock); | 591 | spin_lock(&sb_lock); |
592 | /* lock was dropped, must reset next */ | ||
593 | list_safe_reset_next(sb, n, s_list); | ||
588 | __put_super(sb); | 594 | __put_super(sb); |
589 | } | 595 | } |
590 | spin_unlock(&sb_lock); | 596 | spin_unlock(&sb_lock); |
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c index bbd69bdb0fa8..fcc498ec9b33 100644 --- a/fs/sysv/ialloc.c +++ b/fs/sysv/ialloc.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/stat.h> | 25 | #include <linux/stat.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/writeback.h> | ||
28 | #include "sysv.h" | 29 | #include "sysv.h" |
29 | 30 | ||
30 | /* We don't trust the value of | 31 | /* We don't trust the value of |
@@ -139,6 +140,9 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) | |||
139 | struct inode *inode; | 140 | struct inode *inode; |
140 | sysv_ino_t ino; | 141 | sysv_ino_t ino; |
141 | unsigned count; | 142 | unsigned count; |
143 | struct writeback_control wbc = { | ||
144 | .sync_mode = WB_SYNC_NONE | ||
145 | }; | ||
142 | 146 | ||
143 | inode = new_inode(sb); | 147 | inode = new_inode(sb); |
144 | if (!inode) | 148 | if (!inode) |
@@ -168,7 +172,7 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) | |||
168 | insert_inode_hash(inode); | 172 | insert_inode_hash(inode); |
169 | mark_inode_dirty(inode); | 173 | mark_inode_dirty(inode); |
170 | 174 | ||
171 | sysv_write_inode(inode, 0); /* ensure inode not allocated again */ | 175 | sysv_write_inode(inode, &wbc); /* ensure inode not allocated again */ |
172 | mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ | 176 | mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ |
173 | /* That's it. */ | 177 | /* That's it. */ |
174 | unlock_super(sb); | 178 | unlock_super(sb); |
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index 076ca50e9933..c8ff0d1ae5d3 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
@@ -62,7 +62,9 @@ | |||
62 | */ | 62 | */ |
63 | static void shrink_liability(struct ubifs_info *c, int nr_to_write) | 63 | static void shrink_liability(struct ubifs_info *c, int nr_to_write) |
64 | { | 64 | { |
65 | down_read(&c->vfs_sb->s_umount); | ||
65 | writeback_inodes_sb(c->vfs_sb); | 66 | writeback_inodes_sb(c->vfs_sb); |
67 | up_read(&c->vfs_sb->s_umount); | ||
66 | } | 68 | } |
67 | 69 | ||
68 | /** | 70 | /** |