aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@austin.ibm.com>2005-06-20 09:44:00 -0400
committerDave Kleikamp <shaggy@austin.ibm.com>2005-06-20 09:44:00 -0400
commitd039ba24f135147f60a13bcaa768189a5b773b6e (patch)
tree444b7596ab8312b5954d15c3135052a7c09c6fbe /fs
parent72e3148a6e987974e3e949c5668e5ca812d7c818 (diff)
parent8b22c249e7de453961e4d253b19fc2a0bdd65d53 (diff)
Merge with /home/shaggy/git/linus-clean/
Diffstat (limited to 'fs')
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/binfmt_flat.c6
-rw-r--r--fs/cifs/CHANGES3
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/file.c2
-rw-r--r--fs/cifs/inode.c34
-rw-r--r--fs/exec.c16
-rw-r--r--fs/jbd/checkpoint.c5
-rw-r--r--fs/mpage.c5
-rw-r--r--fs/namei.c153
-rw-r--r--fs/nfs/dir.c49
-rw-r--r--fs/nfs/file.c42
12 files changed, 201 insertions, 118 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index c374be51b041..f8f6b6b76179 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1125,7 +1125,7 @@ static int dump_write(struct file *file, const void *addr, int nr)
1125 return file->f_op->write(file, addr, nr, &file->f_pos) == nr; 1125 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
1126} 1126}
1127 1127
1128static int dump_seek(struct file *file, off_t off) 1128static int dump_seek(struct file *file, loff_t off)
1129{ 1129{
1130 if (file->f_op->llseek) { 1130 if (file->f_op->llseek) {
1131 if (file->f_op->llseek(file, off, 0) != off) 1131 if (file->f_op->llseek(file, off, 0) != off)
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index f0cd67d9d31b..c8998dc66882 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -520,7 +520,7 @@ static int load_flat_file(struct linux_binprm * bprm,
520 DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); 520 DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n");
521 521
522 down_write(&current->mm->mmap_sem); 522 down_write(&current->mm->mmap_sem);
523 textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0); 523 textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 0);
524 up_write(&current->mm->mmap_sem); 524 up_write(&current->mm->mmap_sem);
525 if (!textpos || textpos >= (unsigned long) -4096) { 525 if (!textpos || textpos >= (unsigned long) -4096) {
526 if (!textpos) 526 if (!textpos)
@@ -532,7 +532,7 @@ static int load_flat_file(struct linux_binprm * bprm,
532 down_write(&current->mm->mmap_sem); 532 down_write(&current->mm->mmap_sem);
533 realdatastart = do_mmap(0, 0, data_len + extra + 533 realdatastart = do_mmap(0, 0, data_len + extra +
534 MAX_SHARED_LIBS * sizeof(unsigned long), 534 MAX_SHARED_LIBS * sizeof(unsigned long),
535 PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0); 535 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
536 up_write(&current->mm->mmap_sem); 536 up_write(&current->mm->mmap_sem);
537 537
538 if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { 538 if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) {
@@ -574,7 +574,7 @@ static int load_flat_file(struct linux_binprm * bprm,
574 down_write(&current->mm->mmap_sem); 574 down_write(&current->mm->mmap_sem);
575 textpos = do_mmap(0, 0, text_len + data_len + extra + 575 textpos = do_mmap(0, 0, text_len + data_len + extra +
576 MAX_SHARED_LIBS * sizeof(unsigned long), 576 MAX_SHARED_LIBS * sizeof(unsigned long),
577 PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0); 577 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
578 up_write(&current->mm->mmap_sem); 578 up_write(&current->mm->mmap_sem);
579 if (!textpos || textpos >= (unsigned long) -4096) { 579 if (!textpos || textpos >= (unsigned long) -4096) {
580 if (!textpos) 580 if (!textpos)
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 95483baab706..dab4774ee7bb 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -6,7 +6,8 @@ kills the cifsd thread (NB: killing the cifs kernel threads is not
6recommended, unmount and rmmod cifs will kill them when they are 6recommended, unmount and rmmod cifs will kill them when they are
7no longer needed). Fix readdir to ASCII servers (ie older servers 7no longer needed). Fix readdir to ASCII servers (ie older servers
8which do not support Unicode) and also require asterik. 8which do not support Unicode) and also require asterik.
9 9Fix out of memory case in which data could be written one page
10off in the page cache.
10 11
11Version 1.33 12Version 1.33
12------------ 13------------
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index d00b3bfe1a52..78af5850c558 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -96,5 +96,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
96extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 96extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
97extern int cifs_ioctl (struct inode * inode, struct file * filep, 97extern int cifs_ioctl (struct inode * inode, struct file * filep,
98 unsigned int command, unsigned long arg); 98 unsigned int command, unsigned long arg);
99#define CIFS_VERSION "1.34" 99#define CIFS_VERSION "1.35"
100#endif /* _CIFSFS_H */ 100#endif /* _CIFSFS_H */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index dde2d251fc3d..30ab70ce5547 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1352,6 +1352,8 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
1352 GFP_KERNEL)) { 1352 GFP_KERNEL)) {
1353 page_cache_release(page); 1353 page_cache_release(page);
1354 cFYI(1, ("Add page cache failed")); 1354 cFYI(1, ("Add page cache failed"));
1355 data += PAGE_CACHE_SIZE;
1356 bytes_read -= PAGE_CACHE_SIZE;
1355 continue; 1357 continue;
1356 } 1358 }
1357 1359
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index b8b78cbb34c9..8d336a900255 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -82,12 +82,12 @@ int cifs_get_inode_info_unix(struct inode **pinode,
82 /* get new inode */ 82 /* get new inode */
83 if (*pinode == NULL) { 83 if (*pinode == NULL) {
84 *pinode = new_inode(sb); 84 *pinode = new_inode(sb);
85 if(*pinode == NULL) 85 if (*pinode == NULL)
86 return -ENOMEM; 86 return -ENOMEM;
87 /* Is an i_ino of zero legal? */ 87 /* Is an i_ino of zero legal? */
88 /* Are there sanity checks we can use to ensure that 88 /* Are there sanity checks we can use to ensure that
89 the server is really filling in that field? */ 89 the server is really filling in that field? */
90 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 90 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
91 (*pinode)->i_ino = 91 (*pinode)->i_ino =
92 (unsigned long)findData.UniqueId; 92 (unsigned long)findData.UniqueId;
93 } /* note ino incremented to unique num in new_inode */ 93 } /* note ino incremented to unique num in new_inode */
@@ -134,7 +134,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
134 inode->i_gid = le64_to_cpu(findData.Gid); 134 inode->i_gid = le64_to_cpu(findData.Gid);
135 inode->i_nlink = le64_to_cpu(findData.Nlinks); 135 inode->i_nlink = le64_to_cpu(findData.Nlinks);
136 136
137 if(is_size_safe_to_change(cifsInfo)) { 137 if (is_size_safe_to_change(cifsInfo)) {
138 /* can not safely change the file size here if the 138 /* can not safely change the file size here if the
139 client is writing to it due to potential races */ 139 client is writing to it due to potential races */
140 140
@@ -162,7 +162,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
162 if (S_ISREG(inode->i_mode)) { 162 if (S_ISREG(inode->i_mode)) {
163 cFYI(1, (" File inode ")); 163 cFYI(1, (" File inode "));
164 inode->i_op = &cifs_file_inode_ops; 164 inode->i_op = &cifs_file_inode_ops;
165 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 165 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
166 inode->i_fop = &cifs_file_direct_ops; 166 inode->i_fop = &cifs_file_direct_ops;
167 else 167 else
168 inode->i_fop = &cifs_file_ops; 168 inode->i_fop = &cifs_file_ops;
@@ -198,17 +198,17 @@ int cifs_get_inode_info(struct inode **pinode,
198 pTcon = cifs_sb->tcon; 198 pTcon = cifs_sb->tcon;
199 cFYI(1,("Getting info on %s ", search_path)); 199 cFYI(1,("Getting info on %s ", search_path));
200 200
201 if((pfindData == NULL) && (*pinode != NULL)) { 201 if ((pfindData == NULL) && (*pinode != NULL)) {
202 if(CIFS_I(*pinode)->clientCanCacheRead) { 202 if (CIFS_I(*pinode)->clientCanCacheRead) {
203 cFYI(1,("No need to revalidate cached inode sizes")); 203 cFYI(1,("No need to revalidate cached inode sizes"));
204 return rc; 204 return rc;
205 } 205 }
206 } 206 }
207 207
208 /* if file info not passed in then get it from server */ 208 /* if file info not passed in then get it from server */
209 if(pfindData == NULL) { 209 if (pfindData == NULL) {
210 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 210 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
211 if(buf == NULL) 211 if (buf == NULL)
212 return -ENOMEM; 212 return -ENOMEM;
213 pfindData = (FILE_ALL_INFO *)buf; 213 pfindData = (FILE_ALL_INFO *)buf;
214 /* could do find first instead but this returns more info */ 214 /* could do find first instead but this returns more info */
@@ -268,7 +268,7 @@ int cifs_get_inode_info(struct inode **pinode,
268 IndexNumber field is not guaranteed unique? */ 268 IndexNumber field is not guaranteed unique? */
269 269
270#ifdef CONFIG_CIFS_EXPERIMENTAL 270#ifdef CONFIG_CIFS_EXPERIMENTAL
271 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){ 271 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){
272 int rc1 = 0; 272 int rc1 = 0;
273 __u64 inode_num; 273 __u64 inode_num;
274 274
@@ -277,7 +277,7 @@ int cifs_get_inode_info(struct inode **pinode,
277 cifs_sb->local_nls, 277 cifs_sb->local_nls,
278 cifs_sb->mnt_cifs_flags & 278 cifs_sb->mnt_cifs_flags &
279 CIFS_MOUNT_MAP_SPECIAL_CHR); 279 CIFS_MOUNT_MAP_SPECIAL_CHR);
280 if(rc1) { 280 if (rc1) {
281 cFYI(1,("GetSrvInodeNum rc %d", rc1)); 281 cFYI(1,("GetSrvInodeNum rc %d", rc1));
282 /* BB EOPNOSUPP disable SERVER_INUM? */ 282 /* BB EOPNOSUPP disable SERVER_INUM? */
283 } else /* do we need cast or hash to ino? */ 283 } else /* do we need cast or hash to ino? */
@@ -355,7 +355,7 @@ int cifs_get_inode_info(struct inode **pinode,
355 if (S_ISREG(inode->i_mode)) { 355 if (S_ISREG(inode->i_mode)) {
356 cFYI(1, (" File inode ")); 356 cFYI(1, (" File inode "));
357 inode->i_op = &cifs_file_inode_ops; 357 inode->i_op = &cifs_file_inode_ops;
358 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 358 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
359 inode->i_fop = &cifs_file_direct_ops; 359 inode->i_fop = &cifs_file_direct_ops;
360 else 360 else
361 inode->i_fop = &cifs_file_ops; 361 inode->i_fop = &cifs_file_ops;
@@ -422,7 +422,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
422 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 422 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
423 423
424 if (!rc) { 424 if (!rc) {
425 if(direntry->d_inode) 425 if (direntry->d_inode)
426 direntry->d_inode->i_nlink--; 426 direntry->d_inode->i_nlink--;
427 } else if (rc == -ENOENT) { 427 } else if (rc == -ENOENT) {
428 d_drop(direntry); 428 d_drop(direntry);
@@ -441,7 +441,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
441 cifs_sb->mnt_cifs_flags & 441 cifs_sb->mnt_cifs_flags &
442 CIFS_MOUNT_MAP_SPECIAL_CHR); 442 CIFS_MOUNT_MAP_SPECIAL_CHR);
443 CIFSSMBClose(xid, pTcon, netfid); 443 CIFSSMBClose(xid, pTcon, netfid);
444 if(direntry->d_inode) 444 if (direntry->d_inode)
445 direntry->d_inode->i_nlink--; 445 direntry->d_inode->i_nlink--;
446 } 446 }
447 } else if (rc == -EACCES) { 447 } else if (rc == -EACCES) {
@@ -496,7 +496,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
496 cifs_sb->mnt_cifs_flags & 496 cifs_sb->mnt_cifs_flags &
497 CIFS_MOUNT_MAP_SPECIAL_CHR); 497 CIFS_MOUNT_MAP_SPECIAL_CHR);
498 if (!rc) { 498 if (!rc) {
499 if(direntry->d_inode) 499 if (direntry->d_inode)
500 direntry->d_inode->i_nlink--; 500 direntry->d_inode->i_nlink--;
501 } else if (rc == -ETXTBSY) { 501 } else if (rc == -ETXTBSY) {
502 int oplock = FALSE; 502 int oplock = FALSE;
@@ -517,14 +517,14 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
517 cifs_sb->mnt_cifs_flags & 517 cifs_sb->mnt_cifs_flags &
518 CIFS_MOUNT_MAP_SPECIAL_CHR); 518 CIFS_MOUNT_MAP_SPECIAL_CHR);
519 CIFSSMBClose(xid, pTcon, netfid); 519 CIFSSMBClose(xid, pTcon, netfid);
520 if(direntry->d_inode) 520 if (direntry->d_inode)
521 direntry->d_inode->i_nlink--; 521 direntry->d_inode->i_nlink--;
522 } 522 }
523 /* BB if rc = -ETXTBUSY goto the rename logic BB */ 523 /* BB if rc = -ETXTBUSY goto the rename logic BB */
524 } 524 }
525 } 525 }
526 } 526 }
527 if(direntry->d_inode) { 527 if (direntry->d_inode) {
528 cifsInode = CIFS_I(direntry->d_inode); 528 cifsInode = CIFS_I(direntry->d_inode);
529 cifsInode->time = 0; /* will force revalidate to get info 529 cifsInode->time = 0; /* will force revalidate to get info
530 when needed */ 530 when needed */
@@ -582,7 +582,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
582 if (direntry->d_inode) 582 if (direntry->d_inode)
583 direntry->d_inode->i_nlink = 2; 583 direntry->d_inode->i_nlink = 2;
584 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) 584 if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
585 if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 585 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
586 CIFSSMBUnixSetPerms(xid, pTcon, full_path, 586 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
587 mode, 587 mode,
588 (__u64)current->euid, 588 (__u64)current->euid,
diff --git a/fs/exec.c b/fs/exec.c
index e56ee2437025..3a4b35a14c0d 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -649,6 +649,7 @@ static inline int de_thread(struct task_struct *tsk)
649 } 649 }
650 sig->group_exit_task = NULL; 650 sig->group_exit_task = NULL;
651 sig->notify_count = 0; 651 sig->notify_count = 0;
652 sig->real_timer.data = (unsigned long)current;
652 spin_unlock_irq(lock); 653 spin_unlock_irq(lock);
653 654
654 /* 655 /*
@@ -675,10 +676,8 @@ static inline int de_thread(struct task_struct *tsk)
675 proc_dentry2 = proc_pid_unhash(leader); 676 proc_dentry2 = proc_pid_unhash(leader);
676 write_lock_irq(&tasklist_lock); 677 write_lock_irq(&tasklist_lock);
677 678
678 if (leader->tgid != current->tgid) 679 BUG_ON(leader->tgid != current->tgid);
679 BUG(); 680 BUG_ON(current->pid == current->tgid);
680 if (current->pid == current->tgid)
681 BUG();
682 /* 681 /*
683 * An exec() starts a new thread group with the 682 * An exec() starts a new thread group with the
684 * TGID of the previous thread group. Rehash the 683 * TGID of the previous thread group. Rehash the
@@ -726,8 +725,7 @@ static inline int de_thread(struct task_struct *tsk)
726 proc_pid_flush(proc_dentry1); 725 proc_pid_flush(proc_dentry1);
727 proc_pid_flush(proc_dentry2); 726 proc_pid_flush(proc_dentry2);
728 727
729 if (exit_state != EXIT_ZOMBIE) 728 BUG_ON(exit_state != EXIT_ZOMBIE);
730 BUG();
731 release_task(leader); 729 release_task(leader);
732 } 730 }
733 731
@@ -772,10 +770,8 @@ no_thread_group:
772 kmem_cache_free(sighand_cachep, oldsighand); 770 kmem_cache_free(sighand_cachep, oldsighand);
773 } 771 }
774 772
775 if (!thread_group_empty(current)) 773 BUG_ON(!thread_group_empty(current));
776 BUG(); 774 BUG_ON(!thread_group_leader(current));
777 if (!thread_group_leader(current))
778 BUG();
779 return 0; 775 return 0;
780} 776}
781 777
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 98d830401c56..5a97e346bd95 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -188,7 +188,6 @@ static int __cleanup_transaction(journal_t *journal, transaction_t *transaction)
188 } else { 188 } else {
189 jbd_unlock_bh_state(bh); 189 jbd_unlock_bh_state(bh);
190 } 190 }
191 jh = next_jh;
192 } while (jh != last_jh); 191 } while (jh != last_jh);
193 192
194 return ret; 193 return ret;
@@ -339,8 +338,10 @@ int log_do_checkpoint(journal_t *journal)
339 } 338 }
340 } while (jh != last_jh && !retry); 339 } while (jh != last_jh && !retry);
341 340
342 if (batch_count) 341 if (batch_count) {
343 __flush_batch(journal, bhs, &batch_count); 342 __flush_batch(journal, bhs, &batch_count);
343 retry = 1;
344 }
344 345
345 /* 346 /*
346 * If someone cleaned up this transaction while we slept, we're 347 * If someone cleaned up this transaction while we slept, we're
diff --git a/fs/mpage.c b/fs/mpage.c
index b92c0e64aefa..bb9aebe93862 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -79,8 +79,11 @@ static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err)
79 if (--bvec >= bio->bi_io_vec) 79 if (--bvec >= bio->bi_io_vec)
80 prefetchw(&bvec->bv_page->flags); 80 prefetchw(&bvec->bv_page->flags);
81 81
82 if (!uptodate) 82 if (!uptodate){
83 SetPageError(page); 83 SetPageError(page);
84 if (page->mapping)
85 set_bit(AS_EIO, &page->mapping->flags);
86 }
84 end_page_writeback(page); 87 end_page_writeback(page);
85 } while (bvec >= bio->bi_io_vec); 88 } while (bvec >= bio->bi_io_vec);
86 bio_put(bio); 89 bio_put(bio);
diff --git a/fs/namei.c b/fs/namei.c
index dd78f01b6de8..a7f7f44119b3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -493,12 +493,21 @@ fail:
493 return PTR_ERR(link); 493 return PTR_ERR(link);
494} 494}
495 495
496static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) 496struct path {
497 struct vfsmount *mnt;
498 struct dentry *dentry;
499};
500
501static inline int __do_follow_link(struct path *path, struct nameidata *nd)
497{ 502{
498 int error; 503 int error;
504 struct dentry *dentry = path->dentry;
499 505
500 touch_atime(nd->mnt, dentry); 506 touch_atime(path->mnt, dentry);
501 nd_set_link(nd, NULL); 507 nd_set_link(nd, NULL);
508
509 if (path->mnt == nd->mnt)
510 mntget(path->mnt);
502 error = dentry->d_inode->i_op->follow_link(dentry, nd); 511 error = dentry->d_inode->i_op->follow_link(dentry, nd);
503 if (!error) { 512 if (!error) {
504 char *s = nd_get_link(nd); 513 char *s = nd_get_link(nd);
@@ -507,6 +516,8 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
507 if (dentry->d_inode->i_op->put_link) 516 if (dentry->d_inode->i_op->put_link)
508 dentry->d_inode->i_op->put_link(dentry, nd); 517 dentry->d_inode->i_op->put_link(dentry, nd);
509 } 518 }
519 dput(dentry);
520 mntput(path->mnt);
510 521
511 return error; 522 return error;
512} 523}
@@ -518,7 +529,7 @@ static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd)
518 * Without that kind of total limit, nasty chains of consecutive 529 * Without that kind of total limit, nasty chains of consecutive
519 * symlinks can cause almost arbitrarily long lookups. 530 * symlinks can cause almost arbitrarily long lookups.
520 */ 531 */
521static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) 532static inline int do_follow_link(struct path *path, struct nameidata *nd)
522{ 533{
523 int err = -ELOOP; 534 int err = -ELOOP;
524 if (current->link_count >= MAX_NESTED_LINKS) 535 if (current->link_count >= MAX_NESTED_LINKS)
@@ -527,17 +538,20 @@ static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd)
527 goto loop; 538 goto loop;
528 BUG_ON(nd->depth >= MAX_NESTED_LINKS); 539 BUG_ON(nd->depth >= MAX_NESTED_LINKS);
529 cond_resched(); 540 cond_resched();
530 err = security_inode_follow_link(dentry, nd); 541 err = security_inode_follow_link(path->dentry, nd);
531 if (err) 542 if (err)
532 goto loop; 543 goto loop;
533 current->link_count++; 544 current->link_count++;
534 current->total_link_count++; 545 current->total_link_count++;
535 nd->depth++; 546 nd->depth++;
536 err = __do_follow_link(dentry, nd); 547 err = __do_follow_link(path, nd);
537 current->link_count--; 548 current->link_count--;
538 nd->depth--; 549 nd->depth--;
539 return err; 550 return err;
540loop: 551loop:
552 dput(path->dentry);
553 if (path->mnt != nd->mnt)
554 mntput(path->mnt);
541 path_release(nd); 555 path_release(nd);
542 return err; 556 return err;
543} 557}
@@ -565,87 +579,91 @@ int follow_up(struct vfsmount **mnt, struct dentry **dentry)
565/* no need for dcache_lock, as serialization is taken care in 579/* no need for dcache_lock, as serialization is taken care in
566 * namespace.c 580 * namespace.c
567 */ 581 */
568static int follow_mount(struct vfsmount **mnt, struct dentry **dentry) 582static int __follow_mount(struct path *path)
569{ 583{
570 int res = 0; 584 int res = 0;
585 while (d_mountpoint(path->dentry)) {
586 struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry);
587 if (!mounted)
588 break;
589 dput(path->dentry);
590 if (res)
591 mntput(path->mnt);
592 path->mnt = mounted;
593 path->dentry = dget(mounted->mnt_root);
594 res = 1;
595 }
596 return res;
597}
598
599static void follow_mount(struct vfsmount **mnt, struct dentry **dentry)
600{
571 while (d_mountpoint(*dentry)) { 601 while (d_mountpoint(*dentry)) {
572 struct vfsmount *mounted = lookup_mnt(*mnt, *dentry); 602 struct vfsmount *mounted = lookup_mnt(*mnt, *dentry);
573 if (!mounted) 603 if (!mounted)
574 break; 604 break;
605 dput(*dentry);
575 mntput(*mnt); 606 mntput(*mnt);
576 *mnt = mounted; 607 *mnt = mounted;
577 dput(*dentry);
578 *dentry = dget(mounted->mnt_root); 608 *dentry = dget(mounted->mnt_root);
579 res = 1;
580 } 609 }
581 return res;
582} 610}
583 611
584/* no need for dcache_lock, as serialization is taken care in 612/* no need for dcache_lock, as serialization is taken care in
585 * namespace.c 613 * namespace.c
586 */ 614 */
587static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) 615int follow_down(struct vfsmount **mnt, struct dentry **dentry)
588{ 616{
589 struct vfsmount *mounted; 617 struct vfsmount *mounted;
590 618
591 mounted = lookup_mnt(*mnt, *dentry); 619 mounted = lookup_mnt(*mnt, *dentry);
592 if (mounted) { 620 if (mounted) {
621 dput(*dentry);
593 mntput(*mnt); 622 mntput(*mnt);
594 *mnt = mounted; 623 *mnt = mounted;
595 dput(*dentry);
596 *dentry = dget(mounted->mnt_root); 624 *dentry = dget(mounted->mnt_root);
597 return 1; 625 return 1;
598 } 626 }
599 return 0; 627 return 0;
600} 628}
601 629
602int follow_down(struct vfsmount **mnt, struct dentry **dentry) 630static inline void follow_dotdot(struct nameidata *nd)
603{
604 return __follow_down(mnt,dentry);
605}
606
607static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry)
608{ 631{
609 while(1) { 632 while(1) {
610 struct vfsmount *parent; 633 struct vfsmount *parent;
611 struct dentry *old = *dentry; 634 struct dentry *old = nd->dentry;
612 635
613 read_lock(&current->fs->lock); 636 read_lock(&current->fs->lock);
614 if (*dentry == current->fs->root && 637 if (nd->dentry == current->fs->root &&
615 *mnt == current->fs->rootmnt) { 638 nd->mnt == current->fs->rootmnt) {
616 read_unlock(&current->fs->lock); 639 read_unlock(&current->fs->lock);
617 break; 640 break;
618 } 641 }
619 read_unlock(&current->fs->lock); 642 read_unlock(&current->fs->lock);
620 spin_lock(&dcache_lock); 643 spin_lock(&dcache_lock);
621 if (*dentry != (*mnt)->mnt_root) { 644 if (nd->dentry != nd->mnt->mnt_root) {
622 *dentry = dget((*dentry)->d_parent); 645 nd->dentry = dget(nd->dentry->d_parent);
623 spin_unlock(&dcache_lock); 646 spin_unlock(&dcache_lock);
624 dput(old); 647 dput(old);
625 break; 648 break;
626 } 649 }
627 spin_unlock(&dcache_lock); 650 spin_unlock(&dcache_lock);
628 spin_lock(&vfsmount_lock); 651 spin_lock(&vfsmount_lock);
629 parent = (*mnt)->mnt_parent; 652 parent = nd->mnt->mnt_parent;
630 if (parent == *mnt) { 653 if (parent == nd->mnt) {
631 spin_unlock(&vfsmount_lock); 654 spin_unlock(&vfsmount_lock);
632 break; 655 break;
633 } 656 }
634 mntget(parent); 657 mntget(parent);
635 *dentry = dget((*mnt)->mnt_mountpoint); 658 nd->dentry = dget(nd->mnt->mnt_mountpoint);
636 spin_unlock(&vfsmount_lock); 659 spin_unlock(&vfsmount_lock);
637 dput(old); 660 dput(old);
638 mntput(*mnt); 661 mntput(nd->mnt);
639 *mnt = parent; 662 nd->mnt = parent;
640 } 663 }
641 follow_mount(mnt, dentry); 664 follow_mount(&nd->mnt, &nd->dentry);
642} 665}
643 666
644struct path {
645 struct vfsmount *mnt;
646 struct dentry *dentry;
647};
648
649/* 667/*
650 * It's more convoluted than I'd like it to be, but... it's still fairly 668 * It's more convoluted than I'd like it to be, but... it's still fairly
651 * small and for now I'd prefer to have fast path as straight as possible. 669 * small and for now I'd prefer to have fast path as straight as possible.
@@ -664,6 +682,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
664done: 682done:
665 path->mnt = mnt; 683 path->mnt = mnt;
666 path->dentry = dentry; 684 path->dentry = dentry;
685 __follow_mount(path);
667 return 0; 686 return 0;
668 687
669need_lookup: 688need_lookup:
@@ -751,7 +770,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
751 case 2: 770 case 2:
752 if (this.name[1] != '.') 771 if (this.name[1] != '.')
753 break; 772 break;
754 follow_dotdot(&nd->mnt, &nd->dentry); 773 follow_dotdot(nd);
755 inode = nd->dentry->d_inode; 774 inode = nd->dentry->d_inode;
756 /* fallthrough */ 775 /* fallthrough */
757 case 1: 776 case 1:
@@ -771,8 +790,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
771 err = do_lookup(nd, &this, &next); 790 err = do_lookup(nd, &this, &next);
772 if (err) 791 if (err)
773 break; 792 break;
774 /* Check mountpoints.. */
775 follow_mount(&next.mnt, &next.dentry);
776 793
777 err = -ENOENT; 794 err = -ENOENT;
778 inode = next.dentry->d_inode; 795 inode = next.dentry->d_inode;
@@ -783,10 +800,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
783 goto out_dput; 800 goto out_dput;
784 801
785 if (inode->i_op->follow_link) { 802 if (inode->i_op->follow_link) {
786 mntget(next.mnt); 803 err = do_follow_link(&next, nd);
787 err = do_follow_link(next.dentry, nd);
788 dput(next.dentry);
789 mntput(next.mnt);
790 if (err) 804 if (err)
791 goto return_err; 805 goto return_err;
792 err = -ENOENT; 806 err = -ENOENT;
@@ -798,6 +812,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
798 break; 812 break;
799 } else { 813 } else {
800 dput(nd->dentry); 814 dput(nd->dentry);
815 if (nd->mnt != next.mnt)
816 mntput(nd->mnt);
801 nd->mnt = next.mnt; 817 nd->mnt = next.mnt;
802 nd->dentry = next.dentry; 818 nd->dentry = next.dentry;
803 } 819 }
@@ -819,7 +835,7 @@ last_component:
819 case 2: 835 case 2:
820 if (this.name[1] != '.') 836 if (this.name[1] != '.')
821 break; 837 break;
822 follow_dotdot(&nd->mnt, &nd->dentry); 838 follow_dotdot(nd);
823 inode = nd->dentry->d_inode; 839 inode = nd->dentry->d_inode;
824 /* fallthrough */ 840 /* fallthrough */
825 case 1: 841 case 1:
@@ -833,19 +849,17 @@ last_component:
833 err = do_lookup(nd, &this, &next); 849 err = do_lookup(nd, &this, &next);
834 if (err) 850 if (err)
835 break; 851 break;
836 follow_mount(&next.mnt, &next.dentry);
837 inode = next.dentry->d_inode; 852 inode = next.dentry->d_inode;
838 if ((lookup_flags & LOOKUP_FOLLOW) 853 if ((lookup_flags & LOOKUP_FOLLOW)
839 && inode && inode->i_op && inode->i_op->follow_link) { 854 && inode && inode->i_op && inode->i_op->follow_link) {
840 mntget(next.mnt); 855 err = do_follow_link(&next, nd);
841 err = do_follow_link(next.dentry, nd);
842 dput(next.dentry);
843 mntput(next.mnt);
844 if (err) 856 if (err)
845 goto return_err; 857 goto return_err;
846 inode = nd->dentry->d_inode; 858 inode = nd->dentry->d_inode;
847 } else { 859 } else {
848 dput(nd->dentry); 860 dput(nd->dentry);
861 if (nd->mnt != next.mnt)
862 mntput(nd->mnt);
849 nd->mnt = next.mnt; 863 nd->mnt = next.mnt;
850 nd->dentry = next.dentry; 864 nd->dentry = next.dentry;
851 } 865 }
@@ -885,6 +899,8 @@ return_base:
885 return 0; 899 return 0;
886out_dput: 900out_dput:
887 dput(next.dentry); 901 dput(next.dentry);
902 if (nd->mnt != next.mnt)
903 mntput(next.mnt);
888 break; 904 break;
889 } 905 }
890 path_release(nd); 906 path_release(nd);
@@ -1398,7 +1414,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1398int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) 1414int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1399{ 1415{
1400 int acc_mode, error = 0; 1416 int acc_mode, error = 0;
1401 struct dentry *dentry; 1417 struct path path;
1402 struct dentry *dir; 1418 struct dentry *dir;
1403 int count = 0; 1419 int count = 0;
1404 1420
@@ -1442,23 +1458,24 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1442 dir = nd->dentry; 1458 dir = nd->dentry;
1443 nd->flags &= ~LOOKUP_PARENT; 1459 nd->flags &= ~LOOKUP_PARENT;
1444 down(&dir->d_inode->i_sem); 1460 down(&dir->d_inode->i_sem);
1445 dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1461 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
1462 path.mnt = nd->mnt;
1446 1463
1447do_last: 1464do_last:
1448 error = PTR_ERR(dentry); 1465 error = PTR_ERR(path.dentry);
1449 if (IS_ERR(dentry)) { 1466 if (IS_ERR(path.dentry)) {
1450 up(&dir->d_inode->i_sem); 1467 up(&dir->d_inode->i_sem);
1451 goto exit; 1468 goto exit;
1452 } 1469 }
1453 1470
1454 /* Negative dentry, just create the file */ 1471 /* Negative dentry, just create the file */
1455 if (!dentry->d_inode) { 1472 if (!path.dentry->d_inode) {
1456 if (!IS_POSIXACL(dir->d_inode)) 1473 if (!IS_POSIXACL(dir->d_inode))
1457 mode &= ~current->fs->umask; 1474 mode &= ~current->fs->umask;
1458 error = vfs_create(dir->d_inode, dentry, mode, nd); 1475 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
1459 up(&dir->d_inode->i_sem); 1476 up(&dir->d_inode->i_sem);
1460 dput(nd->dentry); 1477 dput(nd->dentry);
1461 nd->dentry = dentry; 1478 nd->dentry = path.dentry;
1462 if (error) 1479 if (error)
1463 goto exit; 1480 goto exit;
1464 /* Don't check for write permission, don't truncate */ 1481 /* Don't check for write permission, don't truncate */
@@ -1476,22 +1493,24 @@ do_last:
1476 if (flag & O_EXCL) 1493 if (flag & O_EXCL)
1477 goto exit_dput; 1494 goto exit_dput;
1478 1495
1479 if (d_mountpoint(dentry)) { 1496 if (__follow_mount(&path)) {
1480 error = -ELOOP; 1497 error = -ELOOP;
1481 if (flag & O_NOFOLLOW) 1498 if (flag & O_NOFOLLOW)
1482 goto exit_dput; 1499 goto exit_dput;
1483 while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry));
1484 } 1500 }
1485 error = -ENOENT; 1501 error = -ENOENT;
1486 if (!dentry->d_inode) 1502 if (!path.dentry->d_inode)
1487 goto exit_dput; 1503 goto exit_dput;
1488 if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) 1504 if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link)
1489 goto do_link; 1505 goto do_link;
1490 1506
1491 dput(nd->dentry); 1507 dput(nd->dentry);
1492 nd->dentry = dentry; 1508 nd->dentry = path.dentry;
1509 if (nd->mnt != path.mnt)
1510 mntput(nd->mnt);
1511 nd->mnt = path.mnt;
1493 error = -EISDIR; 1512 error = -EISDIR;
1494 if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) 1513 if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode))
1495 goto exit; 1514 goto exit;
1496ok: 1515ok:
1497 error = may_open(nd, acc_mode, flag); 1516 error = may_open(nd, acc_mode, flag);
@@ -1500,7 +1519,9 @@ ok:
1500 return 0; 1519 return 0;
1501 1520
1502exit_dput: 1521exit_dput:
1503 dput(dentry); 1522 dput(path.dentry);
1523 if (nd->mnt != path.mnt)
1524 mntput(path.mnt);
1504exit: 1525exit:
1505 path_release(nd); 1526 path_release(nd);
1506 return error; 1527 return error;
@@ -1520,18 +1541,15 @@ do_link:
1520 * are done. Procfs-like symlinks just set LAST_BIND. 1541 * are done. Procfs-like symlinks just set LAST_BIND.
1521 */ 1542 */
1522 nd->flags |= LOOKUP_PARENT; 1543 nd->flags |= LOOKUP_PARENT;
1523 error = security_inode_follow_link(dentry, nd); 1544 error = security_inode_follow_link(path.dentry, nd);
1524 if (error) 1545 if (error)
1525 goto exit_dput; 1546 goto exit_dput;
1526 error = __do_follow_link(dentry, nd); 1547 error = __do_follow_link(&path, nd);
1527 dput(dentry);
1528 if (error) 1548 if (error)
1529 return error; 1549 return error;
1530 nd->flags &= ~LOOKUP_PARENT; 1550 nd->flags &= ~LOOKUP_PARENT;
1531 if (nd->last_type == LAST_BIND) { 1551 if (nd->last_type == LAST_BIND)
1532 dentry = nd->dentry;
1533 goto ok; 1552 goto ok;
1534 }
1535 error = -EISDIR; 1553 error = -EISDIR;
1536 if (nd->last_type != LAST_NORM) 1554 if (nd->last_type != LAST_NORM)
1537 goto exit; 1555 goto exit;
@@ -1546,7 +1564,8 @@ do_link:
1546 } 1564 }
1547 dir = nd->dentry; 1565 dir = nd->dentry;
1548 down(&dir->d_inode->i_sem); 1566 down(&dir->d_inode->i_sem);
1549 dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1567 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd);
1568 path.mnt = nd->mnt;
1550 putname(nd->last.name); 1569 putname(nd->last.name);
1551 goto do_last; 1570 goto do_last;
1552} 1571}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 73f96acd5d37..ff6155f5e8d9 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -528,19 +528,39 @@ static inline void nfs_renew_times(struct dentry * dentry)
528 dentry->d_time = jiffies; 528 dentry->d_time = jiffies;
529} 529}
530 530
531/*
532 * Return the intent data that applies to this particular path component
533 *
534 * Note that the current set of intents only apply to the very last
535 * component of the path.
536 * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT.
537 */
538static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask)
539{
540 if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT))
541 return 0;
542 return nd->flags & mask;
543}
544
545/*
546 * Inode and filehandle revalidation for lookups.
547 *
548 * We force revalidation in the cases where the VFS sets LOOKUP_REVAL,
549 * or if the intent information indicates that we're about to open this
550 * particular file and the "nocto" mount flag is not set.
551 *
552 */
531static inline 553static inline
532int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) 554int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
533{ 555{
534 struct nfs_server *server = NFS_SERVER(inode); 556 struct nfs_server *server = NFS_SERVER(inode);
535 557
536 if (nd != NULL) { 558 if (nd != NULL) {
537 int ndflags = nd->flags;
538 /* VFS wants an on-the-wire revalidation */ 559 /* VFS wants an on-the-wire revalidation */
539 if (ndflags & LOOKUP_REVAL) 560 if (nd->flags & LOOKUP_REVAL)
540 goto out_force; 561 goto out_force;
541 /* This is an open(2) */ 562 /* This is an open(2) */
542 if ((ndflags & LOOKUP_OPEN) && 563 if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 &&
543 !(ndflags & LOOKUP_CONTINUE) &&
544 !(server->flags & NFS_MOUNT_NOCTO)) 564 !(server->flags & NFS_MOUNT_NOCTO))
545 goto out_force; 565 goto out_force;
546 } 566 }
@@ -560,12 +580,8 @@ static inline
560int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, 580int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
561 struct nameidata *nd) 581 struct nameidata *nd)
562{ 582{
563 int ndflags = 0;
564
565 if (nd)
566 ndflags = nd->flags;
567 /* Don't revalidate a negative dentry if we're creating a new file */ 583 /* Don't revalidate a negative dentry if we're creating a new file */
568 if ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE)) 584 if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0)
569 return 0; 585 return 0;
570 return !nfs_check_verifier(dir, dentry); 586 return !nfs_check_verifier(dir, dentry);
571} 587}
@@ -700,12 +716,16 @@ struct dentry_operations nfs_dentry_operations = {
700 .d_iput = nfs_dentry_iput, 716 .d_iput = nfs_dentry_iput,
701}; 717};
702 718
719/*
720 * Use intent information to check whether or not we're going to do
721 * an O_EXCL create using this path component.
722 */
703static inline 723static inline
704int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) 724int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
705{ 725{
706 if (NFS_PROTO(dir)->version == 2) 726 if (NFS_PROTO(dir)->version == 2)
707 return 0; 727 return 0;
708 if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE)) 728 if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
709 return 0; 729 return 0;
710 return (nd->intent.open.flags & O_EXCL) != 0; 730 return (nd->intent.open.flags & O_EXCL) != 0;
711} 731}
@@ -772,12 +792,13 @@ struct dentry_operations nfs4_dentry_operations = {
772 .d_iput = nfs_dentry_iput, 792 .d_iput = nfs_dentry_iput,
773}; 793};
774 794
795/*
796 * Use intent information to determine whether we need to substitute
797 * the NFSv4-style stateful OPEN for the LOOKUP call
798 */
775static int is_atomic_open(struct inode *dir, struct nameidata *nd) 799static int is_atomic_open(struct inode *dir, struct nameidata *nd)
776{ 800{
777 if (!nd) 801 if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0)
778 return 0;
779 /* Check that we are indeed trying to open this file */
780 if ((nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_OPEN))
781 return 0; 802 return 0;
782 /* NFS does not (yet) have a stateful open for directories */ 803 /* NFS does not (yet) have a stateful open for directories */
783 if (nd->flags & LOOKUP_DIRECTORY) 804 if (nd->flags & LOOKUP_DIRECTORY)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f06eee6dcff5..55c907592490 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -37,6 +37,7 @@
37 37
38static int nfs_file_open(struct inode *, struct file *); 38static int nfs_file_open(struct inode *, struct file *);
39static int nfs_file_release(struct inode *, struct file *); 39static int nfs_file_release(struct inode *, struct file *);
40static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin);
40static int nfs_file_mmap(struct file *, struct vm_area_struct *); 41static int nfs_file_mmap(struct file *, struct vm_area_struct *);
41static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); 42static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
42static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); 43static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t);
@@ -48,7 +49,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl);
48static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); 49static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl);
49 50
50struct file_operations nfs_file_operations = { 51struct file_operations nfs_file_operations = {
51 .llseek = remote_llseek, 52 .llseek = nfs_file_llseek,
52 .read = do_sync_read, 53 .read = do_sync_read,
53 .write = do_sync_write, 54 .write = do_sync_write,
54 .aio_read = nfs_file_read, 55 .aio_read = nfs_file_read,
@@ -114,6 +115,45 @@ nfs_file_release(struct inode *inode, struct file *filp)
114 return NFS_PROTO(inode)->file_release(inode, filp); 115 return NFS_PROTO(inode)->file_release(inode, filp);
115} 116}
116 117
118/**
119 * nfs_revalidate_size - Revalidate the file size
120 * @inode - pointer to inode struct
121 * @file - pointer to struct file
122 *
123 * Revalidates the file length. This is basically a wrapper around
124 * nfs_revalidate_inode() that takes into account the fact that we may
125 * have cached writes (in which case we don't care about the server's
126 * idea of what the file length is), or O_DIRECT (in which case we
127 * shouldn't trust the cache).
128 */
129static int nfs_revalidate_file_size(struct inode *inode, struct file *filp)
130{
131 struct nfs_server *server = NFS_SERVER(inode);
132 struct nfs_inode *nfsi = NFS_I(inode);
133
134 if (server->flags & NFS_MOUNT_NOAC)
135 goto force_reval;
136 if (filp->f_flags & O_DIRECT)
137 goto force_reval;
138 if (nfsi->npages != 0)
139 return 0;
140 return nfs_revalidate_inode(server, inode);
141force_reval:
142 return __nfs_revalidate_inode(server, inode);
143}
144
145static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
146{
147 /* origin == SEEK_END => we must revalidate the cached file length */
148 if (origin == 2) {
149 struct inode *inode = filp->f_mapping->host;
150 int retval = nfs_revalidate_file_size(inode, filp);
151 if (retval < 0)
152 return (loff_t)retval;
153 }
154 return remote_llseek(filp, offset, origin);
155}
156
117/* 157/*
118 * Flush all dirty pages, and check for write errors. 158 * Flush all dirty pages, and check for write errors.
119 * 159 *