aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/error.c1
-rw-r--r--fs/9p/fid.c69
-rw-r--r--fs/9p/fid.h5
-rw-r--r--fs/9p/mux.c4
-rw-r--r--fs/9p/v9fs.c11
-rw-r--r--fs/9p/vfs_file.c47
-rw-r--r--fs/9p/vfs_inode.c206
-rw-r--r--fs/binfmt_elf.c51
-rw-r--r--fs/binfmt_elf_fdpic.c8
-rw-r--r--fs/block_dev.c10
-rw-r--r--fs/buffer.c19
-rw-r--r--fs/cifs/CHANGES4
-rw-r--r--fs/cifs/cifs_debug.c4
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/misc.c8
-rw-r--r--fs/cifs/sess.c13
-rw-r--r--fs/fs-writeback.c13
-rw-r--r--fs/fuse/control.c4
-rw-r--r--fs/hostfs/hostfs.h2
-rw-r--r--fs/hostfs/hostfs_kern.c2
-rw-r--r--fs/hostfs/hostfs_user.c4
-rw-r--r--fs/jffs/jffs_fm.c3
-rw-r--r--fs/jffs2/debug.c4
-rw-r--r--fs/jffs2/debug.h1
-rw-r--r--fs/jffs2/fs.c3
-rw-r--r--fs/jffs2/gc.c2
-rw-r--r--fs/jffs2/nodelist.h10
-rw-r--r--fs/jffs2/readinode.c3
-rw-r--r--fs/jffs2/scan.c6
-rw-r--r--fs/jffs2/summary.c6
-rw-r--r--fs/jffs2/super.c7
-rw-r--r--fs/jffs2/symlink.c2
-rw-r--r--fs/jffs2/wbuf.c21
-rw-r--r--fs/jffs2/xattr.c5
-rw-r--r--fs/lockd/clntlock.c4
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/nfs/file.c5
-rw-r--r--fs/nfs/inode.c97
-rw-r--r--fs/nfs/symlink.c4
-rw-r--r--fs/nfsd/export.c1
-rw-r--r--fs/nfsd/nfs3xdr.c9
-rw-r--r--fs/nfsd/nfs4xdr.c5
-rw-r--r--fs/nfsd/nfsfh.c14
-rw-r--r--fs/nfsd/nfssvc.c8
-rw-r--r--fs/nfsd/nfsxdr.c5
-rw-r--r--fs/nfsd/vfs.c29
-rw-r--r--fs/ntfs/ChangeLog7
-rw-r--r--fs/ntfs/Makefile2
-rw-r--r--fs/ntfs/aops.c4
-rw-r--r--fs/ntfs/dir.c45
-rw-r--r--fs/ntfs/inode.c69
-rw-r--r--fs/ntfs/inode.h6
-rw-r--r--fs/ntfs/super.c7
-rw-r--r--fs/ocfs2/export.c5
-rw-r--r--fs/ocfs2/inode.c11
-rw-r--r--fs/ocfs2/namei.c69
-rw-r--r--fs/ocfs2/ocfs2_fs.h43
-rw-r--r--fs/ocfs2/symlink.c3
-rw-r--r--fs/proc/base.c8
-rw-r--r--fs/reiserfs/file.c20
-rw-r--r--fs/reiserfs/inode.c2
-rw-r--r--fs/ufs/balloc.c46
-rw-r--r--fs/ufs/inode.c14
-rw-r--r--fs/ufs/truncate.c4
64 files changed, 677 insertions, 431 deletions
diff --git a/fs/9p/error.c b/fs/9p/error.c
index ae91555c1558..0d7fa4e08812 100644
--- a/fs/9p/error.c
+++ b/fs/9p/error.c
@@ -83,6 +83,7 @@ int v9fs_errstr2errno(char *errstr, int len)
83 83
84 if (errno == 0) { 84 if (errno == 0) {
85 /* TODO: if error isn't found, add it dynamically */ 85 /* TODO: if error isn't found, add it dynamically */
86 errstr[len] = 0;
86 printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__, 87 printk(KERN_ERR "%s: errstr :%s: not found\n", __FUNCTION__,
87 errstr); 88 errstr);
88 errno = 1; 89 errno = 1;
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 27507201f9e7..a9b6301a04fc 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -25,6 +25,7 @@
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <linux/idr.h> 27#include <linux/idr.h>
28#include <asm/semaphore.h>
28 29
29#include "debug.h" 30#include "debug.h"
30#include "v9fs.h" 31#include "v9fs.h"
@@ -84,6 +85,7 @@ struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *v9ses, int fid)
84 new->iounit = 0; 85 new->iounit = 0;
85 new->rdir_pos = 0; 86 new->rdir_pos = 0;
86 new->rdir_fcall = NULL; 87 new->rdir_fcall = NULL;
88 init_MUTEX(&new->lock);
87 INIT_LIST_HEAD(&new->list); 89 INIT_LIST_HEAD(&new->list);
88 90
89 return new; 91 return new;
@@ -102,11 +104,11 @@ void v9fs_fid_destroy(struct v9fs_fid *fid)
102} 104}
103 105
104/** 106/**
105 * v9fs_fid_lookup - retrieve the right fid from a particular dentry 107 * v9fs_fid_lookup - return a locked fid from a dentry
106 * @dentry: dentry to look for fid in 108 * @dentry: dentry to look for fid in
107 * @type: intent of lookup (operation or traversal)
108 * 109 *
109 * find a fid in the dentry 110 * find a fid in the dentry, obtain its semaphore and return a reference to it.
111 * code calling lookup is responsible for releasing lock
110 * 112 *
111 * TODO: only match fids that have the same uid as current user 113 * TODO: only match fids that have the same uid as current user
112 * 114 *
@@ -124,7 +126,68 @@ struct v9fs_fid *v9fs_fid_lookup(struct dentry *dentry)
124 126
125 if (!return_fid) { 127 if (!return_fid) {
126 dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n"); 128 dprintk(DEBUG_ERROR, "Couldn't find a fid in dentry\n");
129 return_fid = ERR_PTR(-EBADF);
127 } 130 }
128 131
132 if(down_interruptible(&return_fid->lock))
133 return ERR_PTR(-EINTR);
134
129 return return_fid; 135 return return_fid;
130} 136}
137
138/**
139 * v9fs_fid_clone - lookup the fid for a dentry, clone a private copy and release it
140 * @dentry: dentry to look for fid in
141 *
142 * find a fid in the dentry and then clone to a new private fid
143 *
144 * TODO: only match fids that have the same uid as current user
145 *
146 */
147
148struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry)
149{
150 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
151 struct v9fs_fid *base_fid, *new_fid = ERR_PTR(-EBADF);
152 struct v9fs_fcall *fcall = NULL;
153 int fid, err;
154
155 base_fid = v9fs_fid_lookup(dentry);
156
157 if(IS_ERR(base_fid))
158 return base_fid;
159
160 if(base_fid) { /* clone fid */
161 fid = v9fs_get_idpool(&v9ses->fidpool);
162 if (fid < 0) {
163 eprintk(KERN_WARNING, "newfid fails!\n");
164 new_fid = ERR_PTR(-ENOSPC);
165 goto Release_Fid;
166 }
167
168 err = v9fs_t_walk(v9ses, base_fid->fid, fid, NULL, &fcall);
169 if (err < 0) {
170 dprintk(DEBUG_ERROR, "clone walk didn't work\n");
171 v9fs_put_idpool(fid, &v9ses->fidpool);
172 new_fid = ERR_PTR(err);
173 goto Free_Fcall;
174 }
175 new_fid = v9fs_fid_create(v9ses, fid);
176 if (new_fid == NULL) {
177 dprintk(DEBUG_ERROR, "out of memory\n");
178 new_fid = ERR_PTR(-ENOMEM);
179 }
180Free_Fcall:
181 kfree(fcall);
182 }
183
184Release_Fid:
185 up(&base_fid->lock);
186 return new_fid;
187}
188
189void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid)
190{
191 v9fs_t_clunk(v9ses, fid->fid);
192 v9fs_fid_destroy(fid);
193}
diff --git a/fs/9p/fid.h b/fs/9p/fid.h
index aa974d6875c3..48fc170c26c8 100644
--- a/fs/9p/fid.h
+++ b/fs/9p/fid.h
@@ -30,6 +30,8 @@ struct v9fs_fid {
30 struct list_head list; /* list of fids associated with a dentry */ 30 struct list_head list; /* list of fids associated with a dentry */
31 struct list_head active; /* XXX - debug */ 31 struct list_head active; /* XXX - debug */
32 32
33 struct semaphore lock;
34
33 u32 fid; 35 u32 fid;
34 unsigned char fidopen; /* set when fid is opened */ 36 unsigned char fidopen; /* set when fid is opened */
35 unsigned char fidclunked; /* set when fid has already been clunked */ 37 unsigned char fidclunked; /* set when fid has already been clunked */
@@ -55,3 +57,6 @@ struct v9fs_fid *v9fs_fid_get_created(struct dentry *);
55void v9fs_fid_destroy(struct v9fs_fid *fid); 57void v9fs_fid_destroy(struct v9fs_fid *fid);
56struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid); 58struct v9fs_fid *v9fs_fid_create(struct v9fs_session_info *, int fid);
57int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry); 59int v9fs_fid_insert(struct v9fs_fid *fid, struct dentry *dentry);
60struct v9fs_fid *v9fs_fid_clone(struct dentry *dentry);
61void v9fs_fid_clunk(struct v9fs_session_info *v9ses, struct v9fs_fid *fid);
62
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
index 944273c3dbff..147ceef8e537 100644
--- a/fs/9p/mux.c
+++ b/fs/9p/mux.c
@@ -132,8 +132,10 @@ int v9fs_mux_global_init(void)
132 v9fs_mux_poll_tasks[i].task = NULL; 132 v9fs_mux_poll_tasks[i].task = NULL;
133 133
134 v9fs_mux_wq = create_workqueue("v9fs"); 134 v9fs_mux_wq = create_workqueue("v9fs");
135 if (!v9fs_mux_wq) 135 if (!v9fs_mux_wq) {
136 printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
136 return -ENOMEM; 137 return -ENOMEM;
138 }
137 139
138 return 0; 140 return 0;
139} 141}
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 0b96fae8b479..d9b561ba5e58 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -457,14 +457,19 @@ static int __init init_v9fs(void)
457 457
458 v9fs_error_init(); 458 v9fs_error_init();
459 459
460 printk(KERN_INFO "Installing v9fs 9P2000 file system support\n"); 460 printk(KERN_INFO "Installing v9fs 9p2000 file system support\n");
461 461
462 ret = v9fs_mux_global_init(); 462 ret = v9fs_mux_global_init();
463 if (!ret) 463 if (ret) {
464 printk(KERN_WARNING "v9fs: starting mux failed\n");
464 return ret; 465 return ret;
466 }
465 ret = register_filesystem(&v9fs_fs_type); 467 ret = register_filesystem(&v9fs_fs_type);
466 if (!ret) 468 if (ret) {
469 printk(KERN_WARNING "v9fs: registering file system failed\n");
467 v9fs_mux_global_exit(); 470 v9fs_mux_global_exit();
471 }
472
468 return ret; 473 return ret;
469} 474}
470 475
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index e86a07151280..9f17b0cacdd0 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -55,53 +55,22 @@ int v9fs_file_open(struct inode *inode, struct file *file)
55 struct v9fs_fid *vfid; 55 struct v9fs_fid *vfid;
56 struct v9fs_fcall *fcall = NULL; 56 struct v9fs_fcall *fcall = NULL;
57 int omode; 57 int omode;
58 int fid = V9FS_NOFID;
59 int err; 58 int err;
60 59
61 dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file); 60 dprintk(DEBUG_VFS, "inode: %p file: %p \n", inode, file);
62 61
63 vfid = v9fs_fid_lookup(file->f_path.dentry); 62 vfid = v9fs_fid_clone(file->f_path.dentry);
64 if (!vfid) { 63 if (IS_ERR(vfid))
65 dprintk(DEBUG_ERROR, "Couldn't resolve fid from dentry\n"); 64 return PTR_ERR(vfid);
66 return -EBADF;
67 }
68
69 fid = v9fs_get_idpool(&v9ses->fidpool);
70 if (fid < 0) {
71 eprintk(KERN_WARNING, "newfid fails!\n");
72 return -ENOSPC;
73 }
74 65
75 err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, &fcall);
76 if (err < 0) {
77 dprintk(DEBUG_ERROR, "rewalk didn't work\n");
78 if (fcall && fcall->id == RWALK)
79 goto clunk_fid;
80 else {
81 v9fs_put_idpool(fid, &v9ses->fidpool);
82 goto free_fcall;
83 }
84 }
85 kfree(fcall);
86
87 /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
88 /* translate open mode appropriately */
89 omode = v9fs_uflags2omode(file->f_flags); 66 omode = v9fs_uflags2omode(file->f_flags);
90 err = v9fs_t_open(v9ses, fid, omode, &fcall); 67 err = v9fs_t_open(v9ses, vfid->fid, omode, &fcall);
91 if (err < 0) { 68 if (err < 0) {
92 PRINT_FCALL_ERROR("open failed", fcall); 69 PRINT_FCALL_ERROR("open failed", fcall);
93 goto clunk_fid; 70 goto Clunk_Fid;
94 }
95
96 vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
97 if (vfid == NULL) {
98 dprintk(DEBUG_ERROR, "out of memory\n");
99 err = -ENOMEM;
100 goto clunk_fid;
101 } 71 }
102 72
103 file->private_data = vfid; 73 file->private_data = vfid;
104 vfid->fid = fid;
105 vfid->fidopen = 1; 74 vfid->fidopen = 1;
106 vfid->fidclunked = 0; 75 vfid->fidclunked = 0;
107 vfid->iounit = fcall->params.ropen.iounit; 76 vfid->iounit = fcall->params.ropen.iounit;
@@ -112,10 +81,8 @@ int v9fs_file_open(struct inode *inode, struct file *file)
112 81
113 return 0; 82 return 0;
114 83
115clunk_fid: 84Clunk_Fid:
116 v9fs_t_clunk(v9ses, fid); 85 v9fs_fid_clunk(v9ses, vfid);
117
118free_fcall:
119 kfree(fcall); 86 kfree(fcall);
120 87
121 return err; 88 return err;
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 18f26cdfd882..9109ba1d6969 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -416,12 +416,8 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
416 sb = file_inode->i_sb; 416 sb = file_inode->i_sb;
417 v9ses = v9fs_inode2v9ses(file_inode); 417 v9ses = v9fs_inode2v9ses(file_inode);
418 v9fid = v9fs_fid_lookup(file); 418 v9fid = v9fs_fid_lookup(file);
419 419 if(IS_ERR(v9fid))
420 if (!v9fid) { 420 return PTR_ERR(v9fid);
421 dprintk(DEBUG_ERROR,
422 "no v9fs_fid\n");
423 return -EBADF;
424 }
425 421
426 fid = v9fid->fid; 422 fid = v9fid->fid;
427 if (fid < 0) { 423 if (fid < 0) {
@@ -433,11 +429,13 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
433 result = v9fs_t_remove(v9ses, fid, &fcall); 429 result = v9fs_t_remove(v9ses, fid, &fcall);
434 if (result < 0) { 430 if (result < 0) {
435 PRINT_FCALL_ERROR("remove fails", fcall); 431 PRINT_FCALL_ERROR("remove fails", fcall);
432 goto Error;
436 } 433 }
437 434
438 v9fs_put_idpool(fid, &v9ses->fidpool); 435 v9fs_put_idpool(fid, &v9ses->fidpool);
439 v9fs_fid_destroy(v9fid); 436 v9fs_fid_destroy(v9fid);
440 437
438Error:
441 kfree(fcall); 439 kfree(fcall);
442 return result; 440 return result;
443} 441}
@@ -473,9 +471,13 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
473 inode = NULL; 471 inode = NULL;
474 vfid = NULL; 472 vfid = NULL;
475 v9ses = v9fs_inode2v9ses(dir); 473 v9ses = v9fs_inode2v9ses(dir);
476 dfid = v9fs_fid_lookup(dentry->d_parent); 474 dfid = v9fs_fid_clone(dentry->d_parent);
477 perm = unixmode2p9mode(v9ses, mode); 475 if(IS_ERR(dfid)) {
476 err = PTR_ERR(dfid);
477 goto error;
478 }
478 479
480 perm = unixmode2p9mode(v9ses, mode);
479 if (nd && nd->flags & LOOKUP_OPEN) 481 if (nd && nd->flags & LOOKUP_OPEN)
480 flags = nd->intent.open.flags - 1; 482 flags = nd->intent.open.flags - 1;
481 else 483 else
@@ -485,9 +487,10 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
485 perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit); 487 perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit);
486 488
487 if (err) 489 if (err)
488 goto error; 490 goto clunk_dfid;
489 491
490 vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); 492 vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry);
493 v9fs_fid_clunk(v9ses, dfid);
491 if (IS_ERR(vfid)) { 494 if (IS_ERR(vfid)) {
492 err = PTR_ERR(vfid); 495 err = PTR_ERR(vfid);
493 vfid = NULL; 496 vfid = NULL;
@@ -525,6 +528,9 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
525 528
526 return 0; 529 return 0;
527 530
531clunk_dfid:
532 v9fs_fid_clunk(v9ses, dfid);
533
528error: 534error:
529 if (vfid) 535 if (vfid)
530 v9fs_fid_destroy(vfid); 536 v9fs_fid_destroy(vfid);
@@ -551,7 +557,12 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
551 inode = NULL; 557 inode = NULL;
552 vfid = NULL; 558 vfid = NULL;
553 v9ses = v9fs_inode2v9ses(dir); 559 v9ses = v9fs_inode2v9ses(dir);
554 dfid = v9fs_fid_lookup(dentry->d_parent); 560 dfid = v9fs_fid_clone(dentry->d_parent);
561 if(IS_ERR(dfid)) {
562 err = PTR_ERR(dfid);
563 goto error;
564 }
565
555 perm = unixmode2p9mode(v9ses, mode | S_IFDIR); 566 perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
556 567
557 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, 568 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name,
@@ -559,37 +570,36 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
559 570
560 if (err) { 571 if (err) {
561 dprintk(DEBUG_ERROR, "create error %d\n", err); 572 dprintk(DEBUG_ERROR, "create error %d\n", err);
562 goto error; 573 goto clean_up_dfid;
563 }
564
565 err = v9fs_t_clunk(v9ses, fid);
566 if (err) {
567 dprintk(DEBUG_ERROR, "clunk error %d\n", err);
568 goto error;
569 } 574 }
570 575
571 vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); 576 vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry);
572 if (IS_ERR(vfid)) { 577 if (IS_ERR(vfid)) {
573 err = PTR_ERR(vfid); 578 err = PTR_ERR(vfid);
574 vfid = NULL; 579 vfid = NULL;
575 goto error; 580 goto clean_up_dfid;
576 } 581 }
577 582
583 v9fs_fid_clunk(v9ses, dfid);
578 inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); 584 inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb);
579 if (IS_ERR(inode)) { 585 if (IS_ERR(inode)) {
580 err = PTR_ERR(inode); 586 err = PTR_ERR(inode);
581 inode = NULL; 587 inode = NULL;
582 goto error; 588 goto clean_up_fids;
583 } 589 }
584 590
585 dentry->d_op = &v9fs_dentry_operations; 591 dentry->d_op = &v9fs_dentry_operations;
586 d_instantiate(dentry, inode); 592 d_instantiate(dentry, inode);
587 return 0; 593 return 0;
588 594
589error: 595clean_up_fids:
590 if (vfid) 596 if (vfid)
591 v9fs_fid_destroy(vfid); 597 v9fs_fid_destroy(vfid);
592 598
599clean_up_dfid:
600 v9fs_fid_clunk(v9ses, dfid);
601
602error:
593 return err; 603 return err;
594} 604}
595 605
@@ -622,28 +632,23 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
622 dentry->d_op = &v9fs_dentry_operations; 632 dentry->d_op = &v9fs_dentry_operations;
623 dirfid = v9fs_fid_lookup(dentry->d_parent); 633 dirfid = v9fs_fid_lookup(dentry->d_parent);
624 634
625 if (!dirfid) { 635 if(IS_ERR(dirfid))
626 dprintk(DEBUG_ERROR, "no dirfid\n"); 636 return ERR_PTR(PTR_ERR(dirfid));
627 return ERR_PTR(-EINVAL);
628 }
629 637
630 dirfidnum = dirfid->fid; 638 dirfidnum = dirfid->fid;
631 639
632 if (dirfidnum < 0) {
633 dprintk(DEBUG_ERROR, "no dirfid for inode %p, #%lu\n",
634 dir, dir->i_ino);
635 return ERR_PTR(-EBADF);
636 }
637
638 newfid = v9fs_get_idpool(&v9ses->fidpool); 640 newfid = v9fs_get_idpool(&v9ses->fidpool);
639 if (newfid < 0) { 641 if (newfid < 0) {
640 eprintk(KERN_WARNING, "newfid fails!\n"); 642 eprintk(KERN_WARNING, "newfid fails!\n");
641 return ERR_PTR(-ENOSPC); 643 result = -ENOSPC;
644 goto Release_Dirfid;
642 } 645 }
643 646
644 result = v9fs_t_walk(v9ses, dirfidnum, newfid, 647 result = v9fs_t_walk(v9ses, dirfidnum, newfid,
645 (char *)dentry->d_name.name, &fcall); 648 (char *)dentry->d_name.name, &fcall);
646 649
650 up(&dirfid->lock);
651
647 if (result < 0) { 652 if (result < 0) {
648 if (fcall && fcall->id == RWALK) 653 if (fcall && fcall->id == RWALK)
649 v9fs_t_clunk(v9ses, newfid); 654 v9fs_t_clunk(v9ses, newfid);
@@ -701,8 +706,12 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
701 706
702 return NULL; 707 return NULL;
703 708
704 FreeFcall: 709Release_Dirfid:
710 up(&dirfid->lock);
711
712FreeFcall:
705 kfree(fcall); 713 kfree(fcall);
714
706 return ERR_PTR(result); 715 return ERR_PTR(result);
707} 716}
708 717
@@ -746,10 +755,8 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
746 struct inode *old_inode = old_dentry->d_inode; 755 struct inode *old_inode = old_dentry->d_inode;
747 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); 756 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode);
748 struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry); 757 struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry);
749 struct v9fs_fid *olddirfid = 758 struct v9fs_fid *olddirfid;
750 v9fs_fid_lookup(old_dentry->d_parent); 759 struct v9fs_fid *newdirfid;
751 struct v9fs_fid *newdirfid =
752 v9fs_fid_lookup(new_dentry->d_parent);
753 struct v9fs_wstat wstat; 760 struct v9fs_wstat wstat;
754 struct v9fs_fcall *fcall = NULL; 761 struct v9fs_fcall *fcall = NULL;
755 int fid = -1; 762 int fid = -1;
@@ -759,16 +766,26 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
759 766
760 dprintk(DEBUG_VFS, "\n"); 767 dprintk(DEBUG_VFS, "\n");
761 768
762 if ((!oldfid) || (!olddirfid) || (!newdirfid)) { 769 if(IS_ERR(oldfid))
763 dprintk(DEBUG_ERROR, "problem with arguments\n"); 770 return PTR_ERR(oldfid);
764 return -EBADF; 771
772 olddirfid = v9fs_fid_clone(old_dentry->d_parent);
773 if(IS_ERR(olddirfid)) {
774 retval = PTR_ERR(olddirfid);
775 goto Release_lock;
776 }
777
778 newdirfid = v9fs_fid_clone(new_dentry->d_parent);
779 if(IS_ERR(newdirfid)) {
780 retval = PTR_ERR(newdirfid);
781 goto Clunk_olddir;
765 } 782 }
766 783
767 /* 9P can only handle file rename in the same directory */ 784 /* 9P can only handle file rename in the same directory */
768 if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) { 785 if (memcmp(&olddirfid->qid, &newdirfid->qid, sizeof(newdirfid->qid))) {
769 dprintk(DEBUG_ERROR, "old dir and new dir are different\n"); 786 dprintk(DEBUG_ERROR, "old dir and new dir are different\n");
770 retval = -EPERM; 787 retval = -EXDEV;
771 goto FreeFcallnBail; 788 goto Clunk_newdir;
772 } 789 }
773 790
774 fid = oldfid->fid; 791 fid = oldfid->fid;
@@ -779,7 +796,7 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
779 dprintk(DEBUG_ERROR, "no fid for old file #%lu\n", 796 dprintk(DEBUG_ERROR, "no fid for old file #%lu\n",
780 old_inode->i_ino); 797 old_inode->i_ino);
781 retval = -EBADF; 798 retval = -EBADF;
782 goto FreeFcallnBail; 799 goto Clunk_newdir;
783 } 800 }
784 801
785 v9fs_blank_wstat(&wstat); 802 v9fs_blank_wstat(&wstat);
@@ -788,11 +805,20 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
788 805
789 retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall); 806 retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall);
790 807
791 FreeFcallnBail:
792 if (retval < 0) 808 if (retval < 0)
793 PRINT_FCALL_ERROR("wstat error", fcall); 809 PRINT_FCALL_ERROR("wstat error", fcall);
794 810
795 kfree(fcall); 811 kfree(fcall);
812
813Clunk_newdir:
814 v9fs_fid_clunk(v9ses, newdirfid);
815
816Clunk_olddir:
817 v9fs_fid_clunk(v9ses, olddirfid);
818
819Release_lock:
820 up(&oldfid->lock);
821
796 return retval; 822 return retval;
797} 823}
798 824
@@ -810,15 +836,12 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
810{ 836{
811 struct v9fs_fcall *fcall = NULL; 837 struct v9fs_fcall *fcall = NULL;
812 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 838 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
813 struct v9fs_fid *fid = v9fs_fid_lookup(dentry); 839 struct v9fs_fid *fid = v9fs_fid_clone(dentry);
814 int err = -EPERM; 840 int err = -EPERM;
815 841
816 dprintk(DEBUG_VFS, "dentry: %p\n", dentry); 842 dprintk(DEBUG_VFS, "dentry: %p\n", dentry);
817 if (!fid) { 843 if(IS_ERR(fid))
818 dprintk(DEBUG_ERROR, 844 return PTR_ERR(fid);
819 "couldn't find fid associated with dentry\n");
820 return -EBADF;
821 }
822 845
823 err = v9fs_t_stat(v9ses, fid->fid, &fcall); 846 err = v9fs_t_stat(v9ses, fid->fid, &fcall);
824 847
@@ -831,6 +854,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
831 } 854 }
832 855
833 kfree(fcall); 856 kfree(fcall);
857 v9fs_fid_clunk(v9ses, fid);
834 return err; 858 return err;
835} 859}
836 860
@@ -844,18 +868,14 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
844static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) 868static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
845{ 869{
846 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 870 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
847 struct v9fs_fid *fid = v9fs_fid_lookup(dentry); 871 struct v9fs_fid *fid = v9fs_fid_clone(dentry);
848 struct v9fs_fcall *fcall = NULL; 872 struct v9fs_fcall *fcall = NULL;
849 struct v9fs_wstat wstat; 873 struct v9fs_wstat wstat;
850 int res = -EPERM; 874 int res = -EPERM;
851 875
852 dprintk(DEBUG_VFS, "\n"); 876 dprintk(DEBUG_VFS, "\n");
853 877 if(IS_ERR(fid))
854 if (!fid) { 878 return PTR_ERR(fid);
855 dprintk(DEBUG_ERROR,
856 "Couldn't find fid associated with dentry\n");
857 return -EBADF;
858 }
859 879
860 v9fs_blank_wstat(&wstat); 880 v9fs_blank_wstat(&wstat);
861 if (iattr->ia_valid & ATTR_MODE) 881 if (iattr->ia_valid & ATTR_MODE)
@@ -887,6 +907,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
887 if (res >= 0) 907 if (res >= 0)
888 res = inode_setattr(dentry->d_inode, iattr); 908 res = inode_setattr(dentry->d_inode, iattr);
889 909
910 v9fs_fid_clunk(v9ses, fid);
890 return res; 911 return res;
891} 912}
892 913
@@ -987,18 +1008,15 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
987 1008
988 struct v9fs_fcall *fcall = NULL; 1009 struct v9fs_fcall *fcall = NULL;
989 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 1010 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
990 struct v9fs_fid *fid = v9fs_fid_lookup(dentry); 1011 struct v9fs_fid *fid = v9fs_fid_clone(dentry);
991 1012
992 if (!fid) { 1013 if(IS_ERR(fid))
993 dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n"); 1014 return PTR_ERR(fid);
994 retval = -EBADF;
995 goto FreeFcall;
996 }
997 1015
998 if (!v9ses->extended) { 1016 if (!v9ses->extended) {
999 retval = -EBADF; 1017 retval = -EBADF;
1000 dprintk(DEBUG_ERROR, "not extended\n"); 1018 dprintk(DEBUG_ERROR, "not extended\n");
1001 goto FreeFcall; 1019 goto ClunkFid;
1002 } 1020 }
1003 1021
1004 dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name); 1022 dprintk(DEBUG_VFS, " %s\n", dentry->d_name.name);
@@ -1009,8 +1027,10 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1009 goto FreeFcall; 1027 goto FreeFcall;
1010 } 1028 }
1011 1029
1012 if (!fcall) 1030 if (!fcall) {
1013 return -EIO; 1031 retval = -EIO;
1032 goto ClunkFid;
1033 }
1014 1034
1015 if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) { 1035 if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) {
1016 retval = -EINVAL; 1036 retval = -EINVAL;
@@ -1028,9 +1048,12 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1028 fcall->params.rstat.stat.extension.str, buffer); 1048 fcall->params.rstat.stat.extension.str, buffer);
1029 retval = buflen; 1049 retval = buflen;
1030 1050
1031 FreeFcall: 1051FreeFcall:
1032 kfree(fcall); 1052 kfree(fcall);
1033 1053
1054ClunkFid:
1055 v9fs_fid_clunk(v9ses, fid);
1056
1034 return retval; 1057 return retval;
1035} 1058}
1036 1059
@@ -1123,52 +1146,58 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1123 int err; 1146 int err;
1124 u32 fid, perm; 1147 u32 fid, perm;
1125 struct v9fs_session_info *v9ses; 1148 struct v9fs_session_info *v9ses;
1126 struct v9fs_fid *dfid, *vfid; 1149 struct v9fs_fid *dfid, *vfid = NULL;
1127 struct inode *inode; 1150 struct inode *inode = NULL;
1128 1151
1129 inode = NULL;
1130 vfid = NULL;
1131 v9ses = v9fs_inode2v9ses(dir); 1152 v9ses = v9fs_inode2v9ses(dir);
1132 dfid = v9fs_fid_lookup(dentry->d_parent);
1133 perm = unixmode2p9mode(v9ses, mode);
1134
1135 if (!v9ses->extended) { 1153 if (!v9ses->extended) {
1136 dprintk(DEBUG_ERROR, "not extended\n"); 1154 dprintk(DEBUG_ERROR, "not extended\n");
1137 return -EPERM; 1155 return -EPERM;
1138 } 1156 }
1139 1157
1158 dfid = v9fs_fid_clone(dentry->d_parent);
1159 if(IS_ERR(dfid)) {
1160 err = PTR_ERR(dfid);
1161 goto error;
1162 }
1163
1164 perm = unixmode2p9mode(v9ses, mode);
1165
1140 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, 1166 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name,
1141 perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL); 1167 perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL);
1142 1168
1143 if (err) 1169 if (err)
1144 goto error; 1170 goto clunk_dfid;
1145 1171
1146 err = v9fs_t_clunk(v9ses, fid); 1172 err = v9fs_t_clunk(v9ses, fid);
1147 if (err) 1173 if (err)
1148 goto error; 1174 goto clunk_dfid;
1149 1175
1150 vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry); 1176 vfid = v9fs_clone_walk(v9ses, dfid->fid, dentry);
1151 if (IS_ERR(vfid)) { 1177 if (IS_ERR(vfid)) {
1152 err = PTR_ERR(vfid); 1178 err = PTR_ERR(vfid);
1153 vfid = NULL; 1179 vfid = NULL;
1154 goto error; 1180 goto clunk_dfid;
1155 } 1181 }
1156 1182
1157 inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb); 1183 inode = v9fs_inode_from_fid(v9ses, vfid->fid, dir->i_sb);
1158 if (IS_ERR(inode)) { 1184 if (IS_ERR(inode)) {
1159 err = PTR_ERR(inode); 1185 err = PTR_ERR(inode);
1160 inode = NULL; 1186 inode = NULL;
1161 goto error; 1187 goto free_vfid;
1162 } 1188 }
1163 1189
1164 dentry->d_op = &v9fs_dentry_operations; 1190 dentry->d_op = &v9fs_dentry_operations;
1165 d_instantiate(dentry, inode); 1191 d_instantiate(dentry, inode);
1166 return 0; 1192 return 0;
1167 1193
1168error: 1194free_vfid:
1169 if (vfid) 1195 v9fs_fid_destroy(vfid);
1170 v9fs_fid_destroy(vfid); 1196
1197clunk_dfid:
1198 v9fs_fid_clunk(v9ses, dfid);
1171 1199
1200error:
1172 return err; 1201 return err;
1173 1202
1174} 1203}
@@ -1209,26 +1238,29 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1209 struct dentry *dentry) 1238 struct dentry *dentry)
1210{ 1239{
1211 int retval; 1240 int retval;
1241 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
1212 struct v9fs_fid *oldfid; 1242 struct v9fs_fid *oldfid;
1213 char *name; 1243 char *name;
1214 1244
1215 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name, 1245 dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
1216 old_dentry->d_name.name); 1246 old_dentry->d_name.name);
1217 1247
1218 oldfid = v9fs_fid_lookup(old_dentry); 1248 oldfid = v9fs_fid_clone(old_dentry);
1219 if (!oldfid) { 1249 if(IS_ERR(oldfid))
1220 dprintk(DEBUG_ERROR, "can't find oldfid\n"); 1250 return PTR_ERR(oldfid);
1221 return -EPERM;
1222 }
1223 1251
1224 name = __getname(); 1252 name = __getname();
1225 if (unlikely(!name)) 1253 if (unlikely(!name)) {
1226 return -ENOMEM; 1254 retval = -ENOMEM;
1255 goto clunk_fid;
1256 }
1227 1257
1228 sprintf(name, "%d\n", oldfid->fid); 1258 sprintf(name, "%d\n", oldfid->fid);
1229 retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); 1259 retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name);
1230 __putname(name); 1260 __putname(name);
1231 1261
1262clunk_fid:
1263 v9fs_fid_clunk(v9ses, oldfid);
1232 return retval; 1264 return retval;
1233} 1265}
1234 1266
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 7cb28720f90e..669dbe5b0317 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -682,6 +682,15 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
682 retval = PTR_ERR(interpreter); 682 retval = PTR_ERR(interpreter);
683 if (IS_ERR(interpreter)) 683 if (IS_ERR(interpreter))
684 goto out_free_interp; 684 goto out_free_interp;
685
686 /*
687 * If the binary is not readable then enforce
688 * mm->dumpable = 0 regardless of the interpreter's
689 * permissions.
690 */
691 if (file_permission(interpreter, MAY_READ) < 0)
692 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
693
685 retval = kernel_read(interpreter, 0, bprm->buf, 694 retval = kernel_read(interpreter, 0, bprm->buf,
686 BINPRM_BUF_SIZE); 695 BINPRM_BUF_SIZE);
687 if (retval != BINPRM_BUF_SIZE) { 696 if (retval != BINPRM_BUF_SIZE) {
@@ -1178,6 +1187,10 @@ static int dump_seek(struct file *file, loff_t off)
1178 */ 1187 */
1179static int maydump(struct vm_area_struct *vma) 1188static int maydump(struct vm_area_struct *vma)
1180{ 1189{
1190 /* The vma can be set up to tell us the answer directly. */
1191 if (vma->vm_flags & VM_ALWAYSDUMP)
1192 return 1;
1193
1181 /* Do not dump I/O mapped devices or special mappings */ 1194 /* Do not dump I/O mapped devices or special mappings */
1182 if (vma->vm_flags & (VM_IO | VM_RESERVED)) 1195 if (vma->vm_flags & (VM_IO | VM_RESERVED))
1183 return 0; 1196 return 0;
@@ -1424,6 +1437,32 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
1424 return sz; 1437 return sz;
1425} 1438}
1426 1439
1440static struct vm_area_struct *first_vma(struct task_struct *tsk,
1441 struct vm_area_struct *gate_vma)
1442{
1443 struct vm_area_struct *ret = tsk->mm->mmap;
1444
1445 if (ret)
1446 return ret;
1447 return gate_vma;
1448}
1449/*
1450 * Helper function for iterating across a vma list. It ensures that the caller
1451 * will visit `gate_vma' prior to terminating the search.
1452 */
1453static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
1454 struct vm_area_struct *gate_vma)
1455{
1456 struct vm_area_struct *ret;
1457
1458 ret = this_vma->vm_next;
1459 if (ret)
1460 return ret;
1461 if (this_vma == gate_vma)
1462 return NULL;
1463 return gate_vma;
1464}
1465
1427/* 1466/*
1428 * Actual dumper 1467 * Actual dumper
1429 * 1468 *
@@ -1439,7 +1478,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1439 int segs; 1478 int segs;
1440 size_t size = 0; 1479 size_t size = 0;
1441 int i; 1480 int i;
1442 struct vm_area_struct *vma; 1481 struct vm_area_struct *vma, *gate_vma;
1443 struct elfhdr *elf = NULL; 1482 struct elfhdr *elf = NULL;
1444 loff_t offset = 0, dataoff, foffset; 1483 loff_t offset = 0, dataoff, foffset;
1445 unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; 1484 unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
@@ -1525,6 +1564,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1525 segs += ELF_CORE_EXTRA_PHDRS; 1564 segs += ELF_CORE_EXTRA_PHDRS;
1526#endif 1565#endif
1527 1566
1567 gate_vma = get_gate_vma(current);
1568 if (gate_vma != NULL)
1569 segs++;
1570
1528 /* Set up header */ 1571 /* Set up header */
1529 fill_elf_header(elf, segs + 1); /* including notes section */ 1572 fill_elf_header(elf, segs + 1); /* including notes section */
1530 1573
@@ -1592,7 +1635,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1592 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); 1635 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1593 1636
1594 /* Write program headers for segments dump */ 1637 /* Write program headers for segments dump */
1595 for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { 1638 for (vma = first_vma(current, gate_vma); vma != NULL;
1639 vma = next_vma(vma, gate_vma)) {
1596 struct elf_phdr phdr; 1640 struct elf_phdr phdr;
1597 size_t sz; 1641 size_t sz;
1598 1642
@@ -1641,7 +1685,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1641 /* Align to page */ 1685 /* Align to page */
1642 DUMP_SEEK(dataoff - foffset); 1686 DUMP_SEEK(dataoff - foffset);
1643 1687
1644 for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { 1688 for (vma = first_vma(current, gate_vma); vma != NULL;
1689 vma = next_vma(vma, gate_vma)) {
1645 unsigned long addr; 1690 unsigned long addr;
1646 1691
1647 if (!maydump(vma)) 1692 if (!maydump(vma))
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 6e6d4568d548..a4d933a51208 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -234,6 +234,14 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
234 goto error; 234 goto error;
235 } 235 }
236 236
237 /*
238 * If the binary is not readable then enforce
239 * mm->dumpable = 0 regardless of the interpreter's
240 * permissions.
241 */
242 if (file_permission(interpreter, MAY_READ) < 0)
243 bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
244
237 retval = kernel_read(interpreter, 0, bprm->buf, 245 retval = kernel_read(interpreter, 0, bprm->buf,
238 BINPRM_BUF_SIZE); 246 BINPRM_BUF_SIZE);
239 if (retval < 0) 247 if (retval < 0)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 8b18e43b82fe..d9bdf2b3ade2 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -146,7 +146,7 @@ static int blk_end_aio(struct bio *bio, unsigned int bytes_done, int error)
146 iocb->ki_nbytes = -EIO; 146 iocb->ki_nbytes = -EIO;
147 147
148 if (atomic_dec_and_test(bio_count)) { 148 if (atomic_dec_and_test(bio_count)) {
149 if (iocb->ki_nbytes < 0) 149 if ((long)iocb->ki_nbytes < 0)
150 aio_complete(iocb, iocb->ki_nbytes, 0); 150 aio_complete(iocb, iocb->ki_nbytes, 0);
151 else 151 else
152 aio_complete(iocb, iocb->ki_left, 0); 152 aio_complete(iocb, iocb->ki_left, 0);
@@ -190,6 +190,12 @@ static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
190 return pvec->page[pvec->idx++]; 190 return pvec->page[pvec->idx++];
191} 191}
192 192
193/* return a page back to pvec array */
194static void blk_unget_page(struct page *page, struct pvec *pvec)
195{
196 pvec->page[--pvec->idx] = page;
197}
198
193static ssize_t 199static ssize_t
194blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, 200blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
195 loff_t pos, unsigned long nr_segs) 201 loff_t pos, unsigned long nr_segs)
@@ -278,6 +284,8 @@ same_bio:
278 count = min(count, nbytes); 284 count = min(count, nbytes);
279 goto same_bio; 285 goto same_bio;
280 } 286 }
287 } else {
288 blk_unget_page(page, &pvec);
281 } 289 }
282 290
283 /* bio is ready, submit it */ 291 /* bio is ready, submit it */
diff --git a/fs/buffer.c b/fs/buffer.c
index 3b116078b4c3..1ad674fd348c 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2834,7 +2834,7 @@ int try_to_free_buffers(struct page *page)
2834 int ret = 0; 2834 int ret = 0;
2835 2835
2836 BUG_ON(!PageLocked(page)); 2836 BUG_ON(!PageLocked(page));
2837 if (PageDirty(page) || PageWriteback(page)) 2837 if (PageWriteback(page))
2838 return 0; 2838 return 0;
2839 2839
2840 if (mapping == NULL) { /* can this still happen? */ 2840 if (mapping == NULL) { /* can this still happen? */
@@ -2844,6 +2844,23 @@ int try_to_free_buffers(struct page *page)
2844 2844
2845 spin_lock(&mapping->private_lock); 2845 spin_lock(&mapping->private_lock);
2846 ret = drop_buffers(page, &buffers_to_free); 2846 ret = drop_buffers(page, &buffers_to_free);
2847
2848 /*
2849 * If the filesystem writes its buffers by hand (eg ext3)
2850 * then we can have clean buffers against a dirty page. We
2851 * clean the page here; otherwise the VM will never notice
2852 * that the filesystem did any IO at all.
2853 *
2854 * Also, during truncate, discard_buffer will have marked all
2855 * the page's buffers clean. We discover that here and clean
2856 * the page also.
2857 *
2858 * private_lock must be held over this entire operation in order
2859 * to synchronise against __set_page_dirty_buffers and prevent the
2860 * dirty bit from being lost.
2861 */
2862 if (ret)
2863 cancel_dirty_page(page, PAGE_CACHE_SIZE);
2847 spin_unlock(&mapping->private_lock); 2864 spin_unlock(&mapping->private_lock);
2848out: 2865out:
2849 if (buffers_to_free) { 2866 if (buffers_to_free) {
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 3539d6ef9611..d04d2f7448d9 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,7 @@
1Version 1.47
2------------
3Fix oops in list_del during mount caused by unaligned string.
4
1Version 1.46 5Version 1.46
2------------ 6------------
3Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps. 7Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps.
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 96abeb738978..6017c465440e 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -143,8 +143,8 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
143 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); 143 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
144 if((ses->serverDomain == NULL) || (ses->serverOS == NULL) || 144 if((ses->serverDomain == NULL) || (ses->serverOS == NULL) ||
145 (ses->serverNOS == NULL)) { 145 (ses->serverNOS == NULL)) {
146 buf += sprintf("\nentry for %s not fully displayed\n\t", 146 buf += sprintf(buf, "\nentry for %s not fully "
147 ses->serverName); 147 "displayed\n\t", ses->serverName);
148 148
149 } else { 149 } else {
150 length = 150 length =
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index a243f779b363..8aa66dcf13bd 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -100,5 +100,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
100extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 100extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
101extern int cifs_ioctl (struct inode * inode, struct file * filep, 101extern int cifs_ioctl (struct inode * inode, struct file * filep,
102 unsigned int command, unsigned long arg); 102 unsigned int command, unsigned long arg);
103#define CIFS_VERSION "1.46" 103#define CIFS_VERSION "1.47"
104#endif /* _CIFSFS_H */ 104#endif /* _CIFSFS_H */
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index aedf683f011f..19cc294c7c70 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -71,9 +71,7 @@ sesInfoAlloc(void)
71{ 71{
72 struct cifsSesInfo *ret_buf; 72 struct cifsSesInfo *ret_buf;
73 73
74 ret_buf = 74 ret_buf = kzalloc(sizeof (struct cifsSesInfo), GFP_KERNEL);
75 (struct cifsSesInfo *) kzalloc(sizeof (struct cifsSesInfo),
76 GFP_KERNEL);
77 if (ret_buf) { 75 if (ret_buf) {
78 write_lock(&GlobalSMBSeslock); 76 write_lock(&GlobalSMBSeslock);
79 atomic_inc(&sesInfoAllocCount); 77 atomic_inc(&sesInfoAllocCount);
@@ -109,9 +107,7 @@ struct cifsTconInfo *
109tconInfoAlloc(void) 107tconInfoAlloc(void)
110{ 108{
111 struct cifsTconInfo *ret_buf; 109 struct cifsTconInfo *ret_buf;
112 ret_buf = 110 ret_buf = kzalloc(sizeof (struct cifsTconInfo), GFP_KERNEL);
113 (struct cifsTconInfo *) kzalloc(sizeof (struct cifsTconInfo),
114 GFP_KERNEL);
115 if (ret_buf) { 111 if (ret_buf) {
116 write_lock(&GlobalSMBSeslock); 112 write_lock(&GlobalSMBSeslock);
117 atomic_inc(&tconInfoAllocCount); 113 atomic_inc(&tconInfoAllocCount);
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index bbdda99dce61..758464630893 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -182,11 +182,14 @@ static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInf
182 cFYI(1,("bleft %d",bleft)); 182 cFYI(1,("bleft %d",bleft));
183 183
184 184
185 /* word align, if bytes remaining is not even */ 185 /* SMB header is unaligned, so cifs servers word align start of
186 if(bleft % 2) { 186 Unicode strings */
187 bleft--; 187 data++;
188 data++; 188 bleft--; /* Windows servers do not always double null terminate
189 } 189 their final Unicode string - in which case we
190 now will not attempt to decode the byte of junk
191 which follows it */
192
190 words_left = bleft / 2; 193 words_left = bleft / 2;
191 194
192 /* save off server operating system */ 195 /* save off server operating system */
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index c403b66ec83c..a4b142a6a2c7 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -251,8 +251,19 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
251 WARN_ON(inode->i_state & I_WILL_FREE); 251 WARN_ON(inode->i_state & I_WILL_FREE);
252 252
253 if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) { 253 if ((wbc->sync_mode != WB_SYNC_ALL) && (inode->i_state & I_LOCK)) {
254 struct address_space *mapping = inode->i_mapping;
255 int ret;
256
254 list_move(&inode->i_list, &inode->i_sb->s_dirty); 257 list_move(&inode->i_list, &inode->i_sb->s_dirty);
255 return 0; 258
259 /*
260 * Even if we don't actually write the inode itself here,
261 * we can at least start some of the data writeout..
262 */
263 spin_unlock(&inode_lock);
264 ret = do_writepages(mapping, wbc);
265 spin_lock(&inode_lock);
266 return ret;
256 } 267 }
257 268
258 /* 269 /*
diff --git a/fs/fuse/control.c b/fs/fuse/control.c
index 8c58bd453993..1794305f9ed8 100644
--- a/fs/fuse/control.c
+++ b/fs/fuse/control.c
@@ -193,8 +193,12 @@ static int fuse_ctl_get_sb(struct file_system_type *fs_type, int flags,
193 193
194static void fuse_ctl_kill_sb(struct super_block *sb) 194static void fuse_ctl_kill_sb(struct super_block *sb)
195{ 195{
196 struct fuse_conn *fc;
197
196 mutex_lock(&fuse_mutex); 198 mutex_lock(&fuse_mutex);
197 fuse_control_sb = NULL; 199 fuse_control_sb = NULL;
200 list_for_each_entry(fc, &fuse_conn_list, entry)
201 fc->ctl_ndents = 0;
198 mutex_unlock(&fuse_mutex); 202 mutex_unlock(&fuse_mutex);
199 203
200 kill_litter_super(sb); 204 kill_litter_super(sb);
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index cca3fb693f99..70543b17e4c7 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -76,7 +76,7 @@ extern int make_symlink(const char *from, const char *to);
76extern int unlink_file(const char *file); 76extern int unlink_file(const char *file);
77extern int do_mkdir(const char *file, int mode); 77extern int do_mkdir(const char *file, int mode);
78extern int do_rmdir(const char *file); 78extern int do_rmdir(const char *file);
79extern int do_mknod(const char *file, int mode, int dev); 79extern int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor);
80extern int link_file(const char *from, const char *to); 80extern int link_file(const char *from, const char *to);
81extern int do_readlink(char *file, char *buf, int size); 81extern int do_readlink(char *file, char *buf, int size);
82extern int rename_file(char *from, char *to); 82extern int rename_file(char *from, char *to);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 1e6fc3799876..69a376f35a68 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -755,7 +755,7 @@ int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
755 goto out_put; 755 goto out_put;
756 756
757 init_special_inode(inode, mode, dev); 757 init_special_inode(inode, mode, dev);
758 err = do_mknod(name, mode, dev); 758 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
759 if(err) 759 if(err)
760 goto out_free; 760 goto out_free;
761 761
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index 23b7cee72123..1ed5ea389f15 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -295,11 +295,11 @@ int do_rmdir(const char *file)
295 return(0); 295 return(0);
296} 296}
297 297
298int do_mknod(const char *file, int mode, int dev) 298int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
299{ 299{
300 int err; 300 int err;
301 301
302 err = mknod(file, mode, dev); 302 err = mknod(file, mode, makedev(major, minor));
303 if(err) return(-errno); 303 if(err) return(-errno);
304 return(0); 304 return(0);
305} 305}
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
index 077258b2103e..5a95fbdd6fdb 100644
--- a/fs/jffs/jffs_fm.c
+++ b/fs/jffs/jffs_fm.c
@@ -17,6 +17,7 @@
17 * 17 *
18 */ 18 */
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/err.h>
20#include <linux/blkdev.h> 21#include <linux/blkdev.h>
21#include <linux/jffs.h> 22#include <linux/jffs.h>
22#include "jffs_fm.h" 23#include "jffs_fm.h"
@@ -104,7 +105,7 @@ jffs_build_begin(struct jffs_control *c, int unit)
104 105
105 mtd = get_mtd_device(NULL, unit); 106 mtd = get_mtd_device(NULL, unit);
106 107
107 if (!mtd) { 108 if (IS_ERR(mtd)) {
108 kfree(fmc); 109 kfree(fmc);
109 DJM(no_jffs_fmcontrol--); 110 DJM(no_jffs_fmcontrol--);
110 return NULL; 111 return NULL;
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c
index 72b4fc13a106..4189e4a36050 100644
--- a/fs/jffs2/debug.c
+++ b/fs/jffs2/debug.c
@@ -178,8 +178,8 @@ __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
178 while (ref2) { 178 while (ref2) {
179 uint32_t totlen = ref_totlen(c, jeb, ref2); 179 uint32_t totlen = ref_totlen(c, jeb, ref2);
180 180
181 if (ref2->flash_offset < jeb->offset || 181 if (ref_offset(ref2) < jeb->offset ||
182 ref2->flash_offset > jeb->offset + c->sector_size) { 182 ref_offset(ref2) > jeb->offset + c->sector_size) {
183 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n", 183 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
184 ref_offset(ref2), jeb->offset); 184 ref_offset(ref2), jeb->offset);
185 goto error; 185 goto error;
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h
index 3daf3bca0376..f89c85d5a3f8 100644
--- a/fs/jffs2/debug.h
+++ b/fs/jffs2/debug.h
@@ -13,6 +13,7 @@
13#ifndef _JFFS2_DEBUG_H_ 13#ifndef _JFFS2_DEBUG_H_
14#define _JFFS2_DEBUG_H_ 14#define _JFFS2_DEBUG_H_
15 15
16#include <linux/sched.h>
16 17
17#ifndef CONFIG_JFFS2_FS_DEBUG 18#ifndef CONFIG_JFFS2_FS_DEBUG
18#define CONFIG_JFFS2_FS_DEBUG 0 19#define CONFIG_JFFS2_FS_DEBUG 0
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 7bc1a4201c0c..abb90c0c09cc 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -502,12 +502,11 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
502 if (ret) 502 if (ret)
503 return ret; 503 return ret;
504 504
505 c->inocache_list = kmalloc(INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *), GFP_KERNEL); 505 c->inocache_list = kcalloc(INOCACHE_HASHSIZE, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
506 if (!c->inocache_list) { 506 if (!c->inocache_list) {
507 ret = -ENOMEM; 507 ret = -ENOMEM;
508 goto out_wbuf; 508 goto out_wbuf;
509 } 509 }
510 memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *));
511 510
512 jffs2_init_xattr_subsystem(c); 511 jffs2_init_xattr_subsystem(c);
513 512
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index daff3341ff92..3a3cf225981f 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -838,6 +838,8 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
838 838
839 for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) { 839 for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) {
840 840
841 cond_resched();
842
841 /* We only care about obsolete ones */ 843 /* We only care about obsolete ones */
842 if (!(ref_obsolete(raw))) 844 if (!(ref_obsolete(raw)))
843 continue; 845 continue;
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index 0ddfd70307fb..4178b4b55948 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -294,23 +294,21 @@ static inline int jffs2_encode_dev(union jffs2_device_node *jdev, dev_t rdev)
294 294
295static inline struct jffs2_node_frag *frag_first(struct rb_root *root) 295static inline struct jffs2_node_frag *frag_first(struct rb_root *root)
296{ 296{
297 struct rb_node *node = root->rb_node; 297 struct rb_node *node = rb_first(root);
298 298
299 if (!node) 299 if (!node)
300 return NULL; 300 return NULL;
301 while(node->rb_left) 301
302 node = node->rb_left;
303 return rb_entry(node, struct jffs2_node_frag, rb); 302 return rb_entry(node, struct jffs2_node_frag, rb);
304} 303}
305 304
306static inline struct jffs2_node_frag *frag_last(struct rb_root *root) 305static inline struct jffs2_node_frag *frag_last(struct rb_root *root)
307{ 306{
308 struct rb_node *node = root->rb_node; 307 struct rb_node *node = rb_last(root);
309 308
310 if (!node) 309 if (!node)
311 return NULL; 310 return NULL;
312 while(node->rb_right) 311
313 node = node->rb_right;
314 return rb_entry(node, struct jffs2_node_frag, rb); 312 return rb_entry(node, struct jffs2_node_frag, rb);
315} 313}
316 314
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 266423b2709d..58a0b912e9d0 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -944,13 +944,12 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
944int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 944int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
945{ 945{
946 struct jffs2_raw_inode n; 946 struct jffs2_raw_inode n;
947 struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL); 947 struct jffs2_inode_info *f = kzalloc(sizeof(*f), GFP_KERNEL);
948 int ret; 948 int ret;
949 949
950 if (!f) 950 if (!f)
951 return -ENOMEM; 951 return -ENOMEM;
952 952
953 memset(f, 0, sizeof(*f));
954 init_MUTEX_LOCKED(&f->sem); 953 init_MUTEX_LOCKED(&f->sem);
955 f->inocache = ic; 954 f->inocache = ic;
956 955
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index e2413466ddd5..3af746eaff0e 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -128,17 +128,19 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
128 } 128 }
129 129
130 if (jffs2_sum_active()) { 130 if (jffs2_sum_active()) {
131 s = kmalloc(sizeof(struct jffs2_summary), GFP_KERNEL); 131 s = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
132 if (!s) { 132 if (!s) {
133 kfree(flashbuf);
133 JFFS2_WARNING("Can't allocate memory for summary\n"); 134 JFFS2_WARNING("Can't allocate memory for summary\n");
134 return -ENOMEM; 135 return -ENOMEM;
135 } 136 }
136 memset(s, 0, sizeof(struct jffs2_summary));
137 } 137 }
138 138
139 for (i=0; i<c->nr_blocks; i++) { 139 for (i=0; i<c->nr_blocks; i++) {
140 struct jffs2_eraseblock *jeb = &c->blocks[i]; 140 struct jffs2_eraseblock *jeb = &c->blocks[i];
141 141
142 cond_resched();
143
142 /* reset summary info for next eraseblock scan */ 144 /* reset summary info for next eraseblock scan */
143 jffs2_sum_reset_collected(s); 145 jffs2_sum_reset_collected(s);
144 146
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index e52cef526d90..25265965bdc1 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -26,15 +26,13 @@
26 26
27int jffs2_sum_init(struct jffs2_sb_info *c) 27int jffs2_sum_init(struct jffs2_sb_info *c)
28{ 28{
29 c->summary = kmalloc(sizeof(struct jffs2_summary), GFP_KERNEL); 29 c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
30 30
31 if (!c->summary) { 31 if (!c->summary) {
32 JFFS2_WARNING("Can't allocate memory for summary information!\n"); 32 JFFS2_WARNING("Can't allocate memory for summary information!\n");
33 return -ENOMEM; 33 return -ENOMEM;
34 } 34 }
35 35
36 memset(c->summary, 0, sizeof(struct jffs2_summary));
37
38 c->summary->sum_buf = vmalloc(c->sector_size); 36 c->summary->sum_buf = vmalloc(c->sector_size);
39 37
40 if (!c->summary->sum_buf) { 38 if (!c->summary->sum_buf) {
@@ -398,6 +396,8 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
398 for (i=0; i<je32_to_cpu(summary->sum_num); i++) { 396 for (i=0; i<je32_to_cpu(summary->sum_num); i++) {
399 dbg_summary("processing summary index %d\n", i); 397 dbg_summary("processing summary index %d\n", i);
400 398
399 cond_resched();
400
401 /* Make sure there's a spare ref for dirty space */ 401 /* Make sure there's a spare ref for dirty space */
402 err = jffs2_prealloc_raw_node_refs(c, jeb, 2); 402 err = jffs2_prealloc_raw_node_refs(c, jeb, 2);
403 if (err) 403 if (err)
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 7deb78254021..08a0e6c49e61 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -17,6 +17,7 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/err.h>
20#include <linux/mount.h> 21#include <linux/mount.h>
21#include <linux/jffs2.h> 22#include <linux/jffs2.h>
22#include <linux/pagemap.h> 23#include <linux/pagemap.h>
@@ -184,9 +185,9 @@ static int jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
184 struct mtd_info *mtd; 185 struct mtd_info *mtd;
185 186
186 mtd = get_mtd_device(NULL, mtdnr); 187 mtd = get_mtd_device(NULL, mtdnr);
187 if (!mtd) { 188 if (IS_ERR(mtd)) {
188 D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr)); 189 D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr));
189 return -EINVAL; 190 return PTR_ERR(mtd);
190 } 191 }
191 192
192 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt); 193 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
@@ -221,7 +222,7 @@ static int jffs2_get_sb(struct file_system_type *fs_type,
221 D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd:%%s, name \"%s\"\n", dev_name+4)); 222 D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd:%%s, name \"%s\"\n", dev_name+4));
222 for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) { 223 for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) {
223 mtd = get_mtd_device(NULL, mtdnr); 224 mtd = get_mtd_device(NULL, mtdnr);
224 if (mtd) { 225 if (!IS_ERR(mtd)) {
225 if (!strcmp(mtd->name, dev_name+4)) 226 if (!strcmp(mtd->name, dev_name+4))
226 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt); 227 return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd, mnt);
227 put_mtd_device(mtd); 228 put_mtd_device(mtd);
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index fc211b6e9b03..b90d5aa3d969 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -51,7 +51,7 @@ static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
51 */ 51 */
52 52
53 if (!p) { 53 if (!p) {
54 printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); 54 printk(KERN_ERR "jffs2_follow_link(): can't find symlink target\n");
55 p = ERR_PTR(-EIO); 55 p = ERR_PTR(-EIO);
56 } 56 }
57 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->target)); 57 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->target));
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 70707309dfa1..9c99859f5edd 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -969,8 +969,7 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
969 int oobsize = c->mtd->oobsize; 969 int oobsize = c->mtd->oobsize;
970 struct mtd_oob_ops ops; 970 struct mtd_oob_ops ops;
971 971
972 ops.len = NR_OOB_SCAN_PAGES * oobsize; 972 ops.ooblen = NR_OOB_SCAN_PAGES * oobsize;
973 ops.ooblen = oobsize;
974 ops.oobbuf = c->oobbuf; 973 ops.oobbuf = c->oobbuf;
975 ops.ooboffs = 0; 974 ops.ooboffs = 0;
976 ops.datbuf = NULL; 975 ops.datbuf = NULL;
@@ -983,10 +982,10 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
983 return ret; 982 return ret;
984 } 983 }
985 984
986 if (ops.retlen < ops.len) { 985 if (ops.oobretlen < ops.ooblen) {
987 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB " 986 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB "
988 "returned short read (%zd bytes not %d) for block " 987 "returned short read (%zd bytes not %d) for block "
989 "at %08x\n", ops.retlen, ops.len, jeb->offset)); 988 "at %08x\n", ops.oobretlen, ops.ooblen, jeb->offset));
990 return -EIO; 989 return -EIO;
991 } 990 }
992 991
@@ -1005,7 +1004,7 @@ int jffs2_check_oob_empty(struct jffs2_sb_info *c,
1005 } 1004 }
1006 1005
1007 /* we know, we are aligned :) */ 1006 /* we know, we are aligned :) */
1008 for (page = oobsize; page < ops.len; page += sizeof(long)) { 1007 for (page = oobsize; page < ops.ooblen; page += sizeof(long)) {
1009 long dat = *(long *)(&ops.oobbuf[page]); 1008 long dat = *(long *)(&ops.oobbuf[page]);
1010 if(dat != -1) 1009 if(dat != -1)
1011 return 1; 1010 return 1;
@@ -1033,7 +1032,6 @@ int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c,
1033 return 2; 1032 return 2;
1034 } 1033 }
1035 1034
1036 ops.len = oobsize;
1037 ops.ooblen = oobsize; 1035 ops.ooblen = oobsize;
1038 ops.oobbuf = c->oobbuf; 1036 ops.oobbuf = c->oobbuf;
1039 ops.ooboffs = 0; 1037 ops.ooboffs = 0;
@@ -1048,10 +1046,10 @@ int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c,
1048 return ret; 1046 return ret;
1049 } 1047 }
1050 1048
1051 if (ops.retlen < ops.len) { 1049 if (ops.oobretlen < ops.ooblen) {
1052 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): " 1050 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): "
1053 "Read OOB return short read (%zd bytes not %d) " 1051 "Read OOB return short read (%zd bytes not %d) "
1054 "for block at %08x\n", ops.retlen, ops.len, 1052 "for block at %08x\n", ops.oobretlen, ops.ooblen,
1055 jeb->offset)); 1053 jeb->offset));
1056 return -EIO; 1054 return -EIO;
1057 } 1055 }
@@ -1090,8 +1088,7 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
1090 n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); 1088 n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
1091 n.totlen = cpu_to_je32(8); 1089 n.totlen = cpu_to_je32(8);
1092 1090
1093 ops.len = c->fsdata_len; 1091 ops.ooblen = c->fsdata_len;
1094 ops.ooblen = c->fsdata_len;;
1095 ops.oobbuf = (uint8_t *)&n; 1092 ops.oobbuf = (uint8_t *)&n;
1096 ops.ooboffs = c->fsdata_pos; 1093 ops.ooboffs = c->fsdata_pos;
1097 ops.datbuf = NULL; 1094 ops.datbuf = NULL;
@@ -1105,10 +1102,10 @@ int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
1105 jeb->offset, ret)); 1102 jeb->offset, ret));
1106 return ret; 1103 return ret;
1107 } 1104 }
1108 if (ops.retlen != ops.len) { 1105 if (ops.oobretlen != ops.ooblen) {
1109 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): " 1106 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): "
1110 "Short write for block at %08x: %zd not %d\n", 1107 "Short write for block at %08x: %zd not %d\n",
1111 jeb->offset, ops.retlen, ops.len)); 1108 jeb->offset, ops.oobretlen, ops.ooblen));
1112 return -EIO; 1109 return -EIO;
1113 } 1110 }
1114 return 0; 1111 return 0;
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 4da09ce1d1f5..4bb3f1897330 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -399,8 +399,6 @@ static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datu
399{ 399{
400 /* must be called under down_write(xattr_sem) */ 400 /* must be called under down_write(xattr_sem) */
401 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) { 401 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {
402 uint32_t xid = xd->xid, version = xd->version;
403
404 unload_xattr_datum(c, xd); 402 unload_xattr_datum(c, xd);
405 xd->flags |= JFFS2_XFLAGS_DEAD; 403 xd->flags |= JFFS2_XFLAGS_DEAD;
406 if (xd->node == (void *)xd) { 404 if (xd->node == (void *)xd) {
@@ -411,7 +409,8 @@ static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datu
411 } 409 }
412 spin_unlock(&c->erase_completion_lock); 410 spin_unlock(&c->erase_completion_lock);
413 411
414 dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xid, version); 412 dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n",
413 xd->xid, xd->version);
415 } 414 }
416} 415}
417 416
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index 062707745162..f4d45d4d835b 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -176,7 +176,7 @@ reclaimer(void *ptr)
176 lock_kernel(); 176 lock_kernel();
177 lockd_up(0); /* note: this cannot fail as lockd is already running */ 177 lockd_up(0); /* note: this cannot fail as lockd is already running */
178 178
179 dprintk("lockd: reclaiming locks for host %s", host->h_name); 179 dprintk("lockd: reclaiming locks for host %s\n", host->h_name);
180 180
181restart: 181restart:
182 nsmstate = host->h_nsmstate; 182 nsmstate = host->h_nsmstate;
@@ -206,7 +206,7 @@ restart:
206 206
207 host->h_reclaiming = 0; 207 host->h_reclaiming = 0;
208 up_write(&host->h_rwsem); 208 up_write(&host->h_rwsem);
209 dprintk("NLM: done reclaiming locks for host %s", host->h_name); 209 dprintk("NLM: done reclaiming locks for host %s\n", host->h_name);
210 210
211 /* Now, wake up all processes that sleep on a blocked lock */ 211 /* Now, wake up all processes that sleep on a blocked lock */
212 list_for_each_entry(block, &nlm_blocked, b_list) { 212 list_for_each_entry(block, &nlm_blocked, b_list) {
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index dee3d6c0f194..d9ba8cb0ee75 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -532,7 +532,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
532 532
533 lock_kernel(); 533 lock_kernel();
534 534
535 res = nfs_revalidate_mapping(inode, filp->f_mapping); 535 res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping);
536 if (res < 0) { 536 if (res < 0) {
537 unlock_kernel(); 537 unlock_kernel();
538 return res; 538 return res;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index fab20d06d936..9e4a2b70995a 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -434,8 +434,9 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
434 BUG(); 434 BUG();
435 } 435 }
436 if (res < 0) 436 if (res < 0)
437 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", 437 dprintk(KERN_WARNING "%s: VFS is out of sync with lock manager"
438 __FUNCTION__); 438 " - error %d!\n",
439 __FUNCTION__, res);
439 return res; 440 return res;
440} 441}
441 442
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 63e470279309..d83498282837 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -665,49 +665,86 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
665 return __nfs_revalidate_inode(server, inode); 665 return __nfs_revalidate_inode(server, inode);
666} 666}
667 667
668static int nfs_invalidate_mapping_nolock(struct inode *inode, struct address_space *mapping)
669{
670 struct nfs_inode *nfsi = NFS_I(inode);
671
672 if (mapping->nrpages != 0) {
673 int ret = invalidate_inode_pages2(mapping);
674 if (ret < 0)
675 return ret;
676 }
677 spin_lock(&inode->i_lock);
678 nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
679 if (S_ISDIR(inode->i_mode)) {
680 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
681 /* This ensures we revalidate child dentries */
682 nfsi->cache_change_attribute = jiffies;
683 }
684 spin_unlock(&inode->i_lock);
685 nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
686 dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
687 inode->i_sb->s_id, (long long)NFS_FILEID(inode));
688 return 0;
689}
690
691static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
692{
693 int ret = 0;
694
695 mutex_lock(&inode->i_mutex);
696 if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_DATA) {
697 ret = nfs_sync_mapping(mapping);
698 if (ret == 0)
699 ret = nfs_invalidate_mapping_nolock(inode, mapping);
700 }
701 mutex_unlock(&inode->i_mutex);
702 return ret;
703}
704
668/** 705/**
669 * nfs_revalidate_mapping - Revalidate the pagecache 706 * nfs_revalidate_mapping_nolock - Revalidate the pagecache
670 * @inode - pointer to host inode 707 * @inode - pointer to host inode
671 * @mapping - pointer to mapping 708 * @mapping - pointer to mapping
672 */ 709 */
673int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) 710int nfs_revalidate_mapping_nolock(struct inode *inode, struct address_space *mapping)
674{ 711{
675 struct nfs_inode *nfsi = NFS_I(inode); 712 struct nfs_inode *nfsi = NFS_I(inode);
676 int ret = 0; 713 int ret = 0;
677 714
678 if (NFS_STALE(inode))
679 ret = -ESTALE;
680 if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) 715 if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
681 || nfs_attribute_timeout(inode)) 716 || nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
682 ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode); 717 ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
683 if (ret < 0) 718 if (ret < 0)
684 goto out; 719 goto out;
720 }
721 if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
722 ret = nfs_invalidate_mapping_nolock(inode, mapping);
723out:
724 return ret;
725}
685 726
686 if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { 727/**
687 if (mapping->nrpages != 0) { 728 * nfs_revalidate_mapping - Revalidate the pagecache
688 if (S_ISREG(inode->i_mode)) { 729 * @inode - pointer to host inode
689 ret = nfs_sync_mapping(mapping); 730 * @mapping - pointer to mapping
690 if (ret < 0) 731 *
691 goto out; 732 * This version of the function will take the inode->i_mutex and attempt to
692 } 733 * flush out all dirty data if it needs to invalidate the page cache.
693 ret = invalidate_inode_pages2(mapping); 734 */
694 if (ret < 0) 735int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
695 goto out; 736{
696 } 737 struct nfs_inode *nfsi = NFS_I(inode);
697 spin_lock(&inode->i_lock); 738 int ret = 0;
698 nfsi->cache_validity &= ~NFS_INO_INVALID_DATA;
699 if (S_ISDIR(inode->i_mode)) {
700 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
701 /* This ensures we revalidate child dentries */
702 nfsi->cache_change_attribute = jiffies;
703 }
704 spin_unlock(&inode->i_lock);
705 739
706 nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); 740 if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE)
707 dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", 741 || nfs_attribute_timeout(inode) || NFS_STALE(inode)) {
708 inode->i_sb->s_id, 742 ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
709 (long long)NFS_FILEID(inode)); 743 if (ret < 0)
744 goto out;
710 } 745 }
746 if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
747 ret = nfs_invalidate_mapping(inode, mapping);
711out: 748out:
712 return ret; 749 return ret;
713} 750}
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
index 6c686112cc03..525c136c7d8c 100644
--- a/fs/nfs/symlink.c
+++ b/fs/nfs/symlink.c
@@ -50,7 +50,9 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
50{ 50{
51 struct inode *inode = dentry->d_inode; 51 struct inode *inode = dentry->d_inode;
52 struct page *page; 52 struct page *page;
53 void *err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping)); 53 void *err;
54
55 err = ERR_PTR(nfs_revalidate_mapping_nolock(inode, inode->i_mapping));
54 if (err) 56 if (err)
55 goto read_failed; 57 goto read_failed;
56 page = read_cache_page(&inode->i_data, 0, 58 page = read_cache_page(&inode->i_data, 0,
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 248dd92e6a56..49c310b84923 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -35,7 +35,6 @@
35#include <linux/lockd/bind.h> 35#include <linux/lockd/bind.h>
36 36
37#define NFSDDBG_FACILITY NFSDDBG_EXPORT 37#define NFSDDBG_FACILITY NFSDDBG_EXPORT
38#define NFSD_PARANOIA 1
39 38
40typedef struct auth_domain svc_client; 39typedef struct auth_domain svc_client;
41typedef struct svc_export svc_export; 40typedef struct svc_export svc_export;
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 277df40f098d..e695660921ec 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -990,15 +990,16 @@ encode_entry(struct readdir_cd *ccd, const char *name,
990} 990}
991 991
992int 992int
993nfs3svc_encode_entry(struct readdir_cd *cd, const char *name, 993nfs3svc_encode_entry(void *cd, const char *name,
994 int namlen, loff_t offset, ino_t ino, unsigned int d_type) 994 int namlen, loff_t offset, u64 ino, unsigned int d_type)
995{ 995{
996 return encode_entry(cd, name, namlen, offset, ino, d_type, 0); 996 return encode_entry(cd, name, namlen, offset, ino, d_type, 0);
997} 997}
998 998
999int 999int
1000nfs3svc_encode_entry_plus(struct readdir_cd *cd, const char *name, 1000nfs3svc_encode_entry_plus(void *cd, const char *name,
1001 int namlen, loff_t offset, ino_t ino, unsigned int d_type) 1001 int namlen, loff_t offset, u64 ino,
1002 unsigned int d_type)
1002{ 1003{
1003 return encode_entry(cd, name, namlen, offset, ino, d_type, 1); 1004 return encode_entry(cd, name, namlen, offset, ino, d_type, 1);
1004} 1005}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index fea46368afb2..18aa9440df14 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1880,9 +1880,10 @@ nfsd4_encode_rdattr_error(__be32 *p, int buflen, __be32 nfserr)
1880} 1880}
1881 1881
1882static int 1882static int
1883nfsd4_encode_dirent(struct readdir_cd *ccd, const char *name, int namlen, 1883nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
1884 loff_t offset, ino_t ino, unsigned int d_type) 1884 loff_t offset, u64 ino, unsigned int d_type)
1885{ 1885{
1886 struct readdir_cd *ccd = ccdv;
1886 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common); 1887 struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
1887 int buflen; 1888 int buflen;
1888 __be32 *p = cd->buffer; 1889 __be32 *p = cd->buffer;
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index b06bf9f70efc..98338a569dc0 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -24,8 +24,6 @@
24#include <linux/nfsd/nfsd.h> 24#include <linux/nfsd/nfsd.h>
25 25
26#define NFSDDBG_FACILITY NFSDDBG_FH 26#define NFSDDBG_FACILITY NFSDDBG_FH
27#define NFSD_PARANOIA 1
28/* #define NFSD_DEBUG_VERBOSE 1 */
29 27
30 28
31static int nfsd_nr_verified; 29static int nfsd_nr_verified;
@@ -230,13 +228,12 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
230 error = nfserrno(PTR_ERR(dentry)); 228 error = nfserrno(PTR_ERR(dentry));
231 goto out; 229 goto out;
232 } 230 }
233#ifdef NFSD_PARANOIA 231
234 if (S_ISDIR(dentry->d_inode->i_mode) && 232 if (S_ISDIR(dentry->d_inode->i_mode) &&
235 (dentry->d_flags & DCACHE_DISCONNECTED)) { 233 (dentry->d_flags & DCACHE_DISCONNECTED)) {
236 printk("nfsd: find_fh_dentry returned a DISCONNECTED directory: %s/%s\n", 234 printk("nfsd: find_fh_dentry returned a DISCONNECTED directory: %s/%s\n",
237 dentry->d_parent->d_name.name, dentry->d_name.name); 235 dentry->d_parent->d_name.name, dentry->d_name.name);
238 } 236 }
239#endif
240 237
241 fhp->fh_dentry = dentry; 238 fhp->fh_dentry = dentry;
242 fhp->fh_export = exp; 239 fhp->fh_export = exp;
@@ -267,12 +264,13 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
267 /* Finally, check access permissions. */ 264 /* Finally, check access permissions. */
268 error = nfsd_permission(exp, dentry, access); 265 error = nfsd_permission(exp, dentry, access);
269 266
270#ifdef NFSD_PARANOIA_EXTREME
271 if (error) { 267 if (error) {
272 printk("fh_verify: %s/%s permission failure, acc=%x, error=%d\n", 268 dprintk("fh_verify: %s/%s permission failure, "
273 dentry->d_parent->d_name.name, dentry->d_name.name, access, (error >> 24)); 269 "acc=%x, error=%d\n",
270 dentry->d_parent->d_name.name,
271 dentry->d_name.name,
272 access, (error >> 24));
274 } 273 }
275#endif
276out: 274out:
277 if (exp && !IS_ERR(exp)) 275 if (exp && !IS_ERR(exp))
278 exp_put(exp); 276 exp_put(exp);
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 0aaccb03bf76..fbf5d51947ea 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -72,7 +72,7 @@ static struct svc_program nfsd_acl_program = {
72 .pg_prog = NFS_ACL_PROGRAM, 72 .pg_prog = NFS_ACL_PROGRAM,
73 .pg_nvers = NFSD_ACL_NRVERS, 73 .pg_nvers = NFSD_ACL_NRVERS,
74 .pg_vers = nfsd_acl_versions, 74 .pg_vers = nfsd_acl_versions,
75 .pg_name = "nfsd", 75 .pg_name = "nfsacl",
76 .pg_class = "nfsd", 76 .pg_class = "nfsd",
77 .pg_stats = &nfsd_acl_svcstats, 77 .pg_stats = &nfsd_acl_svcstats,
78 .pg_authenticate = &svc_set_client, 78 .pg_authenticate = &svc_set_client,
@@ -118,16 +118,16 @@ int nfsd_vers(int vers, enum vers_op change)
118 switch(change) { 118 switch(change) {
119 case NFSD_SET: 119 case NFSD_SET:
120 nfsd_versions[vers] = nfsd_version[vers]; 120 nfsd_versions[vers] = nfsd_version[vers];
121 break;
122#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 121#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
123 if (vers < NFSD_ACL_NRVERS) 122 if (vers < NFSD_ACL_NRVERS)
124 nfsd_acl_version[vers] = nfsd_acl_version[vers]; 123 nfsd_acl_versions[vers] = nfsd_acl_version[vers];
125#endif 124#endif
125 break;
126 case NFSD_CLEAR: 126 case NFSD_CLEAR:
127 nfsd_versions[vers] = NULL; 127 nfsd_versions[vers] = NULL;
128#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) 128#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
129 if (vers < NFSD_ACL_NRVERS) 129 if (vers < NFSD_ACL_NRVERS)
130 nfsd_acl_version[vers] = NULL; 130 nfsd_acl_versions[vers] = NULL;
131#endif 131#endif
132 break; 132 break;
133 case NFSD_TEST: 133 case NFSD_TEST:
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index f5243f943996..6555c50d9006 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -462,9 +462,10 @@ nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p,
462} 462}
463 463
464int 464int
465nfssvc_encode_entry(struct readdir_cd *ccd, const char *name, 465nfssvc_encode_entry(void *ccdv, const char *name,
466 int namlen, loff_t offset, ino_t ino, unsigned int d_type) 466 int namlen, loff_t offset, u64 ino, unsigned int d_type)
467{ 467{
468 struct readdir_cd *ccd = ccdv;
468 struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common); 469 struct nfsd_readdirres *cd = container_of(ccd, struct nfsd_readdirres, common);
469 __be32 *p = cd->buffer; 470 __be32 *p = cd->buffer;
470 int buflen, slen; 471 int buflen, slen;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 7a79c23aa6d4..8283236c6a0f 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -59,7 +59,6 @@
59#include <asm/uaccess.h> 59#include <asm/uaccess.h>
60 60
61#define NFSDDBG_FACILITY NFSDDBG_FILEOP 61#define NFSDDBG_FACILITY NFSDDBG_FILEOP
62#define NFSD_PARANOIA
63 62
64 63
65/* We must ignore files (but only files) which might have mandatory 64/* We must ignore files (but only files) which might have mandatory
@@ -822,7 +821,8 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset
822 rqstp->rq_res.page_len = size; 821 rqstp->rq_res.page_len = size;
823 } else if (page != pp[-1]) { 822 } else if (page != pp[-1]) {
824 get_page(page); 823 get_page(page);
825 put_page(*pp); 824 if (*pp)
825 put_page(*pp);
826 *pp = page; 826 *pp = page;
827 rqstp->rq_resused++; 827 rqstp->rq_resused++;
828 rqstp->rq_res.page_len += size; 828 rqstp->rq_res.page_len += size;
@@ -1244,7 +1244,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1244 __be32 err; 1244 __be32 err;
1245 int host_err; 1245 int host_err;
1246 __u32 v_mtime=0, v_atime=0; 1246 __u32 v_mtime=0, v_atime=0;
1247 int v_mode=0;
1248 1247
1249 err = nfserr_perm; 1248 err = nfserr_perm;
1250 if (!flen) 1249 if (!flen)
@@ -1281,16 +1280,11 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1281 goto out; 1280 goto out;
1282 1281
1283 if (createmode == NFS3_CREATE_EXCLUSIVE) { 1282 if (createmode == NFS3_CREATE_EXCLUSIVE) {
1284 /* while the verifier would fit in mtime+atime, 1283 /* solaris7 gets confused (bugid 4218508) if these have
1285 * solaris7 gets confused (bugid 4218508) if these have 1284 * the high bit set, so just clear the high bits.
1286 * the high bit set, so we use the mode as well
1287 */ 1285 */
1288 v_mtime = verifier[0]&0x7fffffff; 1286 v_mtime = verifier[0]&0x7fffffff;
1289 v_atime = verifier[1]&0x7fffffff; 1287 v_atime = verifier[1]&0x7fffffff;
1290 v_mode = S_IFREG
1291 | ((verifier[0]&0x80000000) >> (32-7)) /* u+x */
1292 | ((verifier[1]&0x80000000) >> (32-9)) /* u+r */
1293 ;
1294 } 1288 }
1295 1289
1296 if (dchild->d_inode) { 1290 if (dchild->d_inode) {
@@ -1318,7 +1312,6 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1318 case NFS3_CREATE_EXCLUSIVE: 1312 case NFS3_CREATE_EXCLUSIVE:
1319 if ( dchild->d_inode->i_mtime.tv_sec == v_mtime 1313 if ( dchild->d_inode->i_mtime.tv_sec == v_mtime
1320 && dchild->d_inode->i_atime.tv_sec == v_atime 1314 && dchild->d_inode->i_atime.tv_sec == v_atime
1321 && dchild->d_inode->i_mode == v_mode
1322 && dchild->d_inode->i_size == 0 ) 1315 && dchild->d_inode->i_size == 0 )
1323 break; 1316 break;
1324 /* fallthru */ 1317 /* fallthru */
@@ -1340,26 +1333,22 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1340 } 1333 }
1341 1334
1342 if (createmode == NFS3_CREATE_EXCLUSIVE) { 1335 if (createmode == NFS3_CREATE_EXCLUSIVE) {
1343 /* Cram the verifier into atime/mtime/mode */ 1336 /* Cram the verifier into atime/mtime */
1344 iap->ia_valid = ATTR_MTIME|ATTR_ATIME 1337 iap->ia_valid = ATTR_MTIME|ATTR_ATIME
1345 | ATTR_MTIME_SET|ATTR_ATIME_SET 1338 | ATTR_MTIME_SET|ATTR_ATIME_SET;
1346 | ATTR_MODE;
1347 /* XXX someone who knows this better please fix it for nsec */ 1339 /* XXX someone who knows this better please fix it for nsec */
1348 iap->ia_mtime.tv_sec = v_mtime; 1340 iap->ia_mtime.tv_sec = v_mtime;
1349 iap->ia_atime.tv_sec = v_atime; 1341 iap->ia_atime.tv_sec = v_atime;
1350 iap->ia_mtime.tv_nsec = 0; 1342 iap->ia_mtime.tv_nsec = 0;
1351 iap->ia_atime.tv_nsec = 0; 1343 iap->ia_atime.tv_nsec = 0;
1352 iap->ia_mode = v_mode;
1353 } 1344 }
1354 1345
1355 /* Set file attributes. 1346 /* Set file attributes.
1356 * Mode has already been set but we might need to reset it
1357 * for CREATE_EXCLUSIVE
1358 * Irix appears to send along the gid when it tries to 1347 * Irix appears to send along the gid when it tries to
1359 * implement setgid directories via NFS. Clear out all that cruft. 1348 * implement setgid directories via NFS. Clear out all that cruft.
1360 */ 1349 */
1361 set_attr: 1350 set_attr:
1362 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID)) != 0) { 1351 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
1363 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1352 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1364 if (err2) 1353 if (err2)
1365 err = err2; 1354 err = err2;
@@ -1726,7 +1715,7 @@ out:
1726 */ 1715 */
1727__be32 1716__be32
1728nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp, 1717nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
1729 struct readdir_cd *cdp, encode_dent_fn func) 1718 struct readdir_cd *cdp, filldir_t func)
1730{ 1719{
1731 __be32 err; 1720 __be32 err;
1732 int host_err; 1721 int host_err;
@@ -1751,7 +1740,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
1751 1740
1752 do { 1741 do {
1753 cdp->err = nfserr_eof; /* will be cleared on successful read */ 1742 cdp->err = nfserr_eof; /* will be cleared on successful read */
1754 host_err = vfs_readdir(file, (filldir_t) func, cdp); 1743 host_err = vfs_readdir(file, func, cdp);
1755 } while (host_err >=0 && cdp->err == nfs_ok); 1744 } while (host_err >=0 && cdp->err == nfs_ok);
1756 if (host_err) 1745 if (host_err)
1757 err = nfserrno(host_err); 1746 err = nfserrno(host_err);
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 35cc4b1d60f7..af4ef808fa94 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -17,6 +17,13 @@ ToDo/Notes:
17 happen is unclear however so it is worth waiting until someone hits 17 happen is unclear however so it is worth waiting until someone hits
18 the problem. 18 the problem.
19 19
202.1.28 - Fix a deadlock.
21
22 - Fix deadlock in fs/ntfs/inode.c::ntfs_put_inode(). Thanks to Sergey
23 Vlasov for the report and detailed analysis of the deadlock. The fix
24 involved getting rid of ntfs_put_inode() altogether and hence NTFS no
25 longer has a ->put_inode super operation.
26
202.1.27 - Various bug fixes and cleanups. 272.1.27 - Various bug fixes and cleanups.
21 28
22 - Fix two compiler warnings on Alpha. Thanks to Andrew Morton for 29 - Fix two compiler warnings on Alpha. Thanks to Andrew Morton for
diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile
index e27b4eacffbf..825508385565 100644
--- a/fs/ntfs/Makefile
+++ b/fs/ntfs/Makefile
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
6 index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ 6 index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \
7 unistr.o upcase.o 7 unistr.o upcase.o
8 8
9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.27\" 9EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.28\"
10 10
11ifeq ($(CONFIG_NTFS_DEBUG),y) 11ifeq ($(CONFIG_NTFS_DEBUG),y)
12EXTRA_CFLAGS += -DDEBUG 12EXTRA_CFLAGS += -DDEBUG
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 7b2c8f4f6a6f..629e7abdd840 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -92,10 +92,12 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
92 ofs = 0; 92 ofs = 0;
93 if (file_ofs < init_size) 93 if (file_ofs < init_size)
94 ofs = init_size - file_ofs; 94 ofs = init_size - file_ofs;
95 local_irq_save(flags);
95 kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ); 96 kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ);
96 memset(kaddr + bh_offset(bh) + ofs, 0, 97 memset(kaddr + bh_offset(bh) + ofs, 0,
97 bh->b_size - ofs); 98 bh->b_size - ofs);
98 kunmap_atomic(kaddr, KM_BIO_SRC_IRQ); 99 kunmap_atomic(kaddr, KM_BIO_SRC_IRQ);
100 local_irq_restore(flags);
99 flush_dcache_page(page); 101 flush_dcache_page(page);
100 } 102 }
101 } else { 103 } else {
@@ -143,11 +145,13 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
143 recs = PAGE_CACHE_SIZE / rec_size; 145 recs = PAGE_CACHE_SIZE / rec_size;
144 /* Should have been verified before we got here... */ 146 /* Should have been verified before we got here... */
145 BUG_ON(!recs); 147 BUG_ON(!recs);
148 local_irq_save(flags);
146 kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ); 149 kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ);
147 for (i = 0; i < recs; i++) 150 for (i = 0; i < recs; i++)
148 post_read_mst_fixup((NTFS_RECORD*)(kaddr + 151 post_read_mst_fixup((NTFS_RECORD*)(kaddr +
149 i * rec_size), rec_size); 152 i * rec_size), rec_size);
150 kunmap_atomic(kaddr, KM_BIO_SRC_IRQ); 153 kunmap_atomic(kaddr, KM_BIO_SRC_IRQ);
154 local_irq_restore(flags);
151 flush_dcache_page(page); 155 flush_dcache_page(page);
152 if (likely(page_uptodate && !PageError(page))) 156 if (likely(page_uptodate && !PageError(page)))
153 SetPageUptodate(page); 157 SetPageUptodate(page);
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 8296c29ae3b8..74f99a6a369b 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1,7 +1,7 @@
1/** 1/**
2 * dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project. 2 * dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project.
3 * 3 *
4 * Copyright (c) 2001-2005 Anton Altaparmakov 4 * Copyright (c) 2001-2007 Anton Altaparmakov
5 * Copyright (c) 2002 Richard Russon 5 * Copyright (c) 2002 Richard Russon
6 * 6 *
7 * This program/include file is free software; you can redistribute it and/or 7 * This program/include file is free software; you can redistribute it and/or
@@ -1249,16 +1249,12 @@ skip_index_root:
1249 /* Get the offset into the index allocation attribute. */ 1249 /* Get the offset into the index allocation attribute. */
1250 ia_pos = (s64)fpos - vol->mft_record_size; 1250 ia_pos = (s64)fpos - vol->mft_record_size;
1251 ia_mapping = vdir->i_mapping; 1251 ia_mapping = vdir->i_mapping;
1252 bmp_vi = ndir->itype.index.bmp_ino; 1252 ntfs_debug("Inode 0x%lx, getting index bitmap.", vdir->i_ino);
1253 if (unlikely(!bmp_vi)) { 1253 bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4);
1254 ntfs_debug("Inode 0x%lx, regetting index bitmap.", vdir->i_ino); 1254 if (IS_ERR(bmp_vi)) {
1255 bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); 1255 ntfs_error(sb, "Failed to get bitmap attribute.");
1256 if (IS_ERR(bmp_vi)) { 1256 err = PTR_ERR(bmp_vi);
1257 ntfs_error(sb, "Failed to get bitmap attribute."); 1257 goto err_out;
1258 err = PTR_ERR(bmp_vi);
1259 goto err_out;
1260 }
1261 ndir->itype.index.bmp_ino = bmp_vi;
1262 } 1258 }
1263 bmp_mapping = bmp_vi->i_mapping; 1259 bmp_mapping = bmp_vi->i_mapping;
1264 /* Get the starting bitmap bit position and sanity check it. */ 1260 /* Get the starting bitmap bit position and sanity check it. */
@@ -1266,7 +1262,7 @@ skip_index_root:
1266 if (unlikely(bmp_pos >> 3 >= i_size_read(bmp_vi))) { 1262 if (unlikely(bmp_pos >> 3 >= i_size_read(bmp_vi))) {
1267 ntfs_error(sb, "Current index allocation position exceeds " 1263 ntfs_error(sb, "Current index allocation position exceeds "
1268 "index bitmap size."); 1264 "index bitmap size.");
1269 goto err_out; 1265 goto iput_err_out;
1270 } 1266 }
1271 /* Get the starting bit position in the current bitmap page. */ 1267 /* Get the starting bit position in the current bitmap page. */
1272 cur_bmp_pos = bmp_pos & ((PAGE_CACHE_SIZE * 8) - 1); 1268 cur_bmp_pos = bmp_pos & ((PAGE_CACHE_SIZE * 8) - 1);
@@ -1282,7 +1278,7 @@ get_next_bmp_page:
1282 ntfs_error(sb, "Reading index bitmap failed."); 1278 ntfs_error(sb, "Reading index bitmap failed.");
1283 err = PTR_ERR(bmp_page); 1279 err = PTR_ERR(bmp_page);
1284 bmp_page = NULL; 1280 bmp_page = NULL;
1285 goto err_out; 1281 goto iput_err_out;
1286 } 1282 }
1287 bmp = (u8*)page_address(bmp_page); 1283 bmp = (u8*)page_address(bmp_page);
1288 /* Find next index block in use. */ 1284 /* Find next index block in use. */
@@ -1429,6 +1425,7 @@ find_next_index_buffer:
1429 /* @ia_page is already unlocked in this case. */ 1425 /* @ia_page is already unlocked in this case. */
1430 ntfs_unmap_page(ia_page); 1426 ntfs_unmap_page(ia_page);
1431 ntfs_unmap_page(bmp_page); 1427 ntfs_unmap_page(bmp_page);
1428 iput(bmp_vi);
1432 goto abort; 1429 goto abort;
1433 } 1430 }
1434 } 1431 }
@@ -1439,6 +1436,7 @@ unm_EOD:
1439 ntfs_unmap_page(ia_page); 1436 ntfs_unmap_page(ia_page);
1440 } 1437 }
1441 ntfs_unmap_page(bmp_page); 1438 ntfs_unmap_page(bmp_page);
1439 iput(bmp_vi);
1442EOD: 1440EOD:
1443 /* We are finished, set fpos to EOD. */ 1441 /* We are finished, set fpos to EOD. */
1444 fpos = i_size + vol->mft_record_size; 1442 fpos = i_size + vol->mft_record_size;
@@ -1455,8 +1453,11 @@ done:
1455 filp->f_pos = fpos; 1453 filp->f_pos = fpos;
1456 return 0; 1454 return 0;
1457err_out: 1455err_out:
1458 if (bmp_page) 1456 if (bmp_page) {
1459 ntfs_unmap_page(bmp_page); 1457 ntfs_unmap_page(bmp_page);
1458iput_err_out:
1459 iput(bmp_vi);
1460 }
1460 if (ia_page) { 1461 if (ia_page) {
1461 unlock_page(ia_page); 1462 unlock_page(ia_page);
1462 ntfs_unmap_page(ia_page); 1463 ntfs_unmap_page(ia_page);
@@ -1529,14 +1530,22 @@ static int ntfs_dir_open(struct inode *vi, struct file *filp)
1529static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry, 1530static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry,
1530 int datasync) 1531 int datasync)
1531{ 1532{
1532 struct inode *vi = dentry->d_inode; 1533 struct inode *bmp_vi, *vi = dentry->d_inode;
1533 ntfs_inode *ni = NTFS_I(vi);
1534 int err, ret; 1534 int err, ret;
1535 ntfs_attr na;
1535 1536
1536 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); 1537 ntfs_debug("Entering for inode 0x%lx.", vi->i_ino);
1537 BUG_ON(!S_ISDIR(vi->i_mode)); 1538 BUG_ON(!S_ISDIR(vi->i_mode));
1538 if (NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) 1539 /* If the bitmap attribute inode is in memory sync it, too. */
1539 write_inode_now(ni->itype.index.bmp_ino, !datasync); 1540 na.mft_no = vi->i_ino;
1541 na.type = AT_BITMAP;
1542 na.name = I30;
1543 na.name_len = 4;
1544 bmp_vi = ilookup5(vi->i_sb, vi->i_ino, (test_t)ntfs_test_inode, &na);
1545 if (bmp_vi) {
1546 write_inode_now(bmp_vi, !datasync);
1547 iput(bmp_vi);
1548 }
1540 ret = ntfs_write_inode(vi, 1); 1549 ret = ntfs_write_inode(vi, 1);
1541 write_inode_now(vi, !datasync); 1550 write_inode_now(vi, !datasync);
1542 err = sync_blockdev(vi->i_sb->s_bdev); 1551 err = sync_blockdev(vi->i_sb->s_bdev);
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 247989891b4b..f8bf8da67ee8 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -1,7 +1,7 @@
1/** 1/**
2 * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project. 2 * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project.
3 * 3 *
4 * Copyright (c) 2001-2006 Anton Altaparmakov 4 * Copyright (c) 2001-2007 Anton Altaparmakov
5 * 5 *
6 * This program/include file is free software; you can redistribute it and/or 6 * This program/include file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as published 7 * modify it under the terms of the GNU General Public License as published
@@ -95,7 +95,7 @@ int ntfs_test_inode(struct inode *vi, ntfs_attr *na)
95 * If initializing the normal file/directory inode, set @na->type to AT_UNUSED. 95 * If initializing the normal file/directory inode, set @na->type to AT_UNUSED.
96 * In that case, @na->name and @na->name_len should be set to NULL and 0, 96 * In that case, @na->name and @na->name_len should be set to NULL and 0,
97 * respectively. Although that is not strictly necessary as 97 * respectively. Although that is not strictly necessary as
98 * ntfs_read_inode_locked() will fill them in later. 98 * ntfs_read_locked_inode() will fill them in later.
99 * 99 *
100 * Return 0 on success and -errno on error. 100 * Return 0 on success and -errno on error.
101 * 101 *
@@ -171,8 +171,8 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi,
171struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no) 171struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no)
172{ 172{
173 struct inode *vi; 173 struct inode *vi;
174 ntfs_attr na;
175 int err; 174 int err;
175 ntfs_attr na;
176 176
177 na.mft_no = mft_no; 177 na.mft_no = mft_no;
178 na.type = AT_UNUSED; 178 na.type = AT_UNUSED;
@@ -229,8 +229,8 @@ struct inode *ntfs_attr_iget(struct inode *base_vi, ATTR_TYPE type,
229 ntfschar *name, u32 name_len) 229 ntfschar *name, u32 name_len)
230{ 230{
231 struct inode *vi; 231 struct inode *vi;
232 ntfs_attr na;
233 int err; 232 int err;
233 ntfs_attr na;
234 234
235 /* Make sure no one calls ntfs_attr_iget() for indices. */ 235 /* Make sure no one calls ntfs_attr_iget() for indices. */
236 BUG_ON(type == AT_INDEX_ALLOCATION); 236 BUG_ON(type == AT_INDEX_ALLOCATION);
@@ -287,8 +287,8 @@ struct inode *ntfs_index_iget(struct inode *base_vi, ntfschar *name,
287 u32 name_len) 287 u32 name_len)
288{ 288{
289 struct inode *vi; 289 struct inode *vi;
290 ntfs_attr na;
291 int err; 290 int err;
291 ntfs_attr na;
292 292
293 na.mft_no = base_vi->i_ino; 293 na.mft_no = base_vi->i_ino;
294 na.type = AT_INDEX_ALLOCATION; 294 na.type = AT_INDEX_ALLOCATION;
@@ -402,7 +402,6 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)
402 ntfs_init_runlist(&ni->attr_list_rl); 402 ntfs_init_runlist(&ni->attr_list_rl);
403 lockdep_set_class(&ni->attr_list_rl.lock, 403 lockdep_set_class(&ni->attr_list_rl.lock,
404 &attr_list_rl_lock_class); 404 &attr_list_rl_lock_class);
405 ni->itype.index.bmp_ino = NULL;
406 ni->itype.index.block_size = 0; 405 ni->itype.index.block_size = 0;
407 ni->itype.index.vcn_size = 0; 406 ni->itype.index.vcn_size = 0;
408 ni->itype.index.collation_rule = 0; 407 ni->itype.index.collation_rule = 0;
@@ -546,6 +545,7 @@ static int ntfs_read_locked_inode(struct inode *vi)
546{ 545{
547 ntfs_volume *vol = NTFS_SB(vi->i_sb); 546 ntfs_volume *vol = NTFS_SB(vi->i_sb);
548 ntfs_inode *ni; 547 ntfs_inode *ni;
548 struct inode *bvi;
549 MFT_RECORD *m; 549 MFT_RECORD *m;
550 ATTR_RECORD *a; 550 ATTR_RECORD *a;
551 STANDARD_INFORMATION *si; 551 STANDARD_INFORMATION *si;
@@ -780,7 +780,6 @@ skip_attr_list_load:
780 */ 780 */
781 if (S_ISDIR(vi->i_mode)) { 781 if (S_ISDIR(vi->i_mode)) {
782 loff_t bvi_size; 782 loff_t bvi_size;
783 struct inode *bvi;
784 ntfs_inode *bni; 783 ntfs_inode *bni;
785 INDEX_ROOT *ir; 784 INDEX_ROOT *ir;
786 u8 *ir_end, *index_end; 785 u8 *ir_end, *index_end;
@@ -985,13 +984,12 @@ skip_attr_list_load:
985 err = PTR_ERR(bvi); 984 err = PTR_ERR(bvi);
986 goto unm_err_out; 985 goto unm_err_out;
987 } 986 }
988 ni->itype.index.bmp_ino = bvi;
989 bni = NTFS_I(bvi); 987 bni = NTFS_I(bvi);
990 if (NInoCompressed(bni) || NInoEncrypted(bni) || 988 if (NInoCompressed(bni) || NInoEncrypted(bni) ||
991 NInoSparse(bni)) { 989 NInoSparse(bni)) {
992 ntfs_error(vi->i_sb, "$BITMAP attribute is compressed " 990 ntfs_error(vi->i_sb, "$BITMAP attribute is compressed "
993 "and/or encrypted and/or sparse."); 991 "and/or encrypted and/or sparse.");
994 goto unm_err_out; 992 goto iput_unm_err_out;
995 } 993 }
996 /* Consistency check bitmap size vs. index allocation size. */ 994 /* Consistency check bitmap size vs. index allocation size. */
997 bvi_size = i_size_read(bvi); 995 bvi_size = i_size_read(bvi);
@@ -1000,8 +998,10 @@ skip_attr_list_load:
1000 ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) " 998 ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) "
1001 "for index allocation (0x%llx).", 999 "for index allocation (0x%llx).",
1002 bvi_size << 3, vi->i_size); 1000 bvi_size << 3, vi->i_size);
1003 goto unm_err_out; 1001 goto iput_unm_err_out;
1004 } 1002 }
1003 /* No longer need the bitmap attribute inode. */
1004 iput(bvi);
1005skip_large_dir_stuff: 1005skip_large_dir_stuff:
1006 /* Setup the operations for this inode. */ 1006 /* Setup the operations for this inode. */
1007 vi->i_op = &ntfs_dir_inode_ops; 1007 vi->i_op = &ntfs_dir_inode_ops;
@@ -1176,7 +1176,8 @@ no_data_attr_special_case:
1176 vi->i_blocks = ni->allocated_size >> 9; 1176 vi->i_blocks = ni->allocated_size >> 9;
1177 ntfs_debug("Done."); 1177 ntfs_debug("Done.");
1178 return 0; 1178 return 0;
1179 1179iput_unm_err_out:
1180 iput(bvi);
1180unm_err_out: 1181unm_err_out:
1181 if (!err) 1182 if (!err)
1182 err = -EIO; 1183 err = -EIO;
@@ -1697,7 +1698,7 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
1697 vi->i_size); 1698 vi->i_size);
1698 goto iput_unm_err_out; 1699 goto iput_unm_err_out;
1699 } 1700 }
1700 ni->itype.index.bmp_ino = bvi; 1701 iput(bvi);
1701skip_large_index_stuff: 1702skip_large_index_stuff:
1702 /* Setup the operations for this index inode. */ 1703 /* Setup the operations for this index inode. */
1703 vi->i_op = NULL; 1704 vi->i_op = NULL;
@@ -1714,7 +1715,6 @@ skip_large_index_stuff:
1714 1715
1715 ntfs_debug("Done."); 1716 ntfs_debug("Done.");
1716 return 0; 1717 return 0;
1717
1718iput_unm_err_out: 1718iput_unm_err_out:
1719 iput(bvi); 1719 iput(bvi);
1720unm_err_out: 1720unm_err_out:
@@ -2191,37 +2191,6 @@ err_out:
2191 return -1; 2191 return -1;
2192} 2192}
2193 2193
2194/**
2195 * ntfs_put_inode - handler for when the inode reference count is decremented
2196 * @vi: vfs inode
2197 *
2198 * The VFS calls ntfs_put_inode() every time the inode reference count (i_count)
2199 * is about to be decremented (but before the decrement itself.
2200 *
2201 * If the inode @vi is a directory with two references, one of which is being
2202 * dropped, we need to put the attribute inode for the directory index bitmap,
2203 * if it is present, otherwise the directory inode would remain pinned for
2204 * ever.
2205 */
2206void ntfs_put_inode(struct inode *vi)
2207{
2208 if (S_ISDIR(vi->i_mode) && atomic_read(&vi->i_count) == 2) {
2209 ntfs_inode *ni = NTFS_I(vi);
2210 if (NInoIndexAllocPresent(ni)) {
2211 struct inode *bvi = NULL;
2212 mutex_lock(&vi->i_mutex);
2213 if (atomic_read(&vi->i_count) == 2) {
2214 bvi = ni->itype.index.bmp_ino;
2215 if (bvi)
2216 ni->itype.index.bmp_ino = NULL;
2217 }
2218 mutex_unlock(&vi->i_mutex);
2219 if (bvi)
2220 iput(bvi);
2221 }
2222 }
2223}
2224
2225static void __ntfs_clear_inode(ntfs_inode *ni) 2194static void __ntfs_clear_inode(ntfs_inode *ni)
2226{ 2195{
2227 /* Free all alocated memory. */ 2196 /* Free all alocated memory. */
@@ -2287,18 +2256,6 @@ void ntfs_clear_big_inode(struct inode *vi)
2287{ 2256{
2288 ntfs_inode *ni = NTFS_I(vi); 2257 ntfs_inode *ni = NTFS_I(vi);
2289 2258
2290 /*
2291 * If the inode @vi is an index inode we need to put the attribute
2292 * inode for the index bitmap, if it is present, otherwise the index
2293 * inode would disappear and the attribute inode for the index bitmap
2294 * would no longer be referenced from anywhere and thus it would remain
2295 * pinned for ever.
2296 */
2297 if (NInoAttr(ni) && (ni->type == AT_INDEX_ALLOCATION) &&
2298 NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) {
2299 iput(ni->itype.index.bmp_ino);
2300 ni->itype.index.bmp_ino = NULL;
2301 }
2302#ifdef NTFS_RW 2259#ifdef NTFS_RW
2303 if (NInoDirty(ni)) { 2260 if (NInoDirty(ni)) {
2304 bool was_bad = (is_bad_inode(vi)); 2261 bool was_bad = (is_bad_inode(vi));
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h
index f088291e017c..117eaf8032a3 100644
--- a/fs/ntfs/inode.h
+++ b/fs/ntfs/inode.h
@@ -2,7 +2,7 @@
2 * inode.h - Defines for inode structures NTFS Linux kernel driver. Part of 2 * inode.h - Defines for inode structures NTFS Linux kernel driver. Part of
3 * the Linux-NTFS project. 3 * the Linux-NTFS project.
4 * 4 *
5 * Copyright (c) 2001-2005 Anton Altaparmakov 5 * Copyright (c) 2001-2007 Anton Altaparmakov
6 * Copyright (c) 2002 Richard Russon 6 * Copyright (c) 2002 Richard Russon
7 * 7 *
8 * This program/include file is free software; you can redistribute it and/or 8 * This program/include file is free software; you can redistribute it and/or
@@ -101,8 +101,6 @@ struct _ntfs_inode {
101 runlist attr_list_rl; /* Run list for the attribute list value. */ 101 runlist attr_list_rl; /* Run list for the attribute list value. */
102 union { 102 union {
103 struct { /* It is a directory, $MFT, or an index inode. */ 103 struct { /* It is a directory, $MFT, or an index inode. */
104 struct inode *bmp_ino; /* Attribute inode for the
105 index $BITMAP. */
106 u32 block_size; /* Size of an index block. */ 104 u32 block_size; /* Size of an index block. */
107 u32 vcn_size; /* Size of a vcn in this 105 u32 vcn_size; /* Size of a vcn in this
108 index. */ 106 index. */
@@ -300,8 +298,6 @@ extern void ntfs_clear_extent_inode(ntfs_inode *ni);
300 298
301extern int ntfs_read_inode_mount(struct inode *vi); 299extern int ntfs_read_inode_mount(struct inode *vi);
302 300
303extern void ntfs_put_inode(struct inode *vi);
304
305extern int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt); 301extern int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt);
306 302
307#ifdef NTFS_RW 303#ifdef NTFS_RW
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 03a391ac7145..babf94d90def 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. 2 * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.
3 * 3 *
4 * Copyright (c) 2001-2006 Anton Altaparmakov 4 * Copyright (c) 2001-2007 Anton Altaparmakov
5 * Copyright (c) 2001,2002 Richard Russon 5 * Copyright (c) 2001,2002 Richard Russon
6 * 6 *
7 * This program/include file is free software; you can redistribute it and/or 7 * This program/include file is free software; you can redistribute it and/or
@@ -2702,9 +2702,6 @@ static int ntfs_statfs(struct dentry *dentry, struct kstatfs *sfs)
2702static struct super_operations ntfs_sops = { 2702static struct super_operations ntfs_sops = {
2703 .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */ 2703 .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */
2704 .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */ 2704 .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */
2705 .put_inode = ntfs_put_inode, /* VFS: Called just before
2706 the inode reference count
2707 is decreased. */
2708#ifdef NTFS_RW 2705#ifdef NTFS_RW
2709 //.dirty_inode = NULL, /* VFS: Called from 2706 //.dirty_inode = NULL, /* VFS: Called from
2710 // __mark_inode_dirty(). */ 2707 // __mark_inode_dirty(). */
@@ -3261,7 +3258,7 @@ static void __exit exit_ntfs_fs(void)
3261} 3258}
3262 3259
3263MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); 3260MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>");
3264MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2006 Anton Altaparmakov"); 3261MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2007 Anton Altaparmakov");
3265MODULE_VERSION(NTFS_VERSION); 3262MODULE_VERSION(NTFS_VERSION);
3266MODULE_LICENSE("GPL"); 3263MODULE_LICENSE("GPL");
3267#ifdef DEBUG 3264#ifdef DEBUG
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index 06be6e774cf9..56e1fefc1205 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -60,14 +60,11 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp)
60 60
61 inode = ocfs2_iget(OCFS2_SB(sb), handle->ih_blkno, 0); 61 inode = ocfs2_iget(OCFS2_SB(sb), handle->ih_blkno, 0);
62 62
63 if (IS_ERR(inode)) { 63 if (IS_ERR(inode))
64 mlog_errno(PTR_ERR(inode));
65 return (void *)inode; 64 return (void *)inode;
66 }
67 65
68 if (handle->ih_generation != inode->i_generation) { 66 if (handle->ih_generation != inode->i_generation) {
69 iput(inode); 67 iput(inode);
70 mlog_errno(-ESTALE);
71 return ERR_PTR(-ESTALE); 68 return ERR_PTR(-ESTALE);
72 } 69 }
73 70
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index e4d91493d7d7..28ab56f2b98c 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -146,7 +146,6 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, int flags)
146 if (is_bad_inode(inode)) { 146 if (is_bad_inode(inode)) {
147 iput(inode); 147 iput(inode);
148 inode = ERR_PTR(-ESTALE); 148 inode = ERR_PTR(-ESTALE);
149 mlog_errno(PTR_ERR(inode));
150 goto bail; 149 goto bail;
151 } 150 }
152 151
@@ -155,8 +154,7 @@ bail:
155 mlog(0, "returning inode with number %llu\n", 154 mlog(0, "returning inode with number %llu\n",
156 (unsigned long long)OCFS2_I(inode)->ip_blkno); 155 (unsigned long long)OCFS2_I(inode)->ip_blkno);
157 mlog_exit_ptr(inode); 156 mlog_exit_ptr(inode);
158 } else 157 }
159 mlog_errno(PTR_ERR(inode));
160 158
161 return inode; 159 return inode;
162} 160}
@@ -247,7 +245,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
247 * today. change if needed. */ 245 * today. change if needed. */
248 if (!OCFS2_IS_VALID_DINODE(fe) || 246 if (!OCFS2_IS_VALID_DINODE(fe) ||
249 !(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL))) { 247 !(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL))) {
250 mlog(ML_ERROR, "Invalid dinode: i_ino=%lu, i_blkno=%llu, " 248 mlog(0, "Invalid dinode: i_ino=%lu, i_blkno=%llu, "
251 "signature = %.*s, flags = 0x%x\n", 249 "signature = %.*s, flags = 0x%x\n",
252 inode->i_ino, 250 inode->i_ino,
253 (unsigned long long)le64_to_cpu(fe->i_blkno), 7, 251 (unsigned long long)le64_to_cpu(fe->i_blkno), 7,
@@ -478,11 +476,8 @@ static int ocfs2_read_locked_inode(struct inode *inode,
478 S_ISBLK(le16_to_cpu(fe->i_mode))) 476 S_ISBLK(le16_to_cpu(fe->i_mode)))
479 inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev)); 477 inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
480 478
481 if (ocfs2_populate_inode(inode, fe, 0) < 0) { 479 if (ocfs2_populate_inode(inode, fe, 0) < 0)
482 mlog(ML_ERROR, "populate failed! i_blkno=%llu, i_ino=%lu\n",
483 (unsigned long long)fe->i_blkno, inode->i_ino);
484 goto bail; 480 goto bail;
485 }
486 481
487 BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno)); 482 BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno));
488 483
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 9637039c2633..f3d7803b4b46 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -932,14 +932,15 @@ static int ocfs2_unlink(struct inode *dir,
932 goto leave; 932 goto leave;
933 } 933 }
934 934
935 if (S_ISDIR(inode->i_mode)) { 935 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
936 if (S_ISDIR(inode->i_mode))
936 drop_nlink(dir); 937 drop_nlink(dir);
937 status = ocfs2_mark_inode_dirty(handle, dir, 938
938 parent_node_bh); 939 status = ocfs2_mark_inode_dirty(handle, dir, parent_node_bh);
939 if (status < 0) { 940 if (status < 0) {
940 mlog_errno(status); 941 mlog_errno(status);
942 if (S_ISDIR(inode->i_mode))
941 inc_nlink(dir); 943 inc_nlink(dir);
942 }
943 } 944 }
944 945
945leave: 946leave:
@@ -1068,6 +1069,7 @@ static int ocfs2_rename(struct inode *old_dir,
1068 char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; 1069 char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
1069 struct buffer_head *orphan_entry_bh = NULL; 1070 struct buffer_head *orphan_entry_bh = NULL;
1070 struct buffer_head *newfe_bh = NULL; 1071 struct buffer_head *newfe_bh = NULL;
1072 struct buffer_head *old_inode_bh = NULL;
1071 struct buffer_head *insert_entry_bh = NULL; 1073 struct buffer_head *insert_entry_bh = NULL;
1072 struct ocfs2_super *osb = NULL; 1074 struct ocfs2_super *osb = NULL;
1073 u64 newfe_blkno; 1075 u64 newfe_blkno;
@@ -1079,7 +1081,7 @@ static int ocfs2_rename(struct inode *old_dir,
1079 struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above 1081 struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above
1080 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir, 1082 struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
1081 // this is the 1st dirent bh 1083 // this is the 1st dirent bh
1082 nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink; 1084 nlink_t old_dir_nlink = old_dir->i_nlink;
1083 1085
1084 /* At some point it might be nice to break this function up a 1086 /* At some point it might be nice to break this function up a
1085 * bit. */ 1087 * bit. */
@@ -1139,12 +1141,11 @@ static int ocfs2_rename(struct inode *old_dir,
1139 } 1141 }
1140 1142
1141 /* 1143 /*
1142 * Though we don't require an inode meta data update if 1144 * Aside from allowing a meta data update, the locking here
1143 * old_inode is not a directory, we lock anyway here to ensure 1145 * also ensures that the vote thread on other nodes won't have
1144 * the vote thread on other nodes won't have to concurrently 1146 * to concurrently downconvert the inode and the dentry locks.
1145 * downconvert the inode and the dentry locks.
1146 */ 1147 */
1147 status = ocfs2_meta_lock(old_inode, NULL, 1); 1148 status = ocfs2_meta_lock(old_inode, &old_inode_bh, 1);
1148 if (status < 0) { 1149 if (status < 0) {
1149 if (status != -ENOENT) 1150 if (status != -ENOENT)
1150 mlog_errno(status); 1151 mlog_errno(status);
@@ -1355,6 +1356,7 @@ static int ocfs2_rename(struct inode *old_dir,
1355 1356
1356 old_inode->i_ctime = CURRENT_TIME; 1357 old_inode->i_ctime = CURRENT_TIME;
1357 mark_inode_dirty(old_inode); 1358 mark_inode_dirty(old_inode);
1359 ocfs2_mark_inode_dirty(handle, old_inode, old_inode_bh);
1358 1360
1359 /* now that the name has been added to new_dir, remove the old name */ 1361 /* now that the name has been added to new_dir, remove the old name */
1360 status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh); 1362 status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
@@ -1384,27 +1386,22 @@ static int ocfs2_rename(struct inode *old_dir,
1384 } 1386 }
1385 } 1387 }
1386 mark_inode_dirty(old_dir); 1388 mark_inode_dirty(old_dir);
1387 if (new_inode) 1389 ocfs2_mark_inode_dirty(handle, old_dir, old_dir_bh);
1390 if (new_inode) {
1388 mark_inode_dirty(new_inode); 1391 mark_inode_dirty(new_inode);
1392 ocfs2_mark_inode_dirty(handle, new_inode, newfe_bh);
1393 }
1389 1394
1390 if (old_dir != new_dir) 1395 if (old_dir != new_dir) {
1391 if (new_dir_nlink != new_dir->i_nlink) { 1396 /* Keep the same times on both directories.*/
1392 if (!new_dir_bh) { 1397 new_dir->i_ctime = new_dir->i_mtime = old_dir->i_ctime;
1393 mlog(ML_ERROR, "need to change nlink for new " 1398
1394 "dir %llu from %d to %d but bh is NULL\n", 1399 /*
1395 (unsigned long long)OCFS2_I(new_dir)->ip_blkno, 1400 * This will also pick up the i_nlink change from the
1396 (int)new_dir_nlink, new_dir->i_nlink); 1401 * block above.
1397 } else { 1402 */
1398 struct ocfs2_dinode *fe; 1403 ocfs2_mark_inode_dirty(handle, new_dir, new_dir_bh);
1399 status = ocfs2_journal_access(handle, 1404 }
1400 new_dir,
1401 new_dir_bh,
1402 OCFS2_JOURNAL_ACCESS_WRITE);
1403 fe = (struct ocfs2_dinode *) new_dir_bh->b_data;
1404 fe->i_links_count = cpu_to_le16(new_dir->i_nlink);
1405 status = ocfs2_journal_dirty(handle, new_dir_bh);
1406 }
1407 }
1408 1405
1409 if (old_dir_nlink != old_dir->i_nlink) { 1406 if (old_dir_nlink != old_dir->i_nlink) {
1410 if (!old_dir_bh) { 1407 if (!old_dir_bh) {
@@ -1455,6 +1452,8 @@ bail:
1455 iput(new_inode); 1452 iput(new_inode);
1456 if (newfe_bh) 1453 if (newfe_bh)
1457 brelse(newfe_bh); 1454 brelse(newfe_bh);
1455 if (old_inode_bh)
1456 brelse(old_inode_bh);
1458 if (old_dir_bh) 1457 if (old_dir_bh)
1459 brelse(old_dir_bh); 1458 brelse(old_dir_bh);
1460 if (new_dir_bh) 1459 if (new_dir_bh)
@@ -1826,6 +1825,13 @@ static int __ocfs2_add_entry(handle_t *handle,
1826 (le16_to_cpu(de->rec_len) >= rec_len)) || 1825 (le16_to_cpu(de->rec_len) >= rec_len)) ||
1827 (le16_to_cpu(de->rec_len) >= 1826 (le16_to_cpu(de->rec_len) >=
1828 (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) { 1827 (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) {
1828 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
1829 retval = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh);
1830 if (retval < 0) {
1831 mlog_errno(retval);
1832 goto bail;
1833 }
1834
1829 status = ocfs2_journal_access(handle, dir, insert_bh, 1835 status = ocfs2_journal_access(handle, dir, insert_bh,
1830 OCFS2_JOURNAL_ACCESS_WRITE); 1836 OCFS2_JOURNAL_ACCESS_WRITE);
1831 /* By now the buffer is marked for journaling */ 1837 /* By now the buffer is marked for journaling */
@@ -1848,7 +1854,6 @@ static int __ocfs2_add_entry(handle_t *handle,
1848 de->name_len = namelen; 1854 de->name_len = namelen;
1849 memcpy(de->name, name, namelen); 1855 memcpy(de->name, name, namelen);
1850 1856
1851 dir->i_mtime = dir->i_ctime = CURRENT_TIME;
1852 dir->i_version++; 1857 dir->i_version++;
1853 status = ocfs2_journal_dirty(handle, insert_bh); 1858 status = ocfs2_journal_dirty(handle, insert_bh);
1854 retval = 0; 1859 retval = 0;
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index b5c68567077e..e61e218f5e0b 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -85,7 +85,7 @@
85#define OCFS2_CLEAR_INCOMPAT_FEATURE(sb,mask) \ 85#define OCFS2_CLEAR_INCOMPAT_FEATURE(sb,mask) \
86 OCFS2_SB(sb)->s_feature_incompat &= ~(mask) 86 OCFS2_SB(sb)->s_feature_incompat &= ~(mask)
87 87
88#define OCFS2_FEATURE_COMPAT_SUPP 0 88#define OCFS2_FEATURE_COMPAT_SUPP OCFS2_FEATURE_COMPAT_BACKUP_SB
89#define OCFS2_FEATURE_INCOMPAT_SUPP OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT 89#define OCFS2_FEATURE_INCOMPAT_SUPP OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT
90#define OCFS2_FEATURE_RO_COMPAT_SUPP 0 90#define OCFS2_FEATURE_RO_COMPAT_SUPP 0
91 91
@@ -110,6 +110,20 @@
110#define OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC 0x0010 110#define OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC 0x0010
111 111
112/* 112/*
113 * backup superblock flag is used to indicate that this volume
114 * has backup superblocks.
115 */
116#define OCFS2_FEATURE_COMPAT_BACKUP_SB 0x0001
117
118/* The byte offset of the first backup block will be 1G.
119 * The following will be 4G, 16G, 64G, 256G and 1T.
120 */
121#define OCFS2_BACKUP_SB_START 1 << 30
122
123/* the max backup superblock nums */
124#define OCFS2_MAX_BACKUP_SUPERBLOCKS 6
125
126/*
113 * Flags on ocfs2_dinode.i_flags 127 * Flags on ocfs2_dinode.i_flags
114 */ 128 */
115#define OCFS2_VALID_FL (0x00000001) /* Inode is valid */ 129#define OCFS2_VALID_FL (0x00000001) /* Inode is valid */
@@ -566,6 +580,20 @@ static inline int ocfs2_truncate_recs_per_inode(struct super_block *sb)
566 580
567 return size / sizeof(struct ocfs2_truncate_rec); 581 return size / sizeof(struct ocfs2_truncate_rec);
568} 582}
583
584static inline u64 ocfs2_backup_super_blkno(struct super_block *sb, int index)
585{
586 u64 offset = OCFS2_BACKUP_SB_START;
587
588 if (index >= 0 && index < OCFS2_MAX_BACKUP_SUPERBLOCKS) {
589 offset <<= (2 * index);
590 offset >>= sb->s_blocksize_bits;
591 return offset;
592 }
593
594 return 0;
595
596}
569#else 597#else
570static inline int ocfs2_fast_symlink_chars(int blocksize) 598static inline int ocfs2_fast_symlink_chars(int blocksize)
571{ 599{
@@ -631,6 +659,19 @@ static inline int ocfs2_truncate_recs_per_inode(int blocksize)
631 659
632 return size / sizeof(struct ocfs2_truncate_rec); 660 return size / sizeof(struct ocfs2_truncate_rec);
633} 661}
662
663static inline uint64_t ocfs2_backup_super_blkno(int blocksize, int index)
664{
665 uint64_t offset = OCFS2_BACKUP_SB_START;
666
667 if (index >= 0 && index < OCFS2_MAX_BACKUP_SUPERBLOCKS) {
668 offset <<= (2 * index);
669 offset /= blocksize;
670 return offset;
671 }
672
673 return 0;
674}
634#endif /* __KERNEL__ */ 675#endif /* __KERNEL__ */
635 676
636 677
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index 957d6878b03e..03b0191534d5 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -158,8 +158,7 @@ static void *ocfs2_follow_link(struct dentry *dentry,
158 } 158 }
159 159
160 status = vfs_follow_link(nd, link); 160 status = vfs_follow_link(nd, link);
161 if (status && status != -ENOENT) 161
162 mlog_errno(status);
163bail: 162bail:
164 if (page) { 163 if (page) {
165 kunmap(page); 164 kunmap(page);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 77a57b5799c4..ff7a66850602 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -371,9 +371,11 @@ static int mounts_open(struct inode *inode, struct file *file)
371 371
372 if (task) { 372 if (task) {
373 task_lock(task); 373 task_lock(task);
374 ns = task->nsproxy->mnt_ns; 374 if (task->nsproxy) {
375 if (ns) 375 ns = task->nsproxy->mnt_ns;
376 get_mnt_ns(ns); 376 if (ns)
377 get_mnt_ns(ns);
378 }
377 task_unlock(task); 379 task_unlock(task);
378 put_task_struct(task); 380 put_task_struct(task);
379 } 381 }
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 99b6f329ba23..5109f1d5e7ff 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -48,6 +48,11 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
48 } 48 }
49 49
50 mutex_lock(&inode->i_mutex); 50 mutex_lock(&inode->i_mutex);
51
52 mutex_lock(&(REISERFS_I(inode)->i_mmap));
53 if (REISERFS_I(inode)->i_flags & i_ever_mapped)
54 REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
55
51 reiserfs_write_lock(inode->i_sb); 56 reiserfs_write_lock(inode->i_sb);
52 /* freeing preallocation only involves relogging blocks that 57 /* freeing preallocation only involves relogging blocks that
53 * are already in the current transaction. preallocation gets 58 * are already in the current transaction. preallocation gets
@@ -100,11 +105,24 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
100 err = reiserfs_truncate_file(inode, 0); 105 err = reiserfs_truncate_file(inode, 0);
101 } 106 }
102 out: 107 out:
108 mutex_unlock(&(REISERFS_I(inode)->i_mmap));
103 mutex_unlock(&inode->i_mutex); 109 mutex_unlock(&inode->i_mutex);
104 reiserfs_write_unlock(inode->i_sb); 110 reiserfs_write_unlock(inode->i_sb);
105 return err; 111 return err;
106} 112}
107 113
114static int reiserfs_file_mmap(struct file *file, struct vm_area_struct *vma)
115{
116 struct inode *inode;
117
118 inode = file->f_path.dentry->d_inode;
119 mutex_lock(&(REISERFS_I(inode)->i_mmap));
120 REISERFS_I(inode)->i_flags |= i_ever_mapped;
121 mutex_unlock(&(REISERFS_I(inode)->i_mmap));
122
123 return generic_file_mmap(file, vma);
124}
125
108static void reiserfs_vfs_truncate_file(struct inode *inode) 126static void reiserfs_vfs_truncate_file(struct inode *inode)
109{ 127{
110 reiserfs_truncate_file(inode, 1); 128 reiserfs_truncate_file(inode, 1);
@@ -1527,7 +1545,7 @@ const struct file_operations reiserfs_file_operations = {
1527#ifdef CONFIG_COMPAT 1545#ifdef CONFIG_COMPAT
1528 .compat_ioctl = reiserfs_compat_ioctl, 1546 .compat_ioctl = reiserfs_compat_ioctl,
1529#endif 1547#endif
1530 .mmap = generic_file_mmap, 1548 .mmap = reiserfs_file_mmap,
1531 .open = generic_file_open, 1549 .open = generic_file_open,
1532 .release = reiserfs_file_release, 1550 .release = reiserfs_file_release,
1533 .fsync = reiserfs_sync_file, 1551 .fsync = reiserfs_sync_file,
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index f3d1c4a77979..9fcbfe316977 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1125,6 +1125,7 @@ static void init_inode(struct inode *inode, struct treepath *path)
1125 REISERFS_I(inode)->i_prealloc_count = 0; 1125 REISERFS_I(inode)->i_prealloc_count = 0;
1126 REISERFS_I(inode)->i_trans_id = 0; 1126 REISERFS_I(inode)->i_trans_id = 0;
1127 REISERFS_I(inode)->i_jl = NULL; 1127 REISERFS_I(inode)->i_jl = NULL;
1128 mutex_init(&(REISERFS_I(inode)->i_mmap));
1128 reiserfs_init_acl_access(inode); 1129 reiserfs_init_acl_access(inode);
1129 reiserfs_init_acl_default(inode); 1130 reiserfs_init_acl_default(inode);
1130 reiserfs_init_xattr_rwsem(inode); 1131 reiserfs_init_xattr_rwsem(inode);
@@ -1832,6 +1833,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
1832 REISERFS_I(inode)->i_attrs = 1833 REISERFS_I(inode)->i_attrs =
1833 REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK; 1834 REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
1834 sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode); 1835 sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
1836 mutex_init(&(REISERFS_I(inode)->i_mmap));
1835 reiserfs_init_acl_access(inode); 1837 reiserfs_init_acl_access(inode);
1836 reiserfs_init_acl_default(inode); 1838 reiserfs_init_acl_default(inode);
1837 reiserfs_init_xattr_rwsem(inode); 1839 reiserfs_init_xattr_rwsem(inode);
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 2e0021e8f366..638f4c585e89 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -227,24 +227,27 @@ failed:
227 * We can come here from ufs_writepage or ufs_prepare_write, 227 * We can come here from ufs_writepage or ufs_prepare_write,
228 * locked_page is argument of these functions, so we already lock it. 228 * locked_page is argument of these functions, so we already lock it.
229 */ 229 */
230static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk, 230static void ufs_change_blocknr(struct inode *inode, unsigned int beg,
231 unsigned int count, unsigned int oldb, 231 unsigned int count, unsigned int oldb,
232 unsigned int newb, struct page *locked_page) 232 unsigned int newb, struct page *locked_page)
233{ 233{
234 unsigned int blk_per_page = 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); 234 const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1;
235 struct address_space *mapping = inode->i_mapping; 235 struct address_space * const mapping = inode->i_mapping;
236 pgoff_t index, cur_index = locked_page->index; 236 pgoff_t index, cur_index;
237 unsigned int i, j; 237 unsigned end, pos, j;
238 struct page *page; 238 struct page *page;
239 struct buffer_head *head, *bh; 239 struct buffer_head *head, *bh;
240 240
241 UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n", 241 UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n",
242 inode->i_ino, count, oldb, newb); 242 inode->i_ino, count, oldb, newb);
243 243
244 BUG_ON(!locked_page);
244 BUG_ON(!PageLocked(locked_page)); 245 BUG_ON(!PageLocked(locked_page));
245 246
246 for (i = 0; i < count; i += blk_per_page) { 247 cur_index = locked_page->index;
247 index = (baseblk+i) >> (PAGE_CACHE_SHIFT - inode->i_blkbits); 248
249 for (end = count + beg; beg < end; beg = (beg | mask) + 1) {
250 index = beg >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
248 251
249 if (likely(cur_index != index)) { 252 if (likely(cur_index != index)) {
250 page = ufs_get_locked_page(mapping, index); 253 page = ufs_get_locked_page(mapping, index);
@@ -253,21 +256,32 @@ static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk,
253 } else 256 } else
254 page = locked_page; 257 page = locked_page;
255 258
256 j = i;
257 head = page_buffers(page); 259 head = page_buffers(page);
258 bh = head; 260 bh = head;
261 pos = beg & mask;
262 for (j = 0; j < pos; ++j)
263 bh = bh->b_this_page;
264 j = 0;
259 do { 265 do {
260 if (likely(bh->b_blocknr == j + oldb && j < count)) { 266 if (buffer_mapped(bh)) {
261 unmap_underlying_metadata(bh->b_bdev, 267 pos = bh->b_blocknr - oldb;
262 bh->b_blocknr); 268 if (pos < count) {
263 bh->b_blocknr = newb + j++; 269 UFSD(" change from %llu to %llu\n",
264 mark_buffer_dirty(bh); 270 (unsigned long long)pos + oldb,
271 (unsigned long long)pos + newb);
272 bh->b_blocknr = newb + pos;
273 unmap_underlying_metadata(bh->b_bdev,
274 bh->b_blocknr);
275 mark_buffer_dirty(bh);
276 ++j;
277 }
265 } 278 }
266 279
267 bh = bh->b_this_page; 280 bh = bh->b_this_page;
268 } while (bh != head); 281 } while (bh != head);
269 282
270 set_page_dirty(page); 283 if (j)
284 set_page_dirty(page);
271 285
272 if (likely(cur_index != index)) 286 if (likely(cur_index != index))
273 ufs_put_locked_page(page); 287 ufs_put_locked_page(page);
@@ -415,14 +429,14 @@ unsigned ufs_new_fragments(struct inode * inode, __fs32 * p, unsigned fragment,
415 } 429 }
416 result = ufs_alloc_fragments (inode, cgno, goal, request, err); 430 result = ufs_alloc_fragments (inode, cgno, goal, request, err);
417 if (result) { 431 if (result) {
432 ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
433 locked_page != NULL);
418 ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, 434 ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp,
419 result, locked_page); 435 result, locked_page);
420 436
421 *p = cpu_to_fs32(sb, result); 437 *p = cpu_to_fs32(sb, result);
422 *err = 0; 438 *err = 0;
423 UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); 439 UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count);
424 ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
425 locked_page != NULL);
426 unlock_super(sb); 440 unlock_super(sb);
427 if (newcount < request) 441 if (newcount < request)
428 ufs_free_fragments (inode, result + newcount, request - newcount); 442 ufs_free_fragments (inode, result + newcount, request - newcount);
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 2fbab0aab688..4295ca91cf85 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -242,7 +242,8 @@ repeat:
242 goal = tmp + uspi->s_fpb; 242 goal = tmp + uspi->s_fpb;
243 tmp = ufs_new_fragments (inode, p, fragment - blockoff, 243 tmp = ufs_new_fragments (inode, p, fragment - blockoff,
244 goal, required + blockoff, 244 goal, required + blockoff,
245 err, locked_page); 245 err,
246 phys != NULL ? locked_page : NULL);
246 } 247 }
247 /* 248 /*
248 * We will extend last allocated block 249 * We will extend last allocated block
@@ -250,7 +251,7 @@ repeat:
250 else if (lastblock == block) { 251 else if (lastblock == block) {
251 tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff), 252 tmp = ufs_new_fragments(inode, p, fragment - (blockoff - lastblockoff),
252 fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff), 253 fs32_to_cpu(sb, *p), required + (blockoff - lastblockoff),
253 err, locked_page); 254 err, phys != NULL ? locked_page : NULL);
254 } else /* (lastblock > block) */ { 255 } else /* (lastblock > block) */ {
255 /* 256 /*
256 * We will allocate new block before last allocated block 257 * We will allocate new block before last allocated block
@@ -261,7 +262,8 @@ repeat:
261 goal = tmp + uspi->s_fpb; 262 goal = tmp + uspi->s_fpb;
262 } 263 }
263 tmp = ufs_new_fragments(inode, p, fragment - blockoff, 264 tmp = ufs_new_fragments(inode, p, fragment - blockoff,
264 goal, uspi->s_fpb, err, locked_page); 265 goal, uspi->s_fpb, err,
266 phys != NULL ? locked_page : NULL);
265 } 267 }
266 if (!tmp) { 268 if (!tmp) {
267 if ((!blockoff && *p) || 269 if ((!blockoff && *p) ||
@@ -438,9 +440,11 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head
438 * it much more readable: 440 * it much more readable:
439 */ 441 */
440#define GET_INODE_DATABLOCK(x) \ 442#define GET_INODE_DATABLOCK(x) \
441 ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new, bh_result->b_page) 443 ufs_inode_getfrag(inode, x, fragment, 1, &err, &phys, &new,\
444 bh_result->b_page)
442#define GET_INODE_PTR(x) \ 445#define GET_INODE_PTR(x) \
443 ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL, NULL) 446 ufs_inode_getfrag(inode, x, fragment, uspi->s_fpb, &err, NULL, NULL,\
447 bh_result->b_page)
444#define GET_INDIRECT_DATABLOCK(x) \ 448#define GET_INDIRECT_DATABLOCK(x) \
445 ufs_inode_getblock(inode, bh, x, fragment, \ 449 ufs_inode_getblock(inode, bh, x, fragment, \
446 &err, &phys, &new, bh_result->b_page) 450 &err, &phys, &new, bh_result->b_page)
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index ea11d04c41a0..0437b0a6fe97 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -109,10 +109,10 @@ static int ufs_trunc_direct (struct inode * inode)
109 tmp = fs32_to_cpu(sb, *p); 109 tmp = fs32_to_cpu(sb, *p);
110 if (!tmp ) 110 if (!tmp )
111 ufs_panic (sb, "ufs_trunc_direct", "internal error"); 111 ufs_panic (sb, "ufs_trunc_direct", "internal error");
112 frag2 -= frag1;
112 frag1 = ufs_fragnum (frag1); 113 frag1 = ufs_fragnum (frag1);
113 frag2 = ufs_fragnum (frag2);
114 114
115 ufs_free_fragments (inode, tmp + frag1, frag2 - frag1); 115 ufs_free_fragments(inode, tmp + frag1, frag2);
116 mark_inode_dirty(inode); 116 mark_inode_dirty(inode);
117 frag_to_free = tmp + frag1; 117 frag_to_free = tmp + frag1;
118 118