aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig8
-rw-r--r--fs/autofs4/waitq.c4
-rw-r--r--fs/bio.c2
-rw-r--r--fs/buffer.c25
-rw-r--r--fs/dcookies.c6
-rw-r--r--fs/ext3/inode.c2
-rw-r--r--fs/hppfs/hppfs_kern.c7
-rw-r--r--fs/inode.c4
-rw-r--r--fs/ioprio.c4
-rw-r--r--fs/locks.c4
-rw-r--r--fs/namei.c2
-rw-r--r--fs/namespace.c130
-rw-r--r--fs/nfsd/nfs4proc.c6
-rw-r--r--fs/nfsd/nfs4recover.c32
-rw-r--r--fs/nfsd/nfs4state.c231
-rw-r--r--fs/nfsd/nfs4xdr.c15
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/super.c1
18 files changed, 238 insertions, 247 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 062177956239..aae0686a15fb 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -29,6 +29,7 @@ config EXT2_FS_XATTR
29config EXT2_FS_POSIX_ACL 29config EXT2_FS_POSIX_ACL
30 bool "Ext2 POSIX Access Control Lists" 30 bool "Ext2 POSIX Access Control Lists"
31 depends on EXT2_FS_XATTR 31 depends on EXT2_FS_XATTR
32 select FS_POSIX_ACL
32 help 33 help
33 Posix Access Control Lists (ACLs) support permissions for users and 34 Posix Access Control Lists (ACLs) support permissions for users and
34 groups beyond the owner/group/world scheme. 35 groups beyond the owner/group/world scheme.
@@ -114,6 +115,7 @@ config EXT3_FS_XATTR
114config EXT3_FS_POSIX_ACL 115config EXT3_FS_POSIX_ACL
115 bool "Ext3 POSIX Access Control Lists" 116 bool "Ext3 POSIX Access Control Lists"
116 depends on EXT3_FS_XATTR 117 depends on EXT3_FS_XATTR
118 select FS_POSIX_ACL
117 help 119 help
118 Posix Access Control Lists (ACLs) support permissions for users and 120 Posix Access Control Lists (ACLs) support permissions for users and
119 groups beyond the owner/group/world scheme. 121 groups beyond the owner/group/world scheme.
@@ -241,6 +243,7 @@ config REISERFS_FS_XATTR
241config REISERFS_FS_POSIX_ACL 243config REISERFS_FS_POSIX_ACL
242 bool "ReiserFS POSIX Access Control Lists" 244 bool "ReiserFS POSIX Access Control Lists"
243 depends on REISERFS_FS_XATTR 245 depends on REISERFS_FS_XATTR
246 select FS_POSIX_ACL
244 help 247 help
245 Posix Access Control Lists (ACLs) support permissions for users and 248 Posix Access Control Lists (ACLs) support permissions for users and
246 groups beyond the owner/group/world scheme. 249 groups beyond the owner/group/world scheme.
@@ -274,6 +277,7 @@ config JFS_FS
274config JFS_POSIX_ACL 277config JFS_POSIX_ACL
275 bool "JFS POSIX Access Control Lists" 278 bool "JFS POSIX Access Control Lists"
276 depends on JFS_FS 279 depends on JFS_FS
280 select FS_POSIX_ACL
277 help 281 help
278 Posix Access Control Lists (ACLs) support permissions for users and 282 Posix Access Control Lists (ACLs) support permissions for users and
279 groups beyond the owner/group/world scheme. 283 groups beyond the owner/group/world scheme.
@@ -318,8 +322,7 @@ config FS_POSIX_ACL
318# Never use this symbol for ifdefs. 322# Never use this symbol for ifdefs.
319# 323#
320 bool 324 bool
321 depends on EXT2_FS_POSIX_ACL || EXT3_FS_POSIX_ACL || JFS_POSIX_ACL || REISERFS_FS_POSIX_ACL || NFSD_V4 325 default n
322 default y
323 326
324source "fs/xfs/Kconfig" 327source "fs/xfs/Kconfig"
325 328
@@ -1438,6 +1441,7 @@ config NFSD_V4
1438 select NFSD_TCP 1441 select NFSD_TCP
1439 select CRYPTO_MD5 1442 select CRYPTO_MD5
1440 select CRYPTO 1443 select CRYPTO
1444 select FS_POSIX_ACL
1441 help 1445 help
1442 If you would like to include the NFSv4 server as well as the NFSv2 1446 If you would like to include the NFSv4 server as well as the NFSv2
1443 and NFSv3 servers, say Y here. This feature is experimental, and 1447 and NFSv3 servers, say Y here. This feature is experimental, and
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index fa2348dcd671..3df86285a1c7 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -231,8 +231,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
231 int type = (notify == NFY_MOUNT ? 231 int type = (notify == NFY_MOUNT ?
232 autofs_ptype_missing : autofs_ptype_expire_multi); 232 autofs_ptype_missing : autofs_ptype_expire_multi);
233 233
234 DPRINTK(("new wait id = 0x%08lx, name = %.*s, nfy=%d\n", 234 DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d\n",
235 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify)); 235 (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
236 236
237 /* autofs4_notify_daemon() may block */ 237 /* autofs4_notify_daemon() may block */
238 autofs4_notify_daemon(sbi, wq, type); 238 autofs4_notify_daemon(sbi, wq, type);
diff --git a/fs/bio.c b/fs/bio.c
index 3a1472acc361..ca8f7a850fe3 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -52,7 +52,7 @@ struct biovec_slab {
52 */ 52 */
53 53
54#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) } 54#define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
55static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] = { 55static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly = {
56 BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES), 56 BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
57}; 57};
58#undef BV 58#undef BV
diff --git a/fs/buffer.c b/fs/buffer.c
index 561e63a14966..6a25d7df89b1 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -513,8 +513,8 @@ static void free_more_memory(void)
513 */ 513 */
514static void end_buffer_async_read(struct buffer_head *bh, int uptodate) 514static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
515{ 515{
516 static DEFINE_SPINLOCK(page_uptodate_lock);
517 unsigned long flags; 516 unsigned long flags;
517 struct buffer_head *first;
518 struct buffer_head *tmp; 518 struct buffer_head *tmp;
519 struct page *page; 519 struct page *page;
520 int page_uptodate = 1; 520 int page_uptodate = 1;
@@ -536,7 +536,9 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
536 * two buffer heads end IO at almost the same time and both 536 * two buffer heads end IO at almost the same time and both
537 * decide that the page is now completely done. 537 * decide that the page is now completely done.
538 */ 538 */
539 spin_lock_irqsave(&page_uptodate_lock, flags); 539 first = page_buffers(page);
540 local_irq_save(flags);
541 bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
540 clear_buffer_async_read(bh); 542 clear_buffer_async_read(bh);
541 unlock_buffer(bh); 543 unlock_buffer(bh);
542 tmp = bh; 544 tmp = bh;
@@ -549,7 +551,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
549 } 551 }
550 tmp = tmp->b_this_page; 552 tmp = tmp->b_this_page;
551 } while (tmp != bh); 553 } while (tmp != bh);
552 spin_unlock_irqrestore(&page_uptodate_lock, flags); 554 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
555 local_irq_restore(flags);
553 556
554 /* 557 /*
555 * If none of the buffers had errors and they are all 558 * If none of the buffers had errors and they are all
@@ -561,7 +564,8 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
561 return; 564 return;
562 565
563still_busy: 566still_busy:
564 spin_unlock_irqrestore(&page_uptodate_lock, flags); 567 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
568 local_irq_restore(flags);
565 return; 569 return;
566} 570}
567 571
@@ -572,8 +576,8 @@ still_busy:
572void end_buffer_async_write(struct buffer_head *bh, int uptodate) 576void end_buffer_async_write(struct buffer_head *bh, int uptodate)
573{ 577{
574 char b[BDEVNAME_SIZE]; 578 char b[BDEVNAME_SIZE];
575 static DEFINE_SPINLOCK(page_uptodate_lock);
576 unsigned long flags; 579 unsigned long flags;
580 struct buffer_head *first;
577 struct buffer_head *tmp; 581 struct buffer_head *tmp;
578 struct page *page; 582 struct page *page;
579 583
@@ -594,7 +598,10 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
594 SetPageError(page); 598 SetPageError(page);
595 } 599 }
596 600
597 spin_lock_irqsave(&page_uptodate_lock, flags); 601 first = page_buffers(page);
602 local_irq_save(flags);
603 bit_spin_lock(BH_Uptodate_Lock, &first->b_state);
604
598 clear_buffer_async_write(bh); 605 clear_buffer_async_write(bh);
599 unlock_buffer(bh); 606 unlock_buffer(bh);
600 tmp = bh->b_this_page; 607 tmp = bh->b_this_page;
@@ -605,12 +612,14 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
605 } 612 }
606 tmp = tmp->b_this_page; 613 tmp = tmp->b_this_page;
607 } 614 }
608 spin_unlock_irqrestore(&page_uptodate_lock, flags); 615 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
616 local_irq_restore(flags);
609 end_page_writeback(page); 617 end_page_writeback(page);
610 return; 618 return;
611 619
612still_busy: 620still_busy:
613 spin_unlock_irqrestore(&page_uptodate_lock, flags); 621 bit_spin_unlock(BH_Uptodate_Lock, &first->b_state);
622 local_irq_restore(flags);
614 return; 623 return;
615} 624}
616 625
diff --git a/fs/dcookies.c b/fs/dcookies.c
index 581aac959cd3..02aa0ddc582a 100644
--- a/fs/dcookies.c
+++ b/fs/dcookies.c
@@ -94,12 +94,10 @@ static struct dcookie_struct * alloc_dcookie(struct dentry * dentry,
94 if (!dcs) 94 if (!dcs)
95 return NULL; 95 return NULL;
96 96
97 atomic_inc(&dentry->d_count);
98 atomic_inc(&vfsmnt->mnt_count);
99 dentry->d_cookie = dcs; 97 dentry->d_cookie = dcs;
100 98
101 dcs->dentry = dentry; 99 dcs->dentry = dget(dentry);
102 dcs->vfsmnt = vfsmnt; 100 dcs->vfsmnt = mntget(vfsmnt);
103 hash_dcookie(dcs); 101 hash_dcookie(dcs);
104 102
105 return dcs; 103 return dcs;
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 0b2db4f618cb..9989fdcf4d5a 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2663,7 +2663,7 @@ static int ext3_do_update_inode(handle_t *handle,
2663 } else for (block = 0; block < EXT3_N_BLOCKS; block++) 2663 } else for (block = 0; block < EXT3_N_BLOCKS; block++)
2664 raw_inode->i_block[block] = ei->i_data[block]; 2664 raw_inode->i_block[block] = ei->i_data[block];
2665 2665
2666 if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) 2666 if (ei->i_extra_isize)
2667 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); 2667 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
2668 2668
2669 BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); 2669 BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index f8e0cbd0cb60..6f553e17c375 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <linux/fs.h> 6#include <linux/fs.h>
7#include <linux/file.h>
7#include <linux/module.h> 8#include <linux/module.h>
8#include <linux/init.h> 9#include <linux/init.h>
9#include <linux/slab.h> 10#include <linux/slab.h>
@@ -491,7 +492,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
491 fd = open_host_sock(host_file, &filter); 492 fd = open_host_sock(host_file, &filter);
492 if(fd > 0){ 493 if(fd > 0){
493 data->contents = hppfs_get_data(fd, filter, 494 data->contents = hppfs_get_data(fd, filter,
494 &data->proc_file, 495 data->proc_file,
495 file, &data->len); 496 file, &data->len);
496 if(!IS_ERR(data->contents)) 497 if(!IS_ERR(data->contents))
497 data->host_fd = fd; 498 data->host_fd = fd;
@@ -543,7 +544,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file)
543static loff_t hppfs_llseek(struct file *file, loff_t off, int where) 544static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
544{ 545{
545 struct hppfs_private *data = file->private_data; 546 struct hppfs_private *data = file->private_data;
546 struct file *proc_file = &data->proc_file; 547 struct file *proc_file = data->proc_file;
547 loff_t (*llseek)(struct file *, loff_t, int); 548 loff_t (*llseek)(struct file *, loff_t, int);
548 loff_t ret; 549 loff_t ret;
549 550
@@ -586,7 +587,7 @@ static int hppfs_filldir(void *d, const char *name, int size,
586static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) 587static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
587{ 588{
588 struct hppfs_private *data = file->private_data; 589 struct hppfs_private *data = file->private_data;
589 struct file *proc_file = &data->proc_file; 590 struct file *proc_file = data->proc_file;
590 int (*readdir)(struct file *, void *, filldir_t); 591 int (*readdir)(struct file *, void *, filldir_t);
591 struct hppfs_dirent dirent = ((struct hppfs_dirent) 592 struct hppfs_dirent dirent = ((struct hppfs_dirent)
592 { .vfs_dirent = ent, 593 { .vfs_dirent = ent,
diff --git a/fs/inode.c b/fs/inode.c
index 1f9a3a2b89bc..6d695037a0a3 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1052,7 +1052,7 @@ static void generic_forget_inode(struct inode *inode)
1052 * inode when the usage count drops to zero, and 1052 * inode when the usage count drops to zero, and
1053 * i_nlink is zero. 1053 * i_nlink is zero.
1054 */ 1054 */
1055static void generic_drop_inode(struct inode *inode) 1055void generic_drop_inode(struct inode *inode)
1056{ 1056{
1057 if (!inode->i_nlink) 1057 if (!inode->i_nlink)
1058 generic_delete_inode(inode); 1058 generic_delete_inode(inode);
@@ -1060,6 +1060,8 @@ static void generic_drop_inode(struct inode *inode)
1060 generic_forget_inode(inode); 1060 generic_forget_inode(inode);
1061} 1061}
1062 1062
1063EXPORT_SYMBOL_GPL(generic_drop_inode);
1064
1063/* 1065/*
1064 * Called when we're dropping the last reference 1066 * Called when we're dropping the last reference
1065 * to an inode. 1067 * to an inode.
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 663e420636d6..97e1f088ba00 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -43,7 +43,7 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
43 return 0; 43 return 0;
44} 44}
45 45
46asmlinkage int sys_ioprio_set(int which, int who, int ioprio) 46asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
47{ 47{
48 int class = IOPRIO_PRIO_CLASS(ioprio); 48 int class = IOPRIO_PRIO_CLASS(ioprio);
49 int data = IOPRIO_PRIO_DATA(ioprio); 49 int data = IOPRIO_PRIO_DATA(ioprio);
@@ -115,7 +115,7 @@ asmlinkage int sys_ioprio_set(int which, int who, int ioprio)
115 return ret; 115 return ret;
116} 116}
117 117
118asmlinkage int sys_ioprio_get(int which, int who) 118asmlinkage long sys_ioprio_get(int which, int who)
119{ 119{
120 struct task_struct *g, *p; 120 struct task_struct *g, *p;
121 struct user_struct *user; 121 struct user_struct *user;
diff --git a/fs/locks.c b/fs/locks.c
index a0bc03495bd4..29fa5da6c117 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1276,7 +1276,7 @@ int fcntl_getlease(struct file *filp)
1276 */ 1276 */
1277static int __setlease(struct file *filp, long arg, struct file_lock **flp) 1277static int __setlease(struct file *filp, long arg, struct file_lock **flp)
1278{ 1278{
1279 struct file_lock *fl, **before, **my_before = NULL, *lease = *flp; 1279 struct file_lock *fl, **before, **my_before = NULL, *lease;
1280 struct dentry *dentry = filp->f_dentry; 1280 struct dentry *dentry = filp->f_dentry;
1281 struct inode *inode = dentry->d_inode; 1281 struct inode *inode = dentry->d_inode;
1282 int error, rdlease_count = 0, wrlease_count = 0; 1282 int error, rdlease_count = 0, wrlease_count = 0;
@@ -1287,6 +1287,8 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp)
1287 if (!flp || !(*flp) || !(*flp)->fl_lmops || !(*flp)->fl_lmops->fl_break) 1287 if (!flp || !(*flp) || !(*flp)->fl_lmops || !(*flp)->fl_lmops->fl_break)
1288 goto out; 1288 goto out;
1289 1289
1290 lease = *flp;
1291
1290 error = -EAGAIN; 1292 error = -EAGAIN;
1291 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0)) 1293 if ((arg == F_RDLCK) && (atomic_read(&inode->i_writecount) > 0))
1292 goto out; 1294 goto out;
diff --git a/fs/namei.c b/fs/namei.c
index fa8df81ce8ca..1d93cb4f7c5f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -314,7 +314,7 @@ void path_release(struct nameidata *nd)
314void path_release_on_umount(struct nameidata *nd) 314void path_release_on_umount(struct nameidata *nd)
315{ 315{
316 dput(nd->dentry); 316 dput(nd->dentry);
317 _mntput(nd->mnt); 317 mntput_no_expire(nd->mnt);
318} 318}
319 319
320/* 320/*
diff --git a/fs/namespace.c b/fs/namespace.c
index 208c079e9fdb..587eb0d707ee 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -61,7 +61,7 @@ struct vfsmount *alloc_vfsmnt(const char *name)
61 INIT_LIST_HEAD(&mnt->mnt_child); 61 INIT_LIST_HEAD(&mnt->mnt_child);
62 INIT_LIST_HEAD(&mnt->mnt_mounts); 62 INIT_LIST_HEAD(&mnt->mnt_mounts);
63 INIT_LIST_HEAD(&mnt->mnt_list); 63 INIT_LIST_HEAD(&mnt->mnt_list);
64 INIT_LIST_HEAD(&mnt->mnt_fslink); 64 INIT_LIST_HEAD(&mnt->mnt_expire);
65 if (name) { 65 if (name) {
66 int size = strlen(name)+1; 66 int size = strlen(name)+1;
67 char *newname = kmalloc(size, GFP_KERNEL); 67 char *newname = kmalloc(size, GFP_KERNEL);
@@ -165,8 +165,8 @@ clone_mnt(struct vfsmount *old, struct dentry *root)
165 /* stick the duplicate mount on the same expiry list 165 /* stick the duplicate mount on the same expiry list
166 * as the original if that was on one */ 166 * as the original if that was on one */
167 spin_lock(&vfsmount_lock); 167 spin_lock(&vfsmount_lock);
168 if (!list_empty(&old->mnt_fslink)) 168 if (!list_empty(&old->mnt_expire))
169 list_add(&mnt->mnt_fslink, &old->mnt_fslink); 169 list_add(&mnt->mnt_expire, &old->mnt_expire);
170 spin_unlock(&vfsmount_lock); 170 spin_unlock(&vfsmount_lock);
171 } 171 }
172 return mnt; 172 return mnt;
@@ -345,12 +345,13 @@ static void umount_tree(struct vfsmount *mnt)
345 for (p = mnt; p; p = next_mnt(p, mnt)) { 345 for (p = mnt; p; p = next_mnt(p, mnt)) {
346 list_del(&p->mnt_list); 346 list_del(&p->mnt_list);
347 list_add(&p->mnt_list, &kill); 347 list_add(&p->mnt_list, &kill);
348 p->mnt_namespace = NULL;
348 } 349 }
349 350
350 while (!list_empty(&kill)) { 351 while (!list_empty(&kill)) {
351 mnt = list_entry(kill.next, struct vfsmount, mnt_list); 352 mnt = list_entry(kill.next, struct vfsmount, mnt_list);
352 list_del_init(&mnt->mnt_list); 353 list_del_init(&mnt->mnt_list);
353 list_del_init(&mnt->mnt_fslink); 354 list_del_init(&mnt->mnt_expire);
354 if (mnt->mnt_parent == mnt) { 355 if (mnt->mnt_parent == mnt) {
355 spin_unlock(&vfsmount_lock); 356 spin_unlock(&vfsmount_lock);
356 } else { 357 } else {
@@ -644,7 +645,7 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
644 if (mnt) { 645 if (mnt) {
645 /* stop bind mounts from expiring */ 646 /* stop bind mounts from expiring */
646 spin_lock(&vfsmount_lock); 647 spin_lock(&vfsmount_lock);
647 list_del_init(&mnt->mnt_fslink); 648 list_del_init(&mnt->mnt_expire);
648 spin_unlock(&vfsmount_lock); 649 spin_unlock(&vfsmount_lock);
649 650
650 err = graft_tree(mnt, nd); 651 err = graft_tree(mnt, nd);
@@ -743,7 +744,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
743 744
744 /* if the mount is moved, it should no longer be expire 745 /* if the mount is moved, it should no longer be expire
745 * automatically */ 746 * automatically */
746 list_del_init(&old_nd.mnt->mnt_fslink); 747 list_del_init(&old_nd.mnt->mnt_expire);
747out2: 748out2:
748 spin_unlock(&vfsmount_lock); 749 spin_unlock(&vfsmount_lock);
749out1: 750out1:
@@ -807,12 +808,13 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
807 goto unlock; 808 goto unlock;
808 809
809 newmnt->mnt_flags = mnt_flags; 810 newmnt->mnt_flags = mnt_flags;
811 newmnt->mnt_namespace = current->namespace;
810 err = graft_tree(newmnt, nd); 812 err = graft_tree(newmnt, nd);
811 813
812 if (err == 0 && fslist) { 814 if (err == 0 && fslist) {
813 /* add to the specified expiration list */ 815 /* add to the specified expiration list */
814 spin_lock(&vfsmount_lock); 816 spin_lock(&vfsmount_lock);
815 list_add_tail(&newmnt->mnt_fslink, fslist); 817 list_add_tail(&newmnt->mnt_expire, fslist);
816 spin_unlock(&vfsmount_lock); 818 spin_unlock(&vfsmount_lock);
817 } 819 }
818 820
@@ -824,6 +826,54 @@ unlock:
824 826
825EXPORT_SYMBOL_GPL(do_add_mount); 827EXPORT_SYMBOL_GPL(do_add_mount);
826 828
829static void expire_mount(struct vfsmount *mnt, struct list_head *mounts)
830{
831 spin_lock(&vfsmount_lock);
832
833 /*
834 * Check if mount is still attached, if not, let whoever holds it deal
835 * with the sucker
836 */
837 if (mnt->mnt_parent == mnt) {
838 spin_unlock(&vfsmount_lock);
839 return;
840 }
841
842 /*
843 * Check that it is still dead: the count should now be 2 - as
844 * contributed by the vfsmount parent and the mntget above
845 */
846 if (atomic_read(&mnt->mnt_count) == 2) {
847 struct nameidata old_nd;
848
849 /* delete from the namespace */
850 list_del_init(&mnt->mnt_list);
851 mnt->mnt_namespace = NULL;
852 detach_mnt(mnt, &old_nd);
853 spin_unlock(&vfsmount_lock);
854 path_release(&old_nd);
855
856 /*
857 * Now lay it to rest if this was the last ref on the superblock
858 */
859 if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
860 /* last instance - try to be smart */
861 lock_kernel();
862 DQUOT_OFF(mnt->mnt_sb);
863 acct_auto_close(mnt->mnt_sb);
864 unlock_kernel();
865 }
866 mntput(mnt);
867 } else {
868 /*
869 * Someone brought it back to life whilst we didn't have any
870 * locks held so return it to the expiration list
871 */
872 list_add_tail(&mnt->mnt_expire, mounts);
873 spin_unlock(&vfsmount_lock);
874 }
875}
876
827/* 877/*
828 * process a list of expirable mountpoints with the intent of discarding any 878 * process a list of expirable mountpoints with the intent of discarding any
829 * mountpoints that aren't in use and haven't been touched since last we came 879 * mountpoints that aren't in use and haven't been touched since last we came
@@ -846,13 +896,13 @@ void mark_mounts_for_expiry(struct list_head *mounts)
846 * - still marked for expiry (marked on the last call here; marks are 896 * - still marked for expiry (marked on the last call here; marks are
847 * cleared by mntput()) 897 * cleared by mntput())
848 */ 898 */
849 list_for_each_entry_safe(mnt, next, mounts, mnt_fslink) { 899 list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
850 if (!xchg(&mnt->mnt_expiry_mark, 1) || 900 if (!xchg(&mnt->mnt_expiry_mark, 1) ||
851 atomic_read(&mnt->mnt_count) != 1) 901 atomic_read(&mnt->mnt_count) != 1)
852 continue; 902 continue;
853 903
854 mntget(mnt); 904 mntget(mnt);
855 list_move(&mnt->mnt_fslink, &graveyard); 905 list_move(&mnt->mnt_expire, &graveyard);
856 } 906 }
857 907
858 /* 908 /*
@@ -862,61 +912,19 @@ void mark_mounts_for_expiry(struct list_head *mounts)
862 * - dispose of the corpse 912 * - dispose of the corpse
863 */ 913 */
864 while (!list_empty(&graveyard)) { 914 while (!list_empty(&graveyard)) {
865 mnt = list_entry(graveyard.next, struct vfsmount, mnt_fslink); 915 mnt = list_entry(graveyard.next, struct vfsmount, mnt_expire);
866 list_del_init(&mnt->mnt_fslink); 916 list_del_init(&mnt->mnt_expire);
867 917
868 /* don't do anything if the namespace is dead - all the 918 /* don't do anything if the namespace is dead - all the
869 * vfsmounts from it are going away anyway */ 919 * vfsmounts from it are going away anyway */
870 namespace = mnt->mnt_namespace; 920 namespace = mnt->mnt_namespace;
871 if (!namespace || atomic_read(&namespace->count) <= 0) 921 if (!namespace || !namespace->root)
872 continue; 922 continue;
873 get_namespace(namespace); 923 get_namespace(namespace);
874 924
875 spin_unlock(&vfsmount_lock); 925 spin_unlock(&vfsmount_lock);
876 down_write(&namespace->sem); 926 down_write(&namespace->sem);
877 spin_lock(&vfsmount_lock); 927 expire_mount(mnt, mounts);
878
879 /* check that it is still dead: the count should now be 2 - as
880 * contributed by the vfsmount parent and the mntget above */
881 if (atomic_read(&mnt->mnt_count) == 2) {
882 struct vfsmount *xdmnt;
883 struct dentry *xdentry;
884
885 /* delete from the namespace */
886 list_del_init(&mnt->mnt_list);
887 list_del_init(&mnt->mnt_child);
888 list_del_init(&mnt->mnt_hash);
889 mnt->mnt_mountpoint->d_mounted--;
890
891 xdentry = mnt->mnt_mountpoint;
892 mnt->mnt_mountpoint = mnt->mnt_root;
893 xdmnt = mnt->mnt_parent;
894 mnt->mnt_parent = mnt;
895
896 spin_unlock(&vfsmount_lock);
897
898 mntput(xdmnt);
899 dput(xdentry);
900
901 /* now lay it to rest if this was the last ref on the
902 * superblock */
903 if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
904 /* last instance - try to be smart */
905 lock_kernel();
906 DQUOT_OFF(mnt->mnt_sb);
907 acct_auto_close(mnt->mnt_sb);
908 unlock_kernel();
909 }
910
911 mntput(mnt);
912 } else {
913 /* someone brought it back to life whilst we didn't
914 * have any locks held so return it to the expiration
915 * list */
916 list_add_tail(&mnt->mnt_fslink, mounts);
917 spin_unlock(&vfsmount_lock);
918 }
919
920 up_write(&namespace->sem); 928 up_write(&namespace->sem);
921 929
922 mntput(mnt); 930 mntput(mnt);
@@ -1449,16 +1457,12 @@ void __init mnt_init(unsigned long mempages)
1449 1457
1450void __put_namespace(struct namespace *namespace) 1458void __put_namespace(struct namespace *namespace)
1451{ 1459{
1452 struct vfsmount *mnt; 1460 struct vfsmount *root = namespace->root;
1453 1461 namespace->root = NULL;
1462 spin_unlock(&vfsmount_lock);
1454 down_write(&namespace->sem); 1463 down_write(&namespace->sem);
1455 spin_lock(&vfsmount_lock); 1464 spin_lock(&vfsmount_lock);
1456 1465 umount_tree(root);
1457 list_for_each_entry(mnt, &namespace->list, mnt_list) {
1458 mnt->mnt_namespace = NULL;
1459 }
1460
1461 umount_tree(namespace->root);
1462 spin_unlock(&vfsmount_lock); 1466 spin_unlock(&vfsmount_lock);
1463 up_write(&namespace->sem); 1467 up_write(&namespace->sem);
1464 kfree(namespace); 1468 kfree(namespace);
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index d71f14517b9c..e08edc17c6a0 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -169,12 +169,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open
169 (int)open->op_fname.len, open->op_fname.data, 169 (int)open->op_fname.len, open->op_fname.data,
170 open->op_stateowner); 170 open->op_stateowner);
171 171
172 if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
173 return nfserr_grace;
174
175 if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
176 return nfserr_no_grace;
177
178 /* This check required by spec. */ 172 /* This check required by spec. */
179 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL) 173 if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
180 return nfserr_inval; 174 return nfserr_inval;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 095f1740f3ae..57ed50fe7f85 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -119,25 +119,12 @@ out:
119 return status; 119 return status;
120} 120}
121 121
122static int 122static void
123nfsd4_rec_fsync(struct dentry *dentry) 123nfsd4_sync_rec_dir(void)
124{ 124{
125 struct file *filp; 125 down(&rec_dir.dentry->d_inode->i_sem);
126 int status = nfs_ok; 126 nfsd_sync_dir(rec_dir.dentry);
127 127 up(&rec_dir.dentry->d_inode->i_sem);
128 dprintk("NFSD: nfs4_fsync_rec_dir\n");
129 filp = dentry_open(dget(dentry), mntget(rec_dir.mnt), O_RDWR);
130 if (IS_ERR(filp)) {
131 status = PTR_ERR(filp);
132 goto out;
133 }
134 if (filp->f_op && filp->f_op->fsync)
135 status = filp->f_op->fsync(filp, filp->f_dentry, 0);
136 fput(filp);
137out:
138 if (status)
139 printk("nfsd4: unable to sync recovery directory\n");
140 return status;
141} 128}
142 129
143int 130int
@@ -176,7 +163,7 @@ out_unlock:
176 up(&rec_dir.dentry->d_inode->i_sem); 163 up(&rec_dir.dentry->d_inode->i_sem);
177 if (status == 0) { 164 if (status == 0) {
178 clp->cl_firststate = 1; 165 clp->cl_firststate = 1;
179 status = nfsd4_rec_fsync(rec_dir.dentry); 166 nfsd4_sync_rec_dir();
180 } 167 }
181 nfs4_reset_user(uid, gid); 168 nfs4_reset_user(uid, gid);
182 dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); 169 dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
@@ -302,7 +289,9 @@ nfsd4_unlink_clid_dir(char *name, int namlen)
302 289
303 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name); 290 dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
304 291
292 down(&rec_dir.dentry->d_inode->i_sem);
305 dentry = lookup_one_len(name, rec_dir.dentry, namlen); 293 dentry = lookup_one_len(name, rec_dir.dentry, namlen);
294 up(&rec_dir.dentry->d_inode->i_sem);
306 if (IS_ERR(dentry)) { 295 if (IS_ERR(dentry)) {
307 status = PTR_ERR(dentry); 296 status = PTR_ERR(dentry);
308 return status; 297 return status;
@@ -327,11 +316,12 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
327 if (!rec_dir_init || !clp->cl_firststate) 316 if (!rec_dir_init || !clp->cl_firststate)
328 return; 317 return;
329 318
319 clp->cl_firststate = 0;
330 nfs4_save_user(&uid, &gid); 320 nfs4_save_user(&uid, &gid);
331 status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); 321 status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1);
332 nfs4_reset_user(uid, gid); 322 nfs4_reset_user(uid, gid);
333 if (status == 0) 323 if (status == 0)
334 status = nfsd4_rec_fsync(rec_dir.dentry); 324 nfsd4_sync_rec_dir();
335 if (status) 325 if (status)
336 printk("NFSD: Failed to remove expired client state directory" 326 printk("NFSD: Failed to remove expired client state directory"
337 " %.*s\n", HEXDIR_LEN, clp->cl_recdir); 327 " %.*s\n", HEXDIR_LEN, clp->cl_recdir);
@@ -362,7 +352,7 @@ nfsd4_recdir_purge_old(void) {
362 return; 352 return;
363 status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old); 353 status = nfsd4_list_rec_dir(rec_dir.dentry, purge_old);
364 if (status == 0) 354 if (status == 0)
365 status = nfsd4_rec_fsync(rec_dir.dentry); 355 nfsd4_sync_rec_dir();
366 if (status) 356 if (status)
367 printk("nfsd4: failed to purge old clients from recovery" 357 printk("nfsd4: failed to purge old clients from recovery"
368 " directory %s\n", rec_dir.dentry->d_name.name); 358 " directory %s\n", rec_dir.dentry->d_name.name);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 89e36526d7f2..b83f8fb441e1 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -874,6 +874,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, struct nfsd4_setclientid_confi
874 * change request correctly. */ 874 * change request correctly. */
875 atomic_set(&conf->cl_callback.cb_set, 0); 875 atomic_set(&conf->cl_callback.cb_set, 0);
876 gen_confirm(conf); 876 gen_confirm(conf);
877 nfsd4_remove_clid_dir(unconf);
877 expire_client(unconf); 878 expire_client(unconf);
878 status = nfs_ok; 879 status = nfs_ok;
879 880
@@ -1159,6 +1160,7 @@ init_stateid(struct nfs4_stateid *stp, struct nfs4_file *fp, struct nfsd4_open *
1159 stp->st_deny_bmap = 0; 1160 stp->st_deny_bmap = 0;
1160 __set_bit(open->op_share_access, &stp->st_access_bmap); 1161 __set_bit(open->op_share_access, &stp->st_access_bmap);
1161 __set_bit(open->op_share_deny, &stp->st_deny_bmap); 1162 __set_bit(open->op_share_deny, &stp->st_deny_bmap);
1163 stp->st_openstp = NULL;
1162} 1164}
1163 1165
1164static void 1166static void
@@ -1294,7 +1296,7 @@ nfs4_share_conflict(struct svc_fh *current_fh, unsigned int deny_type)
1294 fp = find_file(ino); 1296 fp = find_file(ino);
1295 if (!fp) 1297 if (!fp)
1296 return nfs_ok; 1298 return nfs_ok;
1297 ret = nfserr_share_denied; 1299 ret = nfserr_locked;
1298 /* Search for conflicting share reservations */ 1300 /* Search for conflicting share reservations */
1299 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) { 1301 list_for_each_entry(stp, &fp->fi_stateids, st_perfile) {
1300 if (test_bit(deny_type, &stp->st_deny_bmap) || 1302 if (test_bit(deny_type, &stp->st_deny_bmap) ||
@@ -1482,7 +1484,7 @@ nfsd4_process_open1(struct nfsd4_open *open)
1482 if (sop) { 1484 if (sop) {
1483 open->op_stateowner = sop; 1485 open->op_stateowner = sop;
1484 /* check for replay */ 1486 /* check for replay */
1485 if (open->op_seqid == sop->so_seqid){ 1487 if (open->op_seqid == sop->so_seqid - 1){
1486 if (sop->so_replay.rp_buflen) 1488 if (sop->so_replay.rp_buflen)
1487 return NFSERR_REPLAY_ME; 1489 return NFSERR_REPLAY_ME;
1488 else { 1490 else {
@@ -1497,7 +1499,7 @@ nfsd4_process_open1(struct nfsd4_open *open)
1497 goto renew; 1499 goto renew;
1498 } 1500 }
1499 } else if (sop->so_confirmed) { 1501 } else if (sop->so_confirmed) {
1500 if (open->op_seqid == sop->so_seqid + 1) 1502 if (open->op_seqid == sop->so_seqid)
1501 goto renew; 1503 goto renew;
1502 status = nfserr_bad_seqid; 1504 status = nfserr_bad_seqid;
1503 goto out; 1505 goto out;
@@ -1530,8 +1532,6 @@ renew:
1530 status = nfs_ok; 1532 status = nfs_ok;
1531 renew_client(sop->so_client); 1533 renew_client(sop->so_client);
1532out: 1534out:
1533 if (status && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1534 status = nfserr_reclaim_bad;
1535 return status; 1535 return status;
1536} 1536}
1537 1537
@@ -1685,19 +1685,11 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_sta
1685} 1685}
1686 1686
1687 1687
1688/* decrement seqid on successful reclaim, it will be bumped in encode_open */
1689static void 1688static void
1690nfs4_set_claim_prev(struct nfsd4_open *open, int *status) 1689nfs4_set_claim_prev(struct nfsd4_open *open)
1691{ 1690{
1692 if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) { 1691 open->op_stateowner->so_confirmed = 1;
1693 if (*status) 1692 open->op_stateowner->so_client->cl_firststate = 1;
1694 *status = nfserr_reclaim_bad;
1695 else {
1696 open->op_stateowner->so_confirmed = 1;
1697 open->op_stateowner->so_client->cl_firststate = 1;
1698 open->op_stateowner->so_seqid--;
1699 }
1700 }
1701} 1693}
1702 1694
1703/* 1695/*
@@ -1789,6 +1781,12 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1789 struct nfs4_delegation *dp = NULL; 1781 struct nfs4_delegation *dp = NULL;
1790 int status; 1782 int status;
1791 1783
1784 if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
1785 return nfserr_grace;
1786
1787 if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1788 return nfserr_no_grace;
1789
1792 status = nfserr_inval; 1790 status = nfserr_inval;
1793 if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny)) 1791 if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny))
1794 goto out; 1792 goto out;
@@ -1823,6 +1821,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1823 status = nfs4_upgrade_open(rqstp, current_fh, stp, open); 1821 status = nfs4_upgrade_open(rqstp, current_fh, stp, open);
1824 if (status) 1822 if (status)
1825 goto out; 1823 goto out;
1824 update_stateid(&stp->st_stateid);
1826 } else { 1825 } else {
1827 /* Stateid was not found, this is a new OPEN */ 1826 /* Stateid was not found, this is a new OPEN */
1828 int flags = 0; 1827 int flags = 0;
@@ -1856,8 +1855,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1856out: 1855out:
1857 if (fp) 1856 if (fp)
1858 put_nfs4_file(fp); 1857 put_nfs4_file(fp);
1859 /* CLAIM_PREVIOUS has different error returns */ 1858 if (status == 0 && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
1860 nfs4_set_claim_prev(open, &status); 1859 nfs4_set_claim_prev(open);
1861 /* 1860 /*
1862 * To finish the open response, we just need to set the rflags. 1861 * To finish the open response, we just need to set the rflags.
1863 */ 1862 */
@@ -1990,14 +1989,11 @@ laundromat_main(void *not_used)
1990 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ); 1989 queue_delayed_work(laundry_wq, &laundromat_work, t*HZ);
1991} 1990}
1992 1991
1993/* search ownerid_hashtbl[] and close_lru for stateid owner
1994 * (stateid->si_stateownerid)
1995 */
1996static struct nfs4_stateowner * 1992static struct nfs4_stateowner *
1997find_openstateowner_id(u32 st_id, int flags) { 1993search_close_lru(u32 st_id, int flags)
1994{
1998 struct nfs4_stateowner *local = NULL; 1995 struct nfs4_stateowner *local = NULL;
1999 1996
2000 dprintk("NFSD: find_openstateowner_id %d\n", st_id);
2001 if (flags & CLOSE_STATE) { 1997 if (flags & CLOSE_STATE) {
2002 list_for_each_entry(local, &close_lru, so_close_lru) { 1998 list_for_each_entry(local, &close_lru, so_close_lru) {
2003 if (local->so_id == st_id) 1999 if (local->so_id == st_id)
@@ -2163,14 +2159,19 @@ out:
2163 return status; 2159 return status;
2164} 2160}
2165 2161
2162static inline int
2163setlkflg (int type)
2164{
2165 return (type == NFS4_READW_LT || type == NFS4_READ_LT) ?
2166 RD_STATE : WR_STATE;
2167}
2166 2168
2167/* 2169/*
2168 * Checks for sequence id mutating operations. 2170 * Checks for sequence id mutating operations.
2169 */ 2171 */
2170static int 2172static int
2171nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, clientid_t *lockclid) 2173nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *stateid, int flags, struct nfs4_stateowner **sopp, struct nfs4_stateid **stpp, struct nfsd4_lock *lock)
2172{ 2174{
2173 int status;
2174 struct nfs4_stateid *stp; 2175 struct nfs4_stateid *stp;
2175 struct nfs4_stateowner *sop; 2176 struct nfs4_stateowner *sop;
2176 2177
@@ -2178,53 +2179,65 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
2178 "stateid = (%08x/%08x/%08x/%08x)\n", seqid, 2179 "stateid = (%08x/%08x/%08x/%08x)\n", seqid,
2179 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, 2180 stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid,
2180 stateid->si_generation); 2181 stateid->si_generation);
2181 2182
2182 *stpp = NULL; 2183 *stpp = NULL;
2183 *sopp = NULL; 2184 *sopp = NULL;
2184 2185
2185 status = nfserr_bad_stateid;
2186 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) { 2186 if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
2187 printk("NFSD: preprocess_seqid_op: magic stateid!\n"); 2187 printk("NFSD: preprocess_seqid_op: magic stateid!\n");
2188 goto out; 2188 return nfserr_bad_stateid;
2189 } 2189 }
2190 2190
2191 status = nfserr_stale_stateid;
2192 if (STALE_STATEID(stateid)) 2191 if (STALE_STATEID(stateid))
2193 goto out; 2192 return nfserr_stale_stateid;
2194 /* 2193 /*
2195 * We return BAD_STATEID if filehandle doesn't match stateid, 2194 * We return BAD_STATEID if filehandle doesn't match stateid,
2196 * the confirmed flag is incorrecly set, or the generation 2195 * the confirmed flag is incorrecly set, or the generation
2197 * number is incorrect. 2196 * number is incorrect.
2198 * If there is no entry in the openfile table for this id,
2199 * we can't always return BAD_STATEID;
2200 * this might be a retransmitted CLOSE which has arrived after
2201 * the openfile has been released.
2202 */ 2197 */
2203 if (!(stp = find_stateid(stateid, flags))) 2198 stp = find_stateid(stateid, flags);
2204 goto no_nfs4_stateid; 2199 if (stp == NULL) {
2205 2200 /*
2206 status = nfserr_bad_stateid; 2201 * Also, we should make sure this isn't just the result of
2202 * a replayed close:
2203 */
2204 sop = search_close_lru(stateid->si_stateownerid, flags);
2205 if (sop == NULL)
2206 return nfserr_bad_stateid;
2207 *sopp = sop;
2208 goto check_replay;
2209 }
2207 2210
2208 /* for new lock stateowners: 2211 if (lock) {
2209 * check that the lock->v.new.open_stateid
2210 * refers to an open stateowner
2211 *
2212 * check that the lockclid (nfs4_lock->v.new.clientid) is the same
2213 * as the open_stateid->st_stateowner->so_client->clientid
2214 */
2215 if (lockclid) {
2216 struct nfs4_stateowner *sop = stp->st_stateowner; 2212 struct nfs4_stateowner *sop = stp->st_stateowner;
2213 clientid_t *lockclid = &lock->v.new.clientid;
2217 struct nfs4_client *clp = sop->so_client; 2214 struct nfs4_client *clp = sop->so_client;
2215 int lkflg = 0;
2216 int status;
2217
2218 lkflg = setlkflg(lock->lk_type);
2219
2220 if (lock->lk_is_new) {
2221 if (!sop->so_is_open_owner)
2222 return nfserr_bad_stateid;
2223 if (!cmp_clid(&clp->cl_clientid, lockclid))
2224 return nfserr_bad_stateid;
2225 /* stp is the open stateid */
2226 status = nfs4_check_openmode(stp, lkflg);
2227 if (status)
2228 return status;
2229 } else {
2230 /* stp is the lock stateid */
2231 status = nfs4_check_openmode(stp->st_openstp, lkflg);
2232 if (status)
2233 return status;
2234 }
2218 2235
2219 if (!sop->so_is_open_owner)
2220 goto out;
2221 if (!cmp_clid(&clp->cl_clientid, lockclid))
2222 goto out;
2223 } 2236 }
2224 2237
2225 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) { 2238 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) {
2226 printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n"); 2239 printk("NFSD: preprocess_seqid_op: fh-stateid mismatch!\n");
2227 goto out; 2240 return nfserr_bad_stateid;
2228 } 2241 }
2229 2242
2230 *stpp = stp; 2243 *stpp = stp;
@@ -2235,63 +2248,41 @@ nfs4_preprocess_seqid_op(struct svc_fh *current_fh, u32 seqid, stateid_t *statei
2235 * For the moment, we ignore the possibility of 2248 * For the moment, we ignore the possibility of
2236 * generation number wraparound. 2249 * generation number wraparound.
2237 */ 2250 */
2238 if (seqid != sop->so_seqid + 1) 2251 if (seqid != sop->so_seqid)
2239 goto check_replay; 2252 goto check_replay;
2240 2253
2241 if (sop->so_confirmed) { 2254 if (sop->so_confirmed && flags & CONFIRM) {
2242 if (flags & CONFIRM) { 2255 printk("NFSD: preprocess_seqid_op: expected"
2243 printk("NFSD: preprocess_seqid_op: expected unconfirmed stateowner!\n"); 2256 " unconfirmed stateowner!\n");
2244 goto out; 2257 return nfserr_bad_stateid;
2245 }
2246 } 2258 }
2247 else { 2259 if (!sop->so_confirmed && !(flags & CONFIRM)) {
2248 if (!(flags & CONFIRM)) { 2260 printk("NFSD: preprocess_seqid_op: stateowner not"
2249 printk("NFSD: preprocess_seqid_op: stateowner not confirmed yet!\n"); 2261 " confirmed yet!\n");
2250 goto out; 2262 return nfserr_bad_stateid;
2251 }
2252 } 2263 }
2253 if (stateid->si_generation > stp->st_stateid.si_generation) { 2264 if (stateid->si_generation > stp->st_stateid.si_generation) {
2254 printk("NFSD: preprocess_seqid_op: future stateid?!\n"); 2265 printk("NFSD: preprocess_seqid_op: future stateid?!\n");
2255 goto out; 2266 return nfserr_bad_stateid;
2256 } 2267 }
2257 2268
2258 status = nfserr_old_stateid;
2259 if (stateid->si_generation < stp->st_stateid.si_generation) { 2269 if (stateid->si_generation < stp->st_stateid.si_generation) {
2260 printk("NFSD: preprocess_seqid_op: old stateid!\n"); 2270 printk("NFSD: preprocess_seqid_op: old stateid!\n");
2261 goto out; 2271 return nfserr_old_stateid;
2262 } 2272 }
2263 /* XXX renew the client lease here */ 2273 renew_client(sop->so_client);
2264 status = nfs_ok; 2274 return nfs_ok;
2265
2266out:
2267 return status;
2268
2269no_nfs4_stateid:
2270
2271 /*
2272 * We determine whether this is a bad stateid or a replay,
2273 * starting by trying to look up the stateowner.
2274 * If stateowner is not found - stateid is bad.
2275 */
2276 if (!(sop = find_openstateowner_id(stateid->si_stateownerid, flags))) {
2277 printk("NFSD: preprocess_seqid_op: no stateowner or nfs4_stateid!\n");
2278 status = nfserr_bad_stateid;
2279 goto out;
2280 }
2281 *sopp = sop;
2282 2275
2283check_replay: 2276check_replay:
2284 if (seqid == sop->so_seqid) { 2277 if (seqid == sop->so_seqid - 1) {
2285 printk("NFSD: preprocess_seqid_op: retransmission?\n"); 2278 printk("NFSD: preprocess_seqid_op: retransmission?\n");
2286 /* indicate replay to calling function */ 2279 /* indicate replay to calling function */
2287 status = NFSERR_REPLAY_ME; 2280 return NFSERR_REPLAY_ME;
2288 } else {
2289 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d\n", sop->so_seqid +1, seqid);
2290
2291 *sopp = NULL;
2292 status = nfserr_bad_seqid;
2293 } 2281 }
2294 goto out; 2282 printk("NFSD: preprocess_seqid_op: bad seqid (expected %d, got %d)\n",
2283 sop->so_seqid, seqid);
2284 *sopp = NULL;
2285 return nfserr_bad_seqid;
2295} 2286}
2296 2287
2297int 2288int
@@ -2609,7 +2600,6 @@ find_lockstateowner_str(struct inode *inode, clientid_t *clid,
2609 * occured. 2600 * occured.
2610 * 2601 *
2611 * strhashval = lock_ownerstr_hashval 2602 * strhashval = lock_ownerstr_hashval
2612 * so_seqid = lock->lk_new_lock_seqid - 1: it gets bumped in encode
2613 */ 2603 */
2614 2604
2615static struct nfs4_stateowner * 2605static struct nfs4_stateowner *
@@ -2634,7 +2624,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str
2634 sop->so_is_open_owner = 0; 2624 sop->so_is_open_owner = 0;
2635 sop->so_id = current_ownerid++; 2625 sop->so_id = current_ownerid++;
2636 sop->so_client = clp; 2626 sop->so_client = clp;
2637 sop->so_seqid = lock->lk_new_lock_seqid - 1; 2627 sop->so_seqid = lock->lk_new_lock_seqid;
2638 sop->so_confirmed = 1; 2628 sop->so_confirmed = 1;
2639 rp = &sop->so_replay; 2629 rp = &sop->so_replay;
2640 rp->rp_status = NFSERR_SERVERFAULT; 2630 rp->rp_status = NFSERR_SERVERFAULT;
@@ -2669,6 +2659,7 @@ alloc_init_lock_stateid(struct nfs4_stateowner *sop, struct nfs4_file *fp, struc
2669 stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */ 2659 stp->st_vfs_file = open_stp->st_vfs_file; /* FIXME refcount?? */
2670 stp->st_access_bmap = open_stp->st_access_bmap; 2660 stp->st_access_bmap = open_stp->st_access_bmap;
2671 stp->st_deny_bmap = open_stp->st_deny_bmap; 2661 stp->st_deny_bmap = open_stp->st_deny_bmap;
2662 stp->st_openstp = open_stp;
2672 2663
2673out: 2664out:
2674 return stp; 2665 return stp;
@@ -2699,22 +2690,17 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2699 (long long) lock->lk_offset, 2690 (long long) lock->lk_offset,
2700 (long long) lock->lk_length); 2691 (long long) lock->lk_length);
2701 2692
2702 if (nfs4_in_grace() && !lock->lk_reclaim)
2703 return nfserr_grace;
2704 if (!nfs4_in_grace() && lock->lk_reclaim)
2705 return nfserr_no_grace;
2706
2707 if (check_lock_length(lock->lk_offset, lock->lk_length)) 2693 if (check_lock_length(lock->lk_offset, lock->lk_length))
2708 return nfserr_inval; 2694 return nfserr_inval;
2709 2695
2710 nfs4_lock_state(); 2696 nfs4_lock_state();
2711 2697
2712 if (lock->lk_is_new) { 2698 if (lock->lk_is_new) {
2713 /* 2699 /*
2714 * Client indicates that this is a new lockowner. 2700 * Client indicates that this is a new lockowner.
2715 * Use open owner and open stateid to create lock owner and lock 2701 * Use open owner and open stateid to create lock owner and
2716 * stateid. 2702 * lock stateid.
2717 */ 2703 */
2718 struct nfs4_stateid *open_stp = NULL; 2704 struct nfs4_stateid *open_stp = NULL;
2719 struct nfs4_file *fp; 2705 struct nfs4_file *fp;
2720 2706
@@ -2724,23 +2710,14 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2724 goto out; 2710 goto out;
2725 } 2711 }
2726 2712
2727 /* is the new lock seqid presented by the client zero? */
2728 status = nfserr_bad_seqid;
2729 if (lock->v.new.lock_seqid != 0)
2730 goto out;
2731
2732 /* validate and update open stateid and open seqid */ 2713 /* validate and update open stateid and open seqid */
2733 status = nfs4_preprocess_seqid_op(current_fh, 2714 status = nfs4_preprocess_seqid_op(current_fh,
2734 lock->lk_new_open_seqid, 2715 lock->lk_new_open_seqid,
2735 &lock->lk_new_open_stateid, 2716 &lock->lk_new_open_stateid,
2736 CHECK_FH | OPEN_STATE, 2717 CHECK_FH | OPEN_STATE,
2737 &open_sop, &open_stp, 2718 &open_sop, &open_stp, lock);
2738 &lock->v.new.clientid); 2719 if (status)
2739 if (status) {
2740 if (lock->lk_reclaim)
2741 status = nfserr_reclaim_bad;
2742 goto out; 2720 goto out;
2743 }
2744 /* create lockowner and lock stateid */ 2721 /* create lockowner and lock stateid */
2745 fp = open_stp->st_file; 2722 fp = open_stp->st_file;
2746 strhashval = lock_ownerstr_hashval(fp->fi_inode, 2723 strhashval = lock_ownerstr_hashval(fp->fi_inode,
@@ -2766,7 +2743,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2766 lock->lk_old_lock_seqid, 2743 lock->lk_old_lock_seqid,
2767 &lock->lk_old_lock_stateid, 2744 &lock->lk_old_lock_stateid,
2768 CHECK_FH | LOCK_STATE, 2745 CHECK_FH | LOCK_STATE,
2769 &lock->lk_stateowner, &lock_stp, NULL); 2746 &lock->lk_stateowner, &lock_stp, lock);
2770 if (status) 2747 if (status)
2771 goto out; 2748 goto out;
2772 } 2749 }
@@ -2778,6 +2755,13 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
2778 goto out; 2755 goto out;
2779 } 2756 }
2780 2757
2758 status = nfserr_grace;
2759 if (nfs4_in_grace() && !lock->lk_reclaim)
2760 goto out;
2761 status = nfserr_no_grace;
2762 if (!nfs4_in_grace() && lock->lk_reclaim)
2763 goto out;
2764
2781 locks_init_lock(&file_lock); 2765 locks_init_lock(&file_lock);
2782 switch (lock->lk_type) { 2766 switch (lock->lk_type) {
2783 case NFS4_READ_LT: 2767 case NFS4_READ_LT:
@@ -2844,10 +2828,10 @@ conflicting_lock:
2844out_destroy_new_stateid: 2828out_destroy_new_stateid:
2845 if (lock->lk_is_new) { 2829 if (lock->lk_is_new) {
2846 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n"); 2830 dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
2847 /* 2831 /*
2848 * An error encountered after instantiation of the new 2832 * An error encountered after instantiation of the new
2849 * stateid has forced us to destroy it. 2833 * stateid has forced us to destroy it.
2850 */ 2834 */
2851 if (!seqid_mutating_err(status)) 2835 if (!seqid_mutating_err(status))
2852 open_sop->so_seqid--; 2836 open_sop->so_seqid--;
2853 2837
@@ -3083,7 +3067,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_release_lockowner *
3083 * of the lockowner state released; so don't release any until all 3067 * of the lockowner state released; so don't release any until all
3084 * have been checked. */ 3068 * have been checked. */
3085 status = nfs_ok; 3069 status = nfs_ok;
3086 list_for_each_entry(sop, &matches, so_perclient) { 3070 while (!list_empty(&matches)) {
3071 sop = list_entry(matches.next, struct nfs4_stateowner,
3072 so_perclient);
3073 /* unhash_stateowner deletes so_perclient only
3074 * for openowners. */
3075 list_del(&sop->so_perclient);
3087 release_stateowner(sop); 3076 release_stateowner(sop);
3088 } 3077 }
3089out: 3078out:
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 91fb171d2ace..4c4146350236 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1210,16 +1210,15 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1210 save = resp->p; 1210 save = resp->p;
1211 1211
1212/* 1212/*
1213 * Routine for encoding the result of a 1213 * Routine for encoding the result of a "seqid-mutating" NFSv4 operation. This
1214 * "seqid-mutating" NFSv4 operation. This is 1214 * is where sequence id's are incremented, and the replay cache is filled.
1215 * where seqids are incremented, and the 1215 * Note that we increment sequence id's here, at the last moment, so we're sure
1216 * replay cache is filled. 1216 * we know whether the error to be returned is a sequence id mutating error.
1217 */ 1217 */
1218 1218
1219#define ENCODE_SEQID_OP_TAIL(stateowner) do { \ 1219#define ENCODE_SEQID_OP_TAIL(stateowner) do { \
1220 if (seqid_mutating_err(nfserr) && stateowner) { \ 1220 if (seqid_mutating_err(nfserr) && stateowner) { \
1221 if (stateowner->so_confirmed) \ 1221 stateowner->so_seqid++; \
1222 stateowner->so_seqid++; \
1223 stateowner->so_replay.rp_status = nfserr; \ 1222 stateowner->so_replay.rp_status = nfserr; \
1224 stateowner->so_replay.rp_buflen = \ 1223 stateowner->so_replay.rp_buflen = \
1225 (((char *)(resp)->p - (char *)save)); \ 1224 (((char *)(resp)->p - (char *)save)); \
@@ -1367,9 +1366,9 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
1367 if ((buflen -= 4) < 0) 1366 if ((buflen -= 4) < 0)
1368 goto out_resource; 1367 goto out_resource;
1369 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) 1368 if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
1370 WRITE32(NFS4_FH_VOLATILE_ANY); 1369 WRITE32(NFS4_FH_PERSISTENT);
1371 else 1370 else
1372 WRITE32(NFS4_FH_VOLATILE_ANY|NFS4_FH_VOL_RENAME); 1371 WRITE32(NFS4_FH_PERSISTENT|NFS4_FH_VOL_RENAME);
1373 } 1372 }
1374 if (bmval0 & FATTR4_WORD0_CHANGE) { 1373 if (bmval0 & FATTR4_WORD0_CHANGE) {
1375 /* 1374 /*
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index be24ead89d94..5e0bf3917607 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -733,7 +733,7 @@ nfsd_sync(struct file *filp)
733 up(&inode->i_sem); 733 up(&inode->i_sem);
734} 734}
735 735
736static void 736void
737nfsd_sync_dir(struct dentry *dp) 737nfsd_sync_dir(struct dentry *dp)
738{ 738{
739 nfsd_dosync(NULL, dp, dp->d_inode->i_fop); 739 nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
diff --git a/fs/super.c b/fs/super.c
index 25bc1ec6bc5d..6e57ee252e14 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -840,7 +840,6 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
840 mnt->mnt_root = dget(sb->s_root); 840 mnt->mnt_root = dget(sb->s_root);
841 mnt->mnt_mountpoint = sb->s_root; 841 mnt->mnt_mountpoint = sb->s_root;
842 mnt->mnt_parent = mnt; 842 mnt->mnt_parent = mnt;
843 mnt->mnt_namespace = current->namespace;
844 up_write(&sb->s_umount); 843 up_write(&sb->s_umount);
845 free_secdata(secdata); 844 free_secdata(secdata);
846 put_filesystem(type); 845 put_filesystem(type);